diff --git a/2018/src/main/java/me/zodac/advent/Day02.java b/2018/src/main/java/me/zodac/advent/Day02.java new file mode 100644 index 00000000..78c08725 --- /dev/null +++ b/2018/src/main/java/me/zodac/advent/Day02.java @@ -0,0 +1,128 @@ +/* + * BSD Zero Clause License + * + * Copyright (c) 2021-2023 zodac.me + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +package me.zodac.advent; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import me.zodac.advent.util.StringUtils; + +/** + * Solution for 2018, Day 2. + * + * @see AoC 2018, Day 2 + */ +public final class Day02 { + + private Day02() { + + } + + /** + * Given some box IDs in the form of {@link String}s, we calculate the checksum by counting the number of box IDs with: + *
+ * These counts are then multiplied to return the checksum of the provided box IDs.
+ *
+ * @param boxIds the {@link String}s of the box IDs
+ * @return the checksum of the box IDs
+ */
+ public static long checksumOfBoxIds(final Iterable
+ * For example, given {@code foobar} and {@code fuubar}, the returned value will be:
+ *
+ * For example, given {@code foobar}, the returned value will be:
+ *
+ * For example, given {@code foobar} and {@code numberOfCharactersToRemove} set to 3, the returned value will be:
+ *
- * For example, {@code foobar} will be returned as {@code abfoor}
+ * For example, given {@code foobar}, the returned value will be:
+ *
+ * {@code fbar}
+ *
+ *
+ * @param first the first {@link String}
+ * @param second the second {@link String}
+ * @return the {@link String} with any differences removed
+ * @throws IllegalArgumentException thrown if the two input {@link String}s do not have the same length, or if either input is {@code null}
+ */
+ public static String removeDifferentCharacters(final String first, final String second) {
+ if (first == null || second == null) {
+ throw new IllegalArgumentException("Inputs must not be null");
+ }
+
+ if (first.length() != second.length()) {
+ throw new IllegalArgumentException(
+ String.format("Expected inputs of equal length, found %s (%s) and %s (%s)", first, first.length(), second, second.length()));
+ }
+
+ final int stringLength = first.length();
+
+ final StringBuilder stringBuilder = new StringBuilder();
+ for (int i = 0; i < stringLength; i++) {
+ final char charFromFirst = first.charAt(i);
+ final char charFromSecond = second.charAt(i);
+
+ if (charFromFirst == charFromSecond) {
+ stringBuilder.append(charFromFirst);
+ }
+ }
+
+ return stringBuilder.toString();
+ }
+
/**
* Removes the last character in the {@link String}.
*
+ *
+ * {@code fooba}
+ *
+ *
* @param input the input {@link String}
* @return the updated {@link String}
*/
@@ -365,6 +410,12 @@ public static String removeLastCharacter(final String input) {
/**
* Removes the last {@code numberOfCharactersToRemove} characters in the {@link String}.
*
+ *
+ * {@code foo}
+ *
+ *
* @param input the input {@link String}
* @param numberOfCharactersToRemove the number of characters to remove
* @return the updated {@link String}
@@ -421,7 +472,10 @@ public static String replaceAtIndex(final String input, final CharSequence subSt
* Sorts the individual characters in the given {@link String} alphabetically.
*
*
+ * {@code abfoor}
+ *
*
* @param input the {@link String} to sort
* @return the sorted {@link String}
diff --git a/common-utils/src/test/java/me/zodac/advent/util/StringUtilsTest.java b/common-utils/src/test/java/me/zodac/advent/util/StringUtilsTest.java
index d7c75829..c1ed18bc 100644
--- a/common-utils/src/test/java/me/zodac/advent/util/StringUtilsTest.java
+++ b/common-utils/src/test/java/me/zodac/advent/util/StringUtilsTest.java
@@ -914,6 +914,87 @@ void whenLookAndSay_givenNullString_thenEmptyStringIsReturned() {
.isEmpty();
}
+ @Test
+ void whenRemoveDifferentCharacters_givenEqualInputs_thenInputIsReturnedWithoutChange() {
+ final String first = "abcdef";
+ final String second = "abcdef";
+ final String output = StringUtils.removeDifferentCharacters(first, second);
+ assertThat(output)
+ .isEqualTo(first);
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenInputsWithSingleDifferent_thenOnlyCommonCharactersAreReturned() {
+ final String first = "abcdef";
+ final String second = "abcqef";
+ final String output = StringUtils.removeDifferentCharacters(first, second);
+ assertThat(output)
+ .isEqualTo("abcef");
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenInputsWithNoCommonCharacters_thenEmptyStringIsReturned() {
+ final String first = "abcdef";
+ final String second = "ghijkl";
+ final String output = StringUtils.removeDifferentCharacters(first, second);
+ assertThat(output)
+ .isEmpty();
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenInputsOfDifferentLength_thenExceptionIsThrown() {
+ final String first = "abcdef";
+ final String second = "abcdefg";
+ assertThatThrownBy(() -> StringUtils.removeDifferentCharacters(first, second))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Expected inputs of equal length, found abcdef (6) and abcdefg (7)");
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenInputIsEmpty_thenEmptyStringIsReturned() {
+ final String first = "";
+ final String second = "";
+ final String output = StringUtils.removeDifferentCharacters(first, second);
+ assertThat(output)
+ .isEmpty();
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenFirstInputIsBlank_thenEmptyStringIsReturned() {
+ final String first = " ";
+ final String second = "a";
+ final String output = StringUtils.removeDifferentCharacters(first, second);
+ assertThat(output)
+ .isEmpty();
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenSecondInputIsBlank_thenEmptyStringIsReturned() {
+ final String first = "a";
+ final String second = " ";
+ final String output = StringUtils.removeDifferentCharacters(first, second);
+ assertThat(output)
+ .isEmpty();
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenFirstInputIsNull_thenExceptionIsThrown() {
+ final String first = null;
+ final String second = "abcdef";
+ assertThatThrownBy(() -> StringUtils.removeDifferentCharacters(first, second))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Inputs must not be null");
+ }
+
+ @Test
+ void whenRemoveDifferentCharacters_givenSecondInputIsNull_thenExceptionIsThrown() {
+ final String first = "abcdef";
+ final String second = null;
+ assertThatThrownBy(() -> StringUtils.removeDifferentCharacters(first, second))
+ .isInstanceOf(IllegalArgumentException.class)
+ .hasMessage("Inputs must not be null");
+ }
+
@Test
void whenRemoveLastCharacter_givenString_thenStringIsReturnedWithoutLastCharacter() {
final String input = "abc";