Browse Source

d14 + d15

isundil 3 years ago
parent
commit
d8049ccd52
2 changed files with 156 additions and 0 deletions
  1. 77 0
      d14/main.js
  2. 79 0
      d15/main.js

+ 77 - 0
d14/main.js

@@ -0,0 +1,77 @@
+
+const fs = require('fs');
+const readline = require('readline');
+
+function RockLine(from, to) {
+    this.from = [];
+    this.to = [];
+    if (from[0] === to[0])
+    {
+        this.from[1] = Math.min(from[1], to[1]);
+        this.to[1] = Math.max(from[1], to[1]);
+        this.from[0] = this.to[0] = from[0];
+    } else {
+        this.from[0] = Math.min(from[0], to[0]);
+        this.to[0] = Math.max(from[0], to[0]);
+        this.from[1] = this.to[1] = from[1];
+    }
+}
+
+RockLine.prototype.contains = function(pos) {
+    if (this.from[0] === this.to[0])
+        return pos[0] === this.from[0] && pos[1] >= this.from[1] && pos[1] <= this.to[1];
+    return pos[1] === this.from[1] && pos[0] >= this.from[0] && pos[0] <= this.to[0];
+}
+
+function Map() {
+    this.rockLines = [];
+    this.sand = [];
+    this.bottom = 0;
+}
+
+Map.prototype.canMove = function(pos) {
+    return !this.sand.find(i => i[0] === pos[0] && i[1] === pos[1]) && !this.rockLines.find(i => i.contains(pos));
+}
+
+Map.prototype.moveSand = function() {
+    const index = this.sand.length -1;
+    if (this.sand[index][1] > this.bottom)
+        return false;
+    if (this.canMove([this.sand[index][0], this.sand[index][1]+1])) {
+        this.sand[index][1]++;
+    } else if (this.canMove([this.sand[index][0]-1, this.sand[index][1]+1])) {
+        this.sand[index][0]--;
+        this.sand[index][1]++;
+    } else if (this.canMove([this.sand[index][0]+1, this.sand[index][1] +1])) {
+        this.sand[index][0]++;
+        this.sand[index][1]++;
+    }
+    else
+        return false;
+    return true;
+}
+
+Map.prototype.round = function(infiniteGround) {
+    if (!this.canMove([500, 0]))
+        return false;
+    this.sand.push([500, 0]);
+    while (this.moveSand());
+    return infiniteGround ? this.sand.slice(-1)[0][1] < this.bottom : true;
+}
+
+async function main() {
+    let map = new Map();
+    for await (let line of readline.createInterface({ input: process.stdin })) {
+        let lines = line.split(' -> ').map(i => i.split(',').map(i => parseInt(i)));
+        for (let i =1; i < lines.length; ++i)
+            map.rockLines.push(new RockLine(lines[i -1], lines[i]));
+    }
+    map.bottom = map.rockLines.map(i => Math.max(i.from[1], i.to[1])).reduce((i, j) => Math.max(i||0, j));
+    while (map.round(true));
+    console.log(map.sand.length -1);
+    while (map.round(false));
+    console.log(map.sand.length);
+};
+
+(main());
+

+ 79 - 0
d15/main.js

@@ -0,0 +1,79 @@
+
+const fs = require('fs');
+const readline = require('readline');
+
+function taxiCab(a, b) {
+    return Math.abs(b[0] - a[0]) + Math.abs(a[1] - b[1]);
+}
+
+function Sensor(arr) {
+    this.pos = [arr[0], arr[1]];
+    this.closestBeacon = [ arr[2], arr[3] ];
+    this.dist = taxiCab(this.pos, this.closestBeacon);
+}
+
+Sensor.prototype.canBeacon = function(pos) {
+    return taxiCab(this.pos, pos) > this.dist || (
+        pos[0] === this.closestBeacon[0] && pos[1] === this.closestBeacon[1]);
+}
+
+Sensor.prototype.canBeDetress = function(pos) {
+    return taxiCab(this.pos, pos) > this.dist;
+}
+
+function checkRow(rowId, minX, maxX, sensors) {
+    let result = 0;
+    for (let i =minX; i < maxX; ++i)
+        if (!sensors.every(s => s.canBeacon([i, rowId])))
+            result++;
+    return result;
+}
+
+function checkPos(sensors, maxSize, i, j) {
+    if (i < maxSize && j < maxSize && i >= 0 && j >=0 && sensors.every(s => s.canBeDetress([i, j])))
+        return [ i, j ];
+    return null;
+}
+
+function findPos(maxSize, sensors) {
+    for (let sensor of sensors) {
+        for (let i =0; i <= sensor.dist +1; ++i) {
+            let j = sensor.dist +1 - i;
+            let result =
+                checkPos(sensors, maxSize, sensor.pos[0] + i, sensor.pos[1] + j) ||
+                checkPos(sensors, maxSize, sensor.pos[0] + i, sensor.pos[1] - j) ||
+                checkPos(sensors, maxSize, sensor.pos[0] - i, sensor.pos[1] - j) ||
+                checkPos(sensors, maxSize, sensor.pos[0] - i, sensor.pos[1] + j);
+            if (result) {
+                console.log(result);
+                return 4000000 * result[0] + result[1];
+            }
+        }
+    }
+}
+
+async function main() {
+    let sensors = [];
+    let minX = Infinity;
+    let maxX = -Infinity;
+    let maxY = -Infinity;
+    let maxDist = -Infinity;
+    for await (let line of readline.createInterface({ input: process.stdin })) {
+        let sensor = new Sensor(line.match(/(-?\d+)/g).map(i => parseInt(i)));
+        minX = Math.min(minX, sensor.pos[0]);
+        maxX = Math.max(maxX, sensor.pos[0]);
+        maxY = Math.max(maxY, sensor.pos[1]);
+        maxDist = Math.max(maxDist, sensor.dist);
+        sensors.push(sensor);
+    }
+    // part1
+    console.log(checkRow(10, minX -maxDist, maxX + maxDist, sensors));
+    console.log(findPos(20, sensors));
+
+    // part2
+    console.log(checkRow(2000000, minX -maxDist, maxX + maxDist, sensors));
+    console.log(findPos(4000000, sensors));
+};
+
+(main());
+