Public
Edited
Jan 14, 2024
Insert cell
Insert cell
Insert cell
in20b = "1|2|-3|3|-2|0|4"
Insert cell
seq = in20.split("|").map(i => parseInt(i))
Insert cell
function mix(seq, N) {
// Prepare
let entries = seq.map((v,i) => ({i,v}));
entries.forEach((o, i, a) => {
o.n = a[(i+1) % entries.length];
o.p = a[(i+entries.length-1) % entries.length];
});

// Mix
for (let i = 0; i < N; i++) {
let e = entries[i % entries.length];
let steps = e.v % (entries.length - 1);

if (steps === 0) continue;
// Remove from old position
let a = e;
let a1 = e.p;
let a2 = e.n;
a1.n = a2;
a2.p = a1;

// Search next position
e = a1;
for (let j = 0; j < Math.abs(steps); j++) {
e = Math.sign(steps) > 0 ? e.n : e.p;
}

// Insert to new position
let e2 = e.n;
e.n = a;
a.p = e;
a.n = e2;
e2.p = a;
}

return entries;
}
Insert cell
function expand(mix, from) {
let r = [];
let a = mix.find(v => v.v === from);
for (let i = 0; i < mix.length; i++) {
r.push(a.v);
a = a.n;
}
return r;
}
Insert cell
part1 = expand(mix(seq, seq.length), 0).filter((v,i) => i === 1000 || i === 2000 || i === 3000).reduce((a,b) => a+b, 0)
Insert cell
part2 = expand(mix(seq.map(n => n * 811589153), 10 * seq.length), 0).filter((v,i) => i === 1000 || i === 2000 || i === 3000).reduce((a,b) => a+b, 0)
Insert cell
Insert cell
Insert cell
in21b = "root: pppw + sjmn|dbpl: 5|cczh: sllz + lgvd|zczc: 2|ptdq: humn - dvpt|dvpt: 3|lfqf: 4|humn: 5|ljgn: 2|sjmn: drzm * dbpl|sllz: 4|pppw: cczh / lfqf|lgvd: ljgn * ptdq|drzm: hmdt - zczc|hmdt: 32"
Insert cell
monkeys = new Map(in21
.split("|").map(a => a.split(": "))
.map(([a,b]) => [a, b.split(" ")])
.map(([a,b]) => [a, b.length === 1 ? parseInt(b[0]) : b]))
Insert cell
value("root")
Insert cell
function value(name) {
let m = monkeys.get(name)
if (typeof m === "number") return m;
let [a,b,c] = m;
let l = value(a);
let r = value(c);
if (b === "+") return l+r;
if (b === "*") return l*r;
if (b === "-") return l-r;
if (b === "/") return l/r;
}
Insert cell
Insert cell
[monkeys.get("root")[0], monkeys.get("root")[2]].map(n => val2(n, NaN))
Insert cell
find(monkeys.get("root")[0], val2(monkeys.get("root")[2], NaN))
Insert cell
function val2(name, repl) {
if (name === "humn") return repl;
let m = monkeys.get(name);
if (typeof m === "number") return m;
let [a,b,c] = m;
let l = val2(a, repl);
let r = val2(c, repl);
if (b === "+") return l+r;
if (b === "*") return l*r;
if (b === "-") return l-r;
if (b === "/") return l/r;
}
Insert cell
function find(name, value) {
if (name === "humn") return value;
let m = monkeys.get(name);
if (typeof m === "number") throw "not good";
let [a,b,c] = m;
let l = val2(a, NaN);
let r = val2(c, NaN);
if (isNaN(l) && isNaN(r)) throw "double naan";
if (!isNaN(l) && !isNaN(r)) throw "no naan";

let inv = false;
let pred;
let real;
if (isNaN(r)) {
inv = true;
[a,c] = [c,a];
[l,r] = [r,l];
}
if (b === "+") pred = find(a, value - r);
if (b === "*") pred = find(a, value / r);
if (b === "-" && !inv) pred = find(a, value + r);
if (b === "-" && inv) pred = find(a, r - value);
if (b === "/" && !inv) pred = find(a, value * r);
if (b === "/" && inv) pred = find(a, r / value);
// real = val2(a, pred);
// if (b === "+") real = real+r;
// if (b === "*") real = real*r;
// if (b === "-" && !inv) real = real-r;
// if (b === "-" && inv) real = r-real;
// if (b === "/" && !inv) real = real/r;
// if (b === "/" && inv) real = r/real;

// if (real !== value) throw [name, value, a,b,c,l,r,pred,real];
return pred;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
instructions = [
in22.split("|").map(l => [...l]),
[].concat(...split(in22b, "L").map(o => split(o, "R"))).map((v,i) => i%2 === 0 ? parseInt(v) : v)
]
Insert cell
instructions2 = [
in22_ex.split("|").map(l => [...l]),
[].concat(...split(in22b_ex, "L").map(o => split(o, "R"))).map((v,i) => i%2 === 0 ? parseInt(v) : v)
]
Insert cell
[instructions[0].map(t => "".concat(...t)), instructions[1]]
Insert cell
end = {
let input = deepCopy(instructions);
let map = input[0];
let path = input[1];

let pos = [0, map[0].findIndex(n => n !== " ")];
let dir = [0, 1];

for (let t = 0; t < path.length; t++) {
let pt = path[t];
if (typeof pt === "number") {
for (let u = 0; u < pt; u++) {
let n = next(map, pos, dir);
if (map[n[0]][n[1]] === "#") {
break;
} else if (map[n[0]][n[1]] === ".") {
pos = n;
} else {
throw "error"
}
}
} else {
dir = turn(dir, pt);
}
}
return [pos, dir];
}
Insert cell
1000 * (end[0][0]+1) + 4 * (end[0][1]+1)
Insert cell
function split(s, h) {
let r = [].concat(...s.split(h).map(t => [t,h]));
r.pop();
return r;
}
Insert cell
Insert cell
next(instructions2[0], [8, 13], [-1, 0])
Insert cell
function turn([a,b], dir) {
if (dir === "R") {
if (a === 0 && b === 1) return [1,0];
if (a === 1 && b === 0) return [0,-1];
if (a === 0 && b === -1) return [-1,0];
if (a === -1 && b === 0) return [0,1];
} else {
if (a === 0 && b === 1) return [-1,0];
if (a === 1 && b === 0) return [0,1];
if (a === 0 && b === -1) return [1,0];
if (a === -1 && b === 0) return [0,-1];
}
}
Insert cell
function deepCopy(a) { if (Array.isArray(a)) { return a.slice(0).map(deepCopy); } else if (typeof a === "object" && a !== null) { return Object.fromEntries(Object.entries(a).map(([k,v]) => [k, deepCopy(v)])) } else { return a; } }
Insert cell
Insert cell
function face(caracs, [j,i]) {
return caracs.faces[4 * Math.floor(j/caracs.size) + Math.floor(i/caracs.size)];
}
Insert cell
CHARACS = ({
size: 50,
faces: [, 1, 2, , , 0, , , 4, 3, , , 5],
coord: [[50,50], [0,50], [0,100], [100,50], [100,0], [150,0]],
next: [
new Map([["1,0", { face: 3, dir: [1,0], for: "down" }], ["0,-1", { face: 4, dir: [1,0], for: "left" }], ["-1,0", { face: 1, dir: [-1,0], for: "up" }], ["0,1", { face: 2, dir: [-1,0], for: "right" }]]),
new Map([["1,0", { face: 0, dir: [1,0], for: "down" }], ["0,-1", { face: 4, dir: [0,1], for: "left" }], ["-1,0", { face: 5, dir: [0,1], for: "up" }], ["0,1", { face: 2, dir: [0,1], for: "right" }]]),
new Map([["1,0", { face: 0, dir: [0,-1], for: "down" }], ["0,-1", { face: 1, dir: [0,-1], for: "left" }], ["-1,0", { face: 5, dir: [-1,0], for: "up" }], ["0,1", { face: 3, dir: [0,-1], for: "right" }]]),
new Map([["1,0", { face: 5, dir: [0,-1], for: "down" }], ["0,-1", { face: 4, dir: [0,-1], for: "left" }], ["-1,0", { face: 0, dir: [-1,0], for: "up" }], ["0,1", { face: 2, dir: [0,-1], for: "right" }]]),
new Map([["1,0", { face: 5, dir: [1,0], for: "down" }], ["0,-1", { face: 1, dir: [0,1], for: "left" }], ["-1,0", { face: 0, dir: [0,1], for: "up" }], ["0,1", { face: 3, dir: [0,1], for: "right" }]]),
new Map([["1,0", { face: 2, dir: [1,0], for: "down" }], ["0,-1", { face: 1, dir: [1,0], for: "left" }], ["-1,0", { face: 4, dir: [-1,0], for: "up" }], ["0,1", { face: 3, dir: [-1,0], for: "right" }]]),
],
})
Insert cell
function next_face(caracs, [j,i], dir) {
let [y, x, yr, xr] = [Math.floor(j/caracs.size), Math.floor(i/caracs.size), j % caracs.size, i % caracs.size];
if (yr+dir[0] >= 0 && yr+dir[0] < caracs.size && xr+dir[1] >= 0 && xr+dir[1] < caracs.size) {
return [[j+dir[0], i+dir[1]], dir];
}
let nf = caracs.next[caracs.faces[4*y+x]].get(dir.toString());
let a,b;
if (nf.dir[0] === 1) {
if (dir[0] === 1) a = xr;
if (dir[0] === -1) a = 49 - xr;
if (dir[1] === 1) a = 49 - yr;
if (dir[1] === -1) a = yr;
b = 0;
}
if (nf.dir[0] === -1) {
if (dir[0] === 1) a = 49 - xr;
if (dir[0] === -1) a = xr;
if (dir[1] === 1) a = yr;
if (dir[1] === -1) a = 49 - yr;
b = 49;
}
if (nf.dir[1] === 1) {
a = 0;
if (dir[0] === 1) b = 49 - xr;
if (dir[0] === -1) b = xr;
if (dir[1] === 1) b = yr;
if (dir[1] === -1) b = 49 - yr;
}
if (nf.dir[1] === -1) {
a = 49;
if (dir[0] === 1) b = xr;
if (dir[0] === -1) b = 49 - xr;
if (dir[1] === 1) b = 49 - yr;
if (dir[1] === -1) b = yr;
}
return [[caracs.coord[nf.face][0]+b,caracs.coord[nf.face][1]+a], nf.dir]
}
Insert cell
1000 * (end2[0][0]+1) + 4 * (end2[0][1]+1)
Insert cell
end2 = {
let input = deepCopy(instructions);
let map = input[0];
let path = input[1];

let pos = [0, map[0].findIndex(n => n !== " ")];
let dir = [0, 1];

for (let t = 0; t < path.length; t++) {
let pt = path[t];
if (typeof pt === "number") {
for (let u = 0; u < pt; u++) {
let [n,dn] = next_face(CHARACS, pos, dir);
if (map[n[0]][n[1]] === "#") {
break;
} else if (map[n[0]][n[1]] === ".") {
pos = n;
dir = dn;
} else {
throw "error"
}
}
} else {
dir = turn(dir, pt);
}
}
return [pos, dir];
}
Insert cell
next_face(CHARACS, [130,99], [0,1])
Insert cell
instructions[0][0][149]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function elf(j, i) {
return {};
}
Insert cell
elves = {
let e = in23.split("|").map(l => [...l])
.map((l,j) => l.map((v,i) => v === "." ? null : elf(j,i)));
let h = e[0].length + 2 * BUFFER;
return [
...new Array(BUFFER).fill(0).map(() => new Array(h).fill(null)),
...e.map(l => [...new Array(BUFFER).fill(null), ...l, ...new Array(BUFFER).fill(null)]),
...new Array(BUFFER).fill(0).map(() => new Array(h).fill(null))
];
}
Insert cell
Insert cell
TURNS = 10000
Insert cell
Insert cell
run = {
let e = deepCopy(elves);
let allElves = [];
e.forEach((l, j) => {
l.forEach((v, i) => {
if (v !== null) {
v.i = i;
v.j = j;
allElves.push(v);
}
});
});

let dirs = ["N", "S", "W", "E"];

for (let t = 0; t < Math.ceil(TURNS); t++) {
let stop = true;
let target = new Map();
// propose & check
allElves.forEach(elf0 => {
elf0.prop = standStill(e, elf0.i, elf0.j);
if (elf0.prop === "?") {
elf0.prop = makeProp(e, elf0.i, elf0.j, dirs);
}
if (elf0.prop !== "0") {
stop = false;

let tg = mv(elf0.i, elf0.j, elf0.prop).toString();
if (target.has(tg)) {
target.set(tg, 2);
} else {
target.set(tg, 1);
}
}
});
if (t === Math.ceil(TURNS) - 1 && TURNS - Math.floor(TURNS) > 0.1) {
break;
}

if (stop) return [e, t+1];

// move
allElves.forEach(elf0 => {
if (elf0.prop !== "0") {
let tg = mv(elf0.i, elf0.j, elf0.prop);
if (target.get(tg.toString()) === 1) {
e[tg[1]][tg[0]] = elf0;
e[elf0.j][elf0.i] = null;
elf0.i = tg[0];
elf0.j = tg[1];
}
}
delete elf0.prop;
});

dirs = [...dirs.slice(1), dirs[0]];
}
return [e, TURNS];
}
Insert cell
function mv(i, j, dir) {
if (dir === "N") {
return [i, j-1];
} else if (dir === "S") {
return [i, j+1];
} else if (dir === "W") {
return [i-1, j];
} else if (dir === "E") {
return [i+1, j];
}
}
Insert cell
function standStill(map, i, j) {
if (map[j-1].slice(i-1, i+2).some(v => v !== null)) return "?";
if (map[j+1].slice(i-1, i+2).some(v => v !== null)) return "?";
if (map[j][i-1] !== null || map[j][i+1] !== null) return "?"
return "0";
}
Insert cell
function makeProp(map, i, j, dirs) {
for (let d of dirs) {
if (propValid(map, i, j, d)) {
return d;
}
}
return "0";
}
Insert cell
function propValid(map, i, j, dir) {
if (dir === "N") {
return map[j-1][i+1] === null && map[j-1][i] === null && map[j-1][i-1] === null;
} else if (dir === "S") {
return map[j+1][i+1] === null && map[j+1][i] === null && map[j+1][i-1] === null;
} else if (dir === "W") {
return map[j-1][i-1] === null && map[j][i-1] === null && map[j+1][i-1] === null;
} else if (dir === "E") {
return map[j-1][i+1] === null && map[j][i+1] === null && map[j+1][i+1] === null;
}
}
Insert cell
Insert cell
Insert cell
Insert cell
blizz_map = {
let map = in24.split("|");
map = map.map(l => [...l].filter((v, i, a) => i > 0 && i < a.length - 1))
.filter((l, i, a) => i > 0 && i < a.length - 1);
let x_max = map[0].length - 1;
let y_max = map.length - 1;
let winds = [].concat(...map.map((l, j) => l.map((v, i) => v === "." ? null : { i, j, dir: v }).filter(v => v)));
return { map, y_max, x_max, winds };
}
Insert cell
{
let bm = deepCopy(blizz_map);
let start = new Set([str([0, -1])]);
let end = str([bm.x_max, bm.y_max]);

let t = 1;
while (t <= BLIZZARD_TURN && !start.has(end)) {
bm.winds.forEach(w => next_blizz(bm, w));
let avoid = new Set(bm.winds.map(w => str([w.i, w.j])));
start = new Set([].concat(...[...start].map(p => validMoves(bm, p, avoid))));
t++;
}

let out = new Array(bm.y_max+1).fill(0).map(() => new Array(bm.x_max+1).fill("."));
out = bm.winds.reduce((cur, w) => {
if (cur[w.j][w.i] === ".") {
cur[w.j][w.i] = w.dir;
} else if ("<>^v".includes(cur[w.j][w.i])) {
cur[w.j][w.i] = "2";
} else {
cur[w.j][w.i] = `${parseInt(cur[w.j][w.i]) + 1}`;
}
return cur;
}, out);
out = [...start].map(pos).reduce((cur, [i,j]) => {
if (j >= 0) {
if (cur[j][i] !== ".") throw "error";
cur[j][i] = "E";
}
return cur;
}, out);
out = out.map(l => "".concat(...l));

return {out, t};
}
Insert cell
Insert cell
Insert cell
function validMoves(bm, s, avoid) {
let [i,j] = pos(s);
let r = [[i,j]];
if (j === -1) {
r.push([0,0]);
return r.map(str).filter(p => !avoid.has(p));
}
if (j === bm.y_max + 1) {
r.push([bm.x_max, bm.y_max]);
return r.map(str).filter(p => !avoid.has(p));
}
if (j > 0) r.push([i,j-1]);
if (i > 0) r.push([i-1,j]);
if (j < bm.y_max) r.push([i,j+1]);
if (i < bm.x_max) r.push([i+1,j]);
return r.map(str).filter(p => !avoid.has(p));
}
Insert cell
function next_blizz(bm, w) {
if (w.dir === ">") {
w.i++;
if (w.i > bm.x_max) w.i = 0;
} else if (w.dir === "<") {
w.i--;
if (w.i < 0) w.i = bm.x_max;
} else if (w.dir === "v") {
w.j++;
if (w.j > bm.y_max) w.j = 0;
} else if (w.dir === "^") {
w.j--;
if (w.j < 0) w.j = bm.y_max;
}
return w;
}
Insert cell
Insert cell
BLIZZARD_TURN = 1000
Insert cell
p2 = {
let bm = deepCopy(blizz_map);

let start, end;
let h = [];
let t = 1;
start = new Set([str([0, -1])]);
end = str([bm.x_max, bm.y_max]);

while (t <= BLIZZARD_TURN && !start.has(end)) {
bm.winds.forEach(w => next_blizz(bm, w));
let avoid = new Set(bm.winds.map(w => str([w.i, w.j])));
start = new Set([].concat(...[...start].map(p => validMoves(bm, p, avoid))));
t++;
}

h.push(t);
t++;
bm.winds.forEach(w => next_blizz(bm, w));

start = new Set([str([bm.x_max, bm.y_max+1])]);
end = str([0, 0]);

while (t <= BLIZZARD_TURN && !start.has(end)) {
bm.winds.forEach(w => next_blizz(bm, w));
let avoid = new Set(bm.winds.map(w => str([w.i, w.j])));
start = new Set([].concat(...[...start].map(p => validMoves(bm, p, avoid))));
t++;
}
h.push(t);
t++;
bm.winds.forEach(w => next_blizz(bm, w));
start = new Set([str([0, -1])]);
end = str([bm.x_max, bm.y_max]);
while (t <= BLIZZARD_TURN && !start.has(end)) {
bm.winds.forEach(w => next_blizz(bm, w));
let avoid = new Set(bm.winds.map(w => str([w.i, w.j])));
start = new Set([].concat(...[...start].map(p => validMoves(bm, p, avoid))));
t++;
}

h.push(t);
return h;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
examples = ex.split("|").map(l => l.split(" ").filter(s => s)).map(([a,b]) => [parseInt(a), b])
Insert cell
fuels = in25.split("|")
Insert cell
unbase5(fuels.map(base5).reduce((a,b) => a+b, 0))
Insert cell
function decimal(d) {
if (d === "=") return -2;
if (d === "-") return -1;
return parseInt(d);
}
Insert cell
function five(d) {
if (d < 3) return [0,d.toString()];
if (d === 3) return [1, "="];
if (d === 4) return [1, "-"];
}
Insert cell
function base5(number) {
if (number.length === 0) return 0;
return 5 * base5(number.slice(0, number.length - 1)) + decimal(number[number.length - 1]);
}
Insert cell
function unbase5(n) {
if (n === 0) return "";
let [r, l] = five(n%5);
return unbase5(Math.floor(n/5)+r) + l;
}
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