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
No related tags found
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
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
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;
import edu.unl.cse.bohn.Puzzle;
import java.util.Arrays;
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 {
......@@ -46,68 +47,69 @@ public class Day14 extends Puzzle {
return initialMolecule;
}
@SuppressWarnings("CommentedOutCode")
private String growMolecule(String molecule) {
// StringBuilder growingMolecule = new StringBuilder();
// String pattern = "";
// for (int i = 0; i < molecule.length() - 1; i++) {
// pattern = molecule.substring(i, i + 2);
// growingMolecule.append(pattern.charAt(0)).append(rules.get(pattern));
// }
// growingMolecule.append(pattern.charAt(1));
// return growingMolecule.toString();
char[] oldElements = molecule.toCharArray();
char[] newElements = new char[2 * molecule.length() - 1];
for (int i = 0; i < oldElements.length - 1; i++) {
newElements[2 * i] = oldElements[i];
newElements[2 * i + 1] = rules.get(molecule.substring(i, i + 2));
}
newElements[newElements.length - 1] = oldElements[oldElements.length - 1];
return new String(newElements);
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));
}
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 Map<Character, Long> countElements(String molecule) {
Map<Character, Long> counts = new HashMap<>();
for (char element : molecule.toCharArray()) {
if (!counts.containsKey(element)) {
counts.put(element, 0L);
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);
}
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) {
String molecule = parseData(data);
for (int i = 0; i < numberOfSteps; i++) {
System.out.print("Molecular growth (" + i + ")--\toriginal size: " + molecule.length());
molecule = growMolecule(molecule);
System.out.println("\tnew size: " + molecule.length());
// if (molecule.length() < 60) {
// String expectedString = switch (i) {
// case 0 -> "NCNBCHB";
// case 1 -> "NBCCNBBBCBHCB";
// case 2 -> "NBBBCNCCNBBNBNBBCHBHHBCHB";
// case 3 -> "NBBNBNBBCCNBCNCCNBBNBBNBBBNBBNBBCBHCBHHNHCBBCBHCB";
// default -> "??";
// };
// System.out.println("\texpected: " + expectedString);
// System.out.println("\t actual: " + molecule);
// assert (molecule.equals(expectedString));
// }
}
Map<Character, Long> elementCounts = countElements(molecule);
char leastFrequentElement = molecule.charAt(0);
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);
@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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment