Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { readFileSync } from 'fs'
- let input = `.|...\\....
- |.-.\\.....
- .....|-...
- ........|.
- ..........
- .........\\
- ..../.\\\\..
- .-.-/..|..
- .|....-|.\\
- ..//.|....`
- function parse(input: string): string[][] {
- const lines = input.trim().split('\n')
- return Array.from({ length: lines.length }, (_, y) =>
- Array.from({ length: lines[0].length }, (_, x) => lines[y][x]),
- )
- }
- function isOutOfBounds({ x, y }: State, grid: string[][]): boolean {
- return x < 0 || y < 0 || y >= grid.length || x >= grid[0].length
- }
- type Direction = 'up' | 'down' | 'left' | 'right'
- type State = {
- x: number
- y: number
- direction: Direction
- seen: Set<string>
- }
- function move(state: State): State {
- const { x, y, direction } = state
- switch (direction) {
- case 'up':
- return { ...state, y: y - 1 }
- case 'down':
- return { ...state, y: y + 1 }
- case 'left':
- return { ...state, x: x - 1 }
- case 'right':
- return { ...state, x: x + 1 }
- }
- }
- function solve(input: string) {
- const grid = parse(input)
- const state: State = {
- x: 0,
- y: 0,
- direction: 'right',
- // A path history of (x,y,direction) so we can detect when beam is stuck in cycle
- seen: new Set(),
- }
- const energized = new Set<string>()
- function step(state: State) {
- if (isOutOfBounds(state, grid)) return
- const { x, y, direction, seen } = state
- //Check for path cycle
- const key = `${x},${y},${direction}`
- if (seen.has(key)) return
- seen.add(key)
- energized.add(`${x},${y}`)
- // render(grid, energized)
- switch (grid[y][x]) {
- case '.':
- step(move(state))
- break
- case '|':
- switch (direction) {
- case 'up':
- case 'down':
- step(move(state))
- break
- case 'left':
- case 'right':
- step(move({ ...state, direction: 'up' }))
- step(move({ ...state, direction: 'down' }))
- break
- }
- break
- case '-':
- switch (direction) {
- case 'left':
- case 'right':
- step(move(state))
- break
- case 'up':
- case 'down':
- step(move({ ...state, direction: 'left' }))
- step(move({ ...state, direction: 'right' }))
- break
- }
- break
- case '/':
- switch (direction) {
- case 'up':
- step(move({ ...state, direction: 'right' }))
- break
- case 'down':
- step(move({ ...state, direction: 'left' }))
- break
- case 'left':
- step(move({ ...state, direction: 'down' }))
- break
- case 'right':
- step(move({ ...state, direction: 'up' }))
- break
- }
- break
- case '\\':
- switch (direction) {
- case 'up':
- step(move({ ...state, direction: 'left' }))
- break
- case 'down':
- step(move({ ...state, direction: 'right' }))
- break
- case 'left':
- step(move({ ...state, direction: 'up' }))
- break
- case 'right':
- step(move({ ...state, direction: 'down' }))
- break
- }
- break
- }
- }
- step(state)
- render(grid, energized)
- console.log(energized.size)
- }
- function render(grid: string[][], energized: Set<string>) {
- for (let y = 0; y < grid.length; y++) {
- let row = ''
- for (let x = 0; x < grid[0].length; x++) {
- row += energized.has(`${x},${y}`) ? '#' : grid[y][x]
- }
- console.log(row)
- }
- }
- input = readFileSync('day16.txt', { encoding: 'utf8' })
- solve(input)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement