diff --git a/2024/07/2024-07.run.xml b/2024/07/2024-07.run.xml
new file mode 100644
index 0000000..6adfae8
--- /dev/null
+++ b/2024/07/2024-07.run.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2024/07/index.test.ts b/2024/07/index.test.ts
new file mode 100644
index 0000000..1566a49
--- /dev/null
+++ b/2024/07/index.test.ts
@@ -0,0 +1,22 @@
+import { describe, expect, it } from 'bun:test';
+import { solveFirst, solveSecond } from './index.ts';
+
+describe('2024-07', () => {
+ const testInput = `190: 10 19
+3267: 81 40 27
+83: 17 5
+156: 15 6
+7290: 6 8 6 15
+161011: 16 10 13
+192: 17 8 14
+21037: 9 7 18 13
+292: 11 6 16 20`;
+ it('first', () => {
+ expect(solveFirst(testInput)).toBe(3749);
+ });
+ it('second', () => {
+ const secondSolution = solveSecond(testInput);
+ expect(secondSolution).toBe(11387);
+ expect(secondSolution).toBeGreaterThanOrEqual(solveFirst(testInput));
+ });
+});
diff --git a/2024/07/index.ts b/2024/07/index.ts
new file mode 100644
index 0000000..91d1f53
--- /dev/null
+++ b/2024/07/index.ts
@@ -0,0 +1,59 @@
+import { sumBy } from '../../utils/array.ts';
+
+export function solveFirst(input: string): number {
+ const regex = /^(\d*): (.*)$/gm;
+ const match = input.matchAll(regex);
+
+ const rows = Array.from(match, (m) => ({
+ sum: Number(m[1]),
+ digits: m[2].split(' ').map((n) => Number(n))
+ }));
+
+ const possible = rows.filter((r) => {
+ for (let t = 0; t < Math.pow(2, r.digits.length - 1); t++) {
+ const sol = r.digits.reduce((sum, curr, i) =>
+ evalTry(t, i, sum + curr, sum * curr)
+ );
+ if (sol === r.sum) {
+ return true;
+ }
+ }
+ return false;
+ });
+
+ // console.log(possible);
+ return sumBy(possible, (p) => p.sum);
+}
+
+export function evalTry(t: number, index: number, ...choices: T[]): T {
+ const base = choices.length;
+ const choice = Math.max(0, Math.floor(t / Math.pow(base, index - 1)) % base);
+
+ return choices[choice];
+}
+
+export function solveSecond(input: string): number {
+ const regex = /^(\d*): (.*)$/gm;
+ const match = input.matchAll(regex);
+
+ const rows = Array.from(match, (m) => ({
+ sum: Number(m[1]),
+ digits: m[2].split(' ').map((n) => Number(n))
+ }));
+
+ const possible = rows.filter((r) => {
+ for (let t = 0; t < Math.pow(3, r.digits.length - 1); t++) {
+ const sol = r.digits.reduce((sum, curr, i) =>
+ evalTry(t, i, sum * curr, sum + curr, Number(`${sum}${curr}`))
+ );
+ if (sol === r.sum) {
+ return true;
+ }
+ }
+
+ return false;
+ });
+
+ // console.log(possible);
+ return sumBy(possible, (p) => p.sum);
+}
diff --git a/2024/07/run.ts b/2024/07/run.ts
new file mode 100644
index 0000000..88783cd
--- /dev/null
+++ b/2024/07/run.ts
@@ -0,0 +1,12 @@
+import { join } from 'path';
+import { solveFirst, solveSecond } from './index.ts';
+
+const input = await Bun.file(join(__dirname, 'input.txt')).text();
+
+const firstAnswer = solveFirst(input);
+
+console.log(firstAnswer);
+
+const secondAnswer = solveSecond(input);
+
+console.log(secondAnswer);
diff --git a/package.json b/package.json
index e22b510..9e1a428 100644
--- a/package.json
+++ b/package.json
@@ -12,11 +12,11 @@
"devDependencies": {
"@types/bun": "latest",
"@types/prompts": "^2.4.9",
+ "p-limit": "^6.1.0",
"prettier": "^3.4.0",
"prettier-plugin-organize-imports": "^4.1.0",
"prompts": "^2.4.2",
- "replace-in-file": "^8.2.0",
- "p-limit": "^6.1.0"
+ "replace-in-file": "^8.2.0"
},
"peerDependencies": {
"typescript": "^5.7.2"