[TASK] Solved Day 14
This commit is contained in:
151
functions/src/day14.ts
Normal file
151
functions/src/day14.ts
Normal file
@@ -0,0 +1,151 @@
|
||||
import Day from "./day";
|
||||
import Utils from "./utils";
|
||||
|
||||
type CharCounts = {[key: string]: bigint};
|
||||
|
||||
class Day14 implements Day {
|
||||
|
||||
part1(input: string[]): number | string {
|
||||
|
||||
const { orig, mapping } = Day14.parseInput(input);
|
||||
|
||||
let current = orig;
|
||||
for (let step = 0; step < 10; step++) {
|
||||
current = this.executeStep(current, mapping);
|
||||
}
|
||||
|
||||
const counts: {[key: string]: number} = {};
|
||||
for (const c of current) {
|
||||
if (c in counts) {
|
||||
counts[c]++;
|
||||
} else {
|
||||
counts[c] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Math.max(...Object.values(counts)) - Math.min(...Object.values(counts));
|
||||
}
|
||||
|
||||
private static parseInput(input: string[]): { orig: string, mapping: Map<string, Map<string, string>>} {
|
||||
const orig = input[0];
|
||||
|
||||
const mapping = new Map<string, Map<string, string>>();
|
||||
for (const line of input.slice(2)) {
|
||||
|
||||
const splitIndex = line.indexOf("->");
|
||||
const from = line.substr(0, splitIndex).trim();
|
||||
const firstChar = from[0];
|
||||
const secondChar = from[1];
|
||||
const to = line.substr(splitIndex + 2).trim();
|
||||
|
||||
const existingMapping = mapping.get(firstChar);
|
||||
if (existingMapping) {
|
||||
existingMapping.set(secondChar, to);
|
||||
} else {
|
||||
mapping.set(firstChar, new Map<string, string>([[secondChar, to]]));
|
||||
}
|
||||
}
|
||||
|
||||
return { orig, mapping };
|
||||
}
|
||||
|
||||
private executeStep(orig: string, mapping: Map<string, Map<string, string>>): string {
|
||||
|
||||
let res = "";
|
||||
for (let i = 0; i < orig.length - 1; i++) {
|
||||
|
||||
const char = orig[i];
|
||||
res += char;
|
||||
const firstCharMatch = mapping.get(char);
|
||||
if (firstCharMatch) {
|
||||
const secondChar = orig[i + 1];
|
||||
const toAdd = firstCharMatch.get(secondChar);
|
||||
if (toAdd) {
|
||||
res += toAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Add the last character as it's not included in the result
|
||||
res += orig[orig.length - 1];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
part2(input: string[]): number | string {
|
||||
|
||||
const { orig, mapping } = Day14.parseInput(input);
|
||||
|
||||
let counts: CharCounts = {};
|
||||
const cache = new Map<string, CharCounts>();
|
||||
for (let i = 0; i < orig.length - 1; i++) {
|
||||
|
||||
const firstChar = orig[i];
|
||||
const secondChar = orig[i + 1];
|
||||
|
||||
this.addOne(firstChar, counts);
|
||||
this.mergeIntoLeft(counts, this.calculateRecursive(firstChar, secondChar, mapping, 40, cache));
|
||||
|
||||
}
|
||||
this.addOne(orig[orig.length - 1], counts);
|
||||
|
||||
return (Utils.bigMax(Object.values(counts)) - Utils.bigMin(Object.values(counts))).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amount of added element of each type
|
||||
*/
|
||||
calculateRecursive(firstChar: string, secondChar: string, mappings: Map<string, Map<string, string>>, stepsLeft: number, cache: Map<string, CharCounts>): CharCounts {
|
||||
|
||||
if (stepsLeft === 0) return {};
|
||||
|
||||
const cacheKey = firstChar + secondChar + stepsLeft;
|
||||
const cachedResult = cache.get(cacheKey);
|
||||
if (cachedResult) return cachedResult;
|
||||
|
||||
const res = {};
|
||||
|
||||
const firstCharMatch = mappings.get(firstChar);
|
||||
if (firstCharMatch) {
|
||||
const toAdd = firstCharMatch.get(secondChar);
|
||||
if (toAdd) {
|
||||
this.addOne(toAdd, res);
|
||||
this.mergeIntoLeft(res, this.calculateRecursive(firstChar, toAdd, mappings, stepsLeft - 1, cache));
|
||||
this.mergeIntoLeft(res, this.calculateRecursive(toAdd, secondChar, mappings, stepsLeft - 1, cache));
|
||||
}
|
||||
}
|
||||
|
||||
cache.set(cacheKey, res);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
mergeIntoLeft(left: CharCounts, right: CharCounts) {
|
||||
|
||||
for (const rightKey in right) {
|
||||
if (rightKey in left) {
|
||||
left[rightKey] += right[rightKey];
|
||||
} else {
|
||||
left[rightKey] = right[rightKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addOne(char: string, counts: CharCounts) {
|
||||
|
||||
if (char in counts) {
|
||||
counts[char]++;
|
||||
} else {
|
||||
counts[char] = 1n;
|
||||
}
|
||||
}
|
||||
|
||||
// calculateCounts(pair: string, mappings: Map<string, Map<string, string>>, cache: Map<string, Map<number, {[key: string]: bigint}>>): {[key: string]: bigint} {
|
||||
//
|
||||
//
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
export default Day14;
|
||||
@@ -15,6 +15,7 @@ import Day10 from "./day10";
|
||||
import Day11 from "./day11";
|
||||
import Day12 from "./day12";
|
||||
import Day13 from "./day13";
|
||||
import Day14 from "./day14";
|
||||
|
||||
|
||||
// // Start writing Firebase Functions
|
||||
@@ -44,6 +45,7 @@ export const day = {
|
||||
11: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day11(), request, response) }),
|
||||
12: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day12(), request, response) }),
|
||||
13: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day13(), request, response) }),
|
||||
14: functions.region("europe-west1").https.onRequest((request, response) => { processDay(new Day14(), request, response) }),
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,14 @@ class Utils {
|
||||
return values.reduce((a, b) => a + b);
|
||||
}
|
||||
|
||||
static bigMax(values: bigint[]): bigint {
|
||||
return values.reduce((a, b) => a > b ? a : b);
|
||||
}
|
||||
|
||||
static bigMin(values: bigint[]): bigint {
|
||||
return values.reduce((a, b) => a < b ? a : b);
|
||||
}
|
||||
|
||||
static zeroes(length: number): number[] {
|
||||
|
||||
const res = [];
|
||||
@@ -31,4 +39,4 @@ class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
export default Utils;
|
||||
export default Utils;
|
||||
|
||||
23
input/day/14-example.http
Normal file
23
input/day/14-example.http
Normal file
@@ -0,0 +1,23 @@
|
||||
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-14
|
||||
Content-Type: text/plain
|
||||
|
||||
NNCB
|
||||
|
||||
CH -> B
|
||||
HH -> N
|
||||
CB -> H
|
||||
NH -> C
|
||||
HB -> C
|
||||
HC -> B
|
||||
HN -> C
|
||||
NN -> C
|
||||
BH -> H
|
||||
NC -> B
|
||||
NB -> B
|
||||
BN -> B
|
||||
BB -> N
|
||||
BC -> B
|
||||
CC -> N
|
||||
CN -> C
|
||||
|
||||
###
|
||||
107
input/day/14.http
Normal file
107
input/day/14.http
Normal file
@@ -0,0 +1,107 @@
|
||||
POST http://localhost:5001/advent-of-code-2021-911a8/europe-west1/day-14
|
||||
Content-Type: text/plain
|
||||
|
||||
CNBPHFBOPCSPKOFNHVKV
|
||||
|
||||
CS -> S
|
||||
FB -> F
|
||||
VK -> V
|
||||
HO -> F
|
||||
SO -> K
|
||||
FK -> B
|
||||
VS -> C
|
||||
PS -> H
|
||||
HH -> P
|
||||
KH -> V
|
||||
PV -> V
|
||||
CB -> N
|
||||
BB -> N
|
||||
HB -> B
|
||||
HV -> O
|
||||
NC -> H
|
||||
NF -> B
|
||||
HP -> B
|
||||
HK -> S
|
||||
SF -> O
|
||||
ON -> K
|
||||
VN -> V
|
||||
SB -> H
|
||||
SK -> H
|
||||
VH -> N
|
||||
KN -> C
|
||||
CC -> N
|
||||
BF -> H
|
||||
SN -> N
|
||||
KP -> B
|
||||
FO -> N
|
||||
KO -> V
|
||||
BP -> O
|
||||
OK -> F
|
||||
HC -> B
|
||||
NH -> O
|
||||
SP -> O
|
||||
OO -> S
|
||||
VC -> O
|
||||
PC -> F
|
||||
VB -> O
|
||||
FF -> S
|
||||
BS -> F
|
||||
KS -> F
|
||||
OV -> P
|
||||
NB -> O
|
||||
CF -> F
|
||||
SS -> V
|
||||
KV -> K
|
||||
FP -> F
|
||||
KC -> C
|
||||
PF -> C
|
||||
OS -> C
|
||||
PN -> B
|
||||
OP -> C
|
||||
FN -> F
|
||||
OF -> C
|
||||
NP -> C
|
||||
CK -> N
|
||||
BN -> K
|
||||
BO -> K
|
||||
OH -> S
|
||||
BH -> O
|
||||
SH -> N
|
||||
CH -> K
|
||||
PO -> V
|
||||
CN -> N
|
||||
BV -> F
|
||||
FV -> B
|
||||
VP -> V
|
||||
FS -> O
|
||||
NV -> P
|
||||
PH -> C
|
||||
HN -> P
|
||||
VV -> C
|
||||
NK -> K
|
||||
CO -> N
|
||||
NS -> P
|
||||
VO -> P
|
||||
CP -> V
|
||||
OC -> S
|
||||
PK -> V
|
||||
NN -> F
|
||||
SC -> P
|
||||
BK -> F
|
||||
BC -> P
|
||||
FH -> B
|
||||
OB -> O
|
||||
FC -> N
|
||||
PB -> N
|
||||
VF -> N
|
||||
PP -> S
|
||||
HS -> O
|
||||
HF -> N
|
||||
KK -> C
|
||||
KB -> N
|
||||
SV -> N
|
||||
KF -> K
|
||||
CV -> N
|
||||
NO -> P
|
||||
|
||||
###
|
||||
Reference in New Issue
Block a user