advent-of-code

Entries to advent of code, multiple years
git clone git://git.finwo.net/misc/advent-of-code
Log | Files | Refs

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   });