1
0
www.mikescher.com/www/statics/aoc/2019/24_solution-2.ts

163 lines
4.4 KiB
TypeScript
Raw Normal View History

2019-12-24 13:34:32 +01:00
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];
}
}