advent-of-code

Entries to advent of code, multiple years
git clone git://git.finwo.net/misc/advent-of-code
Log | Files | Refs

commit a18a0a19e04eb15235442166047e4b856b826785
parent 5654a2ecf00f278afc61fb6177ada182d1154f12
Author: finwo <finwo@pm.me>
Date:   Thu,  9 Dec 2021 21:30:02 +0100

Finished part 2 of day 3

Diffstat:
Rassets/day-01/input-01 -> assets/day-01/input | 0
Rassets/day-02/input-01 -> assets/day-02/input | 0
Rassets/day-03/input-01 -> assets/day-03/input | 0
Msrc/common/index.ts | 3+++
Asrc/common/most-weighted-value.ts | 33+++++++++++++++++++++++++++++++++
Asrc/common/weighted-value.ts | 4++++
Asrc/common/weighted-values.ts | 17+++++++++++++++++
Msrc/day-01/puzzle-01.ts | 2+-
Msrc/day-01/puzzle-02.ts | 2+-
Msrc/day-02/puzzle-01.ts | 2+-
Msrc/day-02/puzzle-02.ts | 2+-
Msrc/day-03/puzzle-01.ts | 2+-
Msrc/day-03/puzzle-02.ts | 77++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------------------
13 files changed, 118 insertions(+), 26 deletions(-)

diff --git a/assets/day-01/input-01 b/assets/day-01/input diff --git a/assets/day-02/input-01 b/assets/day-02/input diff --git a/assets/day-03/input-01 b/assets/day-03/input diff --git a/src/common/index.ts b/src/common/index.ts @@ -1,2 +1,5 @@ export * from './line-by-line'; +export * from './most-weighted-value'; export * from './sum'; +export * from './weighted-value'; +export * from './weighted-values'; diff --git a/src/common/most-weighted-value.ts b/src/common/most-weighted-value.ts @@ -0,0 +1,33 @@ +import { WeightedValue } from './weighted-value'; + +/** + * Returns the most weighted value + */ +export function mostWeightedValue(values: WeightedValue[], keepDuplicate = true) { + let chosen: WeightedValue = { weight: -1, value: undefined }; + let matchesFound = 0; + for(const weightedValue of values) { + + // Track if there are equals + if (weightedValue.weight == chosen.weight) { + matchesFound++; + } + + // Skip lte + if (weightedValue.weight <= chosen.weight) { + continue; + } + + // Found a new high + chosen = weightedValue; + matchesFound = 0; + } + + // equal weights may need to be discarded + if (matchesFound && (!keepDuplicate)) { + return undefined; + } + + // Return highest weighted value + return chosen.value; +} diff --git a/src/common/weighted-value.ts b/src/common/weighted-value.ts @@ -0,0 +1,4 @@ +export type WeightedValue = { + weight: number; + value : any; +}; diff --git a/src/common/weighted-values.ts b/src/common/weighted-values.ts @@ -0,0 +1,17 @@ +import { WeightedValue } from './weighted-value'; + +export function weightedValues(arr: any[]): WeightedValue[] { + const storage: WeightedValue[] = []; + for(const value of arr) { + let found: WeightedValue = storage.find(a => a.value === value); + if (found) { + found.weight++; + } else { + storage.push({ + weight: 1, + value + }); + } + } + return storage; +} diff --git a/src/day-01/puzzle-01.ts b/src/day-01/puzzle-01.ts @@ -11,7 +11,7 @@ let texts = [ (async () => { - await lineByLine(__dirname + '/input-01', line => { + await lineByLine(__dirname + '/input', line => { if ((!line) || isNaN(line)) return; const depth = parseInt(line); diff --git a/src/day-01/puzzle-02.ts b/src/day-01/puzzle-02.ts @@ -12,7 +12,7 @@ let texts = [ (async () => { - await lineByLine(__dirname + '/input-01', line => { + await lineByLine(__dirname + '/input', line => { if ((!line) || isNaN(line)) return; const depth = parseInt(line); history.push(depth); diff --git a/src/day-02/puzzle-01.ts b/src/day-02/puzzle-01.ts @@ -4,7 +4,7 @@ const position = { x: 0, y: 0 }; (async () => { - await lineByLine(__dirname + '/input-01', line => { + await lineByLine(__dirname + '/input', line => { if (!line) return; let [command,range] = line.split(' '); range = parseInt(range); diff --git a/src/day-02/puzzle-02.ts b/src/day-02/puzzle-02.ts @@ -5,7 +5,7 @@ let aim = 0; (async () => { - await lineByLine(__dirname + '/input-01', line => { + await lineByLine(__dirname + '/input', line => { if (!line) return; let [command,range] = line.split(' '); range = parseInt(range); diff --git a/src/day-03/puzzle-01.ts b/src/day-03/puzzle-01.ts @@ -5,7 +5,7 @@ let lines = 0; (async () => { - await lineByLine(__dirname + '/input-01', line => { + await lineByLine(__dirname + '/input', line => { if (!line) return; const lineValues = line.split(''); diff --git a/src/day-03/puzzle-02.ts b/src/day-03/puzzle-02.ts @@ -1,35 +1,70 @@ -import { lineByLine } from '../common'; +import { + lineByLine, + weightedValues, + mostWeightedValue +} from '../common'; -const position = { x: 0, y: 0 }; -let aim = 0; +// let values = null; +// let lines = 0; (async () => { - await lineByLine(__dirname + '/input-01', line => { + // Read whole input into memory this time + const storage = []; + await lineByLine(__dirname + '/input', line => { if (!line) return; - let [command,range] = line.split(' '); - range = parseInt(range); - - switch(command) { - case 'up' : aim -= range; break; - case 'down' : aim += range; break; - case 'forward': position.x += range; position.y += aim * range; break; - default: - throw new Error(`Unknown command: ${command}`); - } + storage.push(line.split('').map(v => parseInt(v, 2))); }); + // The things we need to filter + let oxygenReadings = storage.slice(); + let scrubberReadings = storage.slice(); + + // Filter the oxygen readings + for(let idx = 0 ; oxygenReadings.length > 1 ; idx++) { + const column = oxygenReadings.map(a => a[idx]); + const weights = weightedValues(column); + let mostCommon = mostWeightedValue(weights, false); + + // Equal = 1, as specified + if (mostCommon === undefined) { + mostCommon = 1; + } + + // Remove non-matching values + oxygenReadings = oxygenReadings.filter(v => v[idx] == mostCommon); + } + + // Filter the scrubber readings + for(let idx = 0 ; scrubberReadings.length > 1 ; idx++) { + const column = scrubberReadings.map(a => a[idx]); + const weights = weightedValues(column); + let mostCommon = mostWeightedValue(weights, false); + + // Equal = 1, as inverted of specified + if (mostCommon === undefined) { + mostCommon = 1; + } + + // Invert, we're working binary-ish + const leastCommon = (!mostCommon) | 0; + + // Remove non-matching values + scrubberReadings = scrubberReadings.filter(v => v[idx] == leastCommon); + } + + // Convert into numbers again + const oxygenRating = parseInt(oxygenReadings[0].join(''), 2); + const scrubberRating = parseInt(scrubberReadings[0].join(''), 2); + const lifeSupportRating = oxygenRating * scrubberRating; + process.stdout.write('\n\n'); process.stdout.write('---[ REPORT ]---\n'); process.stdout.write('\n'); - process.stdout.write(`Position\n`); - process.stdout.write(` X: ${position.x}\n`); - process.stdout.write(` Y: ${position.y}\n`); - process.stdout.write('\n'); - process.stdout.write(`Puzzle\n`); - process.stdout.write(` mult: ${position.x * position.y}\n`); + process.stdout.write(`oxygen rating : ${oxygenRating}\n`); + process.stdout.write(`scrubber rating : ${scrubberRating}\n`); + process.stdout.write(`life support rating : ${lifeSupportRating}\n`); process.stdout.write('\n'); - })();