Files
AoC/2024/24/index2.ts

123 lines
3.3 KiB
TypeScript
Raw Normal View History

2024-12-24 10:13:53 +00:00
const fs = require('fs');
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8');
const [initStr, gatesStr] = input.split("\n\n");
const originalValMap: { [key: string]: number }= {};
let valMap: { [key: string]: number } = {};
const gateMap: { [key: string]: [string, string, string] } = {};
let xStr = '';
let yStr = '';
const outputWires: Array<string> = [];
initStr.split("\n").forEach((s: string) => {
const [wire, val] = s.split(': ');
originalValMap[wire] = parseInt(val, 2);
if (wire.startsWith('x')) {
xStr += val;
} else {
yStr += val;
}
});
valMap = {...originalValMap};
2024-12-25 13:55:42 +00:00
const carries: Array<string> = [];
const halfAdds: Array<string> = [];
const badOuts: Array<string> = [];
const badAnds: Array<string> = [];
const gates: Array<[string, string, string, string]> = gatesStr.split("\n").map((s: string) => {
2024-12-24 10:13:53 +00:00
const [inp, out] = s.split(' -> ');
const [val1, op, val2] = inp.split(' ');
2024-12-25 13:55:42 +00:00
return [val1, op, val2, out];
});
gates.forEach(([val1, op, val2, out]) => {
2024-12-24 10:13:53 +00:00
gateMap[out] = [val1, op, val2];
});
function getWireVal(wire: string, trace: Array<string> = []): number {
if (Object.hasOwn(valMap, wire)) {
return valMap[wire];
}
const [wire1, op, wire2] = gateMap[wire];
if (trace.includes(wire1) || trace.includes(wire2)) {
throw Error('Cycle');
}
const val = getVal(wire1, op, wire2, [...trace, wire1, wire2]);
valMap[wire] = val;
return val;
}
function getVal(wire1: string, op: string, wire2: string, trace: Array<string> = []): number {
const val1 = getWireVal(wire1, trace);
const val2 = getWireVal(wire2, trace);
return {
AND: () => val1 & val2,
OR: () => val1 | val2,
XOR: () => val1 ^ val2,
}[op]!();
}
outputWires.sort().reverse();
2024-12-25 14:07:37 +00:00
const expected = (parseInt(xStr, 2) + parseInt(yStr, 2)).toString(2);
2024-12-24 10:13:53 +00:00
function calculate() {
let outputStr = '';
valMap = {...originalValMap};
outputWires.forEach((wire) => {
outputStr += getWireVal(wire);
});
return outputStr;
}
2024-12-25 13:55:42 +00:00
function swap(wire1: string, wire2: string): void {
const wire1Gate = gateMap[wire1];
const wire2Gate = gateMap[wire2];
gateMap[wire1] = wire2Gate;
gateMap[wire2] = wire1Gate;
}
2024-12-24 10:13:53 +00:00
2024-12-25 14:07:37 +00:00
interface HalfAdder {
x: string,
y: string,
out: string,
carry: string,
sumGate: [string, string, string, string],
carryGate: [string, string, string, string],
}
2024-12-24 10:13:53 +00:00
2024-12-25 14:07:37 +00:00
interface FullAdder {
x: string,
y: string,
carryIn: string,
out: string,
carry:string,
halfSumGate: [string, string, string, string],
fullSumGate: [string, string, string, string],
sumCarryGate: [string, string, string, string],
inputCarryGate: [string, string, string, string],
carryGate: [string, string, string, string],
}
function getGate(a: string, b: string, operator: string): undefined|[string, string, string, string] {
return gates.find(([val1, op, val2]) => {
return op === operator
&& ((a === val1 && b === val2) || a === val2 && b === val1);
});
}
2024-12-25 13:55:42 +00:00
2024-12-25 14:07:37 +00:00
const carryGate = getGate('x00', 'y00', 'AND');
const sumGate = getGate('x00', 'y00', 'OR');
const halfAdder: HalfAdder = {
x: 'x00',
y: 'y00',
out: 'z00',
carry: carryGate![3],
carryGate: carryGate!,
sumGate: sumGate!,
2024-12-24 10:13:53 +00:00
}
2024-12-25 14:07:37 +00:00
console.log(halfAdder);