aoc24/solutions/06.ts
2024-12-08 00:30:28 +01:00

123 lines
No EOL
3.9 KiB
TypeScript

import { solvables } from "../main.ts";
import type { Solvable } from "../solvable.ts";
import { readInput, delay } from "../utils.ts";
type Direction = "up" | "right" | "down" | "left"
class DaySix implements Solvable {
input: string[][] = readInput('06').split('\n').map(col => col.split(''))
map = this.input
visitedLoc: Map<string, null> = new Map()
// assigned in part1
startingPosition: [number, number] = [0, 0]
turnRight = (direction: Direction): Direction => {
switch (direction) {
case 'up':
return 'right'
case 'right':
return 'down'
case 'down':
return 'left'
case 'left':
return 'up'
}
}
lookAhead = (x: number, y: number, direction: Direction): [number, number] => {
switch (direction) {
case 'up':
return [x, y - 1]
case 'down':
return [x, y + 1]
case 'right':
return [x + 1, y]
case 'left':
return [x - 1, y]
}
}
// returns true if out of bounds
walk = (x: number, y: number, direction: Direction): [boolean, number, number, Direction] => {
const nextStepInBounds = {
up: y > 0,
down: y < this.map.length - 1,
left: x > 0,
right: x < this.map[0].length - 1,
}
// if oob, return true
if (!nextStepInBounds[direction]) {
console.log('went oob')
return [true, x, y, direction]
} else {
// console.log(y, x, direction)
// if obstacle ahead, return false and current location
const [nextX, nextY] = this.lookAhead(x, y, direction)
if (this.map[nextY][nextX] === '#') {
return [false, x, y, this.turnRight(direction)]
}
// if no obstacle ahead, return false and new location
return [false, nextX, nextY, direction]
}
}
// path [y, x][]
visualizePath = (path: string[]): string => {
const width = this.map[0].length
const screenMat: string[][] = []
for (let i = 0; i < width; i++) screenMat.push(this.map[i].slice())
for (const loc of path) {
const [y, x]: number[] = loc.split(',').map(coord => Number.parseInt(coord))
screenMat[y][x] = 'X'
}
const screen: string = screenMat.map((line: string[]) => line.join('')).join('\n')
return screen
}
public async part1(): Promise<Solvable> {
// find starting position
this.input.forEach((line, y) => line.forEach((char, x) => { if (char === '^') this.startingPosition = [y, x] }))
let [y, x] = [this.startingPosition[0], this.startingPosition[1]]
let direction: Direction = 'up'
let outOfBounds = false
this.visitedLoc.set(y + ',' + x, null) // starting position is a location
// let i = 0
while (!outOfBounds) {
[outOfBounds, x, y, direction] = this.walk(x, y, direction)
this.visitedLoc.set(y + ',' + x, null)
// console animation thingy
// if (i % 10 === 0) {
// const screen = this.visualizePath(this.visitedLoc.keys().toArray())
// console.log(screen)
// await delay(200)
// }
// i++
}
const path = this.visitedLoc.keys().toArray()
const result: number = path.length
console.log(this.visualizePath(path))
const allDistinct = path.filter((loc: string) => path.indexOf(loc) !== path.lastIndexOf(loc)).length === 0
console.log(allDistinct ? 'path values distinct' : 'path values not distinct')
console.log(result)
return new Promise(() => this)
}
public async part2(): Promise<Solvable> {
console.log()
return new Promise(() => this)
}
}
solvables.push(new DaySix())