isundil 3 years ago
parent
commit
7371868818
3 changed files with 279 additions and 0 deletions
  1. 177 0
      d17/main.js
  2. 88 0
      d18/main.js
  3. 14 0
      d18/short.js

+ 177 - 0
d17/main.js

@@ -0,0 +1,177 @@
+
+const fs = require('fs');
+const readline = require('readline');
+
+const MAP_WIDTH = 7;
+const RESET_COLOR = '\x1B[39m';
+const EMPTY_CHAR = ' ';//'\x1B[39m.';
+
+function CircularBuffer(dataArr) {
+    this.data = dataArr;
+    this.pos = 0;
+}
+
+CircularBuffer.prototype.pop = function() {
+    let data = this.data[this.pos++];
+    while (this.pos >= this.data.length)
+        this.pos -= this.data.length;
+    return data;
+}
+
+function Arena() {
+    this.current = null;
+    this.data = [[]];
+    this.dataBit = [ 0xFF ];
+    this.dejavu = [];
+    this.heightRemoved = 0;
+    for (let i =0; i < MAP_WIDTH; ++i) this.data[0].push('-');
+}
+
+Arena.prototype.currentCover = function(px, py) {
+    if (!this.current || this.current.x + this.current.width <= px || this.current.x > px ||
+            this.current.y >= py || this.current.y + this.current.data.length < py)
+        return false;
+    return this.current.data[py - this.current.y -1][px-this.current.x];
+}
+
+Arena.prototype.display = function(size) {
+    if (!size) return Promise.resolve();
+    console.log('\033[2J');
+    for (let i =50; i >= 0; --i) {
+        let border = i === 0 ? '+' : '|';
+        let line = "";
+        for (let j =0; j < MAP_WIDTH; ++j) {
+            if (this.currentCover(j, i))
+                line += this.current.color + this.current.c;
+            else if (this.data[i] && this.data[i][j])
+                line += (typeof this.data[i][j] === 'string' ? this.data[i][j] : (this.data[i][j].color + this.data[i][j].c));
+            else
+                line += EMPTY_CHAR;
+        }
+        console.log(border+line+RESET_COLOR+border);
+    }
+    return new Promise((ok, ko) => setTimeout(ok, 75));
+}
+
+Arena.prototype.canMove = function(dx, dy) {
+    if (this.current.x + dx < 0 || this.current.x + dx >= MAP_WIDTH || this.current.y + dy < 0) return false;
+    return this.current.data
+        .every((bitSet, index) => {
+            if (dx === -1) bitSet <<= 1;
+            else if (dx === 1) bitSet >>= 1;
+            console.log("can move ? ", this.current.height-index+dy+this.current.y, this.dataBit[this.current.height-index+dy+this.current.y], bitSet);
+            return (this.dataBit[this.current.height-index+dy+this.current.y] || 0x00) & bitSet != 0;
+        });
+}
+
+Arena.prototype.move = async function(dx, dy, displaySize) {
+    await this.display(displaySize);
+    if (!this.canMove(dx, dy))
+        return false;
+    this.current.x += dx;
+    this.current.y += dy;
+    return true;
+}
+
+Arena.prototype.stackSize = function(pos) {
+    for (let i = this.dataBit.length-1; i > 0; --i) {
+        if (this.dataBit[i][1 << pos])
+            return i <= 0 ? Infinity : i;
+    }
+    return Infinity;
+}
+
+Arena.prototype.optimHeight = function() {
+    let max = Infinity;
+    for (let i =0; i < MAP_WIDTH; ++i)
+        max = Math.min(max, this.stackSize(i));
+    if (max !== Infinity) {
+        this.heightRemoved += max;
+        while (max-- > 0) {
+            this.data.shift();
+            this.dataBit.shift();
+        }
+    }
+}
+
+Arena.prototype.nextRock = async function(pieces, jetStream, displaySize, round) {
+    const colors = [ '\033[31m', '\033[32m', '\033[33m', '\033[35m', '\033[36m' ];
+    const chars = ['@', '!', '$', '%', '+', '=', '?', '#'];
+    let piece = pieces.pop();
+    let currentData = piece.map(i => i.split('').map(i => i === '#'));
+    this.current = {
+        data: piece.map(i => i.split('').map(i => i === '#')),
+        color: colors[Math.floor(Math.random() * colors.length)],
+        x: 2,
+        y: this.data.length +2,
+        c: chars[Math.floor(Math.random() * chars.length)],
+        height: 0,
+        width: 0
+    };
+    let currentBits = [];
+    for (let i of this.current.data) {
+        let b = 0x00;
+        for (let j =0; j < i.length; ++j)
+            b |= i[j]<<j;
+        currentBits.push(b);
+    }
+    this.current.data = currentBits;
+    this.current.height = this.current.data.length;
+    this.current.width = currentData[0].length;
+    do {
+        await this.move(jetStream.pop(), 0, displaySize);
+    } while (await this.move(0, -1, displaySize));
+    currentData
+        .map((line, y) =>
+            line.map((data, x) => data ? [x+this.current.x, this.current.height-y+this.current.y] : undefined))
+        .reduce((acc, i) => (acc || []).concat(i))
+        .filter(i => !!i)
+        .forEach(i => {
+            while (this.data.length <= i[1]) {
+                this.data.push([]);
+                this.dataBit.push(0x00);
+            }
+            this.data[i[1]][i[0]] = {
+                color: this.current.color,
+                c: this.current.c
+            };
+            this.dataBit[i[1]] |= (1 << i[0]);
+        });
+    this.current = null;
+    this.dejavu[pieces.pos+'x'+jetStream.pos] = { piece: pieces.pos, jetStream: jetStream.pos, index: round };
+    (round %500 === 0) && this.optimHeight();
+    await this.display(displaySize);
+}
+
+const SCREEN_SIZE = 60;
+//const ProgressBar = require('progress');
+
+async function main() {
+    let arena = new Arena();
+    let jetStream = null;
+    let pieces = new CircularBuffer([
+        ["####"],
+        [" # ", "###", " # "],
+        ["  #", "  #", "###"],
+        ["#", "#", "#", "#"],
+        ["##", "##"]
+    ]);
+    for await (let line of readline.createInterface({ input: process.stdin })) {
+        jetStream = new CircularBuffer(line.split('').map(i => i === '<' ? -1 : +1));
+        break;
+    }
+    let i =0;
+    for (; i < 2022; ++i)
+        await arena.nextRock(pieces, jetStream, 0, i);
+    console.log("Part 1", arena.heightRemoved + arena.data.length -1);
+    return;
+    //let Progress = new ProgressBar(':bar', { total: 1000000000000 });
+    for (; i < 1000000000000; ++i) {
+        arena.nextRock(pieces, jetStream, 0, i);
+        //Progress.tick();
+    }
+    console.log("\n\nPart 2", arena.heightRemoved + arena.data.length -1);
+};
+
+(main());
+

+ 88 - 0
d18/main.js

@@ -0,0 +1,88 @@
+
+const fs = require('fs');
+const readline = require('readline');
+
+Array.prototype.count = function(fnc) {
+    return this.reduce((total, i, index) => fnc(i, index) ? total+1 : total, 0);
+}
+
+Array.prototype.countUnique = function(fnc) {
+    return this.reduce((total, i, index) => (total.indexOf(i) === -1 && fnc(i, index)) ? total.concat(i):total, []).length;
+}
+
+function getAdjascents(pos) {
+    return [
+        [ pos.coords[0] -1, pos.coords[1], pos.coords[2] ],
+        [ pos.coords[0] +1, pos.coords[1], pos.coords[2] ],
+        [ pos.coords[0], pos.coords[1] +1, pos.coords[2] ],
+        [ pos.coords[0], pos.coords[1] -1, pos.coords[2] ],
+        [ pos.coords[0], pos.coords[1], pos.coords[2] +1 ],
+        [ pos.coords[0], pos.coords[1], pos.coords[2] -1 ]
+    ];
+}
+
+function countShards(map) {
+    return Object.keys(map).reduce((acc, i) => acc +getAdjascents(map[i]).map(i => i.join(',')).count(i => !map[i]), 0);
+}
+
+function isTrapped(map, arr, obj) {
+    // FIXME
+    return false;
+}
+
+function countShards2(map) {
+    const keys = Object.keys(map);
+    if (keys.length < 8) return countShards(map); // trivial out
+    return Object.keys(map).reduce((acc, i) => acc +getAdjascents(map[i]).map(i => i.join(',')).count(i => !map[i] && !isTrapped(map, i)), 0);
+}
+
+function manhatan(a, b) {
+    return a.reduce((acc, val, index) => acc + Math.abs(b[index]-val), 0);
+}
+
+function mergeIds(map, oldId, newId) {
+    Object.keys(map).forEach(i => { if (map[i].gid === oldId) map[i].gid = newId;});
+}
+
+function computeShardShape(map) {
+    const keys = Object.keys(map);
+    let ids = [];
+    let maxId = 0;
+    for (let i =0; i < keys.length; ++i) {
+        if (map[keys[i]].gid !== undefined) {
+            for (let j = 0; j < i; ++j) {
+                if (map[keys[i]].gid !== map[keys[j]].gid && manhatan(map[keys[i]].coords, map[keys[j]].coords) === 1)
+                    mergeIds(map, map[keys[i]].gid, map[keys[j]].gid);
+            }
+            continue;
+        }
+        map[keys[i]].gid = ++maxId;
+        ids.push(maxId);
+        for (let j = 1; j < keys.length; ++j)
+            if (manhatan(map[keys[i]].coords, map[keys[j]].coords) === 1) {
+                if (map[keys[j]].gid !== undefined)
+                    mergeIds(map, maxId, map[keys[j]].gid);
+                else
+                    map[keys[j]].gid = maxId;
+            }
+    }
+    return ids.map(i => keys.filter(j => i === map[j].gid).map(i => map[i])).filter(i => i.length).map(i => i.reduce((acc, i) => { acc[i.id] = i; return acc; }, {}));
+}
+
+async function main() {
+    let shards = {};
+    for await (let line of readline.createInterface({ input: process.stdin })) {
+        shards[line] = {
+            coords: line.split(',').map(i => parseInt(i)),
+            gid: undefined,
+            id: line
+        }
+    }
+    let extShards = countShards(shards);
+    console.log(extShards);
+    //console.log(require('util').inspect(computeShardShape(shards), { showHidden: false, depth: null, colors: true }));
+    console.log(computeShardShape(shards).reduce((acc, i) => countShards2(i)+acc, 0));
+};
+
+(main());
+

+ 14 - 0
d18/short.js

@@ -0,0 +1,14 @@
+
+(async()=>{
+    let map = {};
+    for await (let line of require('readline').createInterface({ input: process.stdin }))
+        map[line] = { coords: line.split(',').map(i => parseInt(i)) }
+    console.log(Object.keys(map).reduce((acc, i) => acc +[[ map[i].coords[0] -1, map[i].coords[1], map[i].coords[2] ],
+        [ map[i].coords[0] +1, map[i].coords[1], map[i].coords[2] ],
+        [ map[i].coords[0], map[i].coords[1] +1, map[i].coords[2] ],
+        [ map[i].coords[0], map[i].coords[1] -1, map[i].coords[2] ],
+        [ map[i].coords[0], map[i].coords[1], map[i].coords[2] +1 ],
+        [ map[i].coords[0], map[i].coords[1], map[i].coords[2] -1 ]
+    ].map(i => i.join(',')).reduce((acc, i) => !map[i]?acc+1:acc, 0), 0));
+})();
+