From 2390be51d710ea5900f176d88794930390ed0790 Mon Sep 17 00:00:00 2001 From: pareronia <49491686+pareronia@users.noreply.github.com> Date: Wed, 13 Dec 2023 22:43:38 +0100 Subject: [PATCH] AoC 2023 Day 12 - java - refactor --- src/main/java/AoC2023_12.java | 77 +++++++++++++---------------------- 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/src/main/java/AoC2023_12.java b/src/main/java/AoC2023_12.java index b802fea9..df945d13 100644 --- a/src/main/java/AoC2023_12.java +++ b/src/main/java/AoC2023_12.java @@ -2,7 +2,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import com.github.pareronia.aoc.AssertUtils; import com.github.pareronia.aoc.IntegerSequence.Range; @@ -15,7 +14,8 @@ public final class AoC2023_12 extends SolutionBase, Long, Long> { - private final Map cache = new HashMap<>(); + private static final char[] CHARS = {'.', '#'}; + private final Map cache = new HashMap<>(); private AoC2023_12(final boolean debug) { super(debug); @@ -34,31 +34,46 @@ protected List parseInput(final List inputs) { return inputs; } - private long count(final String s, final int[] counts, final int idx) { - if (s.isEmpty()) { - if (counts.length == 0 && idx == 0) { + private long count( + final String s, + final int[] counts, + final int s_idx, + final int c_idx, + final int idx + ) { + if (s_idx == s.length()) { + if (c_idx == counts.length && idx == 0) { return 1; } else { return 0; } } + if (idx == 0) { + int sum = 0; + for (int i = c_idx; i < counts.length; i++) { + sum += counts[i]; + } + if (s.length() - s_idx < sum + counts.length - c_idx - 1) { + return 0; + } + } - final CacheKey key = new CacheKey(new String(s), counts, idx); + final int key = s_idx << 16 | c_idx << 8 | idx; if (this.cache.containsKey(key)) { return this.cache.get(key); } long ans = 0; - final char[] nxts = s.charAt(0) == '?' ? new char[] {'.', '#'} : new char[] {s.charAt(0)}; + final char[] nxts = s.charAt(s_idx) == '?' ? CHARS : new char[] { s.charAt(s_idx) }; for (final char nxt : nxts) { if (nxt == '#') { - ans += count(s.substring(1), counts, idx + 1); + ans += count(s, counts, s_idx + 1, c_idx, idx + 1); } else if (nxt == '.') { if (idx > 0) { - if (counts.length > 0 && counts[0] == idx) { - ans += count(s.substring(1), Arrays.copyOfRange(counts, 1, counts.length), 0); + if (c_idx < counts.length && counts[c_idx] == idx) { + ans += count(s, counts, s_idx + 1, c_idx + 1, 0); } } else { - ans += count(s.substring(1), counts, 0); + ans += count(s, counts, s_idx + 1, c_idx, 0); } } else { AssertUtils.unreachable(); @@ -78,7 +93,7 @@ public Long solvePart1(final List input) { final int[] counts = Arrays.stream(split.right().split(",")) .mapToInt(Integer::parseInt) .toArray(); - ans += count(split.left() + ".", counts, 0); + ans += count(split.left() + ".", counts, 0, 0, 0); } return ans; } @@ -95,7 +110,7 @@ public Long solvePart2(final List input) { final int[] counts = Range.range(5).intStream() .flatMap(i -> Arrays.stream(split.right().split(",")).mapToInt(Integer::parseInt)) .toArray(); - ans += count(s, counts, 0); + ans += count(s, counts, 0, 0, 0); } return ans; } @@ -120,40 +135,4 @@ public static void main(final String[] args) throws Exception { ????.######..#####. 1,6,5 ?###???????? 3,2,1 """; - - private static class CacheKey { - private final String s; - private final int[] counts; - private final int idx; - - public CacheKey(final String s, final int[] counts, final int idx) { - this.s = s; - this.counts = counts; - this.idx = idx; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + Arrays.hashCode(counts); - return prime * result + Objects.hash(idx, s); - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final CacheKey other = (CacheKey) obj; - return Arrays.equals(counts, other.counts) - && idx == other.idx && Objects.equals(s, other.s); - } - } }