index.js (1804B)
1 const fs = require('fs'); 2 const through = require('through2'); 3 const line_for_line = require('../common/line-for-line'); 4 5 const x = 0; 6 const y = 1; 7 const head = 0; 8 const pos = Array(10).fill(0).map(() => [0,0]); 9 const tail = pos.length - 1; 10 11 const movements = { 12 U: [0,1], 13 D: [0,-1], 14 L: [-1,0], 15 R: [1,0], 16 }; 17 18 const follows = [ 19 [[-1, -1],[-1,-1],[ 0,-1],[ 1, -1],[ 1, -1]], 20 [[-1, -1],[ 0, 0],[ 0, 0],[ 0, 0],[ 1, -1]], 21 [[-1, 0],[ 0, 0],[ 0, 0],[ 0, 0],[ 1, 0]], 22 [[-1, 1],[ 0, 0],[ 0, 0],[ 0, 0],[ 1, 1]], 23 [[-1, 1],[-1, 1],[ 0, 1],[ 1, 1],[ 1, 1]], 24 ]; 25 26 const visited = [[0,0]]; 27 28 fs.createReadStream('input') 29 // fs.createReadStream('input') 30 .pipe(line_for_line()) 31 32 // Load grid 33 .pipe(through(function(line, enc, cb) { 34 line = line.toString(); 35 36 const [ aDir, aCnt ] = line.split(' '); 37 const iCnt = parseInt(aCnt); 38 39 // Build head movement reference 40 const mv = movements[aDir]; 41 42 // Run N steps 43 for(let i=0; i<iCnt; i++) { 44 45 // Move head 46 pos[head][x] += mv[x]; 47 pos[head][y] += mv[y]; 48 49 // Iterate over segments for follow movement 50 for(let i=head+1; i<pos.length; i++) { 51 const diff = [ pos[i-1][x] - pos[i][x], pos[i-1][y] - pos[i][y] ]; 52 const follow = follows[diff[y]+2][diff[x]+2]; 53 pos[i][x] += follow[x]; 54 pos[i][y] += follow[y]; 55 } 56 57 // Track position visited 58 visited.push( 59 visited.find((p) => p[x] == pos[tail][x] && p[y] == pos[tail][y]) || [...pos[tail]] 60 ); 61 62 } 63 64 cb(); 65 })) 66 67 .on('finish', () => { 68 69 // So visited, so we can make it unique 70 let unique = 0; 71 visited.forEach((p,i) => { 72 if (visited.indexOf(p) == i) unique++; 73 }); 74 75 console.log({ unique }); 76 77 console.log('finish'); 78 });