diff --git a/AdventOfCode2025/day4/.gitignore b/AdventOfCode2025/day4/.gitignore new file mode 100644 index 0000000..a14702c --- /dev/null +++ b/AdventOfCode2025/day4/.gitignore @@ -0,0 +1,34 @@ +# dependencies (bun install) +node_modules + +# output +out +dist +*.tgz + +# code coverage +coverage +*.lcov + +# logs +logs +_.log +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# caches +.eslintcache +.cache +*.tsbuildinfo + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/AdventOfCode2025/day4/README.md b/AdventOfCode2025/day4/README.md new file mode 100644 index 0000000..24c55e3 --- /dev/null +++ b/AdventOfCode2025/day4/README.md @@ -0,0 +1,15 @@ +# day4 + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.2.8. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/AdventOfCode2025/day4/bun.lock b/AdventOfCode2025/day4/bun.lock new file mode 100644 index 0000000..a0cdc21 --- /dev/null +++ b/AdventOfCode2025/day4/bun.lock @@ -0,0 +1,25 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "day4", + "devDependencies": { + "@types/bun": "latest", + }, + "peerDependencies": { + "typescript": "^5", + }, + }, + }, + "packages": { + "@types/bun": ["@types/bun@1.3.3", "", { "dependencies": { "bun-types": "1.3.3" } }, "sha512-ogrKbJ2X5N0kWLLFKeytG0eHDleBYtngtlbu9cyBKFtNL3cnpDZkNdQj8flVf6WTZUX5ulI9AY1oa7ljhSrp+g=="], + + "@types/node": ["@types/node@24.10.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ=="], + + "bun-types": ["bun-types@1.3.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-z3Xwlg7j2l9JY27x5Qn3Wlyos8YAp0kKRlrePAOjgjMGS5IG6E7Jnlx736vH9UVI4wUICwwhC9anYL++XeOgTQ=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + } +} diff --git a/AdventOfCode2025/day4/index.ts b/AdventOfCode2025/day4/index.ts new file mode 100644 index 0000000..f914359 --- /dev/null +++ b/AdventOfCode2025/day4/index.ts @@ -0,0 +1,78 @@ +const file = Bun.file("./input.txt"); +const content = await file.text(); + +const EMPTY = "."; +const PAPER = "@"; + +const splitContent = [...content.trim().split("\n")] +const lineSize = splitContent[0]!.length + +const grid = [ + '.'.repeat(lineSize), + ...splitContent, + '.'.repeat(lineSize), +].map(l => `.${l}.`.split("")) + +const solve = (grid: string[][]): [number, string[][]] => { + let paperRemoved = 0; + const newGrid = structuredClone(grid) + + for (let y = 1; y < grid.length - 1; y++) { + for (let x = 1; x < grid[0]!.length - 1; x++) { + let adjacentPapers = 0; + + const currentSquare = grid?.[y]?.[x] + if (!currentSquare) { + throw new Error("current square must be defined") + } + + if (currentSquare === EMPTY) { + continue + } + + for (let yOffset = -1; yOffset <= 1; yOffset++) { + for (let xOffset = -1; xOffset <= 1; xOffset++) { + if (yOffset === 0 && xOffset === 0) { + continue + } + + const square = grid![y + yOffset]![x + xOffset]! + if (square === PAPER) { + adjacentPapers++ + } + } + } + + if (adjacentPapers < 4) { + newGrid![y]![x] = EMPTY + paperRemoved++ + } + } + } + + return [paperRemoved, newGrid] +} + +const removePaper = (grid: string[][]): number => { + let totalPaperRemoved = 0; + let currentGrid = grid + + while (true) { + const [paperRemoved, newGrid] = solve(currentGrid) + currentGrid = newGrid + + if (paperRemoved === 0) { + break + } + + totalPaperRemoved += paperRemoved + } + + return totalPaperRemoved +} + +const [part1] = solve(grid) +const part2 = removePaper(grid) + +console.log("Part 1: ", part1) +console.log("Part 2: ", part2) diff --git a/AdventOfCode2025/day4/package.json b/AdventOfCode2025/day4/package.json new file mode 100644 index 0000000..aa21e2d --- /dev/null +++ b/AdventOfCode2025/day4/package.json @@ -0,0 +1,12 @@ +{ + "name": "day4", + "module": "index.ts", + "type": "module", + "private": true, + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5" + } +} diff --git a/AdventOfCode2025/day4/tsconfig.json b/AdventOfCode2025/day4/tsconfig.json new file mode 100644 index 0000000..9c62f74 --- /dev/null +++ b/AdventOfCode2025/day4/tsconfig.json @@ -0,0 +1,28 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +}