isundil 3 năm trước cách đây
mục cha
commit
b3463fc2b0
2 tập tin đã thay đổi với 184 bổ sung0 xóa
  1. 165 0
      d23/main.js
  2. 19 0
      lib.js

+ 165 - 0
d23/main.js

@@ -0,0 +1,165 @@
+
+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;
+}
+
+const COLOR_RESET = '\x1B[39m';
+const CLEAR_SCR = '\033[2J';
+const COLOR_MAP = [ '\033[31m', '\033[32m', '\033[33m', '\033[35m', '\033[36m' ];
+const chars = ['@', '!', '$', '%', '+', '=', '?', '#'];
+
+function Elf(px, py) {
+    this.px = px;
+    this.py = py;
+
+    this.nextX = 0;
+    this.nextY = 0;
+
+    this.moveList = [
+        {
+            cond: (surrounding) => !surrounding[0][0] && !surrounding[1][0] && !surrounding[2][0],
+            action: (self) => { self.nextX = self.px; self.nextY = self.py -1; }
+        },
+        {
+            cond: (surrounding) => !surrounding[0][2] && !surrounding[1][2] && !surrounding[2][2],
+            action: (self) => { self.nextX = self.px; self.nextY = self.py +1; }
+        },
+        {
+            cond: (surrounding) => !surrounding[0][0] && !surrounding[0][1] && !surrounding[0][2],
+            action: (self) => { self.nextX = self.px -1; self.nextY = self.py; }
+        },
+        {
+            cond: (surrounding) => !surrounding[2][0] && !surrounding[2][1] && !surrounding[2][2],
+            action: (self) => { self.nextX = self.px +1; self.nextY = self.py; }
+        }
+    ];
+    this.color = COLOR_MAP[Math.floor(Math.random() * COLOR_MAP.length)];
+    this.c = chars[Math.floor(Math.random() * chars.length)];
+
+    this.done = false;
+}
+
+Elf.prototype.round = function(pool, roundId) {
+    const surrounding = pool.surround(this.px, this.py);
+    if (surrounding._count === 0) {
+        this.nextX = this.px;
+        this.nextY = this.py;
+    } else for (let i =0; i < 4; ++i) {
+        if (this.moveList[(i + roundId) % this.moveList.length].cond(surrounding)) {
+            this.moveList[(i + roundId) % this.moveList.length].action(this);
+            return;
+        }
+    }
+    this.nextX = this.px;
+    this.nextY = this.py;
+}
+
+function ElfPool() {
+    this.elves = [];
+    this.boundaries = [[Infinity, -Infinity], [Infinity, -Infinity]];
+}
+
+ElfPool.prototype.dopush = function(px, py) {
+    this.elves.push(new Elf(px, py));
+    this.boundaries = [
+        [Math.min(this.boundaries[0][0], px), Math.max(this.boundaries[0][1], px)],
+        [Math.min(this.boundaries[1][0], py), Math.max(this.boundaries[1][1], py)]];
+}
+
+ElfPool.prototype.round = function(roundId) {
+    for (let i of this.elves)
+        i.round(this, roundId);
+    if (this.elves.every(x => x.px === x.nextX && x.py === x.nextY)) return true;
+    this.elves.forEach(i => i.done = false);
+    this.boundaries = [[Infinity, -Infinity], [Infinity, -Infinity]];
+    for (let i =0; i < this.elves.length; ++i) {
+        if (!this.elves[i].done)
+            for (let j =i +1; j < this.elves.length; ++j) {
+                if (this.elves[i].nextX === this.elves[j].nextX &&
+                    this.elves[i].nextY === this.elves[j].nextY)
+                    this.elves[i].done = this.elves[j].done = true;
+            }
+        if (!this.elves[i].done) {
+            this.elves[i].px = this.elves[i].nextX;
+            this.elves[i].py = this.elves[i].nextY;
+            this.boundaries = [
+                [Math.min(this.boundaries[0][0], this.elves[i].px), Math.max(this.boundaries[0][1], this.elves[i].px)],
+                [Math.min(this.boundaries[1][0], this.elves[i].py), Math.max(this.boundaries[1][1], this.elves[i].py)]];
+        }
+    }
+    return false;
+}
+
+ElfPool.prototype.surround = function(px, py) {
+    let result = [ [ false, false, false], [ false, false, false ], [ false, false, false ]];
+    result._count = 0;
+    for (let i = px-1; i <= px+1; ++i)
+        for (let j=py -1; j <= py +1; ++j)
+            if ((i !== px || j !== py) && this.elves.some(x => x.py === j && x.px === i)) {
+                result[i-px+1][j-py+1] = true;
+                result._count++;
+            }
+    return result;
+}
+
+ElfPool.prototype.display = async function() {
+    let minY = this.boundaries[1][0];
+    let minX = this.boundaries[0][0];
+    let maxX = this.boundaries[0][1];
+    let elvesRows = [];
+
+    console.log(CLEAR_SCR);
+    for (let i of this.elves) {
+        if (!elvesRows[i.py - minY])
+            elvesRows[i.py - minY] = [];
+        elvesRows[i.py - minY].push({x: i.px, color: i.color, c: i.c });
+    }
+    for (let i =0; i < elvesRows.length; ++i) {
+        _i = (elvesRows[i] || []).sort((a, b) => a.x-b.x);
+        let line = '';
+        for (let pos = minX; pos <= maxX; ++pos) {
+            if (_i[0]?.x === pos) {
+                line += _i[0].color+_i[0].c+COLOR_RESET;
+                _i.shift();
+            } else {
+                line += '.';
+            }
+        }
+        console.log(line);
+    }
+    return new Promise((ok, ko) => setTimeout(ok, 450));
+}
+
+let _main = (async()=>{
+    let pool = new ElfPool();
+    let lineIndex = 0;
+    for await (let line of require('readline').createInterface({ input: process.stdin })) {
+        for (let i =0; i < line.length; ++i)
+            if (line[i] === '#')
+                pool.dopush(i, lineIndex);
+        ++lineIndex;
+    }
+    let i =0;
+    let part1Solution = 0;
+    while (true) {
+        if (i === 10)
+            part1Solution = ((pool.boundaries[0][1]-pool.boundaries[0][0]+1) * (pool.boundaries[1][1]-pool.boundaries[1][0]+1)) - pool.elves.length;
+        if (pool.round(i))
+            break;
+        ++i;
+        await pool.display();
+    }
+    await pool.display();
+    console.log("Part 1: ", part1Solution);
+    console.log("Part 2: ", ++i);
+});
+
+// response < 4241
+// > 4076
+_main();
+
+

+ 19 - 0
lib.js

@@ -0,0 +1,19 @@
+
+
+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;
+}
+
+async function sleep(duration) {
+    return new Promise((ok, ko) => setTimeout(ok, duration));
+}
+
+const COLOR_RESET = '\x1B[39m';
+const CLEAR_SCR = '\033[2J';
+const COLOR_MAP = [ '\033[31m', '\033[32m', '\033[33m', '\033[35m', '\033[36m' ];
+const chars = ['@', '!', '$', '%', '+', '=', '?', '#'];
+