Advertisement
Guest User

Untitled

a guest
Dec 11th, 2023
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { readFileSync } from 'fs'
  2.  
  3. type Point = [number, number]
  4.  
  5. function parse(input: string): Point[] {
  6.     const lines = input.trim().split('\n')
  7.     const points: Point[] = []
  8.     for (let y = 0; y < lines.length; y++) {
  9.         for (let x = 0; x < lines[0].length; x++) {
  10.             if (lines[y][x] === '#') points.push([x, y])
  11.         }
  12.     }
  13.     return points
  14. }
  15.  
  16. function expand(points: Point[], factor: number): Point[] {
  17.     const nonemptyYs = new Set<number>()
  18.     const nonemptyXs = new Set<number>()
  19.     let maxY = 0
  20.     let maxX = 0
  21.     for (const [x, y] of points) {
  22.         nonemptyXs.add(x)
  23.         nonemptyYs.add(y)
  24.         maxY = Math.max(maxY, y)
  25.         maxX = Math.max(maxX, x)
  26.     }
  27.  
  28.     const prefixSumXs: number[] = new Array(maxX + 1).fill(0)
  29.     const prefixSumYs: number[] = new Array(maxY + 1).fill(0)
  30.     for (let x = 0; x <= maxX; x++) {
  31.         prefixSumXs[x] =
  32.             (prefixSumXs[x - 1] || 0) + (!nonemptyXs.has(x) ? 1 : 0)
  33.     }
  34.     for (let y = 0; y <= maxY; y++) {
  35.         prefixSumYs[y] =
  36.             (prefixSumYs[y - 1] || 0) + (!nonemptyYs.has(y) ? 1 : 0)
  37.     }
  38.  
  39.     return points.map(([px, py]) => {
  40.         return [
  41.             px + prefixSumXs[px] * (factor - 1),
  42.             py + prefixSumYs[py] * (factor - 1),
  43.         ]
  44.     })
  45. }
  46.  
  47. function manhattanDistance([ax, ay]: Point, [bx, by]: Point): number {
  48.     return Math.abs(ax - bx) + Math.abs(ay - by)
  49. }
  50.  
  51. function sumPairDistances(points: Point[]): number {
  52.     const considered = new Set<string>()
  53.     let sum = 0
  54.     for (const a of points) {
  55.         for (const b of points) {
  56.             if (a[0] === b[0] && a[1] === b[1]) continue
  57.             // Sort points to ensure [a, b] and [b, a] are treated the same
  58.             const [sortedA, sortedB] = [a, b].sort((p1, p2) => {
  59.                 if (p1[0] === p2[0]) return p1[1] - p2[1]
  60.                 return p1[0] - p2[0]
  61.             })
  62.             const key = `${sortedA[0]}-${sortedA[1]}:${sortedB[0]}-${sortedB[1]}`
  63.             if (considered.has(key)) continue
  64.             sum += manhattanDistance(a, b)
  65.             considered.add(key)
  66.         }
  67.     }
  68.     return sum
  69. }
  70.  
  71. const input = `
  72. ...#......
  73. .......#..
  74. #.........
  75. ..........
  76. ......#...
  77. .#........
  78. .........#
  79. ..........
  80. .......#..
  81. #...#.....`
  82.  
  83. // const input = readFileSync('day11.txt', { encoding: 'utf8' })
  84.  
  85. console.log('part 1:', sumPairDistances(expand(parse(input), 2)))
  86. console.log('part 2:', sumPairDistances(expand(parse(input), 1_000_000)))
  87.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement