Advertisement
Guest User

Untitled

a guest
Dec 10th, 2020 (edited)
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /** Day 10 */
  2.  
  3. class Day10 {
  4.   solve(text, sample) {
  5.     let lines = text.trim().split('\n').map(line => parseInt(line)).sort((a, b) => a - b);
  6.     let jolts = [0, ...lines, lines[lines.length - 1] + 3];
  7.  
  8.     // p1
  9.     let step1 = 0;
  10.     let step3 = 0;
  11.     for (let i=0; i<jolts.length; i++) {
  12.       if (jolts[i+1] - jolts[i] == 1)
  13.         step1++;
  14.       else if (jolts[i+1] - jolts[i] == 3)
  15.         step3++;
  16.     }
  17.  
  18.     // part 2
  19.     const nodes = jolts.map(n => ({jolts: n, conns: 0, in: 0, out: 0, to: []}));
  20.     nodes[0].conns = 1;
  21.     nodes[0].in = 1;
  22.     for (let i=0; i<nodes.length; i++) {
  23.       const node = nodes[i];
  24.       for (let j=i+1; j<nodes.length; j++) {
  25.         if (nodes[j].jolts - node.jolts > 3)
  26.           break;
  27.         nodes[j].conns = nodes[j].conns + node.conns;
  28.  
  29.         // for animation
  30.         node.out += 1;
  31.         nodes[j].in += 1;
  32.         node.to.push(j);
  33.       }
  34.     }
  35.  
  36.     // animation settings
  37.     this.cvs = document.createElement('canvas');
  38.     this.ctx = this.cvs.getContext('2d');
  39.     this.cvs.style.background = '#111';
  40.     this.cvs.width = 600;
  41.     this.cvs.height = 600;
  42.     this.nodes = nodes;
  43.     this.time = {};
  44.     this.time.age = 0;
  45.     this.time.scale = 6;
  46.     this.time.max = this.nodes.length * this.time.scale;
  47.  
  48.     // add canvas to doc
  49.     const target = document.querySelector('#output-window .window__body') ||
  50.       document.querySelector('body');
  51.     target.appendChild(this.cvs);
  52.  
  53.     // run animation
  54.     this.loop();
  55.   }
  56.  
  57.   getNodePosition(node, index) {
  58.     const pad = 32;
  59.     const rows = 8;
  60.     const row = Math.floor(index * rows / this.nodes.length);
  61.     const w = this.nodes.length / rows;
  62.     let x = (index % w) / w;
  63.     x = pad + (row % 2 == 0 ? x : 1 - x) * (this.cvs.width - pad * 2);
  64.     let y = row / rows;
  65.     if (node.in > 1) {
  66.       const offy = 1 / (rows * 2);
  67.       y += node.in == 2 ? offy : node.in >= 4 ? offy * 2 : offy;
  68.     }
  69.     y = pad + y * (this.cvs.height - pad * 2);
  70.     return {x, y};
  71.   }
  72.  
  73.   draw() {
  74.     this.ctx.fillStyle = this.ctx.strokeStyle = '#fff';
  75.     this.ctx.font = '12px monospace';
  76.     this.ctx.lineWidth = 2;
  77.     this.ctx.clearRect(0, 0, this.cvs.width, this.cvs.height);
  78.  
  79.     // draw nodes up to current index
  80.     let conns = 0;
  81.     let lim = Math.floor(this.time.age / this.time.scale);
  82.     let step = (this.time.age % this.time.scale + 1) / this.time.scale;
  83.     this.ctx.beginPath();
  84.  
  85.     for (let i=0; i<lim; i++) {
  86.       const node = this.nodes[i];
  87.       const p = this.getNodePosition(node, i);
  88.       this.ctx.fillRect(p.x-1, p.y-1, 2, 2);
  89.  
  90.       // draw connections
  91.       node.to.forEach(j => {
  92.         this.ctx.moveTo(p.x, p.y);
  93.         const p2 = this.getNodePosition(this.nodes[j], j);
  94.  
  95.         // animate extending line
  96.         if (i == lim - 1) {
  97.           const x = p.x + (p2.x - p.x) * step;
  98.           const y = p.y + (p2.y - p.y) * step;
  99.           this.ctx.lineTo(x, y);
  100.  
  101.         // draw full line
  102.         } else {
  103.           this.ctx.lineTo(p2.x, p2.y);
  104.         }
  105.       });
  106.  
  107.       // indicate outward connections
  108.       if (node.out > 1) {
  109.         this.ctx.fillText(node.out, p.x, p.y - 5);
  110.       }
  111.  
  112.       // get value of current node
  113.       if (i == lim-1) {
  114.         conns = node.conns;
  115.       }
  116.     }
  117.  
  118.     this.ctx.stroke();
  119.  
  120.     // print current connections
  121.     this.ctx.font = '24px monospace';
  122.     this.ctx.fillText('CONNS: ' + conns, 16, this.cvs.height - 16);
  123.   }
  124.  
  125.   loop() {
  126.     if (this.time.age < this.time.max) {
  127.       requestAnimationFrame(() => {
  128.         this.loop();
  129.       });
  130.     }
  131.     this.draw();
  132.     this.time.age++;
  133.   }
  134. }
  135.  
  136. export default Day10;
  137.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement