Compare commits

...

5 Commits

Author SHA1 Message Date
dc8ec1ca17 Day 23 Part 2 2024-12-25 17:20:57 +00:00
eb0ae6d56b Day 25 Part 1 2024-12-25 15:41:07 +00:00
9f9b14fb7b Day 24 Part 2 Complete 2024-12-25 15:26:23 +00:00
97a0dad48d Day 24 Part 2 Attempt 2024-12-25 14:07:37 +00:00
b496e480b1 Day 24 Part 2 Attempt 2024-12-25 13:55:42 +00:00
3 changed files with 228 additions and 53 deletions

48
2024/23/index2.ts Normal file
View File

@@ -0,0 +1,48 @@
const fs = require('fs');
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8');
const connections: { [key: string]: Array<string> }= {};
input.split("\n").forEach((conn: string) => {
const [c1, c2] = conn.split('-');
connections[c1] = [c2, ...(connections[c1] || [])]
connections[c2] = [c1, ...(connections[c2] || [])]
});
let nets: Set<string> = new Set;
for (let key in connections) {
const conns = connections[key];
conns.forEach((c2) => {
connections[c2].forEach((c3) => {
if (connections[c3].includes(key)) {
const arr = [key, c2, c3];
arr.sort();
nets.add(arr.join(','));
}
})
});
}
while (nets.size > 1) {
const nextNets: Set<string> = new Set;
for (let net of nets) {
const cps = net.split(',');
for (let i in connections) {
if (cps.includes(i)) {
continue;
}
const conns = connections[i];
if (cps.every((id) => conns.includes(id))) {
const newNet = [...cps, i];
newNet.sort();
nextNets.add(newNet.join(','));
}
}
}
nets = nextNets;
}
console.log(nets);

View File

@@ -23,13 +23,21 @@ initStr.split("\n").forEach((s: string) => {
}); });
valMap = {...originalValMap}; valMap = {...originalValMap};
gatesStr.split("\n").forEach((s: string) => { 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) => {
const [inp, out] = s.split(' -> '); const [inp, out] = s.split(' -> ');
const [val1, op, val2] = inp.split(' '); const [val1, op, val2] = inp.split(' ');
gateMap[out] = [val1, op, val2]; return [val1, op, val2, out];
if (out.startsWith('z')) { });
gates.forEach(([val1, op, val2, out]) => {
if (out[0] === 'z') {
outputWires.push(out); outputWires.push(out);
} }
gateMap[out] = [val1, op, val2];
}); });
function getWireVal(wire: string, trace: Array<string> = []): number { function getWireVal(wire: string, trace: Array<string> = []): number {
@@ -56,8 +64,8 @@ function getVal(wire1: string, op: string, wire2: string, trace: Array<string> =
}[op]!(); }[op]!();
} }
outputWires.sort().reverse(); outputWires.sort();
const expected = (parseInt(xStr, 2) + parseInt(yStr, 2)).toString(2);
function calculate() { function calculate() {
let outputStr = ''; let outputStr = '';
@@ -68,56 +76,131 @@ function calculate() {
return outputStr; return outputStr;
} }
function mistakes(act: string, exp: string): number { function swap(wire1: string, wire2: string): void {
let mistakes = 0; const wire1Gate = gateMap[wire1];
for (let i = 0; i < act.length; i++) { const wire2Gate = gateMap[wire2];
if (act[i] !== exp[i]) { gateMap[wire1] = wire2Gate;
mistakes++; gateMap[wire2] = wire1Gate;
gates.forEach((gate) => {
if (gate[3] === wire1) {
gate[3] = wire2;
} else if (gate[3] === wire2) {
gate[3] = wire1;
} }
} });
return mistakes;
} }
let fewestMistakes: number|null = null; interface HalfAdder {
let bestSwap: [string, string]|null = null; x: string,
let swapResult: string|null = null; y: string,
out: string,
const wires = Object.keys(gateMap); carry: string,
sumGate: [string, string, string, string],
const expected = (parseInt(xStr, 2) + parseInt(yStr, 2)).toString(2); carryGate: [string, string, string, string],
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;
let actual;
try {
actual = calculate();
} catch (e) {
continue;
} finally {
gateMap[wireA] = gateA;
gateMap[wireB] = gateB;
}
const mist = mistakes(actual, expected);
if (!fewestMistakes || fewestMistakes > mist) {
fewestMistakes = mist;
bestSwap = [wireA, wireB];
swapResult = actual;
}
}
} }
console.log(xStr); interface FullAdder {
console.log(yStr); x: string,
console.log(expected); y: string,
console.log(calculate()); carryIn: string,
console.log(fewestMistakes); out: string,
console.log(bestSwap); carry:string,
console.log(swapResult); 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],
}
const swaps: Array<string> = [];
function getGate(a: string, b: string, operator: string): [string, string, string, string] {
const gate = gates.find(([val1, op, val2]) => {
return op === operator
&& (a === val1 || b === val2 || a === val2 || b === val1);
});
if (!gate) {
throw new Error(`Two bad inputs, could not find gate, ${a}, ${b}`);
}
if ((gate[0] === a && gate[2] === b) || (gate[0] === b && gate[2] === a)) {
return gate;
}
console.log(gate, a, b, operator);
let wrongInput: string;
let shouldBe: string;
if (gate[0] === a) {
wrongInput = b;
shouldBe = gate[2]
} else if (gate[0] === b) {
wrongInput = a;
shouldBe = gate[2]
} if (gate[2] === a) {
wrongInput = b;
shouldBe = gate[0]
} else {
wrongInput = a;
shouldBe = gate[0]
}
swaps.push(wrongInput);
swaps.push(shouldBe);
swap(wrongInput, shouldBe);
console.log(`Wrong input found, ${wrongInput} should be ${shouldBe}`)
return gate;
}
const carryGate = getGate('x00', 'y00', 'AND');
const sumGate = getGate('x00', 'y00', 'XOR');
const halfAdder: HalfAdder = {
x: 'x00',
y: 'y00',
out: 'z00',
carry: carryGate[3],
carryGate: carryGate,
sumGate: sumGate,
}
console.log(halfAdder);
function getAdder(x: string, y: string, carryIn: string, out: string): FullAdder {
const halfSumGate = getGate(x, y, 'XOR');
const fullSumGate = getGate(halfSumGate[3], carryIn, 'XOR');
if (fullSumGate[3] !== out) {
console.log(`Wrong input found, ${fullSumGate[3]} should be ${out}`)
swaps.push(fullSumGate[3]);
swaps.push(out);
swap(fullSumGate[3], out);
}
const sumCarryGate = getGate(halfSumGate[3], carryIn, 'AND');
const inputCarryGate = getGate(x, y, 'AND')!;
const carryGate = getGate(sumCarryGate[3], inputCarryGate[3], 'OR');
return {
x,
y,
carryIn,
out: fullSumGate[3],
carry: carryGate[3],
halfSumGate,
fullSumGate,
sumCarryGate,
inputCarryGate,
carryGate
};
}
let carry = halfAdder.carry;
for (let out of outputWires) {
if (out === 'z00' || out === 'z45') {
continue;
}
const x = out.replace('z', 'x');
const y = out.replace('z', 'y');
const adder = getAdder(x, y, carry, out);
console.log(adder, swaps);
carry = adder.carry;
}
swaps.sort();
console.log(swaps.join(','));

44
2024/25/index.ts Normal file
View File

@@ -0,0 +1,44 @@
const fs = require('fs');
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8');
const keyLocks = input.split("\n\n");
const keys: number[][] = [];
const locks: number[][] = [];
keyLocks.forEach((s: string) => {
const rows = s.split("\n");
const isKey = rows[0] === '.....';
const columns: number[] = [-1, -1, -1, -1, -1];
rows.forEach((row: string) => {
for (let i = 0; i < row.length; i++) {
if (row[i] === '#') {
columns[i]++;
}
}
});
if (isKey) {
keys.push(columns);
} else {
locks.push(columns);
}
});
let matches = 0;
for (let lock of locks) {
keyLoop:
for (let key of keys) {
for (let i in lock) {
if (lock[i] + key[i] >= 6) {
continue keyLoop;
}
}
matches++;
}
}
console.log(locks);
console.log(keys);
console.log(matches);