aoc24/solutions/05.ts

66 lines
No EOL
2.3 KiB
TypeScript

import { solvables } from "../main.ts";
import type { Solvable } from "../solvable.ts";
import { readInput } from "../utils.ts";
class DayFive implements Solvable {
input: string[] = readInput('05').split('\n\n')
rules: number[][] = this.input[0].split('\n').map((input: string) => input.split('|').map(rule => Number.parseInt(rule)))
updates: number[][] = this.input[1].split('\n').map(line => line.split(',').map(update => Number.parseInt(update)))
// generated in part 1 for part 2
invalidUpdates: number[][] = []
followsRules = (update: number[]): [boolean, number, number] => {
for (const rule of this.rules) {
const left = update.findIndex((val) => val === rule[0])
const right = update.findIndex((val) => val === rule[1])
if (left === -1 || right === -1) continue
if (left > right) return [false, left, right]
}
return [true, -1, -1]
}
middles = (updates: number[][]): number =>
updates
.map((update: number[]) => update[Math.floor(update.length / 2)])
.reduce((prev, curr) => prev + curr)
public part1(): Solvable {
const validUpdates: number[][] = []
this.updates.forEach(update => {
if (this.followsRules(update)[0]) {
validUpdates.push(update)
} else {
// store these for part 2
this.invalidUpdates.push(update)
}
})
const result = this.middles(validUpdates)
console.log(result)
return this
}
public part2(): Solvable {
const invalidUpdates = this.invalidUpdates
const sort = (update: number[]): number[] => {
const [compliant, leftIdx, rightIdx] = this.followsRules(update)
if (!compliant) {
// remove offending item and just move it to the back
const removedLeft = update.splice(leftIdx, 1)[0]
const rebuiltUpdate = [...update.slice(0, rightIdx), removedLeft, ...update.slice(rightIdx)]
return sort(rebuiltUpdate)
} else {
return update
}
}
const fixedUpdates = invalidUpdates.map(updates => sort(updates))
const result = this.middles(fixedUpdates)
console.log(result)
return this
}
}
solvables.push(new DayFive())