Skip to content
Snippets Groups Projects
Commit ab35275f authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Day 14 complete

parent af374578
No related branches found
No related tags found
No related merge requests found
...@@ -201,8 +201,14 @@ everything: memory management was definitely a HUGE constant factor. Keeping ...@@ -201,8 +201,14 @@ everything: memory management was definitely a HUGE constant factor. Keeping
track of the positions of each element in the polymer will use very, very little track of the positions of each element in the polymer will use very, very little
memory. memory.
Yup, this has definitely slowed down computation. And, now that I think about it, Yup, this has definitely slowed down computation. And, now that I think about
I have to create as many indices as the original string's length was. This isn't it, I have to create as many indices as the original string's length was. This
a savings. At. All. isn't a savings. At. All.
What am I missing? What am I missing?
Let's try it this way: I don't need to keep track of the molecule *at all*. If
I keep track of the number of occurrences of each pair, then the numbers of
occurrences will grow and shrink in each iteration.
Yup. That did it.
...@@ -3,14 +3,14 @@ package edu.unl.cse.bohn.year2021; ...@@ -3,14 +3,14 @@ package edu.unl.cse.bohn.year2021;
import edu.unl.cse.bohn.Puzzle; import edu.unl.cse.bohn.Puzzle;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class Day14 extends Puzzle { public class Day14 extends Puzzle {
private Map<String, Character> rules; private Map<String, String> rules;
private Map<String, AtomicLong> patterns;
public Day14(boolean isProductionReady) { public Day14(boolean isProductionReady) {
super(isProductionReady); super(isProductionReady);
...@@ -38,78 +38,53 @@ public class Day14 extends Puzzle { ...@@ -38,78 +38,53 @@ public class Day14 extends Puzzle {
private String parseData(List<String> data) { private String parseData(List<String> data) {
String initialMolecule = data.get(0); String initialMolecule = data.get(0);
rules = new HashMap<>(); rules = new HashMap<>();
patterns = new HashMap<>();
for (String rule : data) { for (String rule : data) {
if (rule.contains(" -> ")) { if (rule.contains(" -> ")) {
String[] halves = rule.split(" -> "); String[] halves = rule.split(" -> ");
rules.put(halves[0], halves[1].charAt(0)); rules.put(halves[0], halves[1]);
patterns.put(halves[0], new AtomicLong(0L));
} }
} }
for (int i = 0; i < initialMolecule.length() - 1; i++) {
patterns.get(initialMolecule.substring(i, i + 2)).getAndIncrement();
}
return initialMolecule; return initialMolecule;
} }
private long producePolymer(List<String> data, int numberOfSteps) { private long producePolymer(List<String> data, int numberOfSteps) {
Map<Character, List<AtomicLong>> molecule = new HashMap<>(); String molecule = parseData(data);
long index = 0; String tail = molecule.substring(molecule.length() - 2);
for (char element : parseData(data).toCharArray()) { Map<String, Long> newValues = new HashMap<>();
if (!molecule.containsKey(element)) {
molecule.put(element, new LinkedList<>());
}
molecule.get(element).add(new AtomicLong(index++));
}
for (char element : molecule.keySet()) {
System.out.println("\t\t" + element + ": " + molecule.get(element));
}
for (int i = 0; i < numberOfSteps; i++) { for (int i = 0; i < numberOfSteps; i++) {
System.out.println("\tGrowing...\t" + i); for (String pattern : patterns.keySet()) {
growMolecule(molecule); newValues.put(pattern, 0L);
if (i < 4) { }
for (char element : molecule.keySet()) { for (String pattern : patterns.keySet()) {
System.out.println("\t\t" + element + ": " + molecule.get(element)); String newPattern = pattern.charAt(0) + rules.get(pattern);
} newValues.put(newPattern, newValues.get(newPattern) + patterns.get(pattern).longValue());
} newPattern = rules.get(pattern) + pattern.charAt(1);
} newValues.put(newPattern, newValues.get(newPattern) + patterns.get(pattern).longValue());
long leastFrequentOccurrence = molecule.keySet().stream() }
.mapToLong(element -> molecule.get(element).size()).min().orElseThrow(); for (String pattern : patterns.keySet()) {
long mostFrequentOccurrence = molecule.keySet().stream() patterns.get(pattern).set(newValues.get(pattern));
.mapToLong(element -> molecule.get(element).size()).max().orElseThrow(); }
return mostFrequentOccurrence - leastFrequentOccurrence; tail = rules.get(tail) + tail.charAt(1);
} }
Map<Character, AtomicLong> elementCounts = new HashMap<>();
private Character getCharAt(Map<Character, List<AtomicLong>> molecule, long index) { elementCounts.put(tail.charAt(1), new AtomicLong(1L));
return molecule.keySet().stream() for (String pattern : patterns.keySet()) {
.filter(e -> molecule.get(e).stream().anyMatch(position -> position.get() == index)) char element = pattern.charAt(0);
.findFirst().orElse(null); if (!elementCounts.containsKey(element)) {
} elementCounts.put(element, new AtomicLong(0L));
}
private void incrementIndicesAfter(Map<Character, List<AtomicLong>> molecule, long start) { elementCounts.get(element).getAndAdd(patterns.get(pattern).longValue());
for (char element : molecule.keySet()) { }
molecule.get(element).stream() long leastCommon = elementCounts.keySet().stream()
.filter(position -> start <= position.get()) .mapToLong(element -> elementCounts.get(element).longValue()).min().orElseThrow();
.forEach(AtomicLong::getAndIncrement); long mostCommon = elementCounts.keySet().stream()
} .mapToLong(element -> elementCounts.get(element).longValue()).max().orElseThrow();
} return mostCommon - leastCommon;
@SuppressWarnings("UnusedReturnValue")
private Map<Character, List<AtomicLong>> growMolecule(Map<Character, List<AtomicLong>> molecule) {
boolean stillGrowing = true;
long index = 0;
char[] pattern = {getCharAt(molecule, index), getCharAt(molecule, ++index)};
do {
incrementIndicesAfter(molecule, index);
char newElement = rules.get(new String(pattern));
if (!molecule.containsKey(newElement)) {
molecule.put(newElement, new LinkedList<>());
}
molecule.get(newElement).add(new AtomicLong(index++));
Character nextElement = getCharAt(molecule, ++index);
if (nextElement == null) {
stillGrowing = false;
} else {
pattern[0] = pattern[1];
pattern[1] = nextElement;
}
} while (stillGrowing);
return molecule;
} }
@Override @Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment