diff --git a/.eslintrc.js b/.eslintrc.js index e928b86..d089755 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,10 +1,10 @@ // This configuration only applies to the package manager root. /** @type {import("eslint").Linter.Config} */ module.exports = { - ignorePatterns: ["apps/**", "packages/**"], - extends: ["@repo/eslint-config/library.js"], - parser: "@typescript-eslint/parser", - parserOptions: { - project: true, - }, + ignorePatterns: ["apps/**", "packages/**"], + extends: ["@repo/eslint-config/library.js"], + parser: "@typescript-eslint/parser", + parserOptions: { + project: true, + }, }; diff --git a/.github/workflows/runner-rs.yaml b/.github/workflows/runner-rs.yaml index f2f0d15..6505eb4 100644 --- a/.github/workflows/runner-rs.yaml +++ b/.github/workflows/runner-rs.yaml @@ -1,23 +1,23 @@ name: AoC Test Runner (Rust) on: - push: - branches: [main] - pull_request: - branches: [main] + push: + branches: [main] + pull_request: + branches: [main] jobs: - rust: - name: Test Rust Solutions - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: oven-sh/setup-bun@v1 - - run: bun i -g turbo@latest - - name: Installing Rust - uses: actions-rust-lang/setup-rust-toolchain@v1 - - name: Building with Cargo - uses: actions-rs/cargo@v1 - with: - command: build - args: --release - - name: Testing with Cargo - run: bun rs + rust: + name: Test Rust Solutions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: oven-sh/setup-bun@v1 + - run: bun i -g turbo@latest + - name: Installing Rust + uses: actions-rust-lang/setup-rust-toolchain@v1 + - name: Building with Cargo + uses: actions-rs/cargo@v1 + with: + command: build + args: --release + - name: Testing with Cargo + run: bun rs diff --git a/.github/workflows/runner-ts.yaml b/.github/workflows/runner-ts.yaml index 1610c65..ebdf0c8 100644 --- a/.github/workflows/runner-ts.yaml +++ b/.github/workflows/runner-ts.yaml @@ -1,16 +1,16 @@ name: AoC Test Runner (Typescript) on: - push: - branches: [main] - pull_request: - branches: [main] + push: + branches: [main] + pull_request: + branches: [main] jobs: - typescript: - name: Test Typescript Solutions - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: oven-sh/setup-bun@v1 - - run: bun i - - run: bun i -g turbo@latest - - run: bun ts + typescript: + name: Test Typescript Solutions + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: oven-sh/setup-bun@v1 + - run: bun i + - run: bun i -g turbo@latest + - run: bun ts diff --git a/README.md b/README.md index 259179e..8364561 100644 --- a/README.md +++ b/README.md @@ -6,8 +6,8 @@ This is my repository for the [Advent of Code 2023](https://adventofcode.com/202 Languages used: -- [TypeScript + Bun](https://bun.sh/) -- [Rust](https://www.rust-lang.org/) +- [TypeScript + Bun](https://bun.sh/) +- [Rust](https://www.rust-lang.org/) ## Usage @@ -25,28 +25,28 @@ Check [README.md](code/rs/README.md) in the `rs` directory. ## Checklists -- [x] Day 1 -- [x] Day 2 -- [x] Day 3 -- [x] Day 4 -- [x] Day 5 -- [x] Day 6 -- [x] Day 7 -- [x] Day 8 -- [x] Day 9 -- [x] Day 10 -- [x] Day 11 -- [x] Day 12 -- [x] Day 13 -- [x] Day 14 -- [x] Day 15 -- [x] Day 16 -- [x] Day 17 -- [x] Day 18 -- [x] Day 19 -- [x] Day 20 -- [x] Day 21 -- [x] Day 22 -- [ ] Day 23 -- [ ] Day 24 -- [ ] Day 25 +- [x] Day 1 +- [x] Day 2 +- [x] Day 3 +- [x] Day 4 +- [x] Day 5 +- [x] Day 6 +- [x] Day 7 +- [x] Day 8 +- [x] Day 9 +- [x] Day 10 +- [x] Day 11 +- [x] Day 12 +- [x] Day 13 +- [x] Day 14 +- [x] Day 15 +- [x] Day 16 +- [x] Day 17 +- [x] Day 18 +- [x] Day 19 +- [x] Day 20 +- [x] Day 21 +- [x] Day 22 +- [ ] Day 23 +- [ ] Day 24 +- [ ] Day 25 diff --git a/bun.lockb b/bun.lockb index 2d3114e..fba99e8 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/code/rs/README.md b/code/rs/README.md index 0bef300..ecc9d2a 100644 --- a/code/rs/README.md +++ b/code/rs/README.md @@ -32,7 +32,7 @@ This is my repository for the [Advent of Code 2023](https://adventofcode.com/202 ### Prerequisites -- [Rustup](https://rustup.rs/) +- [Rustup](https://rustup.rs/) ### Run diff --git a/code/rs/package.json b/code/rs/package.json index fe0546a..06c9dd2 100644 --- a/code/rs/package.json +++ b/code/rs/package.json @@ -1,11 +1,11 @@ { - "name": "rs", - "version": "1.0.0", - "description": "Rust Cargo Runner", - "scripts": { - "rust": "cargo run" - }, - "keywords": [], - "author": "BRAVO68WEB", - "license": "ISC" -} + "name": "rs", + "version": "1.0.0", + "description": "Rust Cargo Runner", + "license": "ISC", + "author": "BRAVO68WEB", + "scripts": { + "rust": "cargo run" + }, + "keywords": [] +} \ No newline at end of file diff --git a/code/ts/01/code.ts b/code/ts/01/code.ts index 66a1d74..5706846 100644 --- a/code/ts/01/code.ts +++ b/code/ts/01/code.ts @@ -2,85 +2,80 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/1.txt`).text(); const lines = input.split("\n"); -const sp1 = lines.map((line) => { - let firstDigit: string | undefined; - let lastDigit: string | undefined; - for (let i = 0; i < line.length; i++) { - const maybeFirstDigit = line[i]!; - const maybeLastDigit = line[line.length - i - 1]!; +const sp1 = lines.map(line => { + let firstDigit: string | undefined; + let lastDigit: string | undefined; + for (let i = 0; i < line.length; i++) { + const maybeFirstDigit = line[i]!; + const maybeLastDigit = line[line.length - i - 1]!; - if (firstDigit === undefined && /\d/.test(maybeFirstDigit)) { - firstDigit = maybeFirstDigit; - } + if (firstDigit === undefined && /\d/.test(maybeFirstDigit)) { + firstDigit = maybeFirstDigit; + } - if (lastDigit === undefined && /\d/.test(maybeLastDigit)) { - lastDigit = maybeLastDigit; - } + if (lastDigit === undefined && /\d/.test(maybeLastDigit)) { + lastDigit = maybeLastDigit; + } - if (firstDigit !== undefined && lastDigit !== undefined) { - break; + if (firstDigit !== undefined && lastDigit !== undefined) { + break; + } } - } - return (firstDigit ?? "") + (lastDigit ?? ""); + return (firstDigit ?? "") + (lastDigit ?? ""); }); export const partone = sp1.reduce((acc, curr) => acc + parseInt(curr, 10), 0); const numbers = { - one: "1", - "1": "1", - two: "2", - "2": "2", - three: "3", - "3": "3", - four: "4", - "4": "4", - five: "5", - "5": "5", - six: "6", - "6": "6", - seven: "7", - "7": "7", - eight: "8", - "8": "8", - nine: "9", - "9": "9", + one: "1", + "1": "1", + two: "2", + "2": "2", + three: "3", + "3": "3", + four: "4", + "4": "4", + five: "5", + "5": "5", + six: "6", + "6": "6", + seven: "7", + "7": "7", + eight: "8", + "8": "8", + nine: "9", + "9": "9", } as const; const numbersAsKeys = Object.keys(numbers) as (keyof typeof numbers)[]; -const sp2 = lines.map((line) => { - let firstDigit: string | undefined; - let lastDigit: string | undefined; - for (let i = 0; i < line.length; i++) { - if (firstDigit === undefined) { - const maybeFirstDigit = line.slice(i, i + 5); - const firstTextNumber = numbersAsKeys.find((key) => - maybeFirstDigit.startsWith(key), - ); - if (firstTextNumber) { - firstDigit = numbers[firstTextNumber]; - } - } +const sp2 = lines.map(line => { + let firstDigit: string | undefined; + let lastDigit: string | undefined; + for (let i = 0; i < line.length; i++) { + if (firstDigit === undefined) { + const maybeFirstDigit = line.slice(i, i + 5); + const firstTextNumber = numbersAsKeys.find(key => maybeFirstDigit.startsWith(key)); + if (firstTextNumber) { + firstDigit = numbers[firstTextNumber]; + } + } - if (lastDigit === undefined) { - const maybeDigit = line.slice( - Math.max(line.length - i - 5, 0), - line.length - i, - ); + if (lastDigit === undefined) { + const maybeDigit = line.slice(Math.max(line.length - i - 5, 0), line.length - i); - const textNumber = numbersAsKeys.find((key) => maybeDigit.endsWith(key)); - if (textNumber) { - lastDigit = numbers[textNumber]; - } - } + const textNumber = numbersAsKeys.find(key => maybeDigit.endsWith(key)); + if (textNumber) { + lastDigit = numbers[textNumber]; + } + } - if (firstDigit !== undefined && lastDigit !== undefined) { - break; + if (firstDigit !== undefined && lastDigit !== undefined) { + break; + } } - } - return (firstDigit ?? "") + (lastDigit ?? ""); + return (firstDigit ?? "") + (lastDigit ?? ""); }); export const parttwo = sp2.reduce((acc, curr) => acc + parseInt(curr, 10), 0); diff --git a/code/ts/01/package.json b/code/ts/01/package.json index 827aefa..aac1588 100644 --- a/code/ts/01/package.json +++ b/code/ts/01/package.json @@ -1,15 +1,15 @@ { - "name": "01", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "01", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/01/tsconfig.json b/code/ts/01/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/01/tsconfig.json +++ b/code/ts/01/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/02/code.ts b/code/ts/02/code.ts index 2e367fe..006a82b 100644 --- a/code/ts/02/code.ts +++ b/code/ts/02/code.ts @@ -3,99 +3,90 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/2.txt`).text(); const lines = input.split("\n"); export interface Cube { - red: number; - green: number; - blue: number; + red: number; + green: number; + blue: number; } export interface Game { - id: number; - cubes: Cube[]; + id: number; + cubes: Cube[]; } const parseBag = (bag: string): Cube => { - const [c1, c2, c3] = bag.split(", "); - const [c1v, c1n] = (c1?.trim()?.split(" ") ?? []) as [ - string, - keyof Cube | undefined, - ]; - const [c2v, c2n] = (c2?.trim()?.split(" ") ?? []) as [ - string, - keyof Cube | undefined, - ]; - const [c3v, c3n] = (c3?.trim()?.split(" ") ?? []) as [ - string, - keyof Cube | undefined, - ]; - - const cubeParsed: Cube = { - red: 0, - green: 0, - blue: 0, - }; - - if (c1n !== undefined) { - cubeParsed[c1n] = parseInt(c1v); - } - - if (c2n !== undefined) { - cubeParsed[c2n] = parseInt(c2v); - } - - if (c3n !== undefined) { - cubeParsed[c3n] = parseInt(c3v); - } - - return cubeParsed; + const [c1, c2, c3] = bag.split(", "); + const [c1v, c1n] = (c1?.trim()?.split(" ") ?? []) as [string, keyof Cube | undefined]; + const [c2v, c2n] = (c2?.trim()?.split(" ") ?? []) as [string, keyof Cube | undefined]; + const [c3v, c3n] = (c3?.trim()?.split(" ") ?? []) as [string, keyof Cube | undefined]; + + const cubeParsed: Cube = { + red: 0, + green: 0, + blue: 0, + }; + + if (c1n !== undefined) { + cubeParsed[c1n] = parseInt(c1v); + } + + if (c2n !== undefined) { + cubeParsed[c2n] = parseInt(c2v); + } + + if (c3n !== undefined) { + cubeParsed[c3n] = parseInt(c3v); + } + + return cubeParsed; }; export const parse = (line: string): Game => { - const [rawGameId, data] = line.split(": "); - const [, gameId] = rawGameId.split(" "); + const [rawGameId, data] = line.split(": "); + const [, gameId] = rawGameId.split(" "); - return { - id: parseInt(gameId), - cubes: data.split("; ").map(parseBag), - } as Game; + return { + id: parseInt(gameId), + cubes: data.split("; ").map(parseBag), + } as Game; }; const bagIsValid = (bag: Cube): boolean => { - const { red, green, blue } = bag; + const { red, green, blue } = bag; - return red <= 12 && green <= 13 && blue <= 14; + return red <= 12 && green <= 13 && blue <= 14; }; const gameIsValid = (game: Game): boolean => { - return game.cubes.every(bagIsValid); + return game.cubes.every(bagIsValid); }; const sum = (acc: number, curr: number) => acc + curr; export const partone = lines - .map(parse) - .filter(gameIsValid) - .map((game) => game.id) - .reduce(sum, 0); - -const minCubesToPlayGame = lines.map(parse).map((game) => { - const red = Math.max(...game.cubes.map((cube) => cube.red)); - const green = Math.max(...game.cubes.map((cube) => cube.green)); - const blue = Math.max(...game.cubes.map((cube) => cube.blue)); - - return { - id: game.id, - cubes: { - red, - green, - blue, - }, - }; + .map(parse) + .filter(gameIsValid) + .map(game => game.id) + .reduce(sum, 0); + +const minCubesToPlayGame = lines.map(parse).map(game => { + const red = Math.max(...game.cubes.map(cube => cube.red)); + const green = Math.max(...game.cubes.map(cube => cube.green)); + const blue = Math.max(...game.cubes.map(cube => cube.blue)); + + return { + id: game.id, + cubes: { + red, + green, + blue, + }, + }; }); -const calProd = minCubesToPlayGame.map((game) => { - const { red, green, blue } = game.cubes; +const calProd = minCubesToPlayGame.map(game => { + const { red, green, blue } = game.cubes; - return red * green * blue; + return red * green * blue; }); export const parttwo = calProd.reduce(sum, 0); diff --git a/code/ts/02/package.json b/code/ts/02/package.json index f6d77e0..9221567 100644 --- a/code/ts/02/package.json +++ b/code/ts/02/package.json @@ -1,15 +1,15 @@ { - "name": "02", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "02", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/02/tsconfig.json b/code/ts/02/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/02/tsconfig.json +++ b/code/ts/02/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/03/code.ts b/code/ts/03/code.ts index ded323a..bc51472 100644 --- a/code/ts/03/code.ts +++ b/code/ts/03/code.ts @@ -8,86 +8,74 @@ const width = rows[0].length; const isSymbol = (char: string) => !/[.\d]/.test(char); const isAdjacent = (x: number, y: number) => { - for (let dx = -1; dx <= 1; dx++) { - for (let dy = -1; dy <= 1; dy++) { - if (dx === 0 && dy === 0) continue; - const nx = x + dx; - const ny = y + dy; - if ( - nx >= 0 && - nx < width && - ny >= 0 && - ny < height && - isSymbol(rows[ny][nx]) - ) { - return true; - } + for (let dx = -1; dx <= 1; dx++) { + for (let dy = -1; dy <= 1; dy++) { + if (dx === 0 && dy === 0) continue; + const nx = x + dx; + const ny = y + dy; + if (nx >= 0 && nx < width && ny >= 0 && ny < height && isSymbol(rows[ny][nx])) { + return true; + } + } } - } - return false; + return false; }; export const partone = rows.reduce( - (acc, row, y) => - [...row.matchAll(/\d+/g)].reduce((rowSum, match) => { - const x = match.index || 0; - for (let i = 0; i < match[0].length; i++) - if (isAdjacent(x + i, y)) { - return rowSum + parseInt(match[0]); - } - return rowSum; - }, acc), - 0, + (acc, row, y) => + [...row.matchAll(/\d+/g)].reduce((rowSum, match) => { + const x = match.index || 0; + for (let i = 0; i < match[0].length; i++) + if (isAdjacent(x + i, y)) { + return rowSum + parseInt(match[0]); + } + return rowSum; + }, acc), + 0, ); const isDigit = (char: string) => /\d/.test(char); const getAdjacent = (x: number, y: number, pos: Set) => { - const partNumbers: number[] = []; - for (let dx = -1; dx <= 1; dx++) { - for (let dy = -1; dy <= 1; dy++) { - if (dx === 0 && dy === 0) continue; - const nx = x + dx; - const ny = y + dy; - if ( - nx >= 0 && - nx < width && - ny >= 0 && - ny < height && - isDigit(rows[ny][nx]) - ) { - let numStart = nx; - while (numStart > 0 && isDigit(rows[ny][numStart - 1])) { - numStart--; - } + const partNumbers: number[] = []; + for (let dx = -1; dx <= 1; dx++) { + for (let dy = -1; dy <= 1; dy++) { + if (dx === 0 && dy === 0) continue; + const nx = x + dx; + const ny = y + dy; + if (nx >= 0 && nx < width && ny >= 0 && ny < height && isDigit(rows[ny][nx])) { + let numStart = nx; + while (numStart > 0 && isDigit(rows[ny][numStart - 1])) { + numStart--; + } - const positionKey = `${ny},${numStart}`; - if (pos.has(positionKey)) continue; + const positionKey = `${ny},${numStart}`; + if (pos.has(positionKey)) continue; - const match = rows[ny].substring(numStart).match(/^\d+/); - if (match) { - partNumbers.push(parseInt(match[0])); - pos.add(positionKey); + const match = rows[ny].substring(numStart).match(/^\d+/); + if (match) { + partNumbers.push(parseInt(match[0])); + pos.add(positionKey); + } + } } - } } - } - return partNumbers; + return partNumbers; }; export const parttwo = rows.reduce((total, row, y) => { - const pos = new Set(); - return ( - total + - row.split("").reduce((acc, char, x) => { - if (char === "*") { - const adjacentNums = getAdjacent(x, y, pos); - if (adjacentNums.length === 2) { - return acc + adjacentNums[0] * adjacentNums[1]; - } - } - return acc; - }, 0) - ); + const pos = new Set(); + return ( + total + + row.split("").reduce((acc, char, x) => { + if (char === "*") { + const adjacentNums = getAdjacent(x, y, pos); + if (adjacentNums.length === 2) { + return acc + adjacentNums[0] * adjacentNums[1]; + } + } + return acc; + }, 0) + ); }, 0); diff --git a/code/ts/03/package.json b/code/ts/03/package.json index c76c55e..7b145e9 100644 --- a/code/ts/03/package.json +++ b/code/ts/03/package.json @@ -1,15 +1,15 @@ { - "name": "03", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "03", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/03/tsconfig.json b/code/ts/03/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/03/tsconfig.json +++ b/code/ts/03/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/04/code.ts b/code/ts/04/code.ts index 69c5094..ca3b112 100644 --- a/code/ts/04/code.ts +++ b/code/ts/04/code.ts @@ -3,51 +3,51 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/4.txt`).text(); const lines = input.split("\n"); interface Card { - id: string; - winningNumbers: number[]; - heldNumbers: number[]; - winscore: number; - noOfMatchs: number; + id: string; + winningNumbers: number[]; + heldNumbers: number[]; + winscore: number; + noOfMatchs: number; } const cards: Card[] = []; for (const line of lines) { - let id = line.split(":")[0].trim(); - id = id.split(" ")[1]; - - let numbers = line.split(":")[1].trim(); - let winningNumbers = numbers.split("|")[0].trim(); - let heldNumbers = numbers.split("|")[1].trim(); - - let card: Card = { - id, - winningNumbers: winningNumbers.split(" ").map((n) => parseInt(n)), - heldNumbers: heldNumbers.split(" ").map((n) => parseInt(n)), - noOfMatchs: 0, - winscore: 0, - }; - - card.heldNumbers = card.heldNumbers.filter((n) => !isNaN(n)); - card.winningNumbers = card.winningNumbers.filter((n) => !isNaN(n)); - - for (const heldNumber of card.heldNumbers) { - if (card.winningNumbers.includes(heldNumber)) { - card.noOfMatchs++; + let id = line.split(":")[0].trim(); + id = id.split(" ")[1]; + + let numbers = line.split(":")[1].trim(); + let winningNumbers = numbers.split("|")[0].trim(); + let heldNumbers = numbers.split("|")[1].trim(); + + let card: Card = { + id, + winningNumbers: winningNumbers.split(" ").map(n => parseInt(n)), + heldNumbers: heldNumbers.split(" ").map(n => parseInt(n)), + noOfMatchs: 0, + winscore: 0, + }; + + card.heldNumbers = card.heldNumbers.filter(n => !isNaN(n)); + card.winningNumbers = card.winningNumbers.filter(n => !isNaN(n)); + + for (const heldNumber of card.heldNumbers) { + if (card.winningNumbers.includes(heldNumber)) { + card.noOfMatchs++; + } } - } - if (card.noOfMatchs > 0) { - card.winscore = Math.pow(2, card.noOfMatchs - 1); - } + if (card.noOfMatchs > 0) { + card.winscore = Math.pow(2, card.noOfMatchs - 1); + } - cards.push(card); + cards.push(card); } export let partone = 0; for (const card of cards) { - partone += card.winscore; + partone += card.winscore; } export let parttwo = 0; @@ -55,14 +55,14 @@ export let parttwo = 0; const queue = [...cards]; while (queue.length > 0) { - const currentCard = queue.shift()!; - parttwo += 1; - - const matches = currentCard.noOfMatchs; - for (let i = 1; i <= matches; i++) { - const nextCardIndex = cards.indexOf(currentCard) + i; - if (nextCardIndex < cards.length) { - queue.push(cards[nextCardIndex]); + const currentCard = queue.shift()!; + parttwo += 1; + + const matches = currentCard.noOfMatchs; + for (let i = 1; i <= matches; i++) { + const nextCardIndex = cards.indexOf(currentCard) + i; + if (nextCardIndex < cards.length) { + queue.push(cards[nextCardIndex]); + } } - } } diff --git a/code/ts/04/package.json b/code/ts/04/package.json index 85dda1f..1becdda 100644 --- a/code/ts/04/package.json +++ b/code/ts/04/package.json @@ -1,15 +1,15 @@ { - "name": "04", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "04", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/04/tsconfig.json b/code/ts/04/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/04/tsconfig.json +++ b/code/ts/04/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/05/code.ts b/code/ts/05/code.ts index ed3fc4f..7543c6c 100644 --- a/code/ts/05/code.ts +++ b/code/ts/05/code.ts @@ -2,73 +2,68 @@ const pkg = await Bun.file(`${import.meta.dir}/package.json`).json(); const input = await Bun.file(`${import.meta.dir}/../../../input/5.txt`).text(); const parse = (input: string) => { - const [seeds, ...sections] = input.split("\n\n").map((s) => s.trim()); - return [ - RegExp(/seeds: ([\d ]*)/) - .exec(seeds)![1] - .split(" ") - .map(Number), - sections.map((s) => - RegExp(/\w+-to-\w+ map:([\d \n]*)/) - .exec(s)![1] - .trim() - .split("\n") - .map((row) => { - const [dest, source, range] = row.trim().split(" ").map(Number); - return { - dest: [dest, dest + range + 1] as const, - src: [source, source + range + 1] as const, - }; - }), - ), - ] as const; + const [seeds, ...sections] = input.split("\n\n").map(s => s.trim()); + return [ + RegExp(/seeds: ([\d ]*)/) + .exec(seeds)![1] + .split(" ") + .map(Number), + sections.map(s => + RegExp(/\w+-to-\w+ map:([\d \n]*)/) + .exec(s)![1] + .trim() + .split("\n") + .map(row => { + const [dest, source, range] = row.trim().split(" ").map(Number); + return { + dest: [dest, dest + range + 1] as const, + src: [source, source + range + 1] as const, + }; + }), + ), + ] as const; }; type Seed = ReturnType[0][number]; type Maps = ReturnType[1]; const toLocation = (maps: Maps, value: Seed) => - maps.reduce((curr, map) => { - for (const m of map) { - if (curr >= m.src[0] && curr < m.src[1]) - return curr + m.dest[0] - m.src[0]; - } - return curr; - }, value); + maps.reduce((curr, map) => { + for (const m of map) { + if (curr >= m.src[0] && curr < m.src[1]) return curr + m.dest[0] - m.src[0]; + } + return curr; + }, value); const toSeed = (maps: Maps, value: Seed) => - maps.reduceRight((curr, map) => { - for (const element of map) { - const m = element; - if (curr >= m.dest[0] && curr < m.dest[1]) - return curr + m.src[0] - m.dest[0]; - } - return curr; - }, value); + maps.reduceRight((curr, map) => { + for (const element of map) { + const m = element; + if (curr >= m.dest[0] && curr < m.dest[1]) return curr + m.src[0] - m.dest[0]; + } + return curr; + }, value); -const solve = (seeds: Seed[], maps: Maps) => - Math.min(...seeds.map((s) => toLocation(maps, s))); +const solve = (seeds: Seed[], maps: Maps) => Math.min(...seeds.map(s => toLocation(maps, s))); const part1 = (input: string) => solve(...parse(input)); const isValidSeed = (seeds: Seed[]) => (seed: Seed) => { - for (let i = 0; i < seeds.length; i += 2) { - const [a, b] = seeds.slice(i, i + 2); - if (seed >= a && seed < a + b) return true; - } - return false; + for (let i = 0; i < seeds.length; i += 2) { + const [a, b] = seeds.slice(i, i + 2); + if (seed >= a && seed < a + b) return true; + } + return false; }; const part2 = (input: string) => { - const [seeds, maps] = parse(input); + const [seeds, maps] = parse(input); - const possibleSeeds = maps - .flatMap((m, i) => - m.map(({ dest }) => toSeed(maps.slice(0, i + 1), dest[0])), - ) - .filter(isValidSeed(seeds)); + const possibleSeeds = maps + .flatMap((m, i) => m.map(({ dest }) => toSeed(maps.slice(0, i + 1), dest[0]))) + .filter(isValidSeed(seeds)); - return solve(possibleSeeds, maps); + return solve(possibleSeeds, maps); }; export const partone = part1(input); diff --git a/code/ts/05/package.json b/code/ts/05/package.json index 82bc6b7..bae1b8c 100644 --- a/code/ts/05/package.json +++ b/code/ts/05/package.json @@ -1,15 +1,15 @@ { - "name": "05", - "module": "code.ts", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - }, - "type": "module" -} + "name": "05", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/05/tsconfig.json b/code/ts/05/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/05/tsconfig.json +++ b/code/ts/05/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/06/code.ts b/code/ts/06/code.ts index a403c71..45168c1 100644 --- a/code/ts/06/code.ts +++ b/code/ts/06/code.ts @@ -2,25 +2,21 @@ const pkg = await Bun.file(`${import.meta.dir}/package.json`).json(); const input = await Bun.file(`${import.meta.dir}/../../../input/6.txt`).text(); const calc = (times: number[], dists: number[]) => { - let product = 1; - for (let i = 0; i < times.length; i++) { - const time = times[i]; - const dist = dists[i]; + let product = 1; + for (let i = 0; i < times.length; i++) { + const time = times[i]; + const dist = dists[i]; - const minTime = Math.floor((time - Math.sqrt(time ** 2 - 4 * dist)) / 2); - const noWays = time - 2 * minTime - 1; - product *= noWays; - } - return product; + const minTime = Math.floor((time - Math.sqrt(time ** 2 - 4 * dist)) / 2); + const noWays = time - 2 * minTime - 1; + product *= noWays; + } + return product; }; -let [times, dists] = input - .split("\n") - .map((line) => line.match(/\d+/g)!.map(Number)); +let [times, dists] = input.split("\n").map(line => line.match(/\d+/g)!.map(Number)); export const partone = calc(times, dists); -[times, dists] = input - .split("\n") - .map((line) => [+line.match(/\d+/g)!.join("")]); +[times, dists] = input.split("\n").map(line => [+line.match(/\d+/g)!.join("")]); export const parttwo = calc(times, dists); diff --git a/code/ts/06/package.json b/code/ts/06/package.json index 75fe7e0..c139a9a 100644 --- a/code/ts/06/package.json +++ b/code/ts/06/package.json @@ -1,15 +1,15 @@ { - "name": "06", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "06", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/06/tsconfig.json b/code/ts/06/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/06/tsconfig.json +++ b/code/ts/06/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/07/code.ts b/code/ts/07/code.ts index dc0adbf..9711bc9 100644 --- a/code/ts/07/code.ts +++ b/code/ts/07/code.ts @@ -1,112 +1,104 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/7.txt`).text(); const lines = input - .split("\n") - .map((x) => x.split(" ")) - .map(([cards, bid]) => <[string[], number]>[cards.split(""), parseInt(bid)]); + .split("\n") + .map(x => x.split(" ")) + .map(([cards, bid]) => <[string[], number]>[cards.split(""), parseInt(bid)]); const cardLetters = "AKQJT98765432".split(""); const cardsTypes = boolean>>[ - (counts) => counts.some((x) => x === 5), - (counts) => counts.some((x) => x === 4), - (counts) => counts.some((x) => x === 3) && counts.some((x) => x === 2), - (counts) => counts.some((x) => x === 3), - (counts) => counts.filter((x) => x === 2).length === 2, - (counts) => counts.some((x) => x === 2), - (_) => true, + counts => counts.some(x => x === 5), + counts => counts.some(x => x === 4), + counts => counts.some(x => x === 3) && counts.some(x => x === 2), + counts => counts.some(x => x === 3), + counts => counts.filter(x => x === 2).length === 2, + counts => counts.some(x => x === 2), + _ => true, ]; const countCards = (str: string[]): Record => - str.reduce((acc: any, v) => ({ ...acc, [v]: (acc[v] ?? 0) + 1 }), {}); + str.reduce((acc: any, v) => ({ ...acc, [v]: (acc[v] ?? 0) + 1 }), {}); const getCardsTypeIndex = (cardLetters: string[]): number => { - const cardsCount = Object.values(countCards(cardLetters)); - return cardsTypes.findIndex((x) => x(cardsCount)); + const cardsCount = Object.values(countCards(cardLetters)); + return cardsTypes.findIndex(x => x(cardsCount)); }; const cardOrder = (cardsA: string[], cardsB: string[]) => { - for (let i = 0; i < 5; i++) { - const aIndx = cardLetters.indexOf(cardsA[i]); - const bIndx = cardLetters.indexOf(cardsB[i]); + for (let i = 0; i < 5; i++) { + const aIndx = cardLetters.indexOf(cardsA[i]); + const bIndx = cardLetters.indexOf(cardsB[i]); - if (aIndx < bIndx) return 1; - if (aIndx > bIndx) return -1; - } + if (aIndx < bIndx) return 1; + if (aIndx > bIndx) return -1; + } - throw new Error(`Unexpected case: ${cardsA} ${cardsB}`); + throw new Error(`Unexpected case: ${cardsA} ${cardsB}`); }; const sortCards = (cardsA: string[], cardsB: string[]) => { - const typeA = getCardsTypeIndex(cardsA); - const typeB = getCardsTypeIndex(cardsB); + const typeA = getCardsTypeIndex(cardsA); + const typeB = getCardsTypeIndex(cardsB); - if (typeA < typeB) return 1; - if (typeA > typeB) return -1; + if (typeA < typeB) return 1; + if (typeA > typeB) return -1; - return cardOrder(cardsA, cardsB); + return cardOrder(cardsA, cardsB); }; export const partone = lines - .slice() - .sort((a, b) => sortCards(a[0], b[0])) - .reduce((acc, v, i) => acc + v[1] * (i + 1), 0); - -const cardsTypesWithJokers = < - Array<(counts: number[], jokersCount: number) => boolean> ->[ - (counts, jokersCount) => - jokersCount === 5 || counts.some((x) => x === 5 - jokersCount), - (counts, jokersCount) => counts.some((x) => x === 4 - jokersCount), - (counts, jokersCount) => { - const indx = counts.findIndex((x) => x === 3 - jokersCount); - return indx !== -1 && counts.some((x, i) => x === 2 && indx !== i); - }, - (counts, jokersCount) => counts.some((x) => x === 3 - jokersCount), - (counts, _) => counts.filter((x) => x === 2).length === 2, - (counts, jokersCount) => counts.some((x) => x === 2 - jokersCount), - (_) => true, + .slice() + .sort((a, b) => sortCards(a[0], b[0])) + .reduce((acc, v, i) => acc + v[1] * (i + 1), 0); + +const cardsTypesWithJokers = boolean>>[ + (counts, jokersCount) => jokersCount === 5 || counts.some(x => x === 5 - jokersCount), + (counts, jokersCount) => counts.some(x => x === 4 - jokersCount), + (counts, jokersCount) => { + const indx = counts.findIndex(x => x === 3 - jokersCount); + return indx !== -1 && counts.some((x, i) => x === 2 && indx !== i); + }, + (counts, jokersCount) => counts.some(x => x === 3 - jokersCount), + (counts, _) => counts.filter(x => x === 2).length === 2, + (counts, jokersCount) => counts.some(x => x === 2 - jokersCount), + _ => true, ]; const getCardsTypeIndexWithJokers = (cardLetters: string[]): number => { - const cardsCountLookup = countCards(cardLetters); - const notJokersCount = Object.entries(cardsCountLookup) - .filter((x) => x[0] !== "J") - .map((x) => x[1]); - - return cardsTypesWithJokers.findIndex((x) => - x(notJokersCount, cardsCountLookup["J"] ?? 0), - ); + const cardsCountLookup = countCards(cardLetters); + const notJokersCount = Object.entries(cardsCountLookup) + .filter(x => x[0] !== "J") + .map(x => x[1]); + + return cardsTypesWithJokers.findIndex(x => x(notJokersCount, cardsCountLookup["J"] ?? 0)); }; -const cardLettersWithJokersPriority = [ - ...cardLetters.filter((x) => x !== "J"), - "J", -]; +const cardLettersWithJokersPriority = [...cardLetters.filter(x => x !== "J"), "J"]; const cardOrderWithJokers = (cardsA: string[], cardsB: string[]) => { - for (let i = 0; i < 5; i++) { - const aIndx = cardLettersWithJokersPriority.indexOf(cardsA[i]); - const bIndx = cardLettersWithJokersPriority.indexOf(cardsB[i]); + for (let i = 0; i < 5; i++) { + const aIndx = cardLettersWithJokersPriority.indexOf(cardsA[i]); + const bIndx = cardLettersWithJokersPriority.indexOf(cardsB[i]); - if (aIndx < bIndx) return 1; - if (aIndx > bIndx) return -1; - } + if (aIndx < bIndx) return 1; + if (aIndx > bIndx) return -1; + } - throw new Error(`Unexpected case: ${cardsA} ${cardsB}`); + throw new Error(`Unexpected case: ${cardsA} ${cardsB}`); }; const sortCardsWithJokers = (cardsA: string[], cardsB: string[]) => { - const typeA = getCardsTypeIndexWithJokers(cardsA); - const typeB = getCardsTypeIndexWithJokers(cardsB); + const typeA = getCardsTypeIndexWithJokers(cardsA); + const typeB = getCardsTypeIndexWithJokers(cardsB); - if (typeA < typeB) return 1; - if (typeA > typeB) return -1; + if (typeA < typeB) return 1; + if (typeA > typeB) return -1; - return cardOrderWithJokers(cardsA, cardsB); + return cardOrderWithJokers(cardsA, cardsB); }; export const parttwo = lines - .slice() - .sort((a, b) => sortCardsWithJokers(a[0], b[0])) - .reduce((acc, v, i) => acc + v[1] * (i + 1), 0); + .slice() + .sort((a, b) => sortCardsWithJokers(a[0], b[0])) + .reduce((acc, v, i) => acc + v[1] * (i + 1), 0); diff --git a/code/ts/07/package.json b/code/ts/07/package.json index f3aeb3d..ff2a268 100644 --- a/code/ts/07/package.json +++ b/code/ts/07/package.json @@ -1,15 +1,15 @@ { - "name": "07", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "07", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/07/tsconfig.json b/code/ts/07/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/07/tsconfig.json +++ b/code/ts/07/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/08/code.ts b/code/ts/08/code.ts index b2cccfd..cf8fae7 100644 --- a/code/ts/08/code.ts +++ b/code/ts/08/code.ts @@ -1,39 +1,37 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/8.txt`).text(); const [instructions, network] = input.split("\n\n"); -const nodes = network - .split("\n") - .map((line) => line.replaceAll(/[\(\)]/g, "").split(" = ")); +const nodes = network.split("\n").map(line => line.replaceAll(/[\(\)]/g, "").split(" = ")); const nodeMap = nodes.reduce((acc: any, cur) => { - acc[cur[0]] = cur[1].split(", "); - return acc; + acc[cur[0]] = cur[1].split(", "); + return acc; }, {}) as Record; const solver = - (endCondition: any) => - (position: any): number => { - let step; - for (step = 0; !endCondition(position); step++) { - const instruction = instructions.charAt(step % instructions.length); - const options = nodeMap[position]; - position = options[instruction === "R" ? 1 : 0]; - } - return step; - }; + (endCondition: any) => + (position: any): number => { + let step; + for (step = 0; !endCondition(position); step++) { + const instruction = instructions.charAt(step % instructions.length); + const options = nodeMap[position]; + position = options[instruction === "R" ? 1 : 0]; + } + return step; + }; const p1s = solver((position: any) => position === "ZZZ"); export const partone = p1s("AAA"); const gcd = (a: number, b: number): number => { - return b ? gcd(b, a % b) : a; + return b ? gcd(b, a % b) : a; }; const lcm = (a: number, b: number): number => { - return (a * b) / gcd(a, b); + return (a * b) / gcd(a, b); }; -let startPositions = Object.keys(nodeMap).filter((key) => key.endsWith("A")); +let startPositions = Object.keys(nodeMap).filter(key => key.endsWith("A")); const p2s = solver((position: any) => position.endsWith("Z")); -const stepsForEacStart = startPositions.map((position) => p2s(position)); +const stepsForEacStart = startPositions.map(position => p2s(position)); export const parttwo = stepsForEacStart.reduce((a, b) => lcm(a, b)); diff --git a/code/ts/08/package.json b/code/ts/08/package.json index 1857063..c4f78f8 100644 --- a/code/ts/08/package.json +++ b/code/ts/08/package.json @@ -1,15 +1,15 @@ { - "name": "08", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "08", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/08/tsconfig.json b/code/ts/08/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/08/tsconfig.json +++ b/code/ts/08/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/09/code.ts b/code/ts/09/code.ts index 620375e..59908d0 100644 --- a/code/ts/09/code.ts +++ b/code/ts/09/code.ts @@ -2,28 +2,26 @@ const pkg = await Bun.file(`${import.meta.dir}/package.json`).json(); const input = await Bun.file(`${import.meta.dir}/../../../input/9.txt`).text(); const solve = (ns: number[]): number => - ns.every((n) => n === 0) - ? 0 - : ns[ns.length - 1] + solve(ns.slice(1).map((n, i) => n - ns[i])); + ns.every(n => n === 0) ? 0 : ns[ns.length - 1] + solve(ns.slice(1).map((n, i) => n - ns[i])); const parse = (input: string, reverse = false) => - input - .trim() - .split("\n") - .map((line) => - reverse - ? line.trim().split(" ").map(Number).reverse() - : line.trim().split(" ").map(Number), - ); + input + .trim() + .split("\n") + .map(line => + reverse + ? line.trim().split(" ").map(Number).reverse() + : line.trim().split(" ").map(Number), + ); const part1 = (input: string) => - parse(input) - .map(solve) - .reduce((a, b) => a + b, 0); + parse(input) + .map(solve) + .reduce((a, b) => a + b, 0); export const partone = part1(input); const part2 = (input: string) => - parse(input, true) - .map(solve) - .reduce((a, b) => a + b, 0); + parse(input, true) + .map(solve) + .reduce((a, b) => a + b, 0); export const parttwo = part2(input); diff --git a/code/ts/09/package.json b/code/ts/09/package.json index af6d446..7044052 100644 --- a/code/ts/09/package.json +++ b/code/ts/09/package.json @@ -1,15 +1,15 @@ { - "name": "09", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "09", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/09/tsconfig.json b/code/ts/09/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/09/tsconfig.json +++ b/code/ts/09/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/10/code.ts b/code/ts/10/code.ts index cc7519e..e28d6b5 100644 --- a/code/ts/10/code.ts +++ b/code/ts/10/code.ts @@ -2,83 +2,75 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/10.txt`).text(); type Point = [number, number]; -const distancePointToLine = ( - point: Point, - start: Point, - end: Point, -): number => { - const [x, y] = point; - const [x1, y1] = start; - const [x2, y2] = end; - const numerator = Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1); - const denominator = Math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2); - return numerator / denominator; +const distancePointToLine = (point: Point, start: Point, end: Point): number => { + const [x, y] = point; + const [x1, y1] = start; + const [x2, y2] = end; + const numerator = Math.abs((y2 - y1) * x - (x2 - x1) * y + x2 * y1 - y2 * x1); + const denominator = Math.sqrt((y2 - y1) ** 2 + (x2 - x1) ** 2); + return numerator / denominator; }; export const douglasPeucker = (points: Point[], epsilon: number): Point[] => { - if (points.length <= 2) return points; - - let dmax = 0; - let index = 0; - const start = points[0]; - const end = points[points.length - 1]; - - for (let i = 1; i < points.length - 1; i++) { - const d = distancePointToLine(points[i], start, end); - if (d > dmax) { - index = i; - dmax = d; + if (points.length <= 2) return points; + + let dmax = 0; + let index = 0; + const start = points[0]; + const end = points[points.length - 1]; + + for (let i = 1; i < points.length - 1; i++) { + const d = distancePointToLine(points[i], start, end); + if (d > dmax) { + index = i; + dmax = d; + } + } + + if (dmax > epsilon) { + const recursiveResult1 = douglasPeucker(points.slice(0, index + 1), epsilon); + const recursiveResult2 = douglasPeucker(points.slice(index), epsilon); + + const result = recursiveResult1.slice(0, -1).concat(recursiveResult2); + return result; + } else { + return [start, end]; } - } - - if (dmax > epsilon) { - const recursiveResult1 = douglasPeucker( - points.slice(0, index + 1), - epsilon, - ); - const recursiveResult2 = douglasPeucker(points.slice(index), epsilon); - - const result = recursiveResult1.slice(0, -1).concat(recursiveResult2); - return result; - } else { - return [start, end]; - } }; export const isInside = (vertices: Point[], x: number, y: number) => { - let inside = false; - for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) { - const [xi, yi] = vertices[i]; - const [xj, yj] = vertices[j]; + let inside = false; + for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) { + const [xi, yi] = vertices[i]; + const [xj, yj] = vertices[j]; - const intersect = - yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi; + const intersect = yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi; - if (intersect) inside = !inside; - } - return inside; + if (intersect) inside = !inside; + } + return inside; }; const parse = (input: string) => { - const list = input.trim().split("\n"); - return list.map((row) => row.trim().split("")); + const list = input.trim().split("\n"); + return list.map(row => row.trim().split("")); }; const toGrid = (list: string[][]) => { - const map = new Map(); - list.forEach((row, y) => { - row.forEach((col, x) => { - map.set(`${x},${y}`, col); + const map = new Map(); + list.forEach((row, y) => { + row.forEach((col, x) => { + map.set(`${x},${y}`, col); + }); }); - }); - return map; + return map; }; const findStart = (grid: Map): XY => { - for (const [xy, value] of grid.entries()) { - if (value === "S") return xy.split(",").map(Number) as [number, number]; - } - throw new Error("No start found"); + for (const [xy, value] of grid.entries()) { + if (value === "S") return xy.split(",").map(Number) as [number, number]; + } + throw new Error("No start found"); }; const UP: XY = [0, -1]; @@ -89,83 +81,80 @@ const RIGHT: XY = [1, 0]; const cardinals: XY[] = [UP, DOWN, LEFT, RIGHT]; const dirs: Record = { - "|": [UP, DOWN], - "-": [LEFT, RIGHT], - J: [UP, LEFT], - L: [UP, RIGHT], - "7": [DOWN, LEFT], - F: [DOWN, RIGHT], + "|": [UP, DOWN], + "-": [LEFT, RIGHT], + J: [UP, LEFT], + L: [UP, RIGHT], + "7": [DOWN, LEFT], + F: [DOWN, RIGHT], }; type XY = [number, number]; export const getPath = (input: string) => { - const list = parse(input); - const grid = toGrid(list); - const start = findStart(grid); - - const startingPoints = cardinals - .map(([dx, dy]) => [start[0] + dx, start[1] + dy]) - .filter(([x, y]) => (grid.get(`${x},${y}`) || ".") !== "."); - - for (const element of startingPoints) { - const sp = element; - const visited = new Set([start.join(",")]); - const path = [start, sp]; - - while (true) { - const [x, y] = path[path.length - 1]!; - const key = `${x},${y}`; - const next = grid.get(key); - if (next === "S") return path.slice(0, -1); - if (!next) break; - const nextDirs = dirs[next]; - if (!nextDirs) break; - visited.add(key); - const nextDir = nextDirs.find(([dx, dy]) => { - const [nx, ny] = [x + dx, y + dy]; - const nextKey = `${nx},${ny}`; - return ( - (path.length > 3 && grid.get(nextKey) === "S") || - !visited.has(nextKey) - ); - }); - if (!nextDir) break; - const nx = x + nextDir[0]; - const ny = y + nextDir[1]; - path.push([nx, ny]); + const list = parse(input); + const grid = toGrid(list); + const start = findStart(grid); + + const startingPoints = cardinals + .map(([dx, dy]) => [start[0] + dx, start[1] + dy]) + .filter(([x, y]) => (grid.get(`${x},${y}`) || ".") !== "."); + + for (const element of startingPoints) { + const sp = element; + const visited = new Set([start.join(",")]); + const path = [start, sp]; + + while (true) { + const [x, y] = path[path.length - 1]!; + const key = `${x},${y}`; + const next = grid.get(key); + if (next === "S") return path.slice(0, -1); + if (!next) break; + const nextDirs = dirs[next]; + if (!nextDirs) break; + visited.add(key); + const nextDir = nextDirs.find(([dx, dy]) => { + const [nx, ny] = [x + dx, y + dy]; + const nextKey = `${nx},${ny}`; + return (path.length > 3 && grid.get(nextKey) === "S") || !visited.has(nextKey); + }); + if (!nextDir) break; + const nx = x + nextDir[0]; + const ny = y + nextDir[1]; + path.push([nx, ny]); + } } - } - return null; + return null; }; export const part1 = (input: string) => getPath(input)!.length / 2; export const part2 = (input: string) => { - const path = getPath(input)!; - const optimalPolygon = douglasPeucker(path, 0); - - let [minX, minY, maxX, maxY] = [Infinity, Infinity, -Infinity, -Infinity]; - path.forEach(([x, y]) => { - minX = Math.min(minX, x); - minY = Math.min(minY, y); - maxX = Math.max(maxX, x); - maxY = Math.max(maxY, y); - }); - - const walls = new Set(); - path.forEach(([x, y]) => walls.add(`${x},${y}`)); - - let sum = 0; - for (let y = minY + 1; y < maxY; ++y) { - for (let x = minX + 1; x < maxX; ++x) { - if (walls.has(`${x},${y}`)) continue; - if (isInside(optimalPolygon, x, y)) sum++; + const path = getPath(input)!; + const optimalPolygon = douglasPeucker(path, 0); + + let [minX, minY, maxX, maxY] = [Infinity, Infinity, -Infinity, -Infinity]; + path.forEach(([x, y]) => { + minX = Math.min(minX, x); + minY = Math.min(minY, y); + maxX = Math.max(maxX, x); + maxY = Math.max(maxY, y); + }); + + const walls = new Set(); + path.forEach(([x, y]) => walls.add(`${x},${y}`)); + + let sum = 0; + for (let y = minY + 1; y < maxY; ++y) { + for (let x = minX + 1; x < maxX; ++x) { + if (walls.has(`${x},${y}`)) continue; + if (isInside(optimalPolygon, x, y)) sum++; + } } - } - return sum; + return sum; }; export const partone = part1(input); diff --git a/code/ts/10/package.json b/code/ts/10/package.json index 0164dc0..949ff4b 100644 --- a/code/ts/10/package.json +++ b/code/ts/10/package.json @@ -1,15 +1,15 @@ { - "name": "10", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "10", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/10/tsconfig.json b/code/ts/10/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/10/tsconfig.json +++ b/code/ts/10/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/11/code.ts b/code/ts/11/code.ts index 6f80467..161fb0a 100644 --- a/code/ts/11/code.ts +++ b/code/ts/11/code.ts @@ -1,65 +1,64 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/11.txt`).text(); const parseInput = (input: string, part2 = false) => { - const expansion = part2 ? 1000000 - 1 : 1; - const galaxies: Galaxy[] = []; - const rows = input.trim().split("\n"); - let expandX = 0; - const xExpands: number[] = []; - for (let x = 0; x < rows[0].length; x++) { - if (!rows.some((row) => row[x] === "#")) { - expandX += expansion; - } - xExpands[x] = expandX; - } - let expandY = 0; - rows.forEach((row, y) => { - if (!row.includes("#")) { - expandY += expansion; - } else { - for (let x = 0; x < row.length; x++) { - const char = row[x]; - if (char === "#") { - galaxies.push({ x: x + xExpands[x], y: y + expandY }); + const expansion = part2 ? 1000000 - 1 : 1; + const galaxies: Galaxy[] = []; + const rows = input.trim().split("\n"); + let expandX = 0; + const xExpands: number[] = []; + for (let x = 0; x < rows[0].length; x++) { + if (!rows.some(row => row[x] === "#")) { + expandX += expansion; } - } + xExpands[x] = expandX; } - }); - return galaxies; + let expandY = 0; + rows.forEach((row, y) => { + if (!row.includes("#")) { + expandY += expansion; + } else { + for (let x = 0; x < row.length; x++) { + const char = row[x]; + if (char === "#") { + galaxies.push({ x: x + xExpands[x], y: y + expandY }); + } + } + } + }); + return galaxies; }; type Galaxy = { x: number; y: number }; const galaxyPathName = (g1: number, g2: number) => { - const galaxies = g1 > g2 ? [g2, g1] : [g1, g2]; - return galaxies.join(">"); + const galaxies = g1 > g2 ? [g2, g1] : [g1, g2]; + return galaxies.join(">"); }; function getTotalGalaxyDistance(galaxies: Galaxy[]) { - const paths: Set = new Set(); - let totalDistance = 0; - for (let g1 = 0; g1 < galaxies.length; g1++) { - const galaxy1 = galaxies[g1]; - for (let g2 = 0; g2 < galaxies.length; g2++) { - if (g2 === g1) continue; - const pathName = galaxyPathName(g1, g2); - if (paths.has(pathName)) continue; - paths.add(pathName); - const galaxy2 = galaxies[g2]; - const distance = - Math.abs(galaxy2.x - galaxy1.x) + Math.abs(galaxy2.y - galaxy1.y); - totalDistance += distance; + const paths: Set = new Set(); + let totalDistance = 0; + for (let g1 = 0; g1 < galaxies.length; g1++) { + const galaxy1 = galaxies[g1]; + for (let g2 = 0; g2 < galaxies.length; g2++) { + if (g2 === g1) continue; + const pathName = galaxyPathName(g1, g2); + if (paths.has(pathName)) continue; + paths.add(pathName); + const galaxy2 = galaxies[g2]; + const distance = Math.abs(galaxy2.x - galaxy1.x) + Math.abs(galaxy2.y - galaxy1.y); + totalDistance += distance; + } } - } - return totalDistance; + return totalDistance; } const part1 = (input: string): string | number => { - return getTotalGalaxyDistance(parseInput(input)); + return getTotalGalaxyDistance(parseInput(input)); }; const part2 = (input: string): string | number => { - return getTotalGalaxyDistance(parseInput(input, true)); + return getTotalGalaxyDistance(parseInput(input, true)); }; export const partone = part1(input); diff --git a/code/ts/11/package.json b/code/ts/11/package.json index 89b8989..9341968 100644 --- a/code/ts/11/package.json +++ b/code/ts/11/package.json @@ -1,15 +1,15 @@ { - "name": "11", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "11", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/11/tsconfig.json b/code/ts/11/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/11/tsconfig.json +++ b/code/ts/11/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/12/code.ts b/code/ts/12/code.ts index c65b7b9..c44b03d 100644 --- a/code/ts/12/code.ts +++ b/code/ts/12/code.ts @@ -2,66 +2,61 @@ const pkg = await Bun.file(`${import.meta.dir}/package.json`).json(); const input = await Bun.file(`${import.meta.dir}/../../../input/12.txt`).text(); export const loopSum = (map: (n: T) => number, arr: T[]) => { - let sum = 0; - for (const element of arr) { - sum += map(element); - } - return sum; + let sum = 0; + for (const element of arr) { + sum += map(element); + } + return sum; }; export const memoize = ( - fn: (...args: Args) => Return, + fn: (...args: Args) => Return, ): ((...args: Args) => Return) => { - const cache = new Map(); - return (...args) => { - const key = JSON.stringify(args); - if (!cache.has(key)) cache.set(key, fn(...args)); - return cache.get(key)!; - }; + const cache = new Map(); + return (...args) => { + const key = JSON.stringify(args); + if (!cache.has(key)) cache.set(key, fn(...args)); + return cache.get(key)!; + }; }; export const solver = (input: string, n: number) => { - const calculateVariants = memoize((row: string, groups: number[]): number => { - if (row.startsWith(".")) return calculateVariants(row.slice(1), groups); + const calculateVariants = memoize((row: string, groups: number[]): number => { + if (row.startsWith(".")) return calculateVariants(row.slice(1), groups); - if (groups.length === 0) { - return row.indexOf("#") === -1 ? 1 : 0; - } + if (groups.length === 0) { + return row.indexOf("#") === -1 ? 1 : 0; + } - let sum = 0; - for (const element of groups) { - sum += element; - } - if (row.length < sum + groups.length - 1) { - return 0; - } + let sum = 0; + for (const element of groups) { + sum += element; + } + if (row.length < sum + groups.length - 1) { + return 0; + } - if (row.startsWith("#")) { - const [groupSize, ...remainingGroups] = groups; - if (row.slice(0, groupSize).indexOf(".") !== -1) return 0; - if (row[groupSize] === "#") { - return 0; - } - return calculateVariants(row.slice(groupSize + 1), remainingGroups); - } + if (row.startsWith("#")) { + const [groupSize, ...remainingGroups] = groups; + if (row.slice(0, groupSize).indexOf(".") !== -1) return 0; + if (row[groupSize] === "#") { + return 0; + } + return calculateVariants(row.slice(groupSize + 1), remainingGroups); + } - const nextSlice = row.slice(1); - return ( - calculateVariants("#" + nextSlice, groups) + - calculateVariants("." + nextSlice, groups) - ); - }); + const nextSlice = row.slice(1); + return ( + calculateVariants("#" + nextSlice, groups) + calculateVariants("." + nextSlice, groups) + ); + }); - return loopSum((line) => { - const [str, nums] = line.trim().split(" "); - const record = Array.from({ length: n }).fill(str).join("?"); - const groups = Array.from({ length: n }) - .fill(nums) - .join(",") - .split(",") - .map(Number); - return calculateVariants(record, groups); - }, input.trim().split("\n")); + return loopSum(line => { + const [str, nums] = line.trim().split(" "); + const record = Array.from({ length: n }).fill(str).join("?"); + const groups = Array.from({ length: n }).fill(nums).join(",").split(",").map(Number); + return calculateVariants(record, groups); + }, input.trim().split("\n")); }; const part1 = (input: string) => solver(input, 1); diff --git a/code/ts/12/package.json b/code/ts/12/package.json index 73d4fb6..01e0443 100644 --- a/code/ts/12/package.json +++ b/code/ts/12/package.json @@ -1,15 +1,15 @@ { - "name": "12", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "12", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/12/tsconfig.json b/code/ts/12/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/12/tsconfig.json +++ b/code/ts/12/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/13/code.ts b/code/ts/13/code.ts index a41a423..94203a3 100644 --- a/code/ts/13/code.ts +++ b/code/ts/13/code.ts @@ -1,90 +1,86 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/13.txt`).text(); export const loopSum = (map: (n: T) => number, arr: T[]) => { - let sum = 0; - for (const element of arr) { - sum += map(element); - } - return sum; + let sum = 0; + for (const element of arr) { + sum += map(element); + } + return sum; }; -const vertical = ( - input: string[], - ignore: number | null, - i: number | null, -): number | null => { - if (input.length === 0) return i; - const [f, ...r] = input; - if (i === null) { - for (let j = 0; j < f.length - 1; ++j) { - if (j === ignore) continue; - const o = vertical(input, ignore, j); - if (o !== null) return o; - } - return null; - } else { - const a = f.slice(0, i + 1); - const b = f - .slice(i + 1, input[0].length) - .split("") - .reverse() - .join(""); +const vertical = (input: string[], ignore: number | null, i: number | null): number | null => { + if (input.length === 0) return i; + const [f, ...r] = input; + if (i === null) { + for (let j = 0; j < f.length - 1; ++j) { + if (j === ignore) continue; + const o = vertical(input, ignore, j); + if (o !== null) return o; + } + return null; + } else { + const a = f.slice(0, i + 1); + const b = f + .slice(i + 1, input[0].length) + .split("") + .reverse() + .join(""); - return a.endsWith(b) || b.endsWith(a) ? vertical(r, ignore, i) : null; - } + return a.endsWith(b) || b.endsWith(a) ? vertical(r, ignore, i) : null; + } }; const rotate = (input: string[]): string[] => - Array.from({ length: input[0].length + 1 }, (_, i) => - input.map((l) => l[input[0].length - i]).join(""), - ).filter((v) => v.length > 0); + Array.from({ length: input[0].length + 1 }, (_, i) => + input.map(l => l[input[0].length - i]).join(""), + ).filter(v => v.length > 0); const parse = (input: string) => - input - .trim() - .split("\n\n") - .map((p) => - p + input .trim() - .split("\n") - .map((l) => l.trim()), - ); + .split("\n\n") + .map(p => + p + .trim() + .split("\n") + .map(l => l.trim()), + ); export const part1 = (input: string) => { - const patterns = parse(input); + const patterns = parse(input); - return loopSum((p) => { - const v = vertical(p, null, null); - if (v !== null) return v + 1; - const h = vertical(rotate(p), null, null)!; - return (h + 1) * 100; - }, patterns); + return loopSum(p => { + const v = vertical(p, null, null); + if (v !== null) return v + 1; + const h = vertical(rotate(p), null, null)!; + return (h + 1) * 100; + }, patterns); }; export const part2 = (input: string) => { - const patterns = parse(input); + const patterns = parse(input); - return loopSum((p) => { - const originalV = vertical(p, null, null); - const originalH = vertical(rotate(p), null, null); + return loopSum(p => { + const originalV = vertical(p, null, null); + const originalH = vertical(rotate(p), null, null); - for (let y = 0; y < p.length; ++y) { - for (let x = 0; x < p[y].length; ++x) { - const clone = [...p]; - clone[y] = - clone[y].slice(0, x) + - (clone[y][x] === "." ? "#" : ".") + - clone[y].slice(x + 1); + for (let y = 0; y < p.length; ++y) { + for (let x = 0; x < p[y].length; ++x) { + const clone = [...p]; + clone[y] = + clone[y].slice(0, x) + + (clone[y][x] === "." ? "#" : ".") + + clone[y].slice(x + 1); - const v = vertical(clone, originalV, null); - if (v !== null && v !== originalV) return v + 1; - const h = vertical(rotate(clone), originalH, null); - if (h !== null && h !== originalH) return (h + 1) * 100; - } - } + const v = vertical(clone, originalV, null); + if (v !== null && v !== originalV) return v + 1; + const h = vertical(rotate(clone), originalH, null); + if (h !== null && h !== originalH) return (h + 1) * 100; + } + } - return 0; - }, patterns); + return 0; + }, patterns); }; export const partone = part1(input); diff --git a/code/ts/13/package.json b/code/ts/13/package.json index 4d870f7..85c9076 100644 --- a/code/ts/13/package.json +++ b/code/ts/13/package.json @@ -1,15 +1,15 @@ { - "name": "13", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "13", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/13/tsconfig.json b/code/ts/13/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/13/tsconfig.json +++ b/code/ts/13/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/14/code.ts b/code/ts/14/code.ts index f897f8e..67b9793 100644 --- a/code/ts/14/code.ts +++ b/code/ts/14/code.ts @@ -1,74 +1,67 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/14.txt`).text(); -const platformOriginal = input.split("\n").map((x) => x.split("")); +const platformOriginal = input.split("\n").map(x => x.split("")); -const [platformX, platformY] = [ - platformOriginal[0].length, - platformOriginal.length, -]; +const [platformX, platformY] = [platformOriginal[0].length, platformOriginal.length]; -const clonePlatform = (platform: string[][]) => platform.map((x) => x.slice()); +const clonePlatform = (platform: string[][]) => platform.map(x => x.slice()); const loadOnNorth = (platform: string[][]) => - platform.reduce( - (acc, v, i) => - acc + (platform.length - i) * v.filter((x) => x === "O").length, - 0, - ); + platform.reduce( + (acc, v, i) => acc + (platform.length - i) * v.filter(x => x === "O").length, + 0, + ); const flipNorth = (platform: string[][]) => { - for (let col = 0; col < platformX; col++) { - let insertAt = 0; - for (let row = 0; row < platformY; row++) { - if (platform[row][col] === "#") insertAt = row + 1; - if (platform[row][col] === "O") { - if (insertAt === row) { - insertAt = row + 1; - } else { - [platform[insertAt][col], platform[row][col]] = ["O", "."]; - insertAt++; + for (let col = 0; col < platformX; col++) { + let insertAt = 0; + for (let row = 0; row < platformY; row++) { + if (platform[row][col] === "#") insertAt = row + 1; + if (platform[row][col] === "O") { + if (insertAt === row) { + insertAt = row + 1; + } else { + [platform[insertAt][col], platform[row][col]] = ["O", "."]; + insertAt++; + } + } } - } } - } - return platform; + return platform; }; const part1 = loadOnNorth(flipNorth(clonePlatform(platformOriginal))); const transpose = (platform: string[][]): string[][] => - platform[0].map((_, colIndex) => platform.map((row) => row[colIndex])); -const flipWest = (platform: string[][]) => - transpose(flipNorth(transpose(platform))); + platform[0].map((_, colIndex) => platform.map(row => row[colIndex])); +const flipWest = (platform: string[][]) => transpose(flipNorth(transpose(platform))); const flipEast = (platform: string[][]) => - flipWest(platform.map((x) => x.toReversed())).map((x) => x.toReversed()); -const flipSouth = (platform: string[][]) => - flipNorth(platform.toReversed()).reverse(); -const cycle = (platform: string[][]) => - flipEast(flipSouth(flipWest(flipNorth(platform)))); + flipWest(platform.map(x => x.toReversed())).map(x => x.toReversed()); +const flipSouth = (platform: string[][]) => flipNorth(platform.toReversed()).reverse(); +const cycle = (platform: string[][]) => flipEast(flipSouth(flipWest(flipNorth(platform)))); let platform = clonePlatform(platformOriginal); const atlas: Record = {}; const limit = 1_000_000_000; for (let i = 0; i < limit; i++) { - platform = cycle(platform); - const mapString = platform.map((x) => x.join("")).join("\r\n"); + platform = cycle(platform); + const mapString = platform.map(x => x.join("")).join("\r\n"); - if (atlas[mapString] === undefined) { - atlas[mapString] = { index: i, platform: clonePlatform(platform) }; - continue; - } + if (atlas[mapString] === undefined) { + atlas[mapString] = { index: i, platform: clonePlatform(platform) }; + continue; + } - const cycleStartIndex = atlas[mapString].index; - const cycleLength = i - cycleStartIndex; + const cycleStartIndex = atlas[mapString].index; + const cycleLength = i - cycleStartIndex; - const cycleIndex = (limit - cycleStartIndex - 1) % cycleLength; - platform = atlas[mapString].platform; - for (let j = 0; j < cycleIndex; j++) { - platform = cycle(platform); - } + const cycleIndex = (limit - cycleStartIndex - 1) % cycleLength; + platform = atlas[mapString].platform; + for (let j = 0; j < cycleIndex; j++) { + platform = cycle(platform); + } - break; + break; } const part2 = loadOnNorth(platform); diff --git a/code/ts/14/package.json b/code/ts/14/package.json index 387c247..95aab9c 100644 --- a/code/ts/14/package.json +++ b/code/ts/14/package.json @@ -1,15 +1,15 @@ { - "name": "14", - "module": "code.ts", - "type": "module", - "devDependencies": { - "bun-types": "latest" - }, - "peerDependencies": { - "typescript": "^5.0.0" - }, - "scripts": { - "build": "tsc", - "dev": "bun run code.ts" - } -} + "name": "14", + "type": "module", + "module": "code.ts", + "scripts": { + "build": "tsc", + "dev": "bun run code.ts" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "devDependencies": { + "bun-types": "latest" + } +} \ No newline at end of file diff --git a/code/ts/14/tsconfig.json b/code/ts/14/tsconfig.json index 7556e1d..323691f 100644 --- a/code/ts/14/tsconfig.json +++ b/code/ts/14/tsconfig.json @@ -1,22 +1,22 @@ { - "compilerOptions": { - "lib": ["ESNext"], - "module": "esnext", - "target": "esnext", - "moduleResolution": "bundler", - "moduleDetection": "force", - "allowImportingTsExtensions": true, - "noEmit": true, - "composite": true, - "strict": true, - "downlevelIteration": true, - "skipLibCheck": true, - "jsx": "react-jsx", - "allowSyntheticDefaultImports": true, - "forceConsistentCasingInFileNames": true, - "allowJs": true, - "types": [ - "bun-types" // add Bun global - ] - } -} + "compilerOptions": { + "allowImportingTsExtensions": true, + "allowJs": true, + "allowSyntheticDefaultImports": true, + "composite": true, + "downlevelIteration": true, + "forceConsistentCasingInFileNames": true, + "jsx": "react-jsx", + "lib": ["ESNext"], + "module": "esnext", + "moduleDetection": "force", + "moduleResolution": "bundler", + "noEmit": true, + "skipLibCheck": true, + "strict": true, + "target": "esnext", + "types": [ + "bun-types" // add Bun global + ] + } +} \ No newline at end of file diff --git a/code/ts/15/code.ts b/code/ts/15/code.ts index aec7765..ca1c555 100644 --- a/code/ts/15/code.ts +++ b/code/ts/15/code.ts @@ -1,75 +1,69 @@ const input = await Bun.file(`${import.meta.dir}/../../../input/15.txt`).text(); type SequenceData = { - label: string; - operation: "-" | "="; - focalLength: string; + label: string; + operation: "-" | "="; + focalLength: string; }; type Box = Map; function solvePart1(sequences: string[]) { - return sequences.reduce((sum, s) => sum + computeHash(s), 0); + return sequences.reduce((sum, s) => sum + computeHash(s), 0); } function computeHash(str: string) { - return str - .split("") - .reduce((value, char) => ((value + char.charCodeAt(0)) * 17) % 256, 0); + return str.split("").reduce((value, char) => ((value + char.charCodeAt(0)) * 17) % 256, 0); } function solvePart2(sequences: string[]) { - return computeFocusingPower(setupLenses(sequences)); + return computeFocusingPower(setupLenses(sequences)); } function setupLenses(sequences: string[]) { - return sequences.reduce((boxes, sequence) => { - const sequenceData = parseSequence(sequence); - const box = getBox(boxes, computeHash(sequenceData.label)); - updateBox(box, sequenceData); - return boxes; - }, []); + return sequences.reduce((boxes, sequence) => { + const sequenceData = parseSequence(sequence); + const box = getBox(boxes, computeHash(sequenceData.label)); + updateBox(box, sequenceData); + return boxes; + }, []); } function parseSequence(sequence: string): SequenceData { - return sequence.match(/(?