diff --git a/src/main/java/com/odde/tdd/BudgetCalculation.java b/src/main/java/com/odde/tdd/BudgetCalculation.java new file mode 100644 index 0000000..83186a9 --- /dev/null +++ b/src/main/java/com/odde/tdd/BudgetCalculation.java @@ -0,0 +1,65 @@ +package com.odde.tdd; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.time.temporal.ChronoUnit; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class BudgetCalculation { + + private final BudgetRepo budgetRepo; + + public BudgetCalculation(BudgetRepo budgetRepo) { + this.budgetRepo = budgetRepo; + } + + private long calculateOneMonth(Budget budget, int startDay, int endDay) { + int totalDays = endDay - startDay + 1; + int monthDays = budget.getMonth().lengthOfMonth(); + if (totalDays == monthDays) { + return budget.getAmount(); + } + return totalDays * budget.getAmount() / monthDays; + } + + public long calculate(LocalDate startTime, LocalDate endTime) { + if(startTime.isAfter(endTime)) { + throw new IllegalArgumentException("startTime should be before than endTime."); + } + long totalBudget = 0; + YearMonth startMonth = YearMonth.of(startTime.getYear(), startTime.getMonth()); + YearMonth endMonth = YearMonth.of(endTime.getYear(), endTime.getMonth()); + int startDay = startTime.getDayOfMonth(); + int endDay = endTime.getDayOfMonth(); + List budgetList = budgetRepo.findAll(); + Map budgetMap = budgetList.stream().collect(Collectors.toMap(Budget::getMonth, Function.identity())); + for (int i = 0; !startMonth.isAfter(endMonth); ++i) { + if (i > 0) { + startTime = startTime.plus(1, ChronoUnit.MONTHS); + startMonth = YearMonth.of(startTime.getYear(), startTime.getMonth()); + } + Budget budget = budgetMap.get(startMonth); + if(budget == null) { + startDay = 1; + System.out.println("WARNING: No budget for "+ startMonth + " so that the month's budget is 0"); + continue; + } + if(i == 0 || startMonth.equals(endMonth)) { + // first month or end month + if (startMonth.isBefore(endMonth)) { + totalBudget += calculateOneMonth(budget, startDay, budget.getMonth().lengthOfMonth()); + startDay = 1; + } else if (startMonth.equals(endMonth)) { + totalBudget += calculateOneMonth(budget, startDay, endDay); + break; + } + } else { + totalBudget += budget.getAmount(); + } + } + return totalBudget; + } +} diff --git a/src/main/java/com/odde/tdd/FizzBuzz.java b/src/main/java/com/odde/tdd/FizzBuzz.java new file mode 100644 index 0000000..cee982d --- /dev/null +++ b/src/main/java/com/odde/tdd/FizzBuzz.java @@ -0,0 +1,21 @@ +package com.odde.tdd; + +public class FizzBuzz { + public static String fizzBuzz(int n) { +// if(n <= 0) { +// return ""; +// } + String nStr = String.valueOf(n); + StringBuilder sb = new StringBuilder(); + if((n % 3 == 0) || nStr.contains("3")) { + sb.append("Fizz"); + } + if(n % 5 == 0 || nStr.contains("5")) { + sb.append("Buzz"); + } + if(sb.length() == 0) { + sb.append(n); + } + return sb.toString(); + } +} diff --git a/src/main/java/com/odde/tdd/PrimaryFactorDecompose.java b/src/main/java/com/odde/tdd/PrimaryFactorDecompose.java new file mode 100644 index 0000000..0c94ce6 --- /dev/null +++ b/src/main/java/com/odde/tdd/PrimaryFactorDecompose.java @@ -0,0 +1,33 @@ +package com.odde.tdd; + +import java.util.ArrayList; +import java.util.List; + +public class PrimaryFactorDecompose { + + public static List decompose_fast(long n) { + List factors = new ArrayList<>(); + long m = (long)(Math.sqrt(n)); + for (long i = 2; i <= m && i <= n; ++i) { + while(n % i == 0) { + factors.add(i); + n = n / i; + } + } + if(n > 1) { + factors.add(n); + } + return factors; + } + + public static List decompose(long n) { + List factors = new ArrayList<>(); + for(long i=2; n>1; ++i) { + for(; n % i == 0; n = n / i) { + factors.add(i); + } + } + return factors; + } + +} diff --git a/src/test/java/com/odde/tdd/BudgetCalculationTest.java b/src/test/java/com/odde/tdd/BudgetCalculationTest.java new file mode 100644 index 0000000..2e07680 --- /dev/null +++ b/src/test/java/com/odde/tdd/BudgetCalculationTest.java @@ -0,0 +1,88 @@ +package com.odde.tdd; + +import org.junit.Test; + +import java.time.LocalDate; +import java.time.YearMonth; +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class BudgetCalculationTest { + private BudgetRepo repo = mock(BudgetRepo.class); + private BudgetCalculation budgetCalculation = new BudgetCalculation(repo);; + + @Test + public void calculate_one_day_normal_month() { + LocalDate startTime = LocalDate.parse("2018-11-02"); + when(repo.findAll()).thenReturn(Arrays.asList(new Budget(YearMonth.of(2018, 11), 300))); + assertEquals(10, budgetCalculation.calculate(startTime, startTime)); + } + + @Test + public void calculate_one_day_leap_month() { + LocalDate startTime = LocalDate.parse("2018-10-02"); + when(repo.findAll()).thenReturn(Arrays.asList(new Budget(YearMonth.of(2018, 10), 310))); + assertEquals(10, budgetCalculation.calculate(startTime, startTime)); + } + + @Test + public void calculate_one_month() { + LocalDate startTime = LocalDate.parse("2018-10-01"); + LocalDate endTime = LocalDate.parse("2018-10-31"); + when(repo.findAll()).thenReturn(Arrays.asList(new Budget(YearMonth.of(2018, 10), 310))); + assertEquals(310, budgetCalculation.calculate(startTime, endTime)); + } + + @Test + public void calculate_two_days_normal_month() { + LocalDate startTime = LocalDate.parse("2018-11-02"); + LocalDate endTime = LocalDate.parse("2018-11-03"); + when(repo.findAll()).thenReturn(Arrays.asList(new Budget(YearMonth.of(2018, 11), 300))); + assertEquals(20, budgetCalculation.calculate(startTime, endTime)); + } + + @Test + public void calculate_two_months() { + LocalDate startTime = LocalDate.parse("2018-11-29"); + LocalDate endTime = LocalDate.parse("2018-12-03"); + when(repo.findAll()).thenReturn(Arrays.asList( + new Budget(YearMonth.of(2018, 11), 300) + , new Budget(YearMonth.of(2018, 12), 310) + )); + assertEquals(50, budgetCalculation.calculate(startTime, endTime)); + } + + @Test + public void calculate_two_years() { + LocalDate startTime = LocalDate.parse("2018-11-29"); + LocalDate endTime = LocalDate.parse("2019-01-03"); + when(repo.findAll()).thenReturn(Arrays.asList( + new Budget(YearMonth.of(2018, 11), 300) + , new Budget(YearMonth.of(2018, 12), 310) + , new Budget(YearMonth.of(2019, 1), 310) + )); + assertEquals(360, budgetCalculation.calculate(startTime, endTime)); + } + + @Test + public void calculate_two_years_missing_one_month_and_disorder() { + LocalDate startTime = LocalDate.parse("2018-11-29"); + LocalDate endTime = LocalDate.parse("2019-01-03"); + when(repo.findAll()).thenReturn(Arrays.asList( + new Budget(YearMonth.of(2019, 1), 310) + , new Budget(YearMonth.of(2018, 12), 310) + )); + assertEquals(340, budgetCalculation.calculate(startTime, endTime)); + } + + @Test(expected = IllegalArgumentException.class) + public void calculate_argument_error() { + LocalDate startTime = LocalDate.parse("2018-11-02"); + LocalDate endtime = LocalDate.parse("2018-10-01"); + budgetCalculation.calculate(startTime, endtime); + } + +} \ No newline at end of file diff --git a/src/test/java/com/odde/tdd/FizzBuzzTest.java b/src/test/java/com/odde/tdd/FizzBuzzTest.java new file mode 100644 index 0000000..44a3395 --- /dev/null +++ b/src/test/java/com/odde/tdd/FizzBuzzTest.java @@ -0,0 +1,41 @@ +package com.odde.tdd; + +import junit.framework.TestCase; +import org.junit.Assert; +import org.junit.Test; + +public class FizzBuzzTest extends TestCase { + @Test + public void testFizzBuzz3() { + Assert.assertEquals("Fizz", FizzBuzz.fizzBuzz(-3)); + Assert.assertEquals("Fizz", FizzBuzz.fizzBuzz(3)); + Assert.assertEquals("Fizz", FizzBuzz.fizzBuzz(9)); + Assert.assertEquals("Fizz", FizzBuzz.fizzBuzz(13)); + Assert.assertEquals("Fizz", FizzBuzz.fizzBuzz(33)); + } + + @Test + public void testFizzBuzz5() { + Assert.assertEquals("Buzz", FizzBuzz.fizzBuzz(5)); + Assert.assertEquals("Buzz", FizzBuzz.fizzBuzz(20)); + Assert.assertEquals("Buzz", FizzBuzz.fizzBuzz(151)); + } + + @Test + public void testFizzBuzz3And5() { + Assert.assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(0)); + Assert.assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(15)); + Assert.assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(60)); + Assert.assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(35)); + Assert.assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(45)); + Assert.assertEquals("FizzBuzz", FizzBuzz.fizzBuzz(51)); + } + + @Test + public void testFizzBuzzNumber() { + Assert.assertEquals("2", FizzBuzz.fizzBuzz(2)); + Assert.assertEquals("8", FizzBuzz.fizzBuzz(8)); + Assert.assertEquals("-8", FizzBuzz.fizzBuzz(-8)); + } + +} \ No newline at end of file diff --git a/src/test/java/com/odde/tdd/PrimaryFactorDecomposeTest.java b/src/test/java/com/odde/tdd/PrimaryFactorDecomposeTest.java new file mode 100644 index 0000000..63341ce --- /dev/null +++ b/src/test/java/com/odde/tdd/PrimaryFactorDecomposeTest.java @@ -0,0 +1,59 @@ +package com.odde.tdd; + +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class PrimaryFactorDecomposeTest { + + @Test + public void test_1() { + Assert.assertEquals(Collections.emptyList(), PrimaryFactorDecompose.decompose_fast(1L)); + } + + @Test + public void test_2() { + Assert.assertEquals(Collections.singletonList(2L), PrimaryFactorDecompose.decompose_fast(2L)); + } + + @Test + public void test_3() { + Assert.assertEquals(Collections.singletonList(3L), PrimaryFactorDecompose.decompose_fast(3L)); + } + + @Test + public void test_4() { + Assert.assertEquals(Arrays.asList(2L, 2L), PrimaryFactorDecompose.decompose_fast(4L)); + } + + @Test + public void test_6() { + Assert.assertEquals(Arrays.asList(2L, 3L), PrimaryFactorDecompose.decompose_fast(6L)); + } + + @Test + public void test_26() { + Assert.assertEquals(Arrays.asList(2L, 13L), PrimaryFactorDecompose.decompose_fast(26L)); + } + + @Test + public void test_two_functions() { + for(long i=1; i<10000; ++i) { + List listA = PrimaryFactorDecompose.decompose(i); + List listB = PrimaryFactorDecompose.decompose_fast(i); + Assert.assertEquals(listA, listB); + } + } + + @Test + public void test_decompose_big_number() { + long startTime = System.nanoTime(); + List list = PrimaryFactorDecompose.decompose_fast(1232423232232321123L); + System.out.println("elapsedTime: " + (System.nanoTime() - startTime)); + System.out.println("list: " + list); + } + +} \ No newline at end of file