Advertisement
Guest User

2023/23

a guest
Dec 23rd, 2023
646
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const utils = require('../../utils')
  2. const data = utils.byLine('./input.txt')
  3.  
  4. const START = data[0].indexOf('.')
  5. const END = data.at(-1).indexOf('.')
  6. const VECTORS = [[0, 1], [0, -1], [1, 0], [-1, 0]]
  7. const serialize = ([y, x]) => `${y}_${x}`
  8.  
  9. const getNeighbours = ([y, x], part2) => {
  10.     let neighbours = []
  11.     for (let [vy, vx] of VECTORS) {
  12.         let adjacent = data[y + vy]?.[x + vx]
  13.         if (!adjacent || adjacent === '#') continue
  14.         if (
  15.             part2 ||
  16.             (vx === -1 && adjacent === '<') ||
  17.             (vx === 1 && adjacent === '>') ||
  18.             (vy === -1 && adjacent === '^') ||
  19.             (vy === 1 && adjacent === 'v') ||
  20.             adjacent === '.'
  21.         ) {
  22.             neighbours.push([y + vy, x + vx])
  23.         }
  24.     }
  25.     return neighbours
  26. }
  27.  
  28. const junctions = new Set([
  29.     serialize([0, START]),
  30.     serialize([data.length - 1, END])
  31. ])
  32. utils.loopDataGrid(data, (y, x, point) => {
  33.     if (point === '#') return
  34.     let neighbours = getNeighbours([y, x], true)
  35.     if (neighbours.length > 2) {
  36.         junctions.add(serialize([y, x]))
  37.     }
  38. })
  39.  
  40. function go(distance, visited, forbidden, current, target, getNeighbours, onEnd) {
  41.     if (current[0] === target[0] && current[1] === target[1]) {
  42.         onEnd(distance)
  43.         return
  44.     }
  45.     if (distance && forbidden.has(serialize(current))) {
  46.         return
  47.     }
  48.    
  49.     for (let next of getNeighbours(current)) {
  50.         let key = serialize(next)
  51.         if (visited.has(key)) continue
  52.         visited.add(key)
  53.         go(distance + (next[2] ?? 1), visited, forbidden, next, target, getNeighbours, onEnd)
  54.         visited.delete(key)
  55.     }
  56. }
  57.  
  58. let graph = {}
  59. utils.pairs(Array.from(junctions), (a, b) => {
  60.     go(0, new Set(), junctions, ints(a), ints(b), (current) => getNeighbours(current, true), (distance) => {
  61.         graph[a] ??= new Set()
  62.         graph[b] ??= new Set()
  63.         graph[a].add([...ints(b), distance])
  64.         graph[b].add([...ints(a), distance])
  65.     })
  66. })
  67.  
  68. let p1 = 0
  69. go(0, new Set(), new Set(), [0, START], [data.length - 1, END], getNeighbours, (distance) => {
  70.     if (distance > p1) {
  71.         p1 = distance
  72.     }
  73. })
  74.  
  75. let p2 = 0
  76. go(0, new Set(), new Set(), [0, START], [data.length - 1, END], (current) => graph[serialize(current)], (distance) => {
  77.     if (distance > p2) {
  78.         p2 = distance
  79.     }
  80. })
  81.  
  82. log('Part 1', p1)
  83. log('Part 2', p2)
  84.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement