Skip to content

Instantly share code, notes, and snippets.

@lantius
Last active January 5, 2021 22:36
Show Gist options
  • Save lantius/808a7b0c5f1ca55851a503668ecb2b87 to your computer and use it in GitHub Desktop.
Save lantius/808a7b0c5f1ca55851a503668ecb2b87 to your computer and use it in GitHub Desktop.
AoC 2020
4.2
let a = s.split('\n\n');
let valid = 0;
let rng = (v, min, max) => { return parseInt(v, 10) >= min && parseInt(v, 10) <= max; }
let byr = (v) => /^\d{4}$/.exec(v) && rng(v, 1920, 2002);
let iyr = (v) => /^\d{4}$/.exec(v) && rng(v, 2010, 2020);
let eyr = (v) => /^\d{4}$/.exec(v) && rng(v, 2020, 2030);
let hgt = (v) => /^\d+(?:cm|in)$/.exec(v) && (v.includes('cm') ? rng(v, 150, 193) : rng(v, 59, 76));
let hcl = (v) => /^#[0-9a-f]{6}$/.exec(v);
let ecl = (v) => /^(?:amb|blu|brn|gry|grn|hzl|oth)$/.exec(v);
let pid = (v) => /^\d{9}$/.exec(v);
for (const p of a) {
let vf = 0;
let n,v;
for (const f of p.split(/\s/)) {
[n,v] = f.split(':');
switch(n) {
case 'byr':
if (byr(v)) vf++;
break;
case 'iyr':
if (iyr(v)) vf++;
break;
case 'eyr':
if (eyr(v)) vf++;
break;
case 'hgt':
if (hgt(v)) vf++;
break;
case 'hcl':
if (hcl(v)) vf++;
break;
case 'ecl':
if (ecl(v)) vf++;
break;
case 'pid':
if (pid(v)) vf++;
break;
}
}
if (vf == 7) {
valid++;
console.log(p.split(/\s/).filter((f) => !f.includes('cid')).sort().map((f) => f.split(':')[1]).join('\t'));
}
}
valid;
6.1
let t = 0; for (g of s.split('\n\n')) { for (let i = 0; i < 26; ++i) { const l = String.fromCharCode(97+i); if (g.includes(l)) t++ } } console.log(t);
6.2
let t = 0;
let testGroup = (g, l) => { for (p of g.split('\n')) { if (!p.includes(l)) return false; } return true;};
for (g of s.split('\n\n')) { for (let i = 0; i < 26; ++i) { const l = String.fromCharCode(97+i); if (testGroup(g, l)) { t++; } } } console.log(t);
7.1
let a = s.split('\n').map((v) => v.split(" bags contain")).map((v) => { v[1] = v[1].trim(); return v; }).filter((v) => { return v[1] != "no other bags." });
let tested = {};
let q = [];
let test = (target) => {
for (const [b, c] of a) {
if (c.includes(target) && !tested[b]) { tested[b] = true; q.push(b); }
}
}
test('shiny gold');
while(q.length) test(q.pop());
console.log(Object.keys(tested).length);
7.2
let a = s.split('\n').map((v) => v.split(" bags contain")).map((v) => { v[1] = v[1].trim(); return v; }).map((v) => { v[1] = v[1].split(','); return v; });
let o = {};
for (const [b, c] of a) o[b] = c;
let q = [['shiny gold', 1]];
let sum = 0;
while (q.length) {
let [c, n] = q.pop();
console.log(c, n);
sum += n;
for (b of o[c]) {
m = parseInt(b, 10);
for (cn of Object.keys(o)) {
if(b.includes(cn)) q.push([cn, m*n])
}
}
}
console.log(sum - 1)
8.1
let a = s.split('\n')
let acc = 0;
let run = (instr) => {
let i, v; [i, v] = instr.split(" ");
v = parseInt(v, 10);
console.log(i, v);
switch(i) {
case "nop":
return 1;
case "acc":
acc += v;
return 1;
case "jmp":
return v;
}};
let cur = 0;
while (a[cur] !== undefined) { let instr = a[cur]; a[cur] = undefined; cur += run(instr); } console.log(acc);
8.2
let poss = [];
let runatt = (swp) => {
let a = s.split('\n')
if (swp > 0) {
let instr = a[swp];
let i, v;
[i, v] = instr.split(" ");
i === "nop" ? a[swp] = `jmp ${v}` : a[swp] = `nop ${v}`;
}
let acc = 0;
let run = (instr, cur) => {
let i, v; [i, v] = instr.split(" ");
v = parseInt(v, 10);
switch(i) {
case "nop":
if (swp < 0) poss.push(cur);
return 1;
case "acc":
acc += v;
return 1;
case "jmp":
if (swp < 0) poss.push(cur);
return v;
}};
let cur = 0;
while (a[cur] !== undefined) { let instr = a[cur]; a[cur] = undefined; cur += run(instr, cur); if(cur >= a.length) return acc; } return undefined;
}
runatt(-1);
let finalval; for (let p of poss) { finalval = runatt(p); if (finalval !== undefined) break; } console.log(finalval);
9.1:
let a = s.split('\n').map(n => parseInt(n, 10))
let win = 25;
let test = (pre, v) => { pre.sort(); for (let i = 0; i < pre.length; i++) for (let j = i; j < pre.length; j++) { if (pre[i] + pre[j] === v) return true; } return false; };
for (let i = win; i < a.length; ++i) { let pre = a.slice(i - win, i); if (!test(pre, a[i])) { console.log(a[i]); break; } }
9.2:
let a = s.split('\n').map(n => parseInt(n, 10));
let v = 1124361034; let l = 0; let r = 1; let t = a[0] + a[1]; while(r < a.length && t != v) { if (t < v) t+= a[++r]; if (t > v) t-= a[l++]; } g = a.slice(l, r+1).sort(); console.log(g[0] + g[g.length-1])
10.1
let a = s.split('\n').map(n => parseInt(n, 10)).sort((a, b) => { return a - b } );
let diffs = [0, 0, 0, 1];
let tj = 0;
for (j of a) { diffs[j - tj]++; tj = j }; console.log(diffs)
10.2
let a = s.split('\n').map(n => parseInt(n, 10)).sort((a, b) => { return a-b } );
let b = new Array(a.length);
a.unshift(0);
b.unshift(1);
let p = 0;
for (let i = 1; i < a.length; i++) { b[i] = 0; for (let j = i - 1; j >= 0 && a[i] - a[j] <= 3; j--) { console.log(i, a[i], a[j]); b[i]+=b[j]}}
11.1
let a = s.split('\n').map((r) => r.split(''));
let o = (r, c, a) => {
let s = 0;
let row = a[r];
if (c > 0 && row[c-1] === '#') s++;
if (row[c+1] === '#') s++;
if (r > 0) {
let row = a[r-1];
if (c > 0 && row[c-1] === '#') s++;
if (row[c] === '#') s++;
if (row[c+1] === '#') s++;
}
if (r < a.length - 1) {
let row = a[r+1];
if (c > 0 && row[c-1] === '#') s++;
if (row[c] === '#') s++;
if (row[c+1] === '#') s++;
}
return s;
}
let ua = (a, b) => {
let changed = false;
for (let r = 0; r < a.length; r++) for (c = 0; c < a[r].length; c++) changed = u(r, c, a, b) || changed;
return changed;
}
let u = (r, c, a, b) => {
if (a[r][c] === '.') return false;
if (a[r][c] === 'L' && o(r, c, a) === 0) { b[r][c] = '#'; return true; }
if (a[r][c] === '#' && o(r, c, a) >= 4) { b[r][c] = 'L'; return true; }
return false;
}
let changed = true;
let i = 0;
for (i = 0; i < 100000 && changed; i++) {
let b = JSON.parse(JSON.stringify(a));
changed = ua(a, b);
a = b;
}
f = a.map((r) => r.join('')).join('\n');
console.log(`${i} iterations`);
f.match(/#/g).length;
11.2
let a = s.split('\n').map((r) => r.split(''));
let ray = (r, c, a, u, v) => {
let row = r + u;
let col = c + v;
while(row >= 0 && row < a.length && col >= 0 & col < a[row].length) {
if (a[row][col] === '#') return 1;
if (a[row][col] === 'L') return 0;
row += u;
col += v;
}
return 0;
}
let o = (r, c, a) => {
let seen = 0;
seen += ray(r, c, a, -1, -1);
seen += ray(r, c, a, -1, 0);
seen += ray(r, c, a, -1, 1);
seen += ray(r, c, a, 0, -1);
seen += ray(r, c, a, 0, 1);
seen += ray(r, c, a, 1, -1);
seen += ray(r, c, a, 1, 0);
seen += ray(r, c, a, 1, 1);
return seen;
}
let ua = (a, b) => {
let changed = false;
for (let r = 0; r < a.length; r++) for (c = 0; c < a[r].length; c++) changed = u(r, c, a, b) || changed;
return changed;
}
let u = (r, c, a, b) => {
if (a[r][c] === '.') return false;
if (a[r][c] === 'L' && o(r, c, a) === 0) { b[r][c] = '#'; return true; }
if (a[r][c] === '#' && o(r, c, a) >= 5) { b[r][c] = 'L'; return true; }
return false;
}
let changed = true;
let i = 0;
for (i = 0; i < 100000 && changed; i++) {
let b = JSON.parse(JSON.stringify(a));
changed = ua(a, b);
a = b;
}
f = a.map((r) => r.join('')).join('\n');
console.log(`${i} iterations`);
f.match(/#/g).length;
12.1
let a = s.split('\n');
let pos = [0,0];
let h = 0;
let hvec = [Math.round(Math.cos(0 * Math.PI/180)), Math.round(Math.sin(0 * Math.PI/180))];
for (c of a) {
let t = c.match(/F(\d+)/);
if (t) {
pos[0] += hvec[0] * parseInt(t[1], 10);
pos[1] += hvec[1] * parseInt(t[1], 10);
continue;
}
t = c.match(/N(\d+)/);
if (t) {
pos[1] += parseInt(t[1], 10);
continue;
}
t = c.match(/S(\d+)/);
if (t) {
pos[1] -= parseInt(t[1], 10);
continue;
}
t = c.match(/E(\d+)/);
if (t) {
pos[0] += parseInt(t[1], 10);
continue;
}
t = c.match(/W(\d+)/);
if (t) {
pos[0] -= parseInt(t[1], 10);
continue;
}
t = c.match(/R(\d+)/);
if (t) {
let r = parseInt(t[1], 10);
h = (h - r) % 360;
hvec = [Math.round(Math.cos(h * Math.PI/180)), Math.round(Math.sin(h * Math.PI/180))]
continue;
}
t = c.match(/L(\d+)/);
if (t) {
let r = parseInt(t[1], 10);
h = (h + r) % 360;
hvec = [Math.round(Math.cos(h * Math.PI/180)), Math.round(Math.sin(h * Math.PI/180))]
continue;
}
}
Math.abs(pos[0]) + Math.abs(pos[1]);
12.2
let a = s.split('\n');
let pos = [0,0];
let wpt = [10, 1];
for (c of a) {
let t = c.match(/F(\d+)/);
if (t) {
pos[0] += wpt[0] * parseInt(t[1], 10);
pos[1] += wpt[1] * parseInt(t[1], 10);
continue;
}
t = c.match(/N(\d+)/);
if (t) {
wpt[1] += parseInt(t[1], 10);
continue;
}
t = c.match(/S(\d+)/);
if (t) {
wpt[1] -= parseInt(t[1], 10);
continue;
}
t = c.match(/E(\d+)/);
if (t) {
wpt[0] += parseInt(t[1], 10);
continue;
}
t = c.match(/W(\d+)/);
if (t) {
wpt[0] -= parseInt(t[1], 10);
continue;
}
t = c.match(/R(\d+)/);
if (t) {
let r = -parseInt(t[1], 10) * Math.PI/180;
let sinr = Math.round(Math.sin(r));
let cosr = Math.round(Math.cos(r));
wpt = [wpt[0] * cosr - wpt[1] * sinr,
wpt[0] * sinr + wpt[1] * cosr]
continue;
}
t = c.match(/L(\d+)/);
if (t) {
let r = parseInt(t[1], 10) * Math.PI/180;
let sinr = Math.round(Math.sin(r));
let cosr = Math.round(Math.cos(r));
wpt = [wpt[0] * cosr - wpt[1] * sinr,
wpt[0] * sinr + wpt[1] * cosr]
continue;
}
}
13.1
let t, d;
[t, d] = s.split('\n');
t = parseInt(t, 10);
d = d.split(',').filter((v) => v !== 'x').map((v) => parseInt(v, 10)).map((v) => [v, v - t % v]).sort((a, b) => a[1] - b[1]);
d[0][0] * d[0][1];
13.2
d = s.split(',').map((v) => parseInt(v, 10));
let e = [];
for (let i = 0; i < d.length; i++) if (!isNaN(d[i])) e.push([d[i], d[i] - i % d[i]]);
let prod = e.map((v) => v[0]).reduce((acc, cur) => acc * cur);
let gcde = (a, b) => {
let x = 0;
let y = 1;
let gcd = b;
if (a === 0) return [gcd, x, y];
[gcd, x, y] = gcde(b % a, a);
return [gcd, y - Math.floor(b/a) * x, x];
}
let mi = (a, m) => {
[gcd, x, y] = gcde(a, m);
return (x % m + m) % m
}
result = BigInt(0);
for (const v of e) {
let pn = (prod / v[0]);
let inv = mi(pn, v[0]);
result += BigInt(BigInt(v[1]) * BigInt(inv) * BigInt(pn)) % BigInt(prod)
}
result % BigInt(prod);
14.1
let p = s.split('\n');
let mask = '';
let memory = new Array(36);
let tobin = (v) => {
let a = [];
for (let i = 0; i < 36; i++) {
a.unshift(Math.floor(v / Math.pow(2,i)) % 2)
}
return a;
}
let frombin = (a) => {
return a.reverse().reduce((acc, cur, i) => acc += cur * Math.pow(2,i));
}
for (const l of p) {
let mg = l.match(/mask = ([X10]+)/);
if (mg) {
mask = mg[1];
} else {
let mem = l.match(/mem\[(\d+)\] = (\d+)/);
let addr = mem[1];
let val = mem[2];
let binv = tobin(val);
binv = binv.map((v, i) => mask[i] === 'X' ? v : parseInt(mask[i], 2));
memory[addr] = frombin(binv);
}
}
memory.reduce((acc, cur) => acc += cur);
14.2
let p = s.split('\n');
let mask = '';
let maskbits = [];
let memory = {};
let tobin = (v) => {
let a = [];
for (let i = 0; i < 36; i++) {
a.unshift(Math.floor(v / Math.pow(2,i)) % 2)
}
return a;
}
let frombin = (a) => {
return a.slice().reverse().reduce((acc, cur, i) => acc += cur * Math.pow(2,i));
}
for (const l of p) {
let mg = l.match(/mask = ([X10]+)/);
if (mg) {
mask = mg[1];
maskbits = mask.split('').reverse().map((v, i) => v === 'X' ? i : null).filter((v) => v !== null);
maskmul = maskbits.map((v) => Math.pow(2, v));
perms = [];
for (let i = 0; i < Math.pow(2, maskmul.length); ++i) {
let perm = 0;
for (let j = 0; j < maskmul.length; j++) {
let m = Math.floor(i / Math.pow(2,j)) % 2;
perm += m * maskmul[j];
}
perms.push(perm);
}
} else {
let mem = l.match(/mem\[(\d+)\] = (\d+)/);
let addr = parseInt(mem[1], 10);
let val = parseInt(mem[2], 10);
let binaddr = tobin(addr);
binaddr = binaddr.map((v, i) => mask[i] === '1' ? 1 : v);
binaddr = binaddr.map((v, i) => mask[i] === 'X' ? 0 : v);
let oa = frombin(binaddr);
for (let perm of perms) {
memory[(oa + perm).toString(2)] = val;
}
}
}
let t = 0;
for (v of Object.values(memory)) t+= v;
t;
15.1 15.2
let a = s.split(',');
let sp = new Map();
let last = 0;
for (let i = 1; i < a.length + 1; i++) {
last = parseInt(a[i-1], 10);
sp.set(last, i);
}
let next = 0;
for (let i = a.length + 1; i < 30000000; i++) {
let v = sp.get(next);
sp.set(next, i);
if (v === undefined) {
next = 0;
} else {
next = i - v;
}
}
next;
16.1
let a = s.split('\n');
let rules = [];
let i = 0;
for (; i < a.length && a[i] != ""; i++) {
let r = a[i].match(/(\d+)-(\d+) or (\d+)-(\d+)/);
rules.push({la: r[1], ha: r[2], lb: r[3], hb: r[4]});
}
while (a[i] != 'nearby tickets:' && i < a.length) i++;
let err = 0;
for (i+=1; i < a.length; i++) {
let t = a[i].split(',');
for (let v of t) {
v = parseInt(v, 10);
let valid = false;
for (const {la, ha, lb, hb} of rules) {
if ((v >= la && v <= ha) || (v >= lb && v <= hb)) valid = true;
}
if (!valid) err += v;
}
}
err;
16.2
let target = 'departure';
let a = s.split('\n');
let rules = [];
let i = 0;
for (; i < a.length && a[i] != ""; i++) {
let r = a[i].match(/(\d+)-(\d+) or (\d+)-(\d+)/);
let rule = {la: r[1], ha: r[2], lb: r[3], hb: r[4]};
if (a[i].startsWith(target)) rule['target'] = true;
rules.push(rule);
}
for (let j = 0; j < rules.length; j++) {
rules[j]['possiblefields'] = new Set([...rules.keys()]);
}
while (a[i] != 'nearby tickets:' && i < a.length) i++;
for (i+=1; i < a.length; i++) {
let t = a[i].split(',').map(v => parseInt(v, 10));
let tvr = [];
for (let v of t) {
let validrules = [];
for (let j = 0; j < rules.length; j++) {
let {la, ha, lb, hb} = rules[j];
if ((v >= la && v <= ha) || (v >= lb && v <= hb)) {
validrules.push(j);
}
}
if (validrules.length) tvr.push(validrules);
}
if (tvr.length === t.length) {
for (let j = 0; j < rules.length; j++) {
let rp = rules[j]['possiblefields'];
for (let k = 0; k < tvr.length; k++) {
let vr = new Set(tvr[k]);
if(!vr.has(j)) rp.delete(k);
}
}
}
}
for (let r of rules) r['opf'] = [...r['possiblefields']];
for (let i = 0; i < rules.length; i++) {
for (let j = 0; j < rules.length; j++) {
let r = rules[j];
if (r['possiblefields'].size === 1) {
let f = [...r['possiblefields']][0];
r['field'] = f;
for (let k = 0; k < rules.length; k++) {
rules[k]['possiblefields'].delete(f);
}
break;
}
}
}
i = 0;
while (a[i] != 'your ticket:' && i < a.length) i++;
let yt = a[i+1].split(',').map(v => parseInt(v, 10));
let tot = 1;
for (let r of rules) {
if (r['target']) {
let field = r['field'];
console.log(`field ${field}: ${yt[field]}`);
tot *= yt[field];
}
}
tot;
18.1
let a = s.split('\n').map(l => l.split(''));
let m = (x) => {
let r = 0;
let op = '+';
for (let i = 0; i < x.length; i++) {
let t = x[i].trim();
if (t == '') continue;
if (t == '+' || t == '*') {
op = t;
} else if (t == '(') {
let sx = [];
let np = 1;
for (i+=1; i < x.length && np > 0; i++) {
if (x[i].trim() == ')') np--;
if (x[i].trim() == '(') np++;
if (np > 0) sx.push(x[i]);
}
let sr = m(sx);
r = op == '+' ? r + sr : r * sr;
} else {
let v = parseInt(t, 10);
if (isNaN(v)) console.log(`${t} NaN at position ${i}`);
r = op == '+' ? r + v : r * v;
}
}
return r;
};
let tot = 0;
for (let x of a) {
tot += m(x);
}
tot;
18.2
let a = s.split('\n').map(l => l.split(''));
let p = {'+': 1, '*': 0};
let m = (x) => {
let q = [];
let s = [];
for (let t of x) {
t = t.trim();
let v = parseInt(t, 10);
if (!isNaN(v)) {
q.push(v);
} else if (t === '*' || t === '+') {
while(s.length > 0 && p[s[0]] > p[t] && p[s[0]] != '(') {
q.push(s.shift());
}
s.unshift(t);
}
else if (t === '(') {
s.unshift(t);
}
else if (t === ')') {
while(s.length > 0 && s[0] != '(') {
q.push(s.shift());
}
if (s.length === 0) console.log('unbalanced parens');
if (s[0] == '(') s.shift();
}
}
while (s.length > 0) {
q.push(s.shift());
}
s = [];
for (let t of q) {
if (t !== '*' && t !== '+') s.push(t);
else if (t === '+') s.push(s.pop() + s.pop());
else if (t === '*') s.push(s.pop() * s.pop());
}
return s[0];
}
let tot = 0;
for (let x of a) {
tot += m(x);
}
tot;
19.1
let a = s.split('\n\n');
let ra = a[0].split('\n').map(r => r.split(':'));
let mst = a[1].split('\n');
let c = '';
let rules = [];
for (let r of ra) {
rules[parseInt(r[0], 10)] = r[1].trim();
}
let er = (m, rt) => {
// console.log(`${m} ${rt}`);
if (m.length === 0) return 0;
let r = rt.split('|');
if (r.length > 1) {
let v0 = er(m, r[0].trim());
let v1 = er(m, r[1].trim());
if (v0 && v1) console.log('huh?');
if (v0) return v0;
if (v1) return v1;
return 0;
}
r = rt.split(' ');
let cons = 0;
for (let i = 0; i < r.length; i++) {
let rn = parseInt(r[i], 10);
if (isNaN(rn)) {
if (r[i] == `"${m[0]}"`) return 1;
return 0;
}
let v = er(m.slice(cons), rules[rn]);
if (!v) return 0;
cons += v;
}
return cons;
}
let tot = 0;
for (let m of mst) {
let v = er(m, rules[0]);
if (v == m.length) tot++;
}
tot;
19.2
let a = s.split('\n\n');
let ra = a[0].split('\n').map(r => r.split(':'));
let mst = a[1].split('\n');
let c = '';
let rules = [];
for (let r of ra) {
let pr = r[1].trim();
if (!pr.includes('"')) {
pr = pr.split('|').map(v => v.trim().split(' ').map(v => parseInt(v, 10)));
}
rules[parseInt(r[0], 10)] = pr;
}
rules[8] = [[42], [42,8]];
rules[11] = [[42, 31], [42, 11, 31]];
let er = (m, rr) => {
if (!m.length || !rr.length) return !m.length && !rr.length;
r = rules[rr[0]];
if (r.includes('"')) {
if (r != `"${m[0]}"`) return false;
return er(m.slice(1), rr.slice(1));
} else {
return r.some(t => { let rt = t.concat(rr.slice(1)); return er(m, rt); });
}
}
let tot = 0;
for (let m of mst) {
if (er(m, [0])) tot++;
}
tot;
20.1
let ta = s.split('\n\n').map(t => t.split(':\n'));
let tb = [];
for (let t of ta) {
let b = [];
b[0] = parseInt(t[0].slice(5), 10);
b[1] = [];
let tr = t[1].split('\n');
let tc = tr.map(r => r.split(''));
b[1][0] = tr[0];
b[1][1] = tc.reduce((acc, v) => acc + v[tr[0].length - 1], '')
b[1][2] = tr[tr.length - 1];
b[1][3] = tc.reduce((acc, v) => acc + v[0], '')
tb.push(b);
}
let edges = {};
for (let t of tb) {
let tn = t[0];
let te = t[1];
for (let e of te) {
if (!edges[e]) edges[e] = [];
edges[e].push(tn);
let re = e.split('').reverse().join('');
if (!edges[re]) edges[re] = [];
edges[re].push(tn);
}
}
let tsec = {};
for (let v of Object.values(edges)) {
if (v.length > 1) continue;
let tn = v[0];
if (!tsec[tn]) tsec[tn] = 0;
tsec[tn]++;
}
let tot = BigInt(1);
for (let k of Object.keys(tsec)) {
if(tsec[k] == '4') {
tot *= BigInt(k);
}
}
tot;
20.2
let ta = s.split('\n\n').map(t => t.split(':\n'));
for (let t of ta) {
t[0] = parseInt(t[0].slice(5), 10);
}
let tb = {};
for (let t of ta) {
let b = [];
let tr = t[1].split('\n');
let tc = tr.map(r => r.split(''));
b[0] = tr[0];
b[1] = tc.reduce((acc, v) => acc + v[tr[0].length - 1], '')
b[2] = tr[tr.length - 1];
b[3] = tc.reduce((acc, v) => acc + v[0], '')
tb[t[0]] = b;
}
let edges = {};
for (let tn of Object.keys(tb)) {
tn = parseInt(tn, 10);
let te = tb[tn];
for (let i = 0; i < te.length; i++) {
let e = te[i];
if (!edges[e]) edges[e] = [];
edges[e].push([tn, i]);
let re = e.split('').reverse().join('');
if (!edges[re]) edges[re] = [];
edges[re].push([tn, i]);
}
}
let tm = {};
for (let ek of Object.keys(edges)) {
let ma = edges[ek];
if (ma.length == 1) {
let [tn, dir] = ma[0];
if (!tm[tn]) tm[tn] = [];
tm[tn][dir] = [undefined, ek];
}
if (ma.length == 2) {
let [tna, dira] = ma[0];
let [tnb, dirb] = ma[1];
if (!tm[tna]) tm[tna] = [];
if (!tm[tnb]) tm[tnb] = [];
tm[tna][dira] = [tnb, ek];
tm[tnb][dirb] = [tna, ek];
}
}
let ti = {};
for (let t of ta) {
ti[t[0]] = t[1];
}
let flipv = (img) => {
return img.split('\n').reverse().join('\n');
}
let fliph = (img) => {
return img.split('\n').map(r => r.split('').reverse().join('')).join('\n');
}
let rotr = (img) => {
img = img.split('\n');
let newimg = [];
let d = img.length - 1;
for (let i = 0; i < img[0].length; i++) {
newimg[i] = [];
for (let j = 0; j < img.length; j++) {
newimg[i][d - j] = img[j][i];
}
}
return newimg.map(r => r.join('')).join('\n');
}
let dorotr = (n) => {
ti[n] = rotr(ti[n]);
tm[n] = [tm[n][3], tm[n][0], tm[n][1], tm[n][2]];
tb[n] = [tb[n][3], tb[n][0], tb[n][1], tb[n][2]];
};
let tf = (t, n) => {
let ip = (tm[t].indexOf(n) + 2) % 4;
let rp = tm[n].indexOf(t);
while (ip != rp) {
dorotr(n);
rp = tm[n].indexOf(t);
}
let te = tb[t][ip];
let ne = tb[n][ip];
if (te == ne) return;
if (te !== ne.split('').reverse().join('')) console.log('no match?')
if (ip % 2 == 1) {
let tmp = tm[n][0];
tm[n][0] = tm[n][2];
tm[n][2] = tmp;
ti[n] = flipv(ti[n]);
} else {
let tmp = tm[n][1];
tm[n][1] = tm[n][3];
tm[n][3] = tmp;
ti[n] = fliph(ti[n]);
}
}
21.1
let a = s.split('\n').map(v => v.split('(contains '));
let agns = new Set();
let igds = new Set();
for (let i of a) {
if (i[1].includes(')')) i[1] = i[1].slice(0, i[1].length - 1);
i[0] = new Set(i[0].trim().split(' '));
i[1] = new Set(i[1].split(',').map(v => v.trim()));
for (let igd of i[0]) {
igds.add(igd);
}
for (let agn of i[1]) {
agns.add(agn);
}
}
let d = {};
for (let agn of agns) {
let igd = undefined;
for (let r of a) {
if (!r[1].has(agn)) continue;
if (!igd) igd = new Set([...r[0]]);
igd = new Set([...r[0]].filter(x => igd.has(x)));
}
d[agn] = igd;
}
let oki = igds;
for (let agn of agns) {
oki = new Set([...oki].filter(x => !d[agn].has(x)));
}
let tot = 0;
for (let i of a) {
tot += new Set([...i[0]].filter(x => oki.has(x))).size;
}
tot;
21.2
let a = s.split('\n').map(v => v.split('(contains '));
let agns = new Set();
let igds = new Set();
for (let i of a) {
if (i[1].includes(')')) i[1] = i[1].slice(0, i[1].length - 1);
i[0] = new Set(i[0].trim().split(' '));
i[1] = new Set(i[1].split(',').map(v => v.trim()));
for (let igd of i[0]) {
igds.add(igd);
}
for (let agn of i[1]) {
agns.add(agn);
}
}
let d = {};
for (let agn of agns) {
let igd = undefined;
for (let r of a) {
if (!r[1].has(agn)) continue;
if (!igd) igd = new Set([...r[0]]);
igd = new Set([...r[0]].filter(x => igd.has(x)));
}
d[agn] = igd;
}
for (let i = 0; i < 1000 && [...Object.values(d)].reduce((acc, cur) => acc + cur.size, 0) > [...Object.values(d)].length; i++) {
for (let k of Object.keys(d)) {
if (d[k].size == 1) {
for (let j of Object.keys(d)) {
if (k === j) continue;
d[j].delete([...d[k]][0]);
}
}
}
}
let r = [];
for (let k of Object.keys(d).sort()) {
r.push([...d[k]][0]);
}
r.join(',')
22.1
let [p1, p2] = s.split('\n\n').map(p => p.split('\n').slice(1).map(v => parseInt(v, 10)));
for (let i = 0; i < 1000 && p1.length && p2.length; i++) {
let c1 = p1.shift();
let c2 = p2.shift();
if (c1 > c2) {
p1.push(c1);
p1.push(c2);
} else {
p2.push(c2);
p2.push(c1);
}
}
let w = p1.length ? p1 : p2;
let sc = 0;
for (let i = 0; i < w.length; i++) {
sc += w[i] * (w.length - i);
}
sc;
23.1
let a = s.split('').map(v => parseInt(v, 10));
let cp = 0;
let max = Math.max(...a);
let min = Math.min(...a);
for (let i = 0; i < 100; i++) {
let p1 = (cp + 1) % a.length;
let p2 = (cp + 2) % a.length;
let p3 = (cp + 3) % a.length;
let p = [a[p1], a[p2], a[p3]];
console.log(`a ${a.map((v, i) => i == cp ? `(${v})` : v).join(' ')}`);
a[p1] = a[p2] = a[p3] = undefined;
console.log(`p ${p.join(', ')}`);
let cv = a[cp];
let d = cv - 1;
let di = a.indexOf(d);
while (di == -1) {
d--;
if (d < min) d = max;
di = a.indexOf(d);
}
console.log(`d ${d}`);
if (di === -1) console.log(`no ${d}?`);
a.splice(di + 1, 0, ...p);
a = a.filter(v => v !== undefined);
cp = a.indexOf(cv);
cp = (cp + 1) % a.length;
}
let tot = '';
let off = a.indexOf(1) + 1;
for (let i = 0; i < a.length - 1; i++) {
tot += a[(off + i) % a.length];
}
tot;
23.2
let a = s.split('').map(v => parseInt(v, 10));
let om = 1000000;
let min = 1;
let max = om;
for (let i = a.length + 1; i <= om; i++) {
a.push(i);
}
let b = new Uint32Array(a.length + 1);
for (let i = 0; i < a.length - 1; i++) {
b[a[i]] = a[i+1];
}
b[a[a.length - 1]] = a[0];
let pb = (l) => {
let x = [];
x.push(1);
let v = b[1];
for(let i = 0; i < l; i++) {
x.push(v);
v = b[v];
}
return x;
}
let cp = a[0];
for (let i = 0; i < 10*om; i++) {
let p1 = b[cp];
let p2 = b[p1];
let p3 = b[p2];
let d = cp - 1;
while (d === p1 || d === p2 || d === p3 || d === 0) { d--; if (d < min) d = max; }
let q = b[d];
b[d] = p1;
b[cp] = b[p3];
b[p3] = q;
cp = b[cp];
}
let v1 = b[1];
let v2 = b[v1];
console.log(`${v1} x ${v2} = ${v1 * v2}`);
24.1
let a = s.split('\n');
let parse = (dir) => {
dir = dir.split('');
let da = [];
while (dir.length) {
let c = dir.shift();
if (c == 'e' || c == 'w') {
da.push(c);
} else {
c += dir.shift();
da.push(c);
}
}
return da;
}
let coords = {};
let hex = {
'e': { q: 1, r: 0},
'ne': { q: 1, r: -1},
'nw': { q: 0, r: -1},
'w': { q: -1, r: 0},
'sw': { q: -1, r: 1},
'se': { q: 0, r: 1},
}
for (let d of a) {
let da = parse(d);
let r = 0;
let q = 0;
for (let step of da){
let s = hex[step];
r += s.r;
q += s.q;
}
let coord = `${q},${r}`;
if (!coords[coord]) {
coords[coord] = true;
} else {
coords[coord] = false;
}
}
Object.values(coords).filter(v => v).length;
24.2
let a = s.split('\n');
let parse = (dir) => {
dir = dir.split('');
let da = [];
while (dir.length) {
let c = dir.shift();
if (c == 'e' || c == 'w') {
da.push(c);
} else {
c += dir.shift();
da.push(c);
}
}
return da;
}
let coords = {};
let hex = {
'e': { q: 1, r: 0},
'ne': { q: 1, r: -1},
'nw': { q: 0, r: -1},
'w': { q: -1, r: 0},
'sw': { q: -1, r: 1},
'se': { q: 0, r: 1},
}
let hexf = (q, r, d) => {
let s = hex[d];
return [q + s.q, r + s.r];
}
for (let d of a) {
let da = parse(d);
let r = 0;
let q = 0;
for (let step of da){
[q, r] = hexf(q, r, step);
}
let coord = `${q},${r}`;
if (!coords[coord]) {
coords[coord] = true;
} else {
coords[coord] = false;
}
}
let cbn = (q, r) => {
let bn = 0;
for (dir in hex) {
let cc = hexf(q, r, dir).join(',');
if (coords[cc]) bn++;
}
return bn;
}
for (let i = 0; i < 100; i++) {
let newc = {};
for (let c of Object.keys(coords)) {
if (coords[c]) {
let [q, r] = c.split(',').map(v => parseInt(v, 10));
let bn = cbn(q, r);
if (bn == 1 || bn == 2) newc[c] = true;
for (dir in hex) {
let [qn, rn] = hexf(q, r, dir);
let cn = [qn, rn].join(',');
if (!coords[cn]) {
let bn = cbn(qn, rn);
if (bn === 2) newc[cn] = true;
}
}
}
}
coords = JSON.parse(JSON.stringify(newc))
}
Object.values(coords).filter(v => v).length;
25.1
let [c, d] = s.split('\n').map(v => parseInt(v, 10));
let t = (s, l) => {
let v = 1;
for (let i = 0; i < l; i++) {
v = (v * s) % 20201227;
}
return v;
}
let cl = 0;
let dl = 0;
let v = 1;
for (let l = 1; l < 10000000; l++) {
v = (7 * v) % 20201227;
if (!cl && v === c) cl = l;
if (!dl && v === d) dl = l;
if (cl && dl) break;
}
if (cl && dl) {
let ce = t(d, cl);
let de = t(c, dl);
console.log(ce, de);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment