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
track of the positions of each element in the polymer will use very, very little
memory.
Yup, this has definitely slowed down computation. And, now that I think about it,
I have to create as many indices as the original string's length was. This isn't
a savings. At. All.
Yup, this has definitely slowed down computation. And, now that I think about
it, I have to create as many indices as the original string's length was. This
isn't a savings. At. All.
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;
import edu.unl.cse.bohn.Puzzle;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@SuppressWarnings("unused")
public class Day14 extends Puzzle {
private Map<String, Character> rules;
private Map<String, String> rules;
private Map<String, AtomicLong> patterns;
public Day14(boolean isProductionReady) {
super(isProductionReady);
......@@ -38,78 +38,53 @@ public class Day14 extends Puzzle {
private String parseData(List<String> data) {
String initialMolecule = data.get(0);
rules = new HashMap<>();
patterns = new HashMap<>();
for (String rule : data) {
if (rule.contains(" -> ")) {
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;
}
private long producePolymer(List<String> data, int numberOfSteps) {
Map<Character, List<AtomicLong>> molecule = new HashMap<>();
long index = 0;
for (char element : parseData(data).toCharArray()) {
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));
}
String molecule = parseData(data);
String tail = molecule.substring(molecule.length() - 2);
Map<String, Long> newValues = new HashMap<>();
for (int i = 0; i < numberOfSteps; i++) {
System.out.println("\tGrowing...\t" + i);
growMolecule(molecule);
if (i < 4) {
for (char element : molecule.keySet()) {
System.out.println("\t\t" + element + ": " + molecule.get(element));
}
}
}
long leastFrequentOccurrence = molecule.keySet().stream()
.mapToLong(element -> molecule.get(element).size()).min().orElseThrow();
long mostFrequentOccurrence = molecule.keySet().stream()
.mapToLong(element -> molecule.get(element).size()).max().orElseThrow();
return mostFrequentOccurrence - leastFrequentOccurrence;
}
private Character getCharAt(Map<Character, List<AtomicLong>> molecule, long index) {
return molecule.keySet().stream()
.filter(e -> molecule.get(e).stream().anyMatch(position -> position.get() == index))
.findFirst().orElse(null);
}
private void incrementIndicesAfter(Map<Character, List<AtomicLong>> molecule, long start) {
for (char element : molecule.keySet()) {
molecule.get(element).stream()
.filter(position -> start <= position.get())
.forEach(AtomicLong::getAndIncrement);
}
}
@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;
for (String pattern : patterns.keySet()) {
newValues.put(pattern, 0L);
}
for (String pattern : patterns.keySet()) {
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());
}
for (String pattern : patterns.keySet()) {
patterns.get(pattern).set(newValues.get(pattern));
}
tail = rules.get(tail) + tail.charAt(1);
}
Map<Character, AtomicLong> elementCounts = new HashMap<>();
elementCounts.put(tail.charAt(1), new AtomicLong(1L));
for (String pattern : patterns.keySet()) {
char element = pattern.charAt(0);
if (!elementCounts.containsKey(element)) {
elementCounts.put(element, new AtomicLong(0L));
}
elementCounts.get(element).getAndAdd(patterns.get(pattern).longValue());
}
long leastCommon = elementCounts.keySet().stream()
.mapToLong(element -> elementCounts.get(element).longValue()).min().orElseThrow();
long mostCommon = elementCounts.keySet().stream()
.mapToLong(element -> elementCounts.get(element).longValue()).max().orElseThrow();
return mostCommon - leastCommon;
}
@Override
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment