Compare commits
7 Commits
4574a0f268
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| dc8ec1ca17 | |||
| eb0ae6d56b | |||
| 9f9b14fb7b | |||
| 97a0dad48d | |||
| b496e480b1 | |||
| fdc6260055 | |||
| b9dd983a89 |
59
2024/22/index.ts
Normal file
59
2024/22/index.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8');
|
||||||
|
|
||||||
|
function createSecret(secret: bigint) {
|
||||||
|
secret = ((secret << 6n) ^ secret) % 16777216n;
|
||||||
|
secret = ((secret >> 5n) ^ secret) % 16777216n;
|
||||||
|
return ((secret << 11n) ^ secret) % 16777216n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let sum = 0n;
|
||||||
|
|
||||||
|
const changeMap: { [key: string]: Array<number> } = {};
|
||||||
|
|
||||||
|
input.split("\n").forEach((s: string, index: number) => {
|
||||||
|
let seed = BigInt(parseInt(s));
|
||||||
|
let seedStr = ''+seed;
|
||||||
|
const changes = [];
|
||||||
|
for (let i = 0; i < 2000; i++) {
|
||||||
|
const newSeed = createSecret(seed);
|
||||||
|
const newSeedStr = ''+newSeed;
|
||||||
|
const lastDig = parseInt(newSeedStr[newSeedStr.length - 1]);
|
||||||
|
const diff = lastDig - parseInt(seedStr[seedStr.length - 1]);
|
||||||
|
changes.push(diff);
|
||||||
|
if (i > 3) {
|
||||||
|
changes.shift();
|
||||||
|
const key = changes.join(',');
|
||||||
|
if (!changeMap[key]) {
|
||||||
|
changeMap[key] = [];
|
||||||
|
}
|
||||||
|
if (!changeMap[key][index]) {
|
||||||
|
changeMap[key][index] = lastDig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
seed = newSeed;
|
||||||
|
seedStr = newSeedStr;
|
||||||
|
}
|
||||||
|
sum += seed;
|
||||||
|
});
|
||||||
|
|
||||||
|
let highest: null|number = null;
|
||||||
|
let highestSeq: null|string = null;
|
||||||
|
|
||||||
|
for (let seq in changeMap) {
|
||||||
|
const prices = changeMap[seq];
|
||||||
|
let priceSum = 0;
|
||||||
|
prices.forEach((p) => {
|
||||||
|
if (p) {
|
||||||
|
priceSum += p;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!highest || priceSum > highest) {
|
||||||
|
highest = priceSum;
|
||||||
|
highestSeq = seq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(sum, highest, highestSeq);
|
||||||
30
2024/23/index.ts
Normal file
30
2024/23/index.ts
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
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] || [])]
|
||||||
|
});
|
||||||
|
|
||||||
|
const tCs = new Set;
|
||||||
|
|
||||||
|
for (let key in connections) {
|
||||||
|
const conns = connections[key];
|
||||||
|
if (key.startsWith('t')) {
|
||||||
|
conns.forEach((c2) => {
|
||||||
|
connections[c2].forEach((c3) => {
|
||||||
|
if (connections[c3].includes(key)) {
|
||||||
|
const arr = [key, c2, c3];
|
||||||
|
arr.sort();
|
||||||
|
tCs.add(arr.join(','));
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(tCs, tCs.size);
|
||||||
48
2024/23/index2.ts
Normal file
48
2024/23/index2.ts
Normal 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);
|
||||||
54
2024/24/index.ts
Normal file
54
2024/24/index.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const input = fs.readFileSync(__dirname + '/input.txt', 'utf8');
|
||||||
|
|
||||||
|
const [initStr, gatesStr] = input.split("\n\n");
|
||||||
|
|
||||||
|
const valMap: { [key: string]: number }= {};
|
||||||
|
const gateMap: { [key: string]: [string, string, string] } = {};
|
||||||
|
|
||||||
|
const outputWires: Array<string> = [];
|
||||||
|
|
||||||
|
initStr.split("\n").forEach((s: string) => {
|
||||||
|
const [wire, val] = s.split(': ');
|
||||||
|
valMap[wire] = parseInt(val, 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
gatesStr.split("\n").forEach((s: string) => {
|
||||||
|
const [inp, out] = s.split(' -> ');
|
||||||
|
const [val1, op, val2] = inp.split(' ');
|
||||||
|
gateMap[out] = [val1, op, val2];
|
||||||
|
if (out.startsWith('z')) {
|
||||||
|
outputWires.push(out);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getWireVal(wire: string): number {
|
||||||
|
if (Object.hasOwn(valMap, wire)) {
|
||||||
|
return valMap[wire];
|
||||||
|
}
|
||||||
|
const val = getVal(...gateMap[wire])
|
||||||
|
valMap[wire] = val;
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getVal(wire1: string, op: string, wire2: string): number {
|
||||||
|
const val1 = getWireVal(wire1);
|
||||||
|
const val2 = getWireVal(wire2);
|
||||||
|
|
||||||
|
return {
|
||||||
|
AND: () => val1 & val2,
|
||||||
|
OR: () => val1 | val2,
|
||||||
|
XOR: () => val1 ^ val2,
|
||||||
|
}[op]!();
|
||||||
|
}
|
||||||
|
|
||||||
|
outputWires.sort().reverse();
|
||||||
|
|
||||||
|
let outputStr = '';
|
||||||
|
|
||||||
|
outputWires.forEach((wire) => {
|
||||||
|
outputStr += getWireVal(wire);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(outputStr, parseInt(outputStr, 2));
|
||||||
206
2024/24/index2.ts
Normal file
206
2024/24/index2.ts
Normal file
@@ -0,0 +1,206 @@
|
|||||||
|
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};
|
||||||
|
|
||||||
|
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 [val1, op, val2] = inp.split(' ');
|
||||||
|
return [val1, op, val2, out];
|
||||||
|
});
|
||||||
|
gates.forEach(([val1, op, val2, out]) => {
|
||||||
|
if (out[0] === 'z') {
|
||||||
|
outputWires.push(out);
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
const expected = (parseInt(xStr, 2) + parseInt(yStr, 2)).toString(2);
|
||||||
|
|
||||||
|
function calculate() {
|
||||||
|
let outputStr = '';
|
||||||
|
valMap = {...originalValMap};
|
||||||
|
outputWires.forEach((wire) => {
|
||||||
|
outputStr += getWireVal(wire);
|
||||||
|
});
|
||||||
|
return outputStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
function swap(wire1: string, wire2: string): void {
|
||||||
|
const wire1Gate = gateMap[wire1];
|
||||||
|
const wire2Gate = gateMap[wire2];
|
||||||
|
gateMap[wire1] = wire2Gate;
|
||||||
|
gateMap[wire2] = wire1Gate;
|
||||||
|
gates.forEach((gate) => {
|
||||||
|
if (gate[3] === wire1) {
|
||||||
|
gate[3] = wire2;
|
||||||
|
} else if (gate[3] === wire2) {
|
||||||
|
gate[3] = wire1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HalfAdder {
|
||||||
|
x: string,
|
||||||
|
y: string,
|
||||||
|
out: string,
|
||||||
|
carry: string,
|
||||||
|
sumGate: [string, string, string, string],
|
||||||
|
carryGate: [string, string, string, string],
|
||||||
|
}
|
||||||
|
|
||||||
|
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],
|
||||||
|
}
|
||||||
|
|
||||||
|
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
44
2024/25/index.ts
Normal 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);
|
||||||
Reference in New Issue
Block a user