diff --git a/2024/24/index2.ts b/2024/24/index2.ts index 806e364..a9308d6 100644 --- a/2024/24/index2.ts +++ b/2024/24/index2.ts @@ -23,13 +23,36 @@ initStr.split("\n").forEach((s: string) => { }); valMap = {...originalValMap}; -gatesStr.split("\n").forEach((s: string) => { +const carries: Array = []; +const halfAdds: Array = []; +const badOuts: Array = []; +const badAnds: Array = []; + +const gates: Array<[string, string, string, string]> = gatesStr.split("\n").map((s: string) => { const [inp, out] = s.split(' -> '); const [val1, op, val2] = inp.split(' '); + return [val1, op, val2, out]; +}); +gates.forEach(([val1, op, val2, out]) => { gateMap[out] = [val1, op, val2]; if (out.startsWith('z')) { outputWires.push(out); } + if ((op === 'XOR' && !val1.startsWith('x') && !val1.startsWith('y')) || (op === 'XOR' && (val1 === 'x00' || val1 === 'y00'))) { + if (!out.startsWith('z')) { + badOuts.push(out); + } + } else if (out.startsWith('z')) { + badOuts.push(out); + } + if (op === 'AND') { + for (let [val1, op, val2] of gates) { + if (op !== 'OR' && (val1 === out || val2 === out)) { + badAnds.push(out); + break; + } + } + } }); function getWireVal(wire: string, trace: Array = []): number { @@ -58,7 +81,6 @@ function getVal(wire1: string, op: string, wire2: string, trace: Array = outputWires.sort().reverse(); - function calculate() { let outputStr = ''; valMap = {...originalValMap}; @@ -68,56 +90,65 @@ function calculate() { return outputStr; } -function mistakes(act: string, exp: string): number { - let mistakes = 0; - for (let i = 0; i < act.length; i++) { - if (act[i] !== exp[i]) { - mistakes++; - } +function getPermutations(arr: Array): Array> { + if (arr.length === 1) { + return [arr]; } - return mistakes; + return arr.flatMap((s, i) => { + return getPermutations([...arr.slice(0, i), ...arr.slice(i + 1)]).map((p) => [s, ...p]); + }); } -let fewestMistakes: number|null = null; -let bestSwap: [string, string]|null = null; -let swapResult: string|null = null; - -const wires = Object.keys(gateMap); +function swap(wire1: string, wire2: string): void { + const wire1Gate = gateMap[wire1]; + const wire2Gate = gateMap[wire2]; + gateMap[wire1] = wire2Gate; + gateMap[wire2] = wire1Gate; +} const expected = (parseInt(xStr, 2) + parseInt(yStr, 2)).toString(2); -for (let i = 0; i < wires.length; i++) { - for (let j = i + 1; j < wires.length; j++) { - const wireA = wires[i]; - const wireB = wires[j]; - const gateA = gateMap[wireA]; - const gateB = gateMap[wireB]; - gateMap[wireA] = gateB; - gateMap[wireB] = gateA; +const zOutputsToSwap = badOuts.filter((o) => o[0] === 'z'); +const otherOutputsToSwap = badOuts.filter((o) => o[0] !== 'z'); - let actual; - try { - actual = calculate(); - } catch (e) { - continue; - } finally { - gateMap[wireA] = gateA; - gateMap[wireB] = gateB; - } - const mist = mistakes(actual, expected); +for (let perm of getPermutations(zOutputsToSwap)) { + swap(perm[0], otherOutputsToSwap[0]); + swap(perm[1], otherOutputsToSwap[1]); + swap(perm[2], otherOutputsToSwap[2]); - if (!fewestMistakes || fewestMistakes > mist) { - fewestMistakes = mist; - bestSwap = [wireA, wireB]; - swapResult = actual; + for (let i = 0; i < gates.length - 1; i++) { + for (let j = i + 1; j < gates.length; j++) { + swap(gates[i][3], gates[j][3]); + try { + const output = calculate(); + if (output === expected) { + const swaps = [...perm, ...otherOutputsToSwap, gates[i][3], gates[j][3]]; + swaps.sort(); + console.log(swaps); + break; + } + } catch (e) { + // + } finally { + swap(gates[i][3], gates[j][3]); + } } } + + swap(perm[0], otherOutputsToSwap[0]); + swap(perm[1], otherOutputsToSwap[1]); + swap(perm[2], otherOutputsToSwap[2]); } -console.log(xStr); -console.log(yStr); -console.log(expected); -console.log(calculate()); -console.log(fewestMistakes); -console.log(bestSwap); -console.log(swapResult); +/* + * 1234 + * 4123 + * 3412 + * 2341 + * 4321 + * 1432 + * 2143 + * 3214 + * 1324 + * 4132 +*/ \ No newline at end of file