From e0bcf52a0c7db29a7d6ccd02213ef25dcbe66d2d Mon Sep 17 00:00:00 2001 From: Jack Bond-Preston Date: Mon, 10 Dec 2018 23:14:36 +0000 Subject: [PATCH] Day 10 --- aoc-10/main.html | 340 +++++++++++++++++++++++++++++++++++++++++++++++ aoc-10/main.js | 197 +++++++++++++++++++++++++++ 2 files changed, 537 insertions(+) create mode 100644 aoc-10/main.html create mode 100644 aoc-10/main.js diff --git a/aoc-10/main.html b/aoc-10/main.html new file mode 100644 index 0000000..c579c5d --- /dev/null +++ b/aoc-10/main.html @@ -0,0 +1,340 @@ + + + + Day 10 + + + + + + + +
+ + Points: 0 + Seconds: 0 + + + + + + + + \ No newline at end of file diff --git a/aoc-10/main.js b/aoc-10/main.js new file mode 100644 index 0000000..bca1105 --- /dev/null +++ b/aoc-10/main.js @@ -0,0 +1,197 @@ +class Point { + + constructor(x, y, vx, vy) { + this.x = x; + this.y = y; + this.vx = vx; + this.vy = vy; + } + + next() { + this.x += this.vx; + this.y += this.vy; + } + + prev() { + this.x -= this.vx; + this.y -= this.vy; + } + + // move multiple at once + proceed(turns) { + this.x += turns * this.vx; + this.y += turns * this.vy; + } +} + +let pointsArr = []; +let minDistance = 0; +let turn = 0; + +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +function getColourIndicesForCoord(x, y, width) { + let red = y * (width * 4) + x * 4; + + return { + "red": red, + "green": red + 1, + "blue": red + 2, + "alpha": red + 3 + } +} + +function setVirtualPixel(data, x, y, rgba, scale) { + let xStart = x * scale; + let yStart = y * scale; + + let xEnd = (x + 1) * scale; + let yEnd = (y + 1) * scale; + + for (let i = xStart; i < xEnd; i++) { + for (let j = yStart; j < yEnd; j++) { + let indices = getColourIndicesForCoord(i, j, 1000); + + data.data[indices.red] = rgba.red; + data.data[indices.green] = rgba.green; + data.data[indices.blue] = rgba.blue; + data.data[indices.alpha] = rgba.alpha; + } + } + + return data; +} + +function parseInput(raw) { + let points = [] + + let split = raw.split('\n'); + + let indexes = []; + + for (let i = 0; i < split[0].length; i++) { + if (split[0][i] === '<' || split[0][i] === ',' || split[0][i] === '>') indexes.push(i); + } + + for (let line of raw.split('\n')) { + let x = Number(line.slice(indexes[0] + 1, indexes[1])); + let y = Number(line.slice(indexes[1] + 2, indexes[2])); + + let vx = Number(line.slice(indexes[3] + 1, indexes[4])); + let vy = Number(line.slice(indexes[4] + 2, indexes[5])); + + points.push(new Point(x, y, vx, vy)); + } + updateDistance(points); + turn = 0; + + document.getElementById("points").innerText = "Points: " + points.length; + document.getElementById("turn").innerText = "Seconds: 0"; + + for (let i of document.getElementsByTagName("input")) { + i.disabled = false; + } + + clearCanvas(); + + return points; +} + +function clearCanvas() { + let context = document.getElementById("canvas").getContext("2d"); + + context.putImageData(context.createImageData(canvas.width, canvas.height), 0, 0); +} + +function render(points) { + let canvas = document.getElementById("canvas"); + let context = canvas.getContext("2d"); + + let data = context.createImageData(canvas.width, canvas.height); + const colour = { + red: 255, + green: 0, + blue: 0, + alpha: 255 + }; + + let min = [ + Math.min(... points.map(p => p.x)), + Math.min(... points.map(p => p.y)) + ]; + + let max = [ + Math.max(... points.map(p => p.x)), + Math.max(... points.map(p => p.y)) + ]; + + let offset = [-min[0], -min[1]]; + let maxDiff = Math.max(max[0] - min[0], max[1] - min[1]) + + if (maxDiff > 1000) scale = 1; + else scale = Math.floor(1000 / maxDiff); + + while (1000 % scale !== 0) scale--; + + console.log(`Scale: ${scale}, diff: ${maxDiff}, offset: ${offset}`); + + for (let point of points) { + if (point.x + offset[0] < 1000 && point.y + offset[1] < 1000) + data = setVirtualPixel(data, point.x + offset[0], point.y + offset[1], colour, scale); + } + + context.putImageData(data, 0, 0); +} + +function distance(p1, p2) { + return Math.abs(p1.x - p2.x) + Math.abs(p1.y - p2.y); +} + +function updateDistance(points) { + minDistance = Math.min(... + points.map( + point => { + return Math.max(... + points.map(point2 => distance(point, point2)) + ); + } + ) + ); +} + +async function run(points) { + document.getElementById("run").disabled = true; + + let x = 0; + + let prevMin = minDistance + 1; + + console.log(minDistance); + + while (prevMin > minDistance) { + prevMin = minDistance; + + proceedBy(points, Math.ceil(minDistance / 500)); + + updateDistance(points); + + if (minDistance < 1000 && prevMin > minDistance) { + render(points); + await sleep(10); + } + else await sleep(2); + } + + proceedBy(points, -1); + + render(points); +} + +function proceedBy(points, amount) { + points.forEach(point => point.proceed(amount)); + + turn += amount; + document.getElementById("turn").innerText = "Seconds: " + turn; +} \ No newline at end of file