163 lines
4.4 KiB
TypeScript
163 lines
4.4 KiB
TypeScript
|
namespace AdventOfCode2019_24_2
|
||
|
{
|
||
|
const DAY = 24;
|
||
|
const PROBLEM = 2;
|
||
|
|
||
|
export async function run()
|
||
|
{
|
||
|
let input = await AdventOfCode.getInput(DAY);
|
||
|
if (input == null) return;
|
||
|
|
||
|
AdventOfCode.setIntermedOutputSize("0.70vw");
|
||
|
|
||
|
const grid0 = input
|
||
|
.split(new RegExp('\r?\n'))
|
||
|
.filter(p => p.trim().length > 0)
|
||
|
.map(p => p.trim().split('').map(q => q==='#'));
|
||
|
|
||
|
let world: {[_:number]:boolean} = {};
|
||
|
for(let y=0; y<5; y++) for(let x=0; x<5; x++) world[id(x, y, 0)] = grid0[y][x];
|
||
|
|
||
|
let minD = -1;
|
||
|
let maxD = +1;
|
||
|
|
||
|
await AdventOfCode.outputIntermed(tostr2(world, minD, maxD));
|
||
|
await AdventOfCode.sleepIfIntermed(500);
|
||
|
|
||
|
for(let i=0; i<200; i++)
|
||
|
{
|
||
|
[minD, maxD] = step(world, minD, maxD);
|
||
|
|
||
|
await AdventOfCode.outputIntermed(tostr2(world, minD, maxD));
|
||
|
await AdventOfCode.sleepIfIntermed(50);
|
||
|
}
|
||
|
|
||
|
let count = Object.values(world).filter(p => p).length;
|
||
|
|
||
|
AdventOfCode.output(DAY, PROBLEM, count.toString());
|
||
|
}
|
||
|
|
||
|
function tostr1(world: {[_:number]:boolean}, minD: number, maxD: number): string
|
||
|
{
|
||
|
let str = "";
|
||
|
|
||
|
for(let d=minD; d<=maxD; d++)
|
||
|
{
|
||
|
str += "Depth "+d+":\n";
|
||
|
for(let y=0; y<5; y++)
|
||
|
{
|
||
|
for(let x=0; x<5; x++)
|
||
|
{
|
||
|
str += (world[id(x, y, d)] === true) ? "#" : ".";
|
||
|
}
|
||
|
str += "\n";
|
||
|
}
|
||
|
str += "\n";
|
||
|
}
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
function tostr2(world: {[_:number]:boolean}, minD: number, maxD: number): string
|
||
|
{
|
||
|
let str = "";
|
||
|
|
||
|
for (let y = 0; y<11*6; y++)
|
||
|
{
|
||
|
for (let x = 0; x<19*6; x++)
|
||
|
{
|
||
|
let mx = x%6;
|
||
|
let my = y%6;
|
||
|
if (mx===5 || my === 5) str += " "
|
||
|
else if (mx===2 && my === 2) str += "?"
|
||
|
else
|
||
|
{
|
||
|
let md = Math.floor(y/6) * 19 + Math.floor(x/6) - Math.floor((19*11)/2);
|
||
|
|
||
|
str += (world[id(mx, my, md)] === true) ? "#" : ".";
|
||
|
}
|
||
|
}
|
||
|
str += "\n";
|
||
|
}
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
function id(x: number, y: number, depth: number): number
|
||
|
{
|
||
|
return depth*100 + x*10 + y;
|
||
|
}
|
||
|
|
||
|
function step(world: {[_:number]:boolean}, minD: number, maxD: number): [number, number]
|
||
|
{
|
||
|
let newminD = minD;
|
||
|
let newmaxD = minD;
|
||
|
|
||
|
let diff: [number, boolean, number][] = [];
|
||
|
|
||
|
for(let d=minD; d<=maxD; d++)
|
||
|
for(let y=0; y<5; y++)
|
||
|
for(let x=0; x<5; x++)
|
||
|
{
|
||
|
if (x === 2 && y === 2) continue;
|
||
|
|
||
|
let me_id = id(x, y, d);
|
||
|
let me = (world[me_id] === true);
|
||
|
|
||
|
let adjac = 0;
|
||
|
if (x>0 && world[id(x-1, y, d)] === true) adjac++;
|
||
|
if (y>0 && world[id(x, y-1, d)] === true) adjac++;
|
||
|
if (x<4 && world[id(x+1, y, d)] === true) adjac++;
|
||
|
if (y<4 && world[id(x, y+1, d)] === true) adjac++;
|
||
|
|
||
|
if (x === 0 && world[id(1, 2, d-1)] === true) adjac++; // WEST OUTER
|
||
|
if (y === 0 && world[id(2, 1, d-1)] === true) adjac++; // NORTH OUTER
|
||
|
if (x === 4 && world[id(3, 2, d-1)] === true) adjac++; // EAST OUTER
|
||
|
if (y === 4 && world[id(2, 3, d-1)] === true) adjac++; // SOUTH OUTER
|
||
|
|
||
|
if (x === 2 && y === 1) // NORTH INNER
|
||
|
{
|
||
|
if (world[id(0, 0, d+1)] === true) adjac++;
|
||
|
if (world[id(1, 0, d+1)] === true) adjac++;
|
||
|
if (world[id(2, 0, d+1)] === true) adjac++;
|
||
|
if (world[id(3, 0, d+1)] === true) adjac++;
|
||
|
if (world[id(4, 0, d+1)] === true) adjac++;
|
||
|
}
|
||
|
if (x === 3 && y === 2) // EAST INNER
|
||
|
{
|
||
|
if (world[id(4, 0, d+1)] === true) adjac++;
|
||
|
if (world[id(4, 1, d+1)] === true) adjac++;
|
||
|
if (world[id(4, 2, d+1)] === true) adjac++;
|
||
|
if (world[id(4, 3, d+1)] === true) adjac++;
|
||
|
if (world[id(4, 4, d+1)] === true) adjac++;
|
||
|
}
|
||
|
if (x === 2 && y === 3) // SOUTH INNER
|
||
|
{
|
||
|
if (world[id(0, 4, d+1)] === true) adjac++;
|
||
|
if (world[id(1, 4, d+1)] === true) adjac++;
|
||
|
if (world[id(2, 4, d+1)] === true) adjac++;
|
||
|
if (world[id(3, 4, d+1)] === true) adjac++;
|
||
|
if (world[id(4, 4, d+1)] === true) adjac++;
|
||
|
}
|
||
|
if (x === 1 && y === 2) // WEST INNER
|
||
|
{
|
||
|
if (world[id(0, 0, d+1)] === true) adjac++;
|
||
|
if (world[id(0, 1, d+1)] === true) adjac++;
|
||
|
if (world[id(0, 2, d+1)] === true) adjac++;
|
||
|
if (world[id(0, 3, d+1)] === true) adjac++;
|
||
|
if (world[id(0, 4, d+1)] === true) adjac++;
|
||
|
}
|
||
|
|
||
|
if (me && adjac !== 1) diff.push([me_id, false, d]); // A bug dies (becoming an empty space) unless there is exactly one bug adjacent to it.
|
||
|
else if (!me && (adjac === 1 || adjac === 2)) diff.push([me_id, true, d]); // An empty space becomes infested with a bug if exactly one or two bugs are adjacent to it.
|
||
|
}
|
||
|
|
||
|
for (const [id, val, depth] of diff)
|
||
|
{
|
||
|
world[id] = val;
|
||
|
if (depth <= newminD) newminD = depth-1;
|
||
|
if (depth >= newmaxD) newmaxD = depth+1;
|
||
|
}
|
||
|
|
||
|
return [newminD, newmaxD];
|
||
|
}
|
||
|
}
|