Add day 6 (Part 1 complete, Part 2 theoretically complete but needs optimization to actually finish)
Change-Id: I2ff05098d5f0dede9d4b244c7b9e70dc0dc670b9
Reviewed-on: https://git.clicks.codes/c/Coded/AoC2023/+/167
diff --git a/day 4/index.ts b/day 4/index.ts
index 8643cc2..f12ba25 100644
--- a/day 4/index.ts
+++ b/day 4/index.ts
@@ -1,5 +1,6 @@
import { readFileSync } from "fs";
+const time = Date.now();
const input = readFileSync('day 4/input.txt').toString().split('\n');
interface Card {
@@ -75,4 +76,7 @@
console.log(`(Part 2) Total Scratchcards: ${newCards.reduce((acc, curr) => {
return acc + curr.copies;
}, 0)}`)
-})();
\ No newline at end of file
+})();
+
+
+console.log(`Total Time (In millis): ${Date.now() - time}`)
diff --git a/day 5/index.ts b/day 5/index.ts
new file mode 100644
index 0000000..8b8d063
--- /dev/null
+++ b/day 5/index.ts
@@ -0,0 +1,166 @@
+import { readFileSync } from "fs";
+
+const input = readFileSync('day 5/input.txt').toString().split('\n\n')
+
+interface MappedRange {
+ startRange: [number, number];
+ offset: number;
+}
+
+interface Input {
+ sts: MappedRange[];
+ stf: MappedRange[];
+ ftw: MappedRange[];
+ wtl: MappedRange[];
+ ltt: MappedRange[];
+ tth: MappedRange[];
+ htl: MappedRange[];
+}
+
+
+function pointerMap(array: number[][]): MappedRange[] {
+ return array.map(arr => {
+ const startRange: [number, number] = [arr[1], arr[1] + arr[2]];
+ const offset = arr[0] - arr[1];
+ console.log(`Made descriptor (start -> dest): ${arr[1]} -> ${arr[0]} ... ${arr[1] + offset} -> ${arr[0] + offset}`)
+ return {
+ startRange,
+ offset
+ }
+ })
+}
+
+function findSmallestLocation(seeds: number[], mappedInput: Input): {
+ seed: number;
+ location: number;
+} {
+ const locations: {seed: number, location: number}[] = [];
+ for(const seed of seeds) {
+ console.log(`Checking seed ${seed}`)
+
+ let s = mappedInput.sts.find(o => o.startRange[0] <= seed && seed <= o.startRange[1])
+ const soil = (s ? s.offset + seed : null) ?? seed
+ console.log(soil === seed ? `Continuing with default` : `Found ${soil}`)
+
+ let f = mappedInput.stf.find(o => o.startRange[0] <= soil && soil <= o.startRange[1])
+ const fertilizer = (f ? f.offset + soil : null) ?? soil
+ console.log(fertilizer === soil ? `Continuing with default` : `Found ${fertilizer}`)
+
+ let w = mappedInput.ftw.find(o => o.startRange[0] <= fertilizer && fertilizer <= o.startRange[1])
+ const water = (w ? w.offset + fertilizer : null) ?? fertilizer
+ console.log(water === fertilizer ? `Continuing with default` : `Found ${water}`)
+
+ let li = mappedInput.wtl.find(o => o.startRange[0] <= water && water <= o.startRange[1])
+ const light = (li ? li.offset + water : null) ?? water
+ console.log(light === water ? `Continuing with default` : `Found ${light}`)
+
+ let t = mappedInput.ltt.find(o => o.startRange[0] <= light && light <= o.startRange[1])
+ const temperature = (t ? t.offset + light : null) ?? light
+ console.log(temperature === light ? `Continuing with default` : `Found ${temperature}`)
+
+ let h = mappedInput.tth.find(o => o.startRange[0] <= temperature && temperature <= o.startRange[1])
+ const humidity = (h ? h.offset + temperature : null) ?? temperature
+ console.log(humidity === temperature ? `Continuing with default` : `Found ${humidity}`)
+
+ let lo = mappedInput.htl.find(o => o.startRange[0] <= humidity && humidity <= o.startRange[1])
+ const location = (lo ? lo.offset + humidity : null) ?? humidity
+ console.log(location === humidity ? `Continuing with default` : `Found ${location}`)
+
+ locations.push({seed, location})
+ }
+
+ const sorted = locations.sort((a,b) => a.location < b.location ? -1 : 1);
+ return sorted[0]
+}
+
+const mappedInput: Input = {
+ sts: pointerMap(input[1].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
+ stf: pointerMap(input[2].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
+ ftw: pointerMap(input[3].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
+ wtl: pointerMap(input[4].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
+ ltt: pointerMap(input[5].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
+ tth: pointerMap(input[6].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)))),
+ htl: pointerMap(input[7].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n))))
+};
+console.log(`Generating descriptors for seed to soil`);
+console.log(`Generating descriptors for soil to fertilizer`);
+console.log(`Generating descriptors for fertilizer to water`);
+console.log(`Generating descriptors for water to light`);
+console.log(`Generating descriptors for light to temp`);
+console.log(`Generating descriptors for temp to humidity`);
+console.log(`Generating descriptors for humidity to location`);
+
+
+// Part 1
+;(() => {
+ const seeds = input[0].split(':')[1].trim().split(' ').map(i => parseInt(i));
+ const smallest = findSmallestLocation(seeds, mappedInput)
+
+ console.log(`(Part 1) Lowest location number: (seed: ${smallest.seed}) ${smallest.location}`)
+})();
+
+
+// Part 2
+
+function findSmallestLocationRange(seeds: number[], mappedInput: Input): {
+ seed: number;
+ location: number;
+} {
+ const locations: {seed: number, location: number}[] = [];
+ for(const seed of seeds) {
+
+ console.log(`Checking seed ${seed}`)
+
+ let s = mappedInput.sts.find(o => o.startRange[0] <= seed && seed <= o.startRange[1])
+ const soil = (s ? s.offset + seed : null) ?? seed
+ console.log(soil === seed ? `Continuing with default` : `Found ${soil}`)
+
+ let f = mappedInput.stf.find(o => o.startRange[0] <= soil && soil <= o.startRange[1])
+ const fertilizer = (f ? f.offset + soil : null) ?? soil
+ console.log(fertilizer === soil ? `Continuing with default` : `Found ${fertilizer}`)
+
+ let w = mappedInput.ftw.find(o => o.startRange[0] <= fertilizer && fertilizer <= o.startRange[1])
+ const water = (w ? w.offset + fertilizer : null) ?? fertilizer
+ console.log(water === fertilizer ? `Continuing with default` : `Found ${water}`)
+
+ let li = mappedInput.wtl.find(o => o.startRange[0] <= water && water <= o.startRange[1])
+ const light = (li ? li.offset + water : null) ?? water
+ console.log(light === water ? `Continuing with default` : `Found ${light}`)
+
+ let t = mappedInput.ltt.find(o => o.startRange[0] <= light && light <= o.startRange[1])
+ const temperature = (t ? t.offset + light : null) ?? light
+ console.log(temperature === light ? `Continuing with default` : `Found ${temperature}`)
+
+ let h = mappedInput.tth.find(o => o.startRange[0] <= temperature && temperature <= o.startRange[1])
+ const humidity = (h ? h.offset + temperature : null) ?? temperature
+ console.log(humidity === temperature ? `Continuing with default` : `Found ${humidity}`)
+
+ let lo = mappedInput.htl.find(o => o.startRange[0] <= humidity && humidity <= o.startRange[1])
+ const location = (lo ? lo.offset + humidity : null) ?? humidity
+ console.log(location === humidity ? `Continuing with default` : `Found ${location}`)
+
+ locations.push({seed, location})
+ }
+
+ const sorted = locations.sort((a,b) => a.location < b.location ? -1 : 1);
+ return sorted[0]
+}
+
+
+
+;(() => {
+ const unformattedSeeds = input[0].split(':')[1].trim().match(/(\d+ \d+)/g)?.map(i => i.split(' ').map(n => parseInt(n.trim())))
+ const seeds: number[] = [];
+
+ if(!unformattedSeeds) throw new Error('How did this happen')
+
+ for(const US of unformattedSeeds) {
+ for(let i = 0; i < US[1]; i++) {
+ seeds.push(US[0] + i);
+ }
+ }
+
+ const smallest = findSmallestLocation(seeds, mappedInput)
+
+ console.log(`(Part 2) Lowest location number: (seed: ${smallest.seed}) ${smallest.location}`)
+})();
\ No newline at end of file
diff --git a/day 5/old.ts b/day 5/old.ts
new file mode 100644
index 0000000..7654183
--- /dev/null
+++ b/day 5/old.ts
@@ -0,0 +1,97 @@
+import { readFileSync } from "fs";
+
+const input = readFileSync('day 5/input.txt').toString().split('\n\n')
+
+interface MappedRange {
+ start: number;
+ dest: number;
+ rangeLength: number;
+ pointers: Record<number, number>;
+}
+
+interface Input {
+ seeds?: number[];
+ sts?: MappedRange[];
+ stf?: MappedRange[];
+ ftw?: MappedRange[];
+ wtl?: MappedRange[];
+ ltt?: MappedRange[];
+ tth?: MappedRange[];
+ htl?: MappedRange[];
+}
+
+
+const mappedInput: Input = {};
+
+mappedInput.seeds = input[0].split(':')[1].trim().split(' ').map(i => parseInt(i));
+const sts = input[1].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)));
+const stf = input[2].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)));
+const ftw = input[3].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)));
+const wtl = input[4].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)));
+const ltt = input[5].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)));
+const tth = input[6].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)));
+const htl = input[7].split(':')[1].trim().split('\n').map(i => i.split(' ').map(n => parseInt(n)));
+
+function pointerMap(array: number[][]) {
+ return array.map(arr => {
+ const pointers: Record<number, number> = {}
+ for(Object.keys(pointers).length; Object.keys(pointers).length < arr[2];) {
+ const start = arr[1] + Object.keys(pointers).length;
+ const dest = arr[0] + Object.keys(pointers).length
+ console.log(`Creating Pointer ${start} => ${dest}`)
+ pointers[start] = dest;
+ }
+
+ return {
+ pointers,
+ rangeLength: arr[2],
+ start: arr[1],
+ dest: arr[0]
+ }
+ })
+}
+console.log(`Generating Pointers for seed to soil`)
+mappedInput.sts = pointerMap(sts);
+console.log(`Generating Pointers for soil to fertilizer`)
+mappedInput.stf = pointerMap(stf);
+console.log(`Generating Pointers for fertilizer to water`)
+mappedInput.ftw = pointerMap(ftw);
+console.log(`Generating Pointers for water to light`)
+mappedInput.wtl = pointerMap(wtl);
+console.log(`Generating Pointers for light to temp`)
+mappedInput.ltt = pointerMap(ltt);
+console.log(`Generating Pointers for temp to humidity`)
+mappedInput.tth = pointerMap(tth);
+console.log(`Generating Pointers for humidity to location`)
+mappedInput.htl = pointerMap(htl);
+
+
+// Part 1
+(() => {
+ const locations: {seed: number, location: number}[] = []
+ for(const seed of mappedInput.seeds) {
+ console.log(`Checking ${seed}`)
+
+ const soil = mappedInput.stf.find(s => Object.keys(s.pointers).includes(seed.toString()))?.pointers[seed] ?? seed
+ console.log(soil === seed ? `Continuing with default` : `Found ${soil}`)
+ const fertilizer = mappedInput.stf.find(s => Object.keys(s.pointers).includes(soil.toString()))?.pointers[soil] ?? soil
+ console.log(fertilizer === soil ? `Continuing with default` : `Found ${fertilizer}`)
+ const water = mappedInput.stf.find(s => Object.keys(s.pointers).includes(fertilizer.toString()))?.pointers[fertilizer] ?? fertilizer
+ console.log(water === fertilizer ? `Continuing with default` : `Found ${water}`)
+ const light = mappedInput.stf.find(s => Object.keys(s.pointers).includes(water.toString()))?.pointers[water] ?? water
+ console.log(light === water ? `Continuing with default` : `Found ${light}`)
+ const temperature = mappedInput.stf.find(s => Object.keys(s.pointers).includes(light.toString()))?.pointers[light] ?? light
+ console.log(temperature === light ? `Continuing with default` : `Found ${temperature}`)
+ const humidity = mappedInput.stf.find(s => Object.keys(s.pointers).includes(temperature.toString()))?.pointers[temperature] ?? temperature
+ console.log(humidity === temperature ? `Continuing with default` : `Found ${humidity}`)
+ const location = mappedInput.stf.find(s => Object.keys(s.pointers).includes(humidity.toString()))?.pointers[humidity] ?? humidity
+ console.log(location === humidity ? `Continuing with default` : `Found ${location}`)
+
+ locations.push({seed, location})
+ }
+
+ const sorted = locations.sort((a,b) => a.location < b.location ? -1 : 1);
+ console.log(sorted)
+ const smallest = sorted[0]
+ console.log(`(Part 1) Lowest location number: (seed: ${smallest.seed}) ${smallest.location}`)
+})();
\ No newline at end of file
diff --git a/day 5/testdata.txt b/day 5/testdata.txt
new file mode 100644
index 0000000..bd902a4
--- /dev/null
+++ b/day 5/testdata.txt
@@ -0,0 +1,33 @@
+seeds: 79 14 55 13
+
+seed-to-soil map:
+50 98 2
+52 50 48
+
+soil-to-fertilizer map:
+0 15 37
+37 52 2
+39 0 15
+
+fertilizer-to-water map:
+49 53 8
+0 11 42
+42 0 7
+57 7 4
+
+water-to-light map:
+88 18 7
+18 25 70
+
+light-to-temperature map:
+45 77 23
+81 45 19
+68 64 13
+
+temperature-to-humidity map:
+0 69 1
+1 0 69
+
+humidity-to-location map:
+60 56 37
+56 93 4
\ No newline at end of file