index.js (3254B)
1 const fs = require('fs'); 2 const through = require('through2'); 3 const line_by_line = require('../common/line-for-line'); 4 5 String.prototype.startsWith = function(subject) { 6 return this.substr(0, subject.length) === subject; 7 }; 8 9 const rows = []; 10 let xmin = Infinity; 11 let ymin = Infinity; 12 let xmax = -Infinity; 13 let ymax = -Infinity; 14 15 const scanline = 2000000; 16 // const scanline = 10; 17 const small = false; 18 const sensors = []; 19 20 const interestingArea = 4000000; 21 // const interestingArea = 20; 22 23 fs.createReadStream('input') 24 .pipe(line_by_line()) 25 26 // Minor parsing 27 .pipe(through(function(line, enc, cb) { 28 line = line.toString(); 29 30 // Parse locations 31 const parts = line.split(':'); 32 const sensorTokens = parts[0].split(' '); 33 const beaconTokens = parts[1].split(' '); 34 const sensorPosition = [ 35 parseInt(sensorTokens[2].replace(/[^\d\-]/g, '')), 36 parseInt(sensorTokens[3].replace(/[^\d\-]/g, '')), 37 ]; 38 const beaconPosition = [ 39 parseInt(beaconTokens[5].replace(/[^\d\-]/g, '')), 40 parseInt(beaconTokens[6].replace(/[^\d\-]/g, '')), 41 ]; 42 43 // Calculate distance between beacon and sensor 44 const d = Math.abs(sensorPosition[0] - beaconPosition[0]) + Math.abs(sensorPosition[1] - beaconPosition[1]); 45 46 // Store sensor for step 2 47 sensors.push({ 48 pos: sensorPosition, 49 d, 50 }); 51 52 xmin = Math.min(xmin, sensorPosition[0]-d, beaconPosition[0]-d); 53 ymin = Math.min(ymin, sensorPosition[1]-d, beaconPosition[1]-d); 54 xmax = Math.max(xmax, sensorPosition[0]+d, beaconPosition[0]+d); 55 ymax = Math.max(ymax, sensorPosition[1]+d, beaconPosition[1]+d); 56 57 // console.log({ sensorTokens, sensorPosition, beaconTokens, beaconPosition, d }); 58 cb(); 59 })) 60 61 .on('finish', () => { 62 console.log('loaded'); 63 64 // Step 1 65 let covered = -1; 66 for(let x=xmin; x<=xmax; x++) { 67 68 const found = sensors.find(sensor => { 69 const d = Math.abs(sensor.pos[0] - x) + Math.abs(sensor.pos[1] - scanline); 70 return d <= sensor.d; 71 }); 72 73 if (!found) continue; 74 75 // Add width at current Y and skip steps 76 const X = found.d - Math.abs(found.pos[1] - scanline); 77 covered += (found.pos[0] - x) + 1 + X; 78 x = found.pos[0] + X; 79 } 80 81 console.log({ covered }); 82 83 84 // Step 2 85 for(let y=0; y<=interestingArea; y++) { 86 // console.log(y); 87 for(let x=0; x<=interestingArea; x++) { 88 89 const found = sensors.find(sensor => { 90 const d = Math.abs(sensor.pos[0] - x) + Math.abs(sensor.pos[1] - y); 91 return d <= sensor.d; 92 }); 93 94 if (!found) { 95 console.log({ found: [x, y], freq: (x*4000000) + y }); 96 process.exit(0); 97 } 98 99 // Skip X beyong the sensor 100 const X = found.d - Math.abs(found.pos[1] - y); 101 x = found.pos[0] + X; 102 } 103 } 104 105 // for(let y=0; y<=interestingArea; y++) { 106 // for(let x=0; x<=interestingArea; x++) { 107 // if (rows[y][x]) continue; 108 // console.log({ found: [x, y], freq: (x*4000000) + y }); 109 // } 110 // } 111 112 // console.log({ 113 // row: Object.values(rows[scanline]) 114 // .map(c => !!~'#S'.indexOf(c||'.') ? 1 : 0) 115 // .reduce((r,a) => r+a, 0) 116 // }); 117 118 119 });