diff --git a/2024/24/2024-24.run.xml b/2024/24/2024-24.run.xml
new file mode 100644
index 0000000..d7e5113
--- /dev/null
+++ b/2024/24/2024-24.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2024/24/index.test.ts b/2024/24/index.test.ts
new file mode 100644
index 0000000..99f3b1e
--- /dev/null
+++ b/2024/24/index.test.ts
@@ -0,0 +1,67 @@
+import { describe, expect, it } from 'bun:test';
+import { solveFirst } from './index.ts';
+
+describe('2024-24', () => {
+ it('first', () => {
+ const testInput = `x00: 1
+x01: 1
+x02: 1
+y00: 0
+y01: 1
+y02: 0
+
+x00 AND y00 -> z00
+x01 XOR y01 -> z01
+x02 OR y02 -> z02`;
+ expect(solveFirst(testInput)).toBe(4n);
+ expect(
+ solveFirst(`x00: 1
+x01: 0
+x02: 1
+x03: 1
+x04: 0
+y00: 1
+y01: 1
+y02: 1
+y03: 1
+y04: 1
+
+ntg XOR fgs -> mjb
+y02 OR x01 -> tnw
+kwq OR kpj -> z05
+x00 OR x03 -> fst
+tgd XOR rvg -> z01
+vdt OR tnw -> bfw
+bfw AND frj -> z10
+ffh OR nrd -> bqk
+y00 AND y03 -> djm
+y03 OR y00 -> psh
+bqk OR frj -> z08
+tnw OR fst -> frj
+gnj AND tgd -> z11
+bfw XOR mjb -> z00
+x03 OR x00 -> vdt
+gnj AND wpb -> z02
+x04 AND y00 -> kjc
+djm OR pbm -> qhw
+nrd AND vdt -> hwm
+kjc AND fst -> rvg
+y04 OR y02 -> fgs
+y01 AND x02 -> pbm
+ntg OR kjc -> kwq
+psh XOR fgs -> tgd
+qhw XOR tgd -> z09
+pbm OR djm -> kpj
+x03 XOR y03 -> ffh
+x00 XOR y04 -> ntg
+bfw OR bqk -> z06
+nrd XOR fgs -> wpb
+frj XOR qhw -> z04
+bqk OR frj -> z07
+y03 OR x01 -> nrd
+hwm AND bqk -> z03
+tgd XOR rvg -> z12
+tnw OR pbm -> gnj`)
+ ).toBe(2024n);
+ });
+});
diff --git a/2024/24/index.ts b/2024/24/index.ts
new file mode 100644
index 0000000..50e85e4
--- /dev/null
+++ b/2024/24/index.ts
@@ -0,0 +1,112 @@
+import { uniqueCombinations } from '../../utils/array.ts';
+
+type Op = 'AND' | 'OR' | 'XOR';
+interface Operation {
+ a: string;
+ res: string;
+ op: Op;
+ b: string;
+}
+
+function evalOperations(
+ operations: {
+ a: string;
+ res: string;
+ op: 'AND' | 'OR' | 'XOR';
+ b: string;
+ }[],
+ data: Record
+) {
+ while (operations.length) {
+ const operation = operations.shift()!;
+ const { a, b, res, op } = operation;
+
+ if (data[a] === undefined || data[b] === undefined) {
+ operations.push(operation);
+ continue;
+ }
+
+ switch (op) {
+ case 'AND':
+ data[res] = data[a] && data[b];
+ break;
+ case 'OR':
+ data[res] = data[a] || data[b];
+ break;
+ case 'XOR':
+ data[res] = data[a] !== data[b];
+ break;
+ }
+ }
+}
+
+function bitsToBigInt(data: Record, prefix: string) {
+ return Object.keys(data)
+ .filter((k) => k.startsWith(prefix))
+ .toSorted()
+ .reduce((s, k, i) => s + (BigInt(data[k]) << BigInt(i)), 0n);
+}
+
+export function solveFirst(input: string): bigint {
+ const vars = Array.from(
+ input.matchAll(/^(\S*): ([10])$/gm),
+ (m) => [m[1], m[2] === '1'] as [string, boolean]
+ );
+ const operations = Array.from(
+ input.matchAll(/^(\S*) (\w*) (\S*) -> (\S*)$/gm),
+ (m) => ({
+ a: m[1],
+ b: m[3],
+ res: m[4],
+ op: m[2] as Op
+ })
+ );
+ const data: Record = {};
+ vars.forEach(([k, v]) => (data[k] = v));
+ evalOperations(operations, data);
+
+ return bitsToBigInt(data, 'z');
+}
+
+function findDifference(a: bigint, b: bigint) {
+ const indexes: number[] = [];
+ const length = Math.max(a.toString(2).length, b.toString(2).length);
+ const diff = [...(a ^ b).toString(2)];
+ const lengthDiff = length - diff.length;
+ for (let i = 0; i < diff.length; i++)
+ if (diff[i] === '1') indexes.push(length - (i + lengthDiff + 1));
+ return indexes;
+}
+
+function findDependance(operations: Operation[], key: number) {
+ const found = new Set();
+ const k = `z${key.toString().padStart(2, '0')}`;
+ const op = operations.find((o) => o.res === k)!;
+ if (!op.a.match(/^[xyz]/)) {
+ found.add(op.a);
+ }
+ if (!op.b.match(/^[xyz]/)) {
+ found.add(op.b);
+ }
+
+ return [...found];
+}
+
+function getPairs(keys: string[]) {
+ if (keys.length < 4) {
+ return [];
+ }
+
+ const combs = uniqueCombinations(keys);
+ const combs2 = uniqueCombinations(combs).filter(
+ (c) => new Set([c.a.a, c.a.b, c.b.a, c.b.b]).size === 4
+ );
+ console.log(
+ combs.length,
+ combs2.length,
+ combs2[0],
+ combs2[combs2.length - 1]
+ );
+
+ return [];
+}
diff --git a/2024/24/run.ts b/2024/24/run.ts
new file mode 100644
index 0000000..226fb13
--- /dev/null
+++ b/2024/24/run.ts
@@ -0,0 +1,8 @@
+import { join } from 'path';
+import { solveFirst } from './index.ts';
+
+const input = await Bun.file(join(__dirname, 'input.txt')).text();
+
+const firstAnswer = solveFirst(input);
+
+console.log(firstAnswer);