From 73e3d2a0247d76b51d217436e67302ddf4c0bc70 Mon Sep 17 00:00:00 2001 From: Kah Goh Date: Wed, 14 Jan 2026 12:33:10 +0800 Subject: [PATCH] Use LocalDate in baffling birthdays LocalData is a more idiomatic way of representing dates in Java. --- .../src/reference/java/BafflingBirthdays.java | 14 ++- .../src/main/java/BafflingBirthdays.java | 5 +- .../src/test/java/BafflingBirthdaysTest.java | 98 +++++++++++-------- 3 files changed, 66 insertions(+), 51 deletions(-) diff --git a/exercises/practice/baffling-birthdays/.meta/src/reference/java/BafflingBirthdays.java b/exercises/practice/baffling-birthdays/.meta/src/reference/java/BafflingBirthdays.java index 03cf1ae9a..ef58bc2c0 100644 --- a/exercises/practice/baffling-birthdays/.meta/src/reference/java/BafflingBirthdays.java +++ b/exercises/practice/baffling-birthdays/.meta/src/reference/java/BafflingBirthdays.java @@ -9,27 +9,25 @@ class BafflingBirthdays { private static final int nonLeapYear = 2001; private static final int daysInYear = 365; - boolean sharedBirthday(List birthdates) { + boolean sharedBirthday(List birthdates) { Set seen = new HashSet<>(); - for (String birthdate : birthdates) { - String monthDay = birthdate.substring(5); - if (!seen.add(monthDay)) { + for (LocalDate birthdate : birthdates) { + if (!seen.add(birthdate.getMonth().toString() + birthdate.getDayOfMonth())) { return true; } } return false; } - List randomBirthdates(int groupSize) { + List randomBirthdates(int groupSize) { if (groupSize <= 0) { return List.of(); } - List birthdates = new ArrayList<>(groupSize); + List birthdates = new ArrayList<>(groupSize); ThreadLocalRandom random = ThreadLocalRandom.current(); for (int i = 0; i < groupSize; i++) { int dayOfYear = random.nextInt(1, daysInYear + 1); - LocalDate date = LocalDate.ofYearDay(nonLeapYear, dayOfYear); - birthdates.add(date.toString()); + birthdates.add(LocalDate.ofYearDay(nonLeapYear, dayOfYear)); } return birthdates; } diff --git a/exercises/practice/baffling-birthdays/src/main/java/BafflingBirthdays.java b/exercises/practice/baffling-birthdays/src/main/java/BafflingBirthdays.java index 273c6506c..5e1925081 100644 --- a/exercises/practice/baffling-birthdays/src/main/java/BafflingBirthdays.java +++ b/exercises/practice/baffling-birthdays/src/main/java/BafflingBirthdays.java @@ -1,11 +1,12 @@ +import java.time.LocalDate; import java.util.List; class BafflingBirthdays { - boolean sharedBirthday(List birthdates) { + boolean sharedBirthday(List birthdates) { throw new UnsupportedOperationException("Delete this statement and write your own implementation."); } - List randomBirthdates(int groupSize) { + List randomBirthdates(int groupSize) { throw new UnsupportedOperationException("Delete this statement and write your own implementation."); } diff --git a/exercises/practice/baffling-birthdays/src/test/java/BafflingBirthdaysTest.java b/exercises/practice/baffling-birthdays/src/test/java/BafflingBirthdaysTest.java index 9c9497a92..0726301dc 100644 --- a/exercises/practice/baffling-birthdays/src/test/java/BafflingBirthdaysTest.java +++ b/exercises/practice/baffling-birthdays/src/test/java/BafflingBirthdaysTest.java @@ -1,71 +1,105 @@ +import java.time.LocalDate; +import java.util.List; + import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; +import static java.time.Month.APRIL; +import static java.time.Month.AUGUST; +import static java.time.Month.DECEMBER; +import static java.time.Month.FEBRUARY; +import static java.time.Month.JANUARY; +import static java.time.Month.JULY; +import static java.time.Month.MAY; +import static java.time.Month.NOVEMBER; +import static java.time.Month.OCTOBER; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.data.Offset.offset; -import java.time.LocalDate; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - public class BafflingBirthdaysTest { private BafflingBirthdays birthdays = new BafflingBirthdays(); @Test @DisplayName("one birthdate") public void oneBirthdateTest() { - assertThat(birthdays.sharedBirthday(List.of("2000-01-01"))).isFalse(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2000, JANUARY, 1) + ))).isFalse(); } @Disabled("Remove to run test") @Test @DisplayName("two birthdates with same year, month, and day") public void twoBirthdatesWithSameYearMonthAndDayTest() { - assertThat(birthdays.sharedBirthday(List.of("2000-01-01", "2000-01-01"))).isTrue(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2000, JANUARY, 1), + LocalDate.of(2000, JANUARY, 1) + ))).isTrue(); } @Disabled("Remove to run test") @Test @DisplayName("two birthdates with same year and month, but different day") public void twoBirthdatesWithSameYearAndMonthButDifferentDayTest() { - assertThat(birthdays.sharedBirthday(List.of("2012-05-09", "2012-05-17"))).isFalse(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2012, MAY, 9), + LocalDate.of(2012, MAY, 17) + ))).isFalse(); } @Disabled("Remove to run test") @Test @DisplayName("two birthdates with same month and day, but different year") public void twoBirthdatesWithSameMonthAndDayButDifferentYearTest() { - assertThat(birthdays.sharedBirthday(List.of("1999-10-23", "1988-10-23"))).isTrue(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1999, OCTOBER, 23), + LocalDate.of(1988, OCTOBER, 23) + ))).isTrue(); } @Disabled("Remove to run test") @Test @DisplayName("two birthdates with same year, but different month and day") public void twoBirthdatesWithSameYearButDifferentMonthAndDayTest() { - assertThat(birthdays.sharedBirthday(List.of("2007-12-19", "2007-04-27"))).isFalse(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(2007, DECEMBER, 19), + LocalDate.of(2007, APRIL, 27) + ))).isFalse(); } @Disabled("Remove to run test") @Test @DisplayName("two birthdates with different year, month, and day") public void twoBirthdatesWithDifferentYearMonthAndDayTest() { - assertThat(birthdays.sharedBirthday(List.of("1997-08-04", "1963-11-23"))).isFalse(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1997, AUGUST, 4), + LocalDate.of(1963, NOVEMBER, 23) + ))).isFalse(); } @Disabled("Remove to run test") @Test @DisplayName("multiple birthdates without shared birthday") public void multipleBirthdatesWithoutSharedBirthdayTest() { - assertThat(birthdays.sharedBirthday(List.of("1966-07-29", "1977-02-12", "2001-12-25", "1980-11-10"))).isFalse(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1966, AUGUST, 29), + LocalDate.of(1977, FEBRUARY, 12), + LocalDate.of(2001, DECEMBER, 25), + LocalDate.of(1980, NOVEMBER, 10) + ))).isFalse(); } @Disabled("Remove to run test") @Test @DisplayName("multiple birthdates with one shared birthday") public void multipleBirthdatesWithOneSharedBirthdayTest() { - assertThat(birthdays.sharedBirthday(List.of("1966-07-29", "1977-02-12", "2001-07-29", "1980-11-10"))).isTrue(); + assertThat(birthdays.sharedBirthday(List.of( + LocalDate.of(1966, AUGUST, 29), + LocalDate.of(1977, FEBRUARY, 12), + LocalDate.of(2001, AUGUST, 29), + LocalDate.of(1980, NOVEMBER, 10) + ))).isTrue(); } @Disabled("Remove to run test") @@ -73,11 +107,11 @@ public void multipleBirthdatesWithOneSharedBirthdayTest() { @DisplayName("multiple birthdates with more than one shared birthday") public void multipleBirthdatesWithMoreThanOneSharedBirthdayTest() { assertThat(birthdays.sharedBirthday(List.of( - "1966-07-29", - "1977-02-12", - "2001-12-25", - "1980-07-29", - "2019-02-12" + LocalDate.of(1966, JULY, 29), + LocalDate.of(1977, FEBRUARY, 12), + LocalDate.of(2001, DECEMBER, 25), + LocalDate.of(1980, JULY, 29), + LocalDate.of(2019, FEBRUARY, 12) ))).isTrue(); } @@ -93,41 +127,23 @@ public void generateRequestedNumberOfBirthdatesTest() { @Test @DisplayName("years are not leap years") public void yearsAreNotLeapYearsTest() { - for (String birthdate : birthdays.randomBirthdates(100)) { - LocalDate date = LocalDate.parse(birthdate); - assertThat(date.isLeapYear()).isFalse(); - assertThat(date.getMonthValue() == 2 && date.getDayOfMonth() == 29).isFalse(); - } + assertThat(birthdays.randomBirthdates(100)).noneMatch(LocalDate::isLeapYear); } @Disabled("Remove to run test") @Test @DisplayName("months are random") public void monthsAreRandomTest() { - Set months = new HashSet<>(); - for (String birthdate : birthdays.randomBirthdates(500)) { - LocalDate date = LocalDate.parse(birthdate); - months.add(date.getMonthValue()); - if (months.size() >= 7) { - break; - } - } - assertThat(months).hasSizeGreaterThanOrEqualTo(7); + assertThat(birthdays.randomBirthdates(500).stream().map(LocalDate::getMonth).distinct()) + .hasSizeGreaterThanOrEqualTo(7); } @Disabled("Remove to run test") @Test @DisplayName("days are random") public void daysAreRandomTest() { - Set days = new HashSet<>(); - for (String birthdate : birthdays.randomBirthdates(500)) { - LocalDate date = LocalDate.parse(birthdate); - days.add(date.getDayOfMonth()); - if (days.size() >= 11) { - break; - } - } - assertThat(days).hasSizeGreaterThanOrEqualTo(11); + assertThat(birthdays.randomBirthdates(500).stream().map(LocalDate::getDayOfMonth).distinct()) + .hasSizeGreaterThanOrEqualTo(11); } @Disabled("Remove to run test")