Advent of Code 2022 - Day 15: Beacon Exclusion Zone Solution
Union of rangesPart 1
Count number of coords that have distance less than or equal to the distance of each sensor to its nearest beacon
Implementation
1const fs = require("fs")23const coordToStr = ([x, y]) => `${x} ${y}`45const calculateDistance = ([x1, y1], [x2, y2]) =>6 Math.abs(x1 - x2) + Math.abs(y1 - y2)78const readData = () => {9 const data = fs10 .readFileSync("./input", "utf-8")11 .split(/\r?\n/)12 .map(line => line.match(/-?\d+/g).map(Number))13 .map(([x1, y1, x2, y2]) => [14 [x1, y1],15 [x2, y2],16 ])17 .map(([sensor, beacon]) => [18 sensor,19 beacon,20 calculateDistance(sensor, beacon),21 ])2223 const set = new Set()2425 for (const [sensor, beacon] of data) {26 set.add(coordToStr(sensor))27 set.add(coordToStr(beacon))28 }2930 return { coords: data, set }31}3233const main = () => {34 const { coords, set } = readData()3536 const targetY = 200000037 let res = 03839 for (const [sensor, beacon, distance] of coords) {40 const absX = distance - Math.abs(targetY - sensor[1])41 if (absX < 0) continue42 const possibleXs = [sensor[0] + absX, sensor[0] - absX].sort(43 (a, b) => a - b44 )45 for (let x = possibleXs[0]; x <= possibleXs[1]; x++) {46 if (!set.has(coordToStr([x, targetY]))) {47 res++48 set.add(coordToStr([x, targetY]))49 }50 }51 }5253 console.log(res)54}5556main()
Part 2
In each row, find the ranges covered by sensors
Find the union of those ranges
If a row has over than one union ranges, then the distress beacon is in the between
Implementation
1const fs = require("fs")23const coordToStr = ([x, y]) => `${x} ${y}`45const calculateDistance = ([x1, y1], [x2, y2]) =>6 Math.abs(x1 - x2) + Math.abs(y1 - y2)78const readData = () => {9 const data = fs10 .readFileSync("./input", "utf-8")11 .split(/\r?\n/)12 .map(line => line.match(/-?\d+/g).map(Number))13 .map(([x1, y1, x2, y2]) => [14 [x1, y1],15 [x2, y2],16 ])17 .map(([sensor, beacon]) => [18 sensor,19 beacon,20 calculateDistance(sensor, beacon),21 ])2223 const set = new Set()2425 for (const [sensor, beacon] of data) {26 set.add(coordToStr(sensor))27 set.add(coordToStr(beacon))28 }2930 return { coords: data, set }31}3233const main = () => {34 const { coords, set } = readData()3536 const bound = [0, 4000000]3738 let res3940 const getUnion = ranges => {41 const union = []42 ranges.sort(43 (rangeA, rangeB) => rangeA[0] - rangeB[0] || rangeA[1] - rangeB[1]44 )45 for (const [start, end] of ranges) {46 const latestUnionRange = union.slice(-1)[0]47 if (latestUnionRange && latestUnionRange[1] >= start - 1) {48 latestUnionRange[1] = Math.max(latestUnionRange[1], end)49 } else {50 union.push([start, end])51 }52 }5354 return union55 }5657 for (let targetY = 0; targetY <= bound[1]; targetY++) {58 let xRanges = []59 for (const [sensor, beacon, distance] of coords) {60 const absX = distance - Math.abs(targetY - sensor[1])61 if (absX < 0) continue62 const possibleXs = [sensor[0] + absX, sensor[0] - absX].sort(63 (a, b) => a - b64 )65 possibleXs[0] = Math.max(bound[0], possibleXs[0])66 possibleXs[1] = Math.min(bound[1], possibleXs[1])6768 xRanges.push(possibleXs)69 xRanges.push(70 ...[sensor, beacon]71 .filter(([x, y]) => y === targetY && bound[0] <= x && x <= bound[1])72 .map(([x]) => [x, x])73 )74 }7576 const union = getUnion(xRanges)7778 if (union.length === 2) {79 const coord = [union[0][1] + 1, targetY]80 res = coord[0] * bound[1] + coord[1]81 break82 }83 }8485 console.log(res)86}8788main()
References
Comments
Loading comments...
Tags
adventofcode
hash table
union find
Apply and earn a $2,500 bonus once you're hired on your first job!
Clients from the Fortune 500 to Silicon Valley startups
Choose your own rate, get paid on time
From hourly, part-time, to full-time positions
Flexible remote working environment
A lot of open JavaScript jobs!!
Fact corner: Referred talent are 5x more likely to pass the Toptal screening process than the average applicant.
Still hesitate? Read HoningJS author's guide on dealing with Toptal interview process.