-
Notifications
You must be signed in to change notification settings - Fork 0
/
day14.js
103 lines (83 loc) · 2.25 KB
/
day14.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
const { test, data } = require('./data/day14');
const parseInput = (input) => {
const [startRaw, ...rulesRaw] = input;
const start = startRaw.split('')
.reduce((agg, el, idx, arr) => {
if (idx === arr.length - 1) {
return agg;
}
const key = `${el}${arr[idx + 1]}`;
if (!agg[key]) {
agg[key] = 0;
}
agg[key] += 1;
return agg;
}, {});
const rules = rulesRaw.reduce((agg, ruleRaw) => {
const [, pair, insert] = ruleRaw.match(/([A-Z]{2}) -> ([A-Z])/);
const [first, second] = pair.split('');
return {
...agg,
[pair]: [`${first}${insert}`, `${insert}${second}`],
};
}, {});
return { startRaw, start, rules };
};
const advanceStep = (start, rules) => {
return Object.entries(start).reduce((agg, [key, count], idx, arr) => {
const [first, second] = rules[key];
if (!agg[first]) {
agg[first] = 0;
}
if (!agg[second]) {
agg[second] = 0;
}
agg[first] += count;
agg[second] += count;
return agg;
}, {});
};
const applyNSteps = (start, rules, steps) => (
Array.from({ length: steps }).reduce((agg, _, idx) => advanceStep(agg, rules), start)
);
const computeCharCounts = (pairCounts, rawStart) => {
const counts = Object.entries(pairCounts).reduce((agg, [el, count]) => {
const [first, second] = el.split('');
if (!agg[first]) {
agg[first] = 0;
}
if (!agg[second]) {
agg[second] = 0;
}
agg[first] += count;
agg[second] += count;
return agg;
}, {});
counts[rawStart[0]] += 1;
counts[rawStart[rawStart.length - 1]] += 1;
return Object.fromEntries(Object.entries(counts).map(([k,v]) => ([k, v/2])));
};
const getMostMinusLeastFromCounts = (countsObj) => {
const counts = Object.values(countsObj)
const max = Math.max(...counts);
const min = Math.min(...counts);
return max - min;
};
const getDiff = (input, iterations) => {
const parsedInput = parseInput(input);
return getMostMinusLeastFromCounts(
computeCharCounts(
applyNSteps(parsedInput.start, parsedInput.rules, iterations), parsedInput.startRaw
)
);
};
console.log({
test: {
a: getDiff(test, 10),
b: getDiff(test, 40),
},
data: {
a: getDiff(data, 10),
b: getDiff(data, 40),
},
});