Advertisement
degtyar

aoc 9 lame rope

Dec 9th, 2022 (edited)
1,203
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const fs = require('fs')
  2.  
  3. // const input = fs.readFileSync('test.txt').toString().trim()
  4. const input = fs.readFileSync('input.txt').toString().trim()
  5.  
  6. const range = (a) => [...Array(a).keys()]
  7. const abs = Math.abs
  8. const follow = (head, tail) => abs(head[0] - tail[0]) >= 2 || abs(head[1] - tail[1]) >= 2 ? head : null
  9. const move = (rope, [hx, hy]) => {
  10.   const head = rope.head.at(-1)
  11.   const tail = rope.tail.at(-1)
  12.   const newHead = [head[0] + hx, head[1] + hy]
  13.  
  14.   return {
  15.     head: [...rope.head, newHead],
  16.     tail: follow(newHead, tail) ? [...rope.tail, [...head]] : rope.tail,
  17.   }
  18. }
  19.  
  20. const moves = {
  21.   U: (current, count) => range(count).reduce((acc) => move(acc, [1, 0]), current),
  22.   D: (current, count) => range(count).reduce((acc) => move(acc, [-1, 0]), current),
  23.   L: (current, count) => range(count).reduce((acc) => move(acc, [0, -1]), current),
  24.   R: (current, count) => range(count).reduce((acc) => move(acc, [0, 1]), current),
  25. }
  26.  
  27. const pairs = input.split('\n').map((pair) => pair.split(' '))
  28.   .reduce((acc, [direction, count]) => moves[direction](acc, +count), {
  29.     head: [[0, 0]],
  30.     tail: [[0, 0]],
  31.   })
  32.  
  33. console.log(new Set(pairs.tail.map((pairs) => pairs.join('_'))).size)
  34.  
  35. const getModifiers = ([hx, hy], [tx, ty]) => {
  36.   const x = abs(hx - tx) === 2 ? (hx - tx) / 2 :
  37.     abs(hy - ty) === 2 ?
  38.       (abs(hx - tx) === 1 ? hx - tx : 0)
  39.       : 0
  40.   const y = abs(hy - ty) === 2 ? (hy - ty) / 2 :
  41.     abs(hx - tx) === 2 ?
  42.       (abs(hy - ty) === 1 ? hy - ty : 0)
  43.       : 0
  44.  
  45.   return [x, y]
  46. }
  47. const move2 = (rope, [hx, hy]) => {
  48.   const head = [rope.knots[0][0] + hx, rope.knots[0][1] + hy]
  49.   const knots = rope.knots.reduce((acc, knot, i) => {
  50.     if (i === 0) {
  51.       acc[i] = head
  52.       return acc
  53.     }
  54.  
  55.     const prev = acc[i - 1]
  56.     const [dx, dy] = getModifiers(prev, acc[i])
  57.     acc[i] = follow(prev, acc[i]) ? [acc[i][0] + dx, acc[i][1] + dy] : acc[i]
  58.     return acc
  59.   }, rope.knots.map(a => a.slice()))
  60.   return {
  61.     knots: knots,
  62.     tail: [...rope.tail, knots.at(-1)],
  63.   }
  64. }
  65.  
  66. const moves2 = {
  67.   U: (current, count) => range(count).reduce((acc) => move2(acc, [1, 0]), current),
  68.   D: (current, count) => range(count).reduce((acc) => move2(acc, [-1, 0]), current),
  69.   L: (current, count) => range(count).reduce((acc) => move2(acc, [0, -1]), current),
  70.   R: (current, count) => range(count).reduce((acc) => move2(acc, [0, 1]), current),
  71. }
  72.  
  73. const pairs2 = input.split('\n').map((pair) => pair.split(' '))
  74.   .reduce((acc, [direction, count]) => moves2[direction](acc, +count), {
  75.     knots: range(10).map(() => [0, 0]),
  76.     tail: [],
  77.   })
  78.  
  79. console.log(new Set(pairs2.tail.map((s) => s.join('_'))).size)
  80.  
Tags: aoc
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement