mosredna

AoC 2022 day 15

Dec 15th, 2022 (edited)
1,066
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.  
  8. function mDistance(x, y, x2, y2) {
  9.     return Math.abs(x - x2) + Math.abs(y - y2)
  10. }
  11.  
  12. let input = fs
  13.     .readFileSync(__dirname + "/data.txt", "utf8")
  14.     .split(eol)
  15.     .map((s) => {
  16.         let [x, y, bx, by] = s.match(/-?\d+/g).map(Number)
  17.         let distance = mDistance(x, y, bx, by)
  18.         return { x, y, bx, by, distance }
  19.     })
  20.  
  21. let y = input.length == 14 ? 20 : 2000000
  22. let maxSize = input.length == 14 ? 20 : 4000000
  23. let ranges = []
  24. input.forEach((s, i) => {
  25.     let dy = s.distance - Math.abs(y - s.y)
  26.     if (dy > 0) {
  27.         let [lx, rx] = [s.x - dy, s.x + dy]
  28.         ranges.push([lx, rx])
  29.     }
  30. })
  31. ranges = ranges.flat().sort((a, b) => a - b)
  32. part1 = Math.abs(ranges[0] - ranges.pop())
  33.  
  34. function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
  35.     denominator = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1)
  36.     let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator
  37.     let x = x1 + ua * (x2 - x1)
  38.     let y = y1 + ua * (y2 - y1)
  39.     return [~~x, ~~y]
  40. }
  41. let diamonds = []
  42. input.forEach((sensor) => {
  43.     let d = sensor.distance + 1
  44.     let diamond = []
  45.     diamond[0] = [sensor.x + d, sensor.y]
  46.     diamond[1] = [sensor.x, sensor.y + d]
  47.     diamond[2] = [sensor.x - d, sensor.y]
  48.     diamond[3] = [sensor.x, sensor.y - y]
  49.     diamonds.push(diamond)
  50. })
  51.  
  52. main: for (let i = 0; i < diamonds.length; i++) {
  53.     const d1 = diamonds[i]
  54.     for (let j = i + 1; j < diamonds.length; j++) {
  55.         const d2 = diamonds[j]
  56.         for (let s1 = 0; s1 < 4; s1++) {
  57.             for (let s2 = 0; s2 < 4; s2++) {
  58.                 let [xi, yi] = intersect(...d1[s1], ...d1[(s1 + 1) % 4], ...d2[s2], ...d2[(s2 + 1) % 4])
  59.                 if (
  60.                     xi >= 0 &&
  61.                     xi <= maxSize &&
  62.                     yi >= 0 &&
  63.                     yi <= maxSize &&
  64.                     input.every((s) => mDistance(s.x, s.y, xi, yi) > s.distance)
  65.                 ) {
  66.                     part2 = xi * 4000000 + yi
  67.                     break main
  68.                 }
  69.             }
  70.         }
  71.     }
  72. }
  73. let time = performance.now() - startTime
  74. console.log(`Part 1: ${part1}\nPart 2: ${part2}\nTimer: ${time} ms`)
Advertisement
Add Comment
Please, Sign In to add comment