Day 15
This commit is contained in:
		
							parent
							
								
									99988afbe7
								
							
						
					
					
						commit
						f180b38cb3
					
				
							
								
								
									
										38
									
								
								15/input
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								15/input
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					Sensor at x=3556832, y=3209801: closest beacon is at x=3520475, y=3164417
 | 
				
			||||||
 | 
					Sensor at x=3068970, y=3071952: closest beacon is at x=3520475, y=3164417
 | 
				
			||||||
 | 
					Sensor at x=636397, y=1899889: closest beacon is at x=338784, y=1935796
 | 
				
			||||||
 | 
					Sensor at x=3856769, y=3377079: closest beacon is at x=3520475, y=3164417
 | 
				
			||||||
 | 
					Sensor at x=2876227, y=2633203: closest beacon is at x=2595700, y=2684432
 | 
				
			||||||
 | 
					Sensor at x=1435445, y=1194830: closest beacon is at x=925348, y=2000000
 | 
				
			||||||
 | 
					Sensor at x=3764673, y=3881970: closest beacon is at x=3520475, y=3164417
 | 
				
			||||||
 | 
					Sensor at x=3171272, y=1098717: closest beacon is at x=3778277, y=740547
 | 
				
			||||||
 | 
					Sensor at x=3646837, y=966534: closest beacon is at x=3778277, y=740547
 | 
				
			||||||
 | 
					Sensor at x=1736390, y=3309102: closest beacon is at x=1623417, y=4114070
 | 
				
			||||||
 | 
					Sensor at x=1086601, y=2272573: closest beacon is at x=925348, y=2000000
 | 
				
			||||||
 | 
					Sensor at x=3793954, y=2346914: closest beacon is at x=3520475, y=3164417
 | 
				
			||||||
 | 
					Sensor at x=1896054, y=2706210: closest beacon is at x=2595700, y=2684432
 | 
				
			||||||
 | 
					Sensor at x=2298950, y=3449308: closest beacon is at x=2205069, y=3958831
 | 
				
			||||||
 | 
					Sensor at x=1911518, y=3848874: closest beacon is at x=2205069, y=3958831
 | 
				
			||||||
 | 
					Sensor at x=2566355, y=1516144: closest beacon is at x=2595700, y=2684432
 | 
				
			||||||
 | 
					Sensor at x=246553, y=343125: closest beacon is at x=338784, y=1935796
 | 
				
			||||||
 | 
					Sensor at x=2197183, y=3975039: closest beacon is at x=2205069, y=3958831
 | 
				
			||||||
 | 
					Sensor at x=552775, y=3494740: closest beacon is at x=-138318, y=2857049
 | 
				
			||||||
 | 
					Sensor at x=128870, y=1935711: closest beacon is at x=338784, y=1935796
 | 
				
			||||||
 | 
					Sensor at x=2197078, y=3999879: closest beacon is at x=2205069, y=3958831
 | 
				
			||||||
 | 
					Sensor at x=2502533, y=3911039: closest beacon is at x=2205069, y=3958831
 | 
				
			||||||
 | 
					Sensor at x=2289309, y=3024440: closest beacon is at x=2595700, y=2684432
 | 
				
			||||||
 | 
					Sensor at x=3999523, y=551710: closest beacon is at x=3778277, y=740547
 | 
				
			||||||
 | 
					Sensor at x=2246061, y=3999936: closest beacon is at x=2205069, y=3958831
 | 
				
			||||||
 | 
					Sensor at x=3982782, y=1306639: closest beacon is at x=3778277, y=740547
 | 
				
			||||||
 | 
					Sensor at x=1166660, y=2766482: closest beacon is at x=925348, y=2000000
 | 
				
			||||||
 | 
					Sensor at x=3744391, y=440575: closest beacon is at x=3778277, y=740547
 | 
				
			||||||
 | 
					Sensor at x=1480453, y=3997346: closest beacon is at x=1623417, y=4114070
 | 
				
			||||||
 | 
					Sensor at x=9770, y=1844797: closest beacon is at x=338784, y=1935796
 | 
				
			||||||
 | 
					Sensor at x=202829, y=2427690: closest beacon is at x=338784, y=1935796
 | 
				
			||||||
 | 
					Sensor at x=3051096, y=3631595: closest beacon is at x=3147080, y=4258152
 | 
				
			||||||
 | 
					Sensor at x=2111052, y=297293: closest beacon is at x=1552534, y=-431081
 | 
				
			||||||
 | 
					Sensor at x=864326, y=2053355: closest beacon is at x=925348, y=2000000
 | 
				
			||||||
 | 
					Sensor at x=2422495, y=2130146: closest beacon is at x=2595700, y=2684432
 | 
				
			||||||
 | 
					Sensor at x=3655670, y=100751: closest beacon is at x=3778277, y=740547
 | 
				
			||||||
 | 
					Sensor at x=535656, y=2133259: closest beacon is at x=338784, y=1935796
 | 
				
			||||||
 | 
					Sensor at x=263229, y=2101270: closest beacon is at x=338784, y=1935796
 | 
				
			||||||
							
								
								
									
										106
									
								
								15/solution.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										106
									
								
								15/solution.mjs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,106 @@
 | 
				
			|||||||
 | 
					import { readFileSync } from 'node:fs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const input = readFileSync('input', 'utf-8');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const sensors = input
 | 
				
			||||||
 | 
					  .split('\n')
 | 
				
			||||||
 | 
					  .filter(Boolean)
 | 
				
			||||||
 | 
					  .map(line => {
 | 
				
			||||||
 | 
					    const match = line.match(/.*?x=(-?\d+), y=(-?\d+).*?x=(-?\d+), y=(-?\d+)/);
 | 
				
			||||||
 | 
					    if (!match) {
 | 
				
			||||||
 | 
					      throw new Error(`Invalid sensor readout: ${line}`);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const [x, y, bx, by] = match
 | 
				
			||||||
 | 
					      .slice(1)
 | 
				
			||||||
 | 
					      .map(n => parseInt(n));
 | 
				
			||||||
 | 
					    return {x, y, bx, by};
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function rangesOverlap(range1, range2, tollerance=0) {
 | 
				
			||||||
 | 
					  const t = tollerance;
 | 
				
			||||||
 | 
					  range1 = [...range1].sort((a, b) => a - b);
 | 
				
			||||||
 | 
					  range2 = [...range2].sort((a, b) => a - b);
 | 
				
			||||||
 | 
					  return (
 | 
				
			||||||
 | 
					    (range1[0] >= range2[0] - t && range1[0] <= range2[1] + t) ||
 | 
				
			||||||
 | 
					    (range1[1] >= range2[0] - t && range1[1] <= range2[1] + t) ||
 | 
				
			||||||
 | 
					    (range2[0] >= range1[0] - t && range2[0] <= range1[1] + t) ||
 | 
				
			||||||
 | 
					    (range2[1] >= range1[0] - t && range2[1] <= range1[1] + t)
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function mergeCoverage(coverage) {
 | 
				
			||||||
 | 
					  return [...coverage]
 | 
				
			||||||
 | 
					    .map(range => [...range].sort((a, b) => a - b))
 | 
				
			||||||
 | 
					    .sort((a, b) => a[0] - b[0])
 | 
				
			||||||
 | 
					    .reduce((newCoverage, range) => {
 | 
				
			||||||
 | 
					      if (newCoverage.length) {
 | 
				
			||||||
 | 
					        const lastRange = newCoverage[newCoverage.length - 1];
 | 
				
			||||||
 | 
					        if (rangesOverlap(lastRange, range, 1)) {
 | 
				
			||||||
 | 
					          newCoverage[newCoverage.length - 1] = [
 | 
				
			||||||
 | 
					            Math.min(lastRange[0], range[0]),
 | 
				
			||||||
 | 
					            Math.max(lastRange[1], range[1])
 | 
				
			||||||
 | 
					          ];
 | 
				
			||||||
 | 
					          return newCoverage;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      newCoverage.push(range);
 | 
				
			||||||
 | 
					      return newCoverage;
 | 
				
			||||||
 | 
					    }, []);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function getCoverageForRow(y) {
 | 
				
			||||||
 | 
					  const coverage = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for (const s of sensors) {
 | 
				
			||||||
 | 
					    const range = Math.abs(s.x - s.bx) + Math.abs(s.y - s.by);
 | 
				
			||||||
 | 
					    const distanceToSensor = Math.abs(s.y - y);
 | 
				
			||||||
 | 
					    const reducedRange = range - distanceToSensor;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (reducedRange < 0) continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    coverage.push([s.x - reducedRange, s.x + reducedRange]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return mergeCoverage(coverage);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function countBeaconsForRow(y) {
 | 
				
			||||||
 | 
					  return sensors
 | 
				
			||||||
 | 
					    .map(s => [s.bx, s.by])
 | 
				
			||||||
 | 
					    .filter((coord, i, coords) => coords.findLastIndex(
 | 
				
			||||||
 | 
					      c => c[0] === coord[0] && c[1] === coord[1]
 | 
				
			||||||
 | 
					    ) === i)
 | 
				
			||||||
 | 
					    .reduce((total, coord) => total + Number(coord[1] === y), 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function countCoverageForRow(y) {
 | 
				
			||||||
 | 
					  const coverageCount = getCoverageForRow(y)
 | 
				
			||||||
 | 
					    .reduce((total, range) => total + range[1] - range[0] + 1, 0);
 | 
				
			||||||
 | 
					  const beaconCount = countBeaconsForRow(y);
 | 
				
			||||||
 | 
					  return coverageCount - beaconCount;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const row = 2000000;
 | 
				
			||||||
 | 
					const coverageCount = countCoverageForRow(2000000);
 | 
				
			||||||
 | 
					console.log(
 | 
				
			||||||
 | 
					  `There are ${coverageCount} positions that cannot contain a beacon on ` +
 | 
				
			||||||
 | 
					    `row: ${row}`
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function limitCoverage(coverage, min, max) {
 | 
				
			||||||
 | 
					  return coverage
 | 
				
			||||||
 | 
					    .filter(range => rangesOverlap([min, max], range))
 | 
				
			||||||
 | 
					    .map(range => [Math.max(min, range[0]), Math.min(max, range[1])]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					console.log('Locating distress beacon...');
 | 
				
			||||||
 | 
					let tuningFrequency;
 | 
				
			||||||
 | 
					for (let y = 0; y <= 4000000; y++) {
 | 
				
			||||||
 | 
					  const coverage = limitCoverage(getCoverageForRow(y), 0, 4000000);
 | 
				
			||||||
 | 
					  if (coverage.length > 1) {
 | 
				
			||||||
 | 
					    const x = coverage[0][1] + 1;
 | 
				
			||||||
 | 
					    tuningFrequency = x * 4000000 + y;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					console.log(`Tuning frequency for distress beacon: ${tuningFrequency}`);
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user