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

Still working on Day 14

parent 7047dcba
Branches
Tags
No related merge requests found
...@@ -193,3 +193,16 @@ Oh, yes. This is *much* faster. Still taking a while to get through part 2, but ...@@ -193,3 +193,16 @@ Oh, yes. This is *much* faster. Still taking a while to get through part 2, but
in a few seconds we got past the point that the StringBuilder approach took a in a few seconds we got past the point that the StringBuilder approach took a
couple of hours while I was in a meeting. But we still ran out of memory when couple of hours while I was in a meeting. But we still ran out of memory when
growing the new polymer on iteration 28 of the sample data. growing the new polymer on iteration 28 of the sample data.
Perhaps instead of creating strings, we can keep track of the positions of each
element in the polymer. Computationally, this will increase the asymptotic
complexity, probably by two orders of magnitude, but asymptotic complexity isn't
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.
What am I missing?
...@@ -2,10 +2,11 @@ package edu.unl.cse.bohn.year2021; ...@@ -2,10 +2,11 @@ package edu.unl.cse.bohn.year2021;
import edu.unl.cse.bohn.Puzzle; import edu.unl.cse.bohn.Puzzle;
import java.util.Arrays;
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;
@SuppressWarnings("unused") @SuppressWarnings("unused")
public class Day14 extends Puzzle { public class Day14 extends Puzzle {
...@@ -46,68 +47,69 @@ public class Day14 extends Puzzle { ...@@ -46,68 +47,69 @@ public class Day14 extends Puzzle {
return initialMolecule; return initialMolecule;
} }
@SuppressWarnings("CommentedOutCode") private long producePolymer(List<String> data, int numberOfSteps) {
private String growMolecule(String molecule) { Map<Character, List<AtomicLong>> molecule = new HashMap<>();
// StringBuilder growingMolecule = new StringBuilder(); long index = 0;
// String pattern = ""; for (char element : parseData(data).toCharArray()) {
// for (int i = 0; i < molecule.length() - 1; i++) { if (!molecule.containsKey(element)) {
// pattern = molecule.substring(i, i + 2); molecule.put(element, new LinkedList<>());
// growingMolecule.append(pattern.charAt(0)).append(rules.get(pattern)); }
// } molecule.get(element).add(new AtomicLong(index++));
// growingMolecule.append(pattern.charAt(1)); }
// return growingMolecule.toString(); for (char element : molecule.keySet()) {
char[] oldElements = molecule.toCharArray(); System.out.println("\t\t" + element + ": " + molecule.get(element));
char[] newElements = new char[2 * molecule.length() - 1]; }
for (int i = 0; i < oldElements.length - 1; i++) { for (int i = 0; i < numberOfSteps; i++) {
newElements[2 * i] = oldElements[i]; System.out.println("\tGrowing...\t" + i);
newElements[2 * i + 1] = rules.get(molecule.substring(i, i + 2)); growMolecule(molecule);
} if (i < 4) {
newElements[newElements.length - 1] = oldElements[oldElements.length - 1]; for (char element : molecule.keySet()) {
return new String(newElements); 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 Map<Character, Long> countElements(String molecule) { private Character getCharAt(Map<Character, List<AtomicLong>> molecule, long index) {
Map<Character, Long> counts = new HashMap<>(); return molecule.keySet().stream()
for (char element : molecule.toCharArray()) { .filter(e -> molecule.get(e).stream().anyMatch(position -> position.get() == index))
if (!counts.containsKey(element)) { .findFirst().orElse(null);
counts.put(element, 0L);
} }
counts.put(element, counts.get(element) + 1);
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);
} }
return counts;
} }
private long producePolymer(List<String> data, int numberOfSteps) { @SuppressWarnings("UnusedReturnValue")
String molecule = parseData(data); private Map<Character, List<AtomicLong>> growMolecule(Map<Character, List<AtomicLong>> molecule) {
for (int i = 0; i < numberOfSteps; i++) { boolean stillGrowing = true;
System.out.print("Molecular growth (" + i + ")--\toriginal size: " + molecule.length()); long index = 0;
molecule = growMolecule(molecule); char[] pattern = {getCharAt(molecule, index), getCharAt(molecule, ++index)};
System.out.println("\tnew size: " + molecule.length()); do {
// if (molecule.length() < 60) { incrementIndicesAfter(molecule, index);
// String expectedString = switch (i) { char newElement = rules.get(new String(pattern));
// case 0 -> "NCNBCHB"; if (!molecule.containsKey(newElement)) {
// case 1 -> "NBCCNBBBCBHCB"; molecule.put(newElement, new LinkedList<>());
// case 2 -> "NBBBCNCCNBBNBNBBCHBHHBCHB"; }
// case 3 -> "NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB"; molecule.get(newElement).add(new AtomicLong(index++));
// default -> "??"; Character nextElement = getCharAt(molecule, ++index);
// }; if (nextElement == null) {
// System.out.println("\texpected: " + expectedString); stillGrowing = false;
// System.out.println("\t actual: " + molecule); } else {
// assert (molecule.equals(expectedString)); pattern[0] = pattern[1];
// } pattern[1] = nextElement;
} }
Map<Character, Long> elementCounts = countElements(molecule); } while (stillGrowing);
char leastFrequentElement = molecule.charAt(0); return molecule;
char mostFrequentElement = molecule.charAt(0);
for (char element : elementCounts.keySet()) {
if (elementCounts.get(element) < elementCounts.get(leastFrequentElement)) {
leastFrequentElement = element;
}
if (elementCounts.get(element) > elementCounts.get(mostFrequentElement)) {
mostFrequentElement = element;
}
}
return elementCounts.get(mostFrequentElement) - elementCounts.get(leastFrequentElement);
} }
@Override @Override
... ...
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment