Advertisement
Guest User

Untitled

a guest
Dec 27th, 2023
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { readFileSync } from 'fs'
  2.  
  3. let input = `.|...\\....
  4. |.-.\\.....
  5. .....|-...
  6. ........|.
  7. ..........
  8. .........\\
  9. ..../.\\\\..
  10. .-.-/..|..
  11. .|....-|.\\
  12. ..//.|....`
  13.  
  14. function parse(input: string): string[][] {
  15.     const lines = input.trim().split('\n')
  16.     return Array.from({ length: lines.length }, (_, y) =>
  17.         Array.from({ length: lines[0].length }, (_, x) => lines[y][x]),
  18.     )
  19. }
  20.  
  21. function isOutOfBounds({ x, y }: State, grid: string[][]): boolean {
  22.     return x < 0 || y < 0 || y >= grid.length || x >= grid[0].length
  23. }
  24.  
  25. type Direction = 'up' | 'down' | 'left' | 'right'
  26.  
  27. type State = {
  28.     x: number
  29.     y: number
  30.     direction: Direction
  31.     seen: Set<string>
  32. }
  33.  
  34. function move(state: State): State {
  35.     const { x, y, direction } = state
  36.     switch (direction) {
  37.         case 'up':
  38.             return { ...state, y: y - 1 }
  39.         case 'down':
  40.             return { ...state, y: y + 1 }
  41.         case 'left':
  42.             return { ...state, x: x - 1 }
  43.         case 'right':
  44.             return { ...state, x: x + 1 }
  45.     }
  46. }
  47.  
  48. function solve(
  49.     grid: string[][],
  50.     x: number,
  51.     y: number,
  52.     direction: Direction,
  53. ): number {
  54.     const state: State = {
  55.         x,
  56.         y,
  57.         direction,
  58.         // A path history of (x,y,direction) so we can detect when beam is stuck in cycle
  59.         seen: new Set(),
  60.     }
  61.     const energized = new Set<string>()
  62.  
  63.     function step(state: State) {
  64.         if (isOutOfBounds(state, grid)) return
  65.  
  66.         const { x, y, direction, seen } = state
  67.  
  68.         //Check for path cycle
  69.         const key = `${x},${y},${direction}`
  70.         if (seen.has(key)) return
  71.         seen.add(key)
  72.  
  73.         energized.add(`${x},${y}`)
  74.  
  75.         // render(grid, energized)
  76.         switch (grid[y][x]) {
  77.             case '.':
  78.                 step(move(state))
  79.                 break
  80.             case '|':
  81.                 switch (direction) {
  82.                     case 'up':
  83.                     case 'down':
  84.                         step(move(state))
  85.                         break
  86.                     case 'left':
  87.                     case 'right':
  88.                         step(move({ ...state, direction: 'up' }))
  89.                         step(move({ ...state, direction: 'down' }))
  90.                         break
  91.                 }
  92.                 break
  93.             case '-':
  94.                 switch (direction) {
  95.                     case 'left':
  96.                     case 'right':
  97.                         step(move(state))
  98.                         break
  99.                     case 'up':
  100.                     case 'down':
  101.                         step(move({ ...state, direction: 'left' }))
  102.                         step(move({ ...state, direction: 'right' }))
  103.                         break
  104.                 }
  105.                 break
  106.             case '/':
  107.                 switch (direction) {
  108.                     case 'up':
  109.                         step(move({ ...state, direction: 'right' }))
  110.                         break
  111.                     case 'down':
  112.                         step(move({ ...state, direction: 'left' }))
  113.                         break
  114.                     case 'left':
  115.                         step(move({ ...state, direction: 'down' }))
  116.                         break
  117.                     case 'right':
  118.                         step(move({ ...state, direction: 'up' }))
  119.                         break
  120.                 }
  121.                 break
  122.             case '\\':
  123.                 switch (direction) {
  124.                     case 'up':
  125.                         step(move({ ...state, direction: 'left' }))
  126.                         break
  127.                     case 'down':
  128.                         step(move({ ...state, direction: 'right' }))
  129.                         break
  130.                     case 'left':
  131.                         step(move({ ...state, direction: 'up' }))
  132.                         break
  133.                     case 'right':
  134.                         step(move({ ...state, direction: 'down' }))
  135.                         break
  136.                 }
  137.                 break
  138.         }
  139.     }
  140.  
  141.     step(state)
  142.     // render(grid, energized)
  143.     return energized.size
  144. }
  145.  
  146. function render(grid: string[][], energized: Set<string>) {
  147.     for (let y = 0; y < grid.length; y++) {
  148.         let row = ''
  149.         for (let x = 0; x < grid[0].length; x++) {
  150.             row += energized.has(`${x},${y}`) ? '#' : grid[y][x]
  151.         }
  152.         console.log(row)
  153.     }
  154. }
  155.  
  156. function part1(input: string): number {
  157.     const grid = parse(input)
  158.     return solve(grid, 0, 0, 'right')
  159. }
  160.  
  161. function part2(input: string): number {
  162.     const grid = parse(input)
  163.  
  164.     let maxEnergized = 0
  165.  
  166.     for (let x = 0; x < grid[0].length; x++) {
  167.         // top row going down
  168.         maxEnergized = Math.max(maxEnergized, solve(grid, x, 0, 'down'))
  169.         // bot row going up
  170.         maxEnergized = Math.max(
  171.             maxEnergized,
  172.             solve(grid, x, grid.length - 1, 'up'),
  173.         )
  174.     }
  175.  
  176.     for (let y = 0; y < grid.length; y++) {
  177.         // left col going right
  178.         maxEnergized = Math.max(maxEnergized, solve(grid, 0, y, 'right'))
  179.         // right col going left
  180.         maxEnergized = Math.max(
  181.             maxEnergized,
  182.             solve(grid, grid[0].length - 1, y, 'left'),
  183.         )
  184.     }
  185.  
  186.     return maxEnergized
  187. }
  188.  
  189. input = readFileSync('day16.txt', { encoding: 'utf8' })
  190. console.log('part 1:', part1(input))
  191. console.log('part 2:', part2(input))
  192.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement