diff --git a/2021/README.md b/2021/README.md index 7290326e286e4cfff3003136914a3cb19f83de6b..4d512b013779fecc8dc33283ddcba8235c251e54 100644 --- a/2021/README.md +++ b/2021/README.md @@ -35,4 +35,11 @@ less-complex approaches. The straight-forward design I came up with for Day 5 is O(num_lines * num_rows * num_columns); the algebraic approach would be O(num_lines^2), so not too much of a big deal on this problem. But (I'm sure) there will be some problems whose straight-forward solution are a tad -intractable. \ No newline at end of file +intractable. + +## Day 6 + +For example, in the problem statement practically *screams* that the +obvious solution grows exponentially. Normally, death would keep the population +under control, but I guess Death Takes a Holiday. One little extra gotcha: +26984457539 > Integer.MAX_INT, so I need to use a long integer. \ No newline at end of file diff --git a/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java b/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java index b8e5910b085990f0ec27d088ee9369f586acf47d..100704cec7d51d3b557a350d2d62254e850e14e4 100644 --- a/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java +++ b/2021/src/main/java/edu/unl/cse/bohn/Puzzle.java @@ -11,8 +11,8 @@ public abstract class Puzzle { this.isProductionReady = isProductionReady; } - public abstract int computePart1(List<String> data); - public abstract int computePart2(List<String> data); + public abstract long computePart1(List<String> data); + public abstract long computePart2(List<String> data); public void solvePuzzle(ImportData dataSource) { List<String> data = null; diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java index e1b1be5a0297c321d0df1529981801e8f537dabf..3c938d51274770b74f26f1c83b13a81dcf73322c 100644 --- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java +++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day1.java @@ -37,13 +37,13 @@ public class Day1 extends Puzzle { } @Override - public int computePart1(List<String> data) { + public long computePart1(List<String> data) { depths = data.stream().map(Integer::parseInt).toList(); return countIncreases(depths); } @Override - public int computePart2(List<String> data) { + public long computePart2(List<String> data) { int numberOfWindows = depths.size() - 2; List<Integer> slidingWindows = new ArrayList<>(numberOfWindows); for (int i = 0; i < numberOfWindows; i++) { diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java index 92585ee520ca9ffac111c58eee76cf2a66853c44..b837c6def5a7cdd77eb70a2f00c9878226169db8 100644 --- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java +++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day2.java @@ -11,10 +11,10 @@ public class Day2 extends Puzzle { private List<NavigationInstruction> navigationInstructions; - private int range; - private int depth; + private long range; + private long depth; @SuppressWarnings("FieldCanBeLocal") - private int aim; + private long aim; public Day2(boolean isProductionReady) { super(isProductionReady); @@ -28,7 +28,7 @@ public class Day2 extends Puzzle { } @Override - public int computePart1(List<String> data) { + public long computePart1(List<String> data) { navigationInstructions = data.stream() .map(instruction -> new NavigationInstruction( instruction.split(" ")[0], @@ -48,7 +48,7 @@ public class Day2 extends Puzzle { } @Override - public int computePart2(List<String> data) { + public long computePart2(List<String> data) { range = 0; depth = 0; aim = 0; diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java index fa94aab29704fc0e98a3914614edb2dccac62394..7f30d2ed96c04a7c02a7dd387131e2caa5c86b3a 100644 --- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java +++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day3.java @@ -8,7 +8,7 @@ import java.util.function.BiPredicate; @SuppressWarnings("unused") public class Day3 extends Puzzle { - private List<Integer> diagnosticReports; + private List<Long> diagnosticReports; private int reportLength; private int[] ones, zeroes; @@ -30,8 +30,8 @@ public class Day3 extends Puzzle { } @Override - public int computePart1(List<String> data) { - diagnosticReports = data.stream().map(report -> Integer.parseInt(report, 2)).toList(); + public long computePart1(List<String> data) { + diagnosticReports = data.stream().map(report -> Long.parseLong(report, 2)).toList(); reportLength = data.get(0).length(); ones = new int[]{ 0, 0, 0, 0, 0, 0, 0, 0, @@ -43,17 +43,17 @@ public class Day3 extends Puzzle { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - for (int report : diagnosticReports) { + for (long report : diagnosticReports) { for (int bit = 0; bit < reportLength; bit++) { - if ((report & (1 << bit)) == 0) { + if ((report & 1L << bit) == 0) { zeroes[bit]++; } else { ones[bit]++; } } } - int gamma = 0; - int epsilon = 0; + long gamma = 0; + long epsilon = 0; for (int bit = 0; bit < reportLength; bit++) { if (ones[bit] > zeroes[bit]) { gamma |= (1 << bit); @@ -64,8 +64,8 @@ public class Day3 extends Puzzle { return gamma * epsilon; } - private Integer filterReports(int[] onesArray, int[] zeroesArray, BiPredicate<Integer, Integer> predicate) { - List<Integer> workingSet = new ArrayList<>(diagnosticReports); + private Long filterReports(int[] onesArray, int[] zeroesArray, BiPredicate<Integer, Integer> predicate) { + List<Long> workingSet = new ArrayList<>(diagnosticReports); int bit = reportLength - 1; int numberOfOnes = onesArray[bit]; int numberOfZeroes = zeroesArray[bit]; @@ -84,8 +84,8 @@ public class Day3 extends Puzzle { // Need to re-count the ones and zeroes since the old counts are now wrong if (bit >= 0) { numberOfOnes = numberOfZeroes = 0; - for (int report : workingSet) { - if ((report & (1 << bit)) == 0) { + for (long report : workingSet) { + if ((report & (1L << bit)) == 0) { numberOfZeroes++; } else { numberOfOnes++; @@ -97,10 +97,10 @@ public class Day3 extends Puzzle { } @Override - public int computePart2(List<String> data) { - Integer oxygenGeneratorRating = filterReports(ones, zeroes, + public long computePart2(List<String> data) { + Long oxygenGeneratorRating = filterReports(ones, zeroes, (numberOfOnes, numberOfZeroes) -> numberOfOnes >= numberOfZeroes); - Integer co2ScrubberRating = filterReports(ones, zeroes, + Long co2ScrubberRating = filterReports(ones, zeroes, (numberOfOnes, numberOfZeroes) -> numberOfOnes < numberOfZeroes); return oxygenGeneratorRating * co2ScrubberRating; } diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java index 46fa1c2923c6a7afc86131eda0cc2a6ea6c59e11..ead3f3bcbcb85a8b6f03a5d32fcb5892b3da615a 100644 --- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java +++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day4.java @@ -71,7 +71,7 @@ public class Day4 extends Puzzle { } @Override - public int computePart1(List<String> data) { + public long computePart1(List<String> data) { parseData(data); Iterator<Integer> numberIterator = numbers.iterator(); while (cards.stream().noneMatch(BingoCard::hasBingo) && numberIterator.hasNext()) { @@ -85,7 +85,7 @@ public class Day4 extends Puzzle { } @Override - public int computePart2(List<String> data) { + public long computePart2(List<String> data) { Iterator<Integer> numberIterator = numbers.iterator(); while ((cards.stream().filter(BingoCard::hasBingo).count() < cards.size() - 1) && numberIterator.hasNext()) { int number = numberIterator.next(); diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java index 21a443dd82cf27bee41c563869f39f1a7290934e..cd63debb1fd130bf15bdb2c9d4548d1f7912b207 100644 --- a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java +++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day5.java @@ -95,13 +95,13 @@ public class Day5 extends Puzzle { } @Override - public int computePart1(List<String> data) { + public long computePart1(List<String> data) { parseData(data, false); return countIntersectingVentLines(); } @Override - public int computePart2(List<String> data) { + public long computePart2(List<String> data) { parseData(data, true); return countIntersectingVentLines(); } diff --git a/2021/src/main/java/edu/unl/cse/bohn/year2021/Day6.java b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day6.java new file mode 100644 index 0000000000000000000000000000000000000000..703f3441c2e6d2fc2e9ec068ad8dfb068e28410a --- /dev/null +++ b/2021/src/main/java/edu/unl/cse/bohn/year2021/Day6.java @@ -0,0 +1,53 @@ +package edu.unl.cse.bohn.year2021; + +import edu.unl.cse.bohn.Puzzle; + +import java.util.Arrays; +import java.util.List; + +@SuppressWarnings("unused") +public class Day6 extends Puzzle { + private long[] numberOfFishAtCounter; + + public Day6(boolean isProductionReady) { + super(isProductionReady); + sampleData = "3,4,3,1,2"; + } + + private void initializeFishCounters(List<String> data) { + List<Integer> fishCounters = Arrays.stream(data.get(0).split(",")) + .mapToInt(Integer::parseInt) + .boxed().toList(); + numberOfFishAtCounter = new long[9]; + Arrays.fill(numberOfFishAtCounter, 0); + for (int fish : fishCounters) { + numberOfFishAtCounter[fish]++; + } + } + + private void spawnFish(int numberOfDays) { + for (int day = 0; day < numberOfDays; day++) { + long spawningFish = numberOfFishAtCounter[0]; + //noinspection ManualArrayCopy + for(int counter = 0; counter < 8; counter++) { + numberOfFishAtCounter[counter] = numberOfFishAtCounter[counter+1]; + } + numberOfFishAtCounter[8] = spawningFish; // new fish + numberOfFishAtCounter[6] += spawningFish; // reset fish + } + } + + @Override + public long computePart1(List<String> data) { + initializeFishCounters(data); + spawnFish(80); + return Arrays.stream(numberOfFishAtCounter).reduce(Long::sum).orElseThrow(); + } + + @Override + public long computePart2(List<String> data) { + initializeFishCounters(data); + spawnFish(256); + return Arrays.stream(numberOfFishAtCounter).reduce(Long::sum).orElseThrow(); + } +}