Advertisement
mosredna

AoC 2022 day 17

Dec 17th, 2022
1,336
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const fs = require("fs")
  2. const performance = require("perf_hooks").performance
  3. const eol = require("os").EOL
  4.  
  5. let startTime = performance.now()
  6. let part1 = (part2 = 0)
  7. let input = fs
  8.     .readFileSync(__dirname + "/data.txt", "utf8")
  9.     .split(eol)
  10.     .join("")
  11.     .split("")
  12. let chamber = [["#", "#", "#", "#", "#", "#", "#", "#", "#"]]
  13. let segment = ["#", ".", ".", ".", ".", ".", ".", ".", "#"]
  14.  
  15. let bloks = [
  16.     [["#", "#", "#", "#"]],
  17.     [
  18.         [".", "#", "."],
  19.         ["#", "#", "#"],
  20.         [".", "#", "."]
  21.     ],
  22.     [
  23.         ["#", "#", "#"],
  24.         [".", ".", "#"],
  25.         [".", ".", "#"]
  26.     ],
  27.     [["#"], ["#"], ["#"], ["#"]],
  28.     [
  29.         ["#", "#"],
  30.         ["#", "#"]
  31.     ]
  32. ]
  33. let steps = 1000000000000
  34. let blockIndex = 0
  35. let numBlocks = bloks.length
  36. let numjets = input.length
  37. let topIndex = 1
  38. let jetIndex = 0
  39.  
  40. function colides(block, blockX, blockY) {
  41.     return block.some((r, y) => {
  42.         return r.some((state, x) => {
  43.             return state == "#" && chamber[blockY + y][blockX + x] == "#"
  44.         })
  45.     })
  46. }
  47.  
  48. function checkRepeat() {
  49.     let l = topIndex - 1
  50.     let max = ~~(chamber.length / 2) - 5
  51.     let len = max
  52.     for (len; len > input.length / 5; len--) {
  53.         let same = true
  54.         for (let i = 0; i < len; i++) {
  55.             if (!chamber[l - i].every((el, ix) => el === chamber[l - (i + len)][ix])) {
  56.                 same = false
  57.                 break
  58.             }
  59.         }
  60.         if (same) {
  61.             return len
  62.         }
  63.     }
  64.     return -1
  65. }
  66. let repeatFound = false
  67. let repeatLength = 0
  68. let repeatNext = 0
  69. let repeatStep = 0
  70. let mult = 0
  71. while (steps--) {
  72.     let block = bloks[blockIndex]
  73.     let blockHeight = block.length
  74.     let blockY = topIndex + 3
  75.     let blockX = 3
  76.     while (blockY + blockHeight > chamber.length) {
  77.         chamber.push(segment.slice())
  78.     }
  79.  
  80.     while (true) {
  81.         let jet = input[jetIndex++ % numjets] == "<" ? -1 : +1
  82.         if (!colides(block, blockX + jet, blockY)) blockX += jet
  83.         if (!colides(block, blockX, blockY - 1)) {
  84.             blockY--
  85.         } else {
  86.             block.forEach((r, y) => {
  87.                 r.forEach((state, x) => {
  88.                     if (state == "#") chamber[blockY + y][blockX + x] = state
  89.                 })
  90.             })
  91.             topIndex = Math.max(blockY + blockHeight, topIndex)
  92.             break
  93.         }
  94.     }
  95.     if (mult === 0) {
  96.         if (!repeatFound) {
  97.             let repeat = checkRepeat()
  98.             if (repeat != -1) {
  99.                 repeatFound = true
  100.                 repeatNext = topIndex + repeat
  101.                 repeatLength = repeat
  102.                 repeatStep = steps
  103.             }
  104.         } else if (repeatNext == topIndex) {
  105.             repeatStep = repeatStep - steps
  106.             mult = Math.floor(steps / repeatStep)
  107.             let rest = steps % repeatStep
  108.             steps = rest
  109.         }
  110.     }
  111.     if (1000000000000 - steps == 2022) part1 = topIndex - 1
  112.     if (++blockIndex == numBlocks) blockIndex = 0
  113. }
  114. part2 = topIndex - 1 + mult * repeatLength
  115. let time = performance.now() - startTime
  116. console.log(`Part 1: ${part1}\nPart 2: ${part2}\nTimer: ${time} ms`)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement