Published
Edited
Dec 16, 2019
1 star
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md`**${finder.path}**`
Insert cell
Insert cell
program = puzzle.split(",")
Insert cell
Insert cell
scan = finder.grid;
Insert cell
finder = {
const max=2000; //bail out after max recursive moves
const notD=[ // exclude backwards move, still would allow small circles but not in puzzle
[0,2,3],
[1,2,3],
[0,1,2],
[0,1,3]
];
let grid={},v,out,log=[];
let mapgrid = function(v, d, x, y) {
let x1 = x, y1 = y;
switch (d) {
case 0:
y1 = y - 1;
break;
case 1:
y1 = y + 1;
break;
case 2:
x1 = x - 1;
break;
case 3:
x1 = x + 1;
break;
}
switch (v) {
case 1: //moved
grid[[x1, y1]]= ':';
break;
case 0: //wall
grid[[x1, y1]]= '#';
[x1, y1] = [x, y];
break;
case 2:
grid[[x1, y1]]= '*';
debugger;
break;
}
return [x1, y1];
};
let path = function(mem, D, moves, x0, y0) {
let xd, yd; // needs to be in this scope
let tries = notD[D].map( d => {
out = intcomp(mem, [d+1]); v = out.value[0];
[xd, yd] = mapgrid(v, d, x0, y0);
if (v == 2) { return moves+1 }; // last move
if (v == 0) { return -1 }; // dummy to filter out
if (moves > max) { return moves };
return path(out.mem, d, moves+1, xd, yd);
}).filter(m => m != -1).sort((a, b) => a-b)[0]; //just keep smallest moves
return tries;
};
return {path: path(program, 1, 0, 0, 0), grid: (grid[[0,0]]='X', grid)}
};
Insert cell
dims = {
let xs = Object.keys(scan).map(v => v.split(',')[0]).sort((a,b) => a-b);
let ys = Object.keys(scan).map(v => v.split(',')[1]).sort((a,b) => a-b);
return {
origin: [xs[0], ys[0]],
width: xs[xs.length-1] - xs[0] + 1,
height: ys[ys.length-1] - ys[0] + 1
}
}
Insert cell
screen = {
let s = Array(dims.height).fill(0).map(v => Array(dims.width).fill(" "));
Object.entries(scan).forEach( ([key, value]) => {
s[key.split(',')[1]-dims.origin[1]][key.split(',')[0]-dims.origin[0]] = value;
});
return s
}
Insert cell
screentxt = {
const gfx = {
':' : "░░",
1 : "▓",
"#" : "██",
"X" : "<>",
"*" : "O2",
" " : "██"
};
return screen.map(r => r.map(v => gfx[v]).join("")).join("\n");
}
Insert cell
screendiv = html`<div>
<pre style="font-size:12px;line-height:1.2; color: lightgreen; background-color: black">${screentxt}</pre>
</div>
`
Insert cell
Insert cell
md`**${addO2}** minutes.`
Insert cell
addO2 = {
let grid = Object.entries( finder.grid ) //convert to array
.map( v => [v[0].split(',').map(Number), v[1]] );
let toFill = grid.filter( v => v[1] !== '#' ); //only look at non-walls
let minutes = 0;
while (minutes++ < 1000) { // avoid getting stuck
toFill = toFill.map(([pos, v], i, a) => { // go through each cell
if (v == '*') {return [pos, v]} // already has O2
let adj = toFill.filter(ov => ov[1] == '*') // check adjacent O2 cells
.some(([apos, av]) => (
(apos[0] == pos[0] && (apos[1] == pos[1] + 1 || apos[1] == pos[1] - 1)) || // same x, close y
(apos[1] == pos[1] && (apos[0] == pos[0] + 1 || apos[0] == pos[0] - 1)) // same y, close x
));
return [pos, adj ? '*' : v] // fill if adjacent
});
if (toFill.every(v => v[1]=='*')) { break; } // done when every cell has o2
}
return minutes
}
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more