Skip to content

Commit

Permalink
refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
shahata committed Dec 20, 2023
1 parent 19a70ba commit bb43878
Showing 1 changed file with 19 additions and 33 deletions.
52 changes: 19 additions & 33 deletions src/2023/day20.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,36 @@ function parse(input) {
let [part, links] = line.split(' -> ');
let type = part[0];
if (type !== 'b') part = part.slice(1);
links = links.split(', ');
return [part, { part, type, links }];
return [part, { part, type, links: links.split(', ') }];
});
parts = Object.fromEntries(parts);
Object.values(parts).forEach(part => {
if (part.type === '%') part.state = 'low';
if (part.type === '%') part.state = { on: false };
if (part.type === '&') {
const linked = Object.values(parts).filter(x =>
x.links.includes(part.part),
);
part.memory = Object.fromEntries(linked.map(x => [x.part, 'low']));
const m = Object.values(parts).filter(x => x.links.includes(part.part));
part.state = { memory: Object.fromEntries(m.map(x => [x.part, false])) };
}
});
return parts;
}

function signal(parts, wait) {
const queue = [{ part: 'broadcaster', level: 'low', from: 'button' }];
const queue = [{ part: 'broadcaster', level: false, from: 'button' }];
let count = { low: 0, high: 0 };
while (queue.length > 0) {
const { part, level, from } = queue.shift();
count[level]++;
let { part, level, from } = queue.shift();
count[level ? 'high' : 'low']++;

if (`${part},${level},${from}` === wait) throw new Error('wait');
if (!parts[part]) continue;
if (parts[part].type === 'b') {
parts[part].links.forEach(link => {
queue.push({ part: link, level, from: part });
});
}
if (parts[part].type === '%' && level === 'low') {
parts[part].state = parts[part].state === 'low' ? 'high' : 'low';
parts[part].links.forEach(link => {
queue.push({ part: link, level: parts[part].state, from: part });
});
}
if (parts[part].type === '&') {
parts[part].memory[from] = level;
const allHigh = Object.values(parts[part].memory).every(
x => x === 'high',
);
parts[part].links.forEach(link => {
queue.push({ part: link, level: allHigh ? 'low' : 'high', from: part });
});
if (parts[part]) {
const { type, links, state } = parts[part];
if (type === '%' && level) continue;
if (type === '%') level = state.on = !state.on;
if (type === '&') {
state.memory[from] = level;
level = !Object.values(state.memory).every(x => x);
}
links.forEach(link => queue.push({ part: link, level, from: part }));
}
}
return count;
Expand All @@ -67,7 +53,7 @@ function wait(input, part, from) {
const parts = parse(input);
for (let i = 1; i < Infinity; i++) {
try {
signal(parts, `${part},high,${from}`);
signal(parts, `${part},true,${from}`);
} catch {
return i;
}
Expand All @@ -76,7 +62,7 @@ function wait(input, part, from) {

export function part2(input) {
const parts = parse(input);
const conj = Object.values(parts).find(x => x.links[0] === 'rx');
const loops = Object.keys(conj.memory).map(x => wait(input, conj.part, x));
const { part, state } = Object.values(parts).find(x => x.links[0] === 'rx');
const loops = Object.keys(state.memory).map(x => wait(input, part, x));
return loops.reduce((acc, x) => acc * x, 1);
}

0 comments on commit bb43878

Please sign in to comment.