├── 2021 ├── 10 │ ├── test.txt │ ├── a.ts │ └── b.ts ├── 11 │ ├── in.txt │ ├── test.txt │ ├── a.ts │ └── b.ts ├── 12 │ ├── test.txt │ ├── in.txt │ ├── a.ts │ └── b.ts ├── 13 │ ├── test.txt │ ├── b.ts │ └── a.ts ├── 14 │ ├── test.txt │ ├── in.txt │ ├── a.ts │ └── b.ts ├── 15 │ ├── test.txt │ ├── a.ts │ └── b.ts ├── 16 │ ├── test.txt │ └── in.txt ├── 17 │ ├── test.txt │ ├── in.txt │ ├── b.ts │ └── a.ts ├── 18 │ └── test.txt ├── 20 │ ├── test.txt │ ├── b.ts │ └── a.ts ├── 21 │ ├── in.txt │ ├── test.txt │ └── a.ts ├── 22 │ ├── a.ts │ └── b.ts ├── 25 │ ├── ..v │ ├── .v │ ├── .v..v │ ├── v │ ├── vv │ ├── vvv │ ├── .....v │ ├── test.txt │ └── a.ts ├── .gitignore ├── 06 │ ├── test.txt │ ├── in.txt │ ├── a.ts │ └── b.ts ├── 19 (I have no idea) │ └── sadge ├── 07 │ ├── test.txt │ ├── a.ts │ └── b.ts ├── visualizations │ ├── 10 │ │ ├── data.txt │ │ ├── styles.css │ │ └── index.html │ ├── 11 │ │ ├── styles.css │ │ ├── index.html │ │ └── data.txt │ ├── 12 │ │ ├── data.txt │ │ ├── index.html │ │ └── styles.css │ ├── 13 │ │ ├── data.txt │ │ ├── index.html │ │ └── styles.css │ ├── 14 │ │ ├── styles.css │ │ ├── index.html │ │ └── data.txt │ ├── 15 │ │ ├── style.css │ │ ├── index.html │ │ └── data.txt │ ├── 16 │ │ ├── data.txt │ │ ├── style.css │ │ └── index.html │ ├── 17 │ │ ├── index.html │ │ └── style.css │ ├── 18 │ │ ├── index.html │ │ └── style.css │ ├── 20 │ │ ├── style.css │ │ └── index.html │ ├── font │ │ └── Consolas.ttf │ └── 09 │ │ └── index.html ├── 09 │ ├── test.txt │ ├── a.ts │ └── b.ts ├── .prettierrc ├── package.json ├── other │ └── random_number_grid.py ├── 01 │ ├── a.ts │ └── b.ts ├── 08 │ ├── a.ts │ └── test.txt ├── 02 │ ├── a.ts │ └── b.ts ├── 03 │ ├── a.ts │ └── b.ts ├── files.ts ├── 05 │ ├── a.ts │ └── b.ts └── 04 │ ├── b.ts │ └── a.ts ├── 2022 ├── src │ ├── 10 │ │ ├── b.ts │ │ ├── a.ts │ │ ├── test.txt │ │ └── in.txt │ ├── 11 │ │ ├── a.ts │ │ └── b.ts │ ├── 13 │ │ ├── a.ts │ │ └── b.ts │ ├── 14 │ │ ├── a.ts │ │ └── b.ts │ ├── 15 │ │ └── a.ts │ ├── 18 │ │ └── a.ts │ ├── 21 │ │ └── a.ts │ ├── 02 │ │ ├── test.txt │ │ ├── a.ts │ │ └── b.ts │ ├── 06 │ │ ├── test.txt │ │ ├── b.ts │ │ └── a.ts │ ├── 08 │ │ ├── test.txt │ │ ├── a.ts │ │ └── b.ts │ ├── 09 │ │ ├── test.txt │ │ └── a.ts │ ├── 04 │ │ ├── test.txt │ │ ├── a.ts │ │ └── b.ts │ ├── 01 │ │ ├── test.txt │ │ ├── a.ts │ │ └── b.ts │ ├── 05 │ │ ├── test.txt │ │ ├── a.ts │ │ └── b.ts │ ├── 03 │ │ ├── test.txt │ │ ├── b.ts │ │ └── a.ts │ ├── 07 │ │ ├── test.txt │ │ └── a.ts │ └── lib │ │ └── files.ts ├── .gitignore ├── .vscode │ ├── settings.json │ └── launch.json ├── visualizations │ ├── 10 │ │ ├── 10.css │ │ ├── default.txt │ │ └── index.html │ ├── 11 │ │ ├── 11.css │ │ └── index.html │ ├── 12 │ │ ├── 12.css │ │ └── index.html │ ├── 13 │ │ ├── 13.css │ │ └── index.html │ ├── 14 │ │ ├── 14.css │ │ └── index.html │ ├── 15 │ │ ├── 15.css │ │ └── index.html │ ├── fonts │ │ └── caskaydia.otf │ ├── tsconfig.json │ ├── 08 │ │ ├── 08.css │ │ └── index.html │ ├── 06 │ │ ├── 06.css │ │ └── index.html │ ├── 05 │ │ ├── 05.css │ │ └── index.html │ ├── 09 │ │ ├── 09.css │ │ └── index.html │ ├── main.css │ ├── 07 │ │ ├── 07.css │ │ └── index.html │ └── index.ts ├── README.md └── package.json └── 2023 ├── .gitignore ├── package.json └── src ├── 10 └── a.ts ├── 11 ├── a.ts └── b.ts ├── 12 ├── a.ts └── b.ts ├── 13 ├── b.ts └── a.ts ├── 14 └── a.ts ├── 15 ├── a.ts └── b.ts ├── 01 ├── a.ts └── b.ts ├── 06 ├── b.ts └── a.ts ├── 04 ├── a.ts └── b.ts ├── 02 ├── a.ts └── b.ts ├── 08 ├── a.ts └── b.ts ├── 09 ├── b.ts └── a.ts ├── 05 ├── a.ts └── b.ts ├── 07 └── a.ts └── 03 └── a.ts /2021/25/..v: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/25/.v: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/25/.v..v: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/25/v: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/25/vv: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/25/vvv: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/25/.....v: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /2021/06/test.txt: -------------------------------------------------------------------------------- 1 | 3,4,3,1,2 -------------------------------------------------------------------------------- /2021/19 (I have no idea)/sadge: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /2021/07/test.txt: -------------------------------------------------------------------------------- 1 | 16,1,2,0,4,2,7,1,2,14 -------------------------------------------------------------------------------- /2021/16/test.txt: -------------------------------------------------------------------------------- 1 | 9C0141080250320F1802104A08 -------------------------------------------------------------------------------- /2022/src/02/test.txt: -------------------------------------------------------------------------------- 1 | A Y 2 | B X 3 | C Z -------------------------------------------------------------------------------- /2021/17/test.txt: -------------------------------------------------------------------------------- 1 | target area: x=20..30, y=-10..-5 -------------------------------------------------------------------------------- /2022/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | *.txt -------------------------------------------------------------------------------- /2023/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | *.txt -------------------------------------------------------------------------------- /2021/17/in.txt: -------------------------------------------------------------------------------- 1 | target area: x=96..125, y=-144..-98 -------------------------------------------------------------------------------- /2022/src/06/test.txt: -------------------------------------------------------------------------------- 1 | mjqjpqmgbljsphdztnvjfqwrcgsmlb -------------------------------------------------------------------------------- /2021/visualizations/16/data.txt: -------------------------------------------------------------------------------- 1 | 22008cbf8a540113004644860cc10 -------------------------------------------------------------------------------- /2022/src/08/test.txt: -------------------------------------------------------------------------------- 1 | 30373 2 | 25512 3 | 65332 4 | 33549 5 | 35390 -------------------------------------------------------------------------------- /2021/21/in.txt: -------------------------------------------------------------------------------- 1 | Player 1 starting position: 1 2 | Player 2 starting position: 2 -------------------------------------------------------------------------------- /2021/12/test.txt: -------------------------------------------------------------------------------- 1 | start-A 2 | start-b 3 | A-c 4 | A-b 5 | b-d 6 | A-end 7 | b-end -------------------------------------------------------------------------------- /2021/21/test.txt: -------------------------------------------------------------------------------- 1 | Player 1 starting position: 4 2 | Player 2 starting position: 8 -------------------------------------------------------------------------------- /2022/src/09/test.txt: -------------------------------------------------------------------------------- 1 | R 5 2 | U 8 3 | L 8 4 | D 3 5 | R 17 6 | D 10 7 | L 25 8 | U 20 -------------------------------------------------------------------------------- /2021/09/test.txt: -------------------------------------------------------------------------------- 1 | 2199943210 2 | 3987894921 3 | 9856789892 4 | 8767896789 5 | 9899965678 -------------------------------------------------------------------------------- /2022/src/04/test.txt: -------------------------------------------------------------------------------- 1 | 2-4,6-8 2 | 2-3,4-5 3 | 5-7,7-9 4 | 2-8,3-7 5 | 6-6,4-6 6 | 2-6,4-8 -------------------------------------------------------------------------------- /2021/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "printWidth": 140 5 | } 6 | -------------------------------------------------------------------------------- /2022/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "compile-hero.disable-compile-files-on-did-save-code": false 3 | } -------------------------------------------------------------------------------- /2021/visualizations/font/Consolas.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TenViki/advent-of-code/HEAD/2021/visualizations/font/Consolas.ttf -------------------------------------------------------------------------------- /2022/visualizations/fonts/caskaydia.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TenViki/advent-of-code/HEAD/2022/visualizations/fonts/caskaydia.otf -------------------------------------------------------------------------------- /2022/visualizations/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": ["ES2021", "DOM"], 4 | "target": "ESNext" 5 | } 6 | } -------------------------------------------------------------------------------- /2022/src/01/test.txt: -------------------------------------------------------------------------------- 1 | 1000 2 | 2000 3 | 3000 4 | 5 | 4000 6 | 7 | 5000 8 | 6000 9 | 10 | 7000 11 | 8000 12 | 9000 13 | 14 | 10000 -------------------------------------------------------------------------------- /2021/25/test.txt: -------------------------------------------------------------------------------- 1 | v...>>.vv> 2 | .vv>>.vv.. 3 | >>.>v>...v 4 | >>v>>.>.v. 5 | v>v.vv.v.. 6 | >.>>..v... 7 | .vv..>.>v. 8 | v.v..>>v.v 9 | ....v..v.> -------------------------------------------------------------------------------- /2021/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "@types/node": "^16.11.9", 4 | "gpu": "^1.0.0", 5 | "gpu.js": "^2.11.4" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /2021/11/in.txt: -------------------------------------------------------------------------------- 1 | 2478668324 2 | 4283474125 3 | 1663463374 4 | 1738271323 5 | 4285744861 6 | 3551311515 7 | 8574335438 8 | 7843525826 9 | 1366237577 10 | 3554687226 -------------------------------------------------------------------------------- /2021/11/test.txt: -------------------------------------------------------------------------------- 1 | 5483143223 2 | 2745854711 3 | 5264556173 4 | 6141336146 5 | 6357385478 6 | 4167524645 7 | 2176841721 8 | 6882881134 9 | 4846848554 10 | 5283751526 -------------------------------------------------------------------------------- /2021/15/test.txt: -------------------------------------------------------------------------------- 1 | 1163751742 2 | 1381373672 3 | 2136511328 4 | 3694931569 5 | 7463417111 6 | 1319128137 7 | 1359912421 8 | 3125421639 9 | 1293138521 10 | 2311944581 -------------------------------------------------------------------------------- /2022/src/05/test.txt: -------------------------------------------------------------------------------- 1 | [D] 2 | [N] [C] 3 | [Z] [M] [P] 4 | 1 2 3 5 | 6 | move 1 from 2 to 1 7 | move 3 from 1 to 3 8 | move 2 from 2 to 1 9 | move 1 from 1 to 2 -------------------------------------------------------------------------------- /2022/README.md: -------------------------------------------------------------------------------- 1 | # Advent of Code 202 2 | ## Typescript solutions + Visualisations 3 | 4 | https://adventofcode.com/2022 5 | 6 | Visualisations at https://vikithedev.eu/aoc/2022 7 | -------------------------------------------------------------------------------- /2022/src/03/test.txt: -------------------------------------------------------------------------------- 1 | vJrwpWtwJgWrhcsFMMfFFhFp 2 | jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL 3 | PmmdzqPrVvPwwTWBwg 4 | wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn 5 | ttgJtRGJQctTZtZT 6 | CrZsJsPPZsGzwwsLwLmpwMDw -------------------------------------------------------------------------------- /2021/13/test.txt: -------------------------------------------------------------------------------- 1 | 6,10 2 | 0,14 3 | 9,10 4 | 0,3 5 | 10,4 6 | 4,11 7 | 6,0 8 | 6,12 9 | 4,1 10 | 0,13 11 | 10,12 12 | 3,4 13 | 3,0 14 | 8,4 15 | 1,10 16 | 2,14 17 | 8,10 18 | 9,0 19 | 20 | fold along y=7 21 | fold along x=5 -------------------------------------------------------------------------------- /2021/14/test.txt: -------------------------------------------------------------------------------- 1 | NNCB 2 | 3 | CH -> B 4 | HH -> N 5 | CB -> H 6 | NH -> C 7 | HB -> C 8 | HC -> B 9 | HN -> C 10 | NN -> C 11 | BH -> H 12 | NC -> B 13 | NB -> B 14 | BN -> B 15 | BB -> N 16 | BC -> B 17 | CC -> N 18 | CN -> C -------------------------------------------------------------------------------- /2021/other/random_number_grid.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | grid_height = 45 4 | grid_width = 45 5 | 6 | for i in range(grid_height): 7 | for j in range(grid_width): 8 | print(random.randint(0, 9), end='') 9 | print() 10 | -------------------------------------------------------------------------------- /2021/visualizations/13/data.txt: -------------------------------------------------------------------------------- 1 | 6,10 2 | 0,14 3 | 9,10 4 | 0,3 5 | 10,4 6 | 4,11 7 | 6,0 8 | 6,12 9 | 4,1 10 | 0,13 11 | 10,12 12 | 3,4 13 | 3,0 14 | 8,4 15 | 1,10 16 | 2,14 17 | 8,10 18 | 9,0 19 | 20 | fold along y=7 21 | fold along x=5 -------------------------------------------------------------------------------- /2021/12/in.txt: -------------------------------------------------------------------------------- 1 | GC-zi 2 | end-zv 3 | lk-ca 4 | lk-zi 5 | GC-ky 6 | zi-ca 7 | end-FU 8 | iv-FU 9 | lk-iv 10 | lk-FU 11 | GC-end 12 | ca-zv 13 | lk-GC 14 | GC-zv 15 | start-iv 16 | zv-QQ 17 | ca-GC 18 | ca-FU 19 | iv-ca 20 | start-lk 21 | zv-FU 22 | start-zi -------------------------------------------------------------------------------- /2021/visualizations/12/data.txt: -------------------------------------------------------------------------------- 1 | GC-zi 2 | end-zv 3 | lk-ca 4 | lk-zi 5 | GC-ky 6 | zi-ca 7 | end-FU 8 | iv-FU 9 | lk-iv 10 | lk-FU 11 | GC-end 12 | ca-zv 13 | lk-GC 14 | GC-zv 15 | start-iv 16 | zv-QQ 17 | ca-GC 18 | ca-FU 19 | iv-ca 20 | start-lk 21 | zv-FU 22 | start-zi -------------------------------------------------------------------------------- /2022/visualizations/13/13.css: -------------------------------------------------------------------------------- 1 | .packet { 2 | display: flex; 3 | } 4 | 5 | .number { 6 | color: #fff; 7 | } 8 | 9 | .number.active { 10 | color: #f1c40f; 11 | } 12 | 13 | .symbol { 14 | color: #777; 15 | } 16 | 17 | .symbol.active { 18 | color: #f1c40f; 19 | } -------------------------------------------------------------------------------- /2021/10/test.txt: -------------------------------------------------------------------------------- 1 | [({(<(())[]>[[{[]{<()<>> 2 | [(()[<>])]({[<{<<[]>>( 3 | {([(<{}[<>[]}>{[]{[(<()> 4 | (((({<>}<{<{<>}{[]{[]{} 5 | [[<[([]))<([[{}[[()]]] 6 | [{[{({}]{}}([{[{{{}}([] 7 | {<[[]]>}<{[{[{[]{()[[[] 8 | [<(<(<(<{}))><([]([]() 9 | <{([([[(<>()){}]>(<<{{ 10 | <{([{{}}[<[[[<>{}]]]>[]] -------------------------------------------------------------------------------- /2023/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aoc-2023", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "dependencies": { 7 | "@types/node": "^20.10.1", 8 | "cli-table3": "^0.6.3", 9 | "prettier": "^3.1.0", 10 | "ts-node": "^10.9.1" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /2021/visualizations/10/data.txt: -------------------------------------------------------------------------------- 1 | [({(<(())[]>[[{[]{<()<>> 2 | [(()[<>])]({[<{<<[]>>( 3 | {([(<{}[<>[]}>{[]{[(<()> 4 | (((({<>}<{<{<>}{[]{[]{} 5 | [[<[([]))<([[{}[[()]]] 6 | [{[{({}]{}}([{[{{{}}([] 7 | {<[[]]>}<{[{[{[]{()[[[] 8 | [<(<(<(<{}))><([]([]() 9 | <{([([[(<>()){}]>(<<{{ 10 | <{([{{}}[<[[[<>{}]]]>[]] -------------------------------------------------------------------------------- /2022/src/07/test.txt: -------------------------------------------------------------------------------- 1 | $ cd / 2 | $ ls 3 | dir a 4 | 14848514 b.txt 5 | 8504156 c.dat 6 | dir d 7 | $ cd a 8 | $ ls 9 | dir e 10 | 29116 f 11 | 2557 g 12 | 62596 h.lst 13 | $ cd e 14 | $ ls 15 | 584 i 16 | $ cd .. 17 | $ cd .. 18 | $ cd d 19 | $ ls 20 | 4060174 j 21 | 8033020 d.log 22 | 5626152 d.ext 23 | 7214296 k -------------------------------------------------------------------------------- /2021/01/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let prev = null; 5 | let bigger = 0; 6 | while (input.hasNext()) { 7 | let num = +input.next()!; 8 | if (prev !== null && num > prev) { 9 | bigger++; 10 | } 11 | prev = num; 12 | } 13 | 14 | console.log(bigger); 15 | -------------------------------------------------------------------------------- /2021/visualizations/10/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #121212; 3 | color: #fff; 4 | font-family: "consolas", monospace; 5 | } 6 | 7 | .character, 8 | .s { 9 | color: grey; 10 | } 11 | 12 | .wrong { 13 | color: #e74c3c; 14 | } 15 | 16 | .score { 17 | color: #27ae60; 18 | display: inline-block; 19 | margin-left: 0.5rem; 20 | } 21 | -------------------------------------------------------------------------------- /2022/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Current TS File", 6 | "type": "node", 7 | "request": "launch", 8 | "args": ["${relativeFile}"], 9 | "runtimeArgs": ["--nolazy", "-r", "ts-node/register"], 10 | "sourceMaps": true, 11 | "cwd": "${workspaceRoot}", 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /2021/18/test.txt: -------------------------------------------------------------------------------- 1 | [[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]] 2 | [[[5,[2,8]],4],[5,[[9,9],0]]] 3 | [6,[[[6,2],[5,6]],[[7,6],[4,7]]]] 4 | [[[6,[0,7]],[0,9]],[4,[9,[9,0]]]] 5 | [[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]] 6 | [[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]] 7 | [[[[5,4],[7,7]],8],[[8,3],8]] 8 | [[9,3],[[9,9],[6,[4,9]]]] 9 | [[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]] 10 | [[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]] -------------------------------------------------------------------------------- /2022/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aoc-2022", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "commonjs", 7 | "scripts": { 8 | "init": "tsc --init", 9 | "build": "tsc" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@types/node": "^18.11.10", 15 | "ts-node": "^10.9.1", 16 | "typescript": "^4.9.3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /2022/src/01/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("src/01/input.txt"); 4 | 5 | const elves = []; 6 | let i = 0; 7 | 8 | while (inputParser.hasNext()) { 9 | const number = inputParser.nextNumber(); 10 | if (!number) { 11 | i++; 12 | } else { 13 | if (!elves[i]) elves[i] = 0; 14 | elves[i] += number; 15 | debugger; 16 | } 17 | } 18 | 19 | console.log(Math.max(...elves)); 20 | -------------------------------------------------------------------------------- /2022/src/04/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | let score = 0; 6 | 7 | while (inputParser.hasNext()) { 8 | const [[idA1, idA2], [idB1, idB2]] = inputParser 9 | .next()! 10 | .split(",") 11 | .map((ids) => ids.split("-").map(Number)); 12 | 13 | if ((idA1 <= idB1 && idA2 >= idB2) || (idB1 <= idA1 && idB2 >= idA2)) score++; 14 | } 15 | 16 | console.log(score); 17 | -------------------------------------------------------------------------------- /2023/src/15/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const toHash = parser.next()!.split(","); 6 | 7 | let sum = 0; 8 | 9 | for (const str of toHash) { 10 | let currentValue = 0; 11 | 12 | for (const char of str) { 13 | currentValue += char.charCodeAt(0); 14 | currentValue *= 17; 15 | currentValue %= 256; 16 | } 17 | 18 | sum += currentValue; 19 | } 20 | 21 | console.log(sum); 22 | -------------------------------------------------------------------------------- /2021/visualizations/15/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | font-family: "consolas", monospace; 3 | color: #fff; 4 | background-color: #121212; 5 | } 6 | 7 | .weight { 8 | display: inline-block; 9 | width: 2rem; 10 | color: #3498db; 11 | } 12 | 13 | .visiting { 14 | color: #e74c3c; 15 | } 16 | 17 | .visiting-h { 18 | color: #f1c40f; 19 | } 20 | 21 | .done .character:not(.path) { 22 | opacity: 0.2; 23 | transition: 0.5s; 24 | } 25 | 26 | .path { 27 | color: #f1c40f; 28 | } 29 | -------------------------------------------------------------------------------- /2021/01/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let data = input.getFullInput().split("\r\n").map(Number); 5 | 6 | let bigger = 0; 7 | let last: number | null = null; 8 | 9 | data.forEach((number, index) => { 10 | if (index >= data.length - 2) return; 11 | const sum = number + data[index + 1] + data[index + 2]; 12 | if (last !== null && sum > last) { 13 | bigger++; 14 | } 15 | last = sum; 16 | }); 17 | 18 | console.log(bigger); 19 | -------------------------------------------------------------------------------- /2021/visualizations/15/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
[start]
14 | 15 | 16 | -------------------------------------------------------------------------------- /2021/08/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("08/in.txt"); 4 | let numbers = 0; 5 | 6 | const data = input.getFullInput().split("\n"); 7 | data.forEach((d) => { 8 | const [_, digits] = d.split(" | "); 9 | digits.split(" ").forEach((str) => { 10 | switch (str.length) { 11 | case 2: 12 | case 4: 13 | case 3: 14 | case 7: 15 | numbers++; 16 | break; 17 | 18 | default: 19 | break; 20 | } 21 | }); 22 | }); 23 | console.log(numbers); 24 | -------------------------------------------------------------------------------- /2021/20/test.txt: -------------------------------------------------------------------------------- 1 | ..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..###..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###.######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#..#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#......#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#.....####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.......##..####..#...#.#.#...##..#.#..###..#####........#..####......#..# 2 | 3 | #..#. 4 | #.... 5 | ##..# 6 | ..#.. 7 | ..### -------------------------------------------------------------------------------- /2022/src/06/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | const parser = new InputParser("in.txt"); 3 | 4 | const line = parser.next()!; 5 | 6 | const last = new Array(14).fill(""); 7 | 8 | let i = 0; 9 | 10 | for (const char of line) { 11 | i++; 12 | last.shift(); 13 | last.push(char); 14 | 15 | const s: string[] = []; 16 | // check for duplicates 17 | for (const c of last) { 18 | if (s.includes(c) || c == "") continue; 19 | else s.push(c); 20 | } 21 | 22 | if (s.length == last.length) break; 23 | } 24 | 25 | console.log(i); 26 | -------------------------------------------------------------------------------- /2021/visualizations/11/styles.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #121212; 3 | color: #fff; 4 | font-family: "consolas", monospace; 5 | } 6 | 7 | .character { 8 | display: inline-flex; 9 | align-items: center; 10 | justify-content: center; 11 | width: 1.2rem; 12 | height: 1rem; 13 | color: grey; 14 | transition: 0.2s; 15 | } 16 | 17 | .flex { 18 | display: flex; 19 | gap: 1rem; 20 | } 21 | 22 | .n { 23 | color: #3498db; 24 | } 25 | 26 | #run { 27 | color: #3498db; 28 | cursor: pointer; 29 | } 30 | 31 | #run:hover { 32 | color: #2980b9; 33 | } 34 | -------------------------------------------------------------------------------- /2022/src/04/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | let score = 0; 6 | 7 | while (inputParser.hasNext()) { 8 | const [[idA1, idA2], [idB1, idB2]] = inputParser 9 | .next()! 10 | .split(",") 11 | .map((ids) => ids.split("-").map(Number)); 12 | 13 | if ( 14 | (idB1 >= idA1 && idB1 <= idA2) || 15 | (idA1 >= idB1 && idA1 <= idB1) || 16 | (idA2 >= idB1 && idA2 <= idB2) || 17 | (idB2 >= idA1 && idB2 <= idA2) 18 | ) { 19 | score++; 20 | } 21 | } 22 | 23 | console.log(score); 24 | -------------------------------------------------------------------------------- /2022/src/06/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | const parser = new InputParser("in.txt"); 3 | 4 | const line = parser.next()!; 5 | 6 | const lastFour = ["", "", "", ""]; 7 | 8 | let i = 0; 9 | 10 | for (const char of line) { 11 | i++; 12 | lastFour.shift(); 13 | lastFour.push(char); 14 | 15 | const s: string[] = []; 16 | // check for duplicates 17 | for (const c of lastFour) { 18 | if (s.includes(c) || c == "") continue; 19 | else s.push(c); 20 | } 21 | 22 | if (s.length == lastFour.length) break; 23 | } 24 | 25 | console.log(i, lastFour); 26 | -------------------------------------------------------------------------------- /2021/06/in.txt: -------------------------------------------------------------------------------- 1 | 3,5,2,5,4,3,2,2,3,5,2,3,2,2,2,2,3,5,3,5,5,2,2,3,4,2,3,5,5,3,3,5,2,4,5,4,3,5,3,2,5,4,1,1,1,5,1,4,1,4,3,5,2,3,2,2,2,5,2,1,2,2,2,2,3,4,5,2,5,4,1,3,1,5,5,5,3,5,3,1,5,4,2,5,3,3,5,5,5,3,2,2,1,1,3,2,1,2,2,4,3,4,1,3,4,1,2,2,4,1,3,1,4,3,3,1,2,3,1,3,4,1,1,2,5,1,2,1,2,4,1,3,2,1,1,2,4,3,5,1,3,2,1,3,2,3,4,5,5,4,1,3,4,1,2,3,5,2,3,5,2,1,1,5,5,4,4,4,5,3,3,2,5,4,4,1,5,1,5,5,5,2,2,1,2,4,5,1,2,1,4,5,4,2,4,3,2,5,2,2,1,4,3,5,4,2,1,1,5,1,4,5,1,2,5,5,1,4,1,1,4,5,2,5,3,1,4,5,2,1,3,1,3,3,5,5,1,4,1,3,2,2,3,5,4,3,2,5,1,1,1,2,2,5,3,4,2,1,3,2,5,3,2,2,3,5,2,1,4,5,4,4,5,5,3,3,5,4,5,5,4,3,5,3,5,3,1,3,2,2,1,4,4,5,2,2,4,2,1,4 -------------------------------------------------------------------------------- /2021/07/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const positions = input.getFullInput().split(",").map(Number); 5 | positions.sort((a, b) => a - b); 6 | 7 | let currentPosition = positions[0]; 8 | 9 | let fuels = []; 10 | 11 | for (let i = 1; i < positions.length; i++) { 12 | let sum = 0; 13 | positions.forEach((position) => { 14 | sum += Math.abs(position - currentPosition); 15 | }); 16 | 17 | fuels.push(sum); 18 | currentPosition = positions[i]; 19 | } 20 | 21 | fuels.sort((a, b) => a - b); 22 | console.log(fuels[0]); 23 | -------------------------------------------------------------------------------- /2021/02/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let horizontalPosition = 0; 5 | let verticalPosition = 0; 6 | 7 | while (input.hasNext()) { 8 | const line = input.next()!; 9 | 10 | const [dir, am] = line.split(" "); 11 | const amount = +am; 12 | 13 | if (dir === "forward") { 14 | horizontalPosition += amount; 15 | } 16 | 17 | if (dir === "down") { 18 | verticalPosition += amount; 19 | } 20 | 21 | if (dir === "up") { 22 | verticalPosition -= amount; 23 | } 24 | } 25 | 26 | console.log(horizontalPosition, verticalPosition); 27 | -------------------------------------------------------------------------------- /2022/visualizations/14/14.css: -------------------------------------------------------------------------------- 1 | .grid-wrapper { 2 | position: relative; 3 | } 4 | 5 | .row { 6 | display: flex; 7 | } 8 | 9 | .cell { 10 | width: 1.2rem; 11 | height: 1.2rem; 12 | display: flex; 13 | align-items: center; 14 | justify-content: center; 15 | 16 | color: #777; 17 | } 18 | 19 | .sand { 20 | color: #f1c40f; 21 | position: absolute; 22 | transition: .2s; 23 | 24 | width: 1.2rem; 25 | height: 1.2rem; 26 | display: flex; 27 | align-items: center; 28 | justify-content: center; 29 | } 30 | 31 | .sand.end { 32 | opacity: 0; 33 | } 34 | 35 | span { 36 | color: #f1c40f; 37 | } -------------------------------------------------------------------------------- /2021/visualizations/13/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
[start]
16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /2023/src/01/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | let sum = 0; 4 | 5 | const parser = new InputParser("input.txt"); 6 | while (parser.hasNext()) { 7 | const string = parser.next()!; 8 | 9 | let number = 0; 10 | 11 | for (let i = 0; i < string.length; i++) { 12 | if (!isNaN(+string[i])) { 13 | number += +string[i] * 10; 14 | break; 15 | } 16 | } 17 | 18 | for (let i = string.length - 1; i >= 0; i--) { 19 | if (!isNaN(+string[i])) { 20 | number += +string[i]; 21 | break; 22 | } 23 | } 24 | 25 | sum += number; 26 | } 27 | 28 | console.log(sum); 29 | -------------------------------------------------------------------------------- /2022/visualizations/08/08.css: -------------------------------------------------------------------------------- 1 | .col { 2 | color: #777; 3 | margin-right: .6rem; 4 | transition: .05s; 5 | } 6 | 7 | .col:last-child { 8 | margin-right: 0; 9 | } 10 | 11 | .row { 12 | display: flex; 13 | } 14 | 15 | textarea{ 16 | /* white-space: nowrap; */ 17 | } 18 | 19 | .visible, .selected { 20 | color: #f1c40f; 21 | } 22 | 23 | .viewing { 24 | color: #fff; 25 | } 26 | 27 | .grid-wrapper { 28 | position: relative; 29 | } 30 | 31 | .eye { 32 | position: absolute; 33 | transition: .2s; 34 | display: none; 35 | } 36 | 37 | #output { 38 | margin-top: 1rem; 39 | } 40 | 41 | .output-text{ 42 | width: 100%; 43 | } -------------------------------------------------------------------------------- /2021/02/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let horizontalPosition = 0; 5 | let verticalPosition = 0; 6 | let aim = 0; 7 | 8 | while (input.hasNext()) { 9 | const line = input.next()!; 10 | 11 | const [dir, am] = line.split(" "); 12 | const amount = +am; 13 | 14 | if (dir === "forward") { 15 | horizontalPosition += amount; 16 | verticalPosition += aim * amount; 17 | } 18 | 19 | if (dir === "down") { 20 | aim += amount; 21 | } 22 | 23 | if (dir === "up") { 24 | aim -= amount; 25 | } 26 | } 27 | 28 | console.log(horizontalPosition * verticalPosition); 29 | -------------------------------------------------------------------------------- /2022/visualizations/06/06.css: -------------------------------------------------------------------------------- 1 | .characters { 2 | display: flex; 3 | margin-bottom: 1rem; 4 | } 5 | 6 | #row { 7 | white-space: nowrap; 8 | } 9 | 10 | .char { 11 | display: inline-block; 12 | transition: .1s; 13 | width: .8rem; 14 | } 15 | 16 | .char.active{ 17 | color: #3498db; 18 | } 19 | 20 | .char.removing { 21 | color: transparent; 22 | width: 0; 23 | transform: translateX(-100%); 24 | } 25 | 26 | #counter { 27 | color: #777; 28 | margin-right: 1rem; 29 | } 30 | 31 | #part1-win, 32 | #part2-win { 33 | color: #777; 34 | margin-right: 1rem; 35 | } 36 | 37 | #part1-score, 38 | #part2-score { 39 | color: #f1c40f; 40 | } -------------------------------------------------------------------------------- /2022/visualizations/05/05.css: -------------------------------------------------------------------------------- 1 | #grid { 2 | display: flex; 3 | align-items: flex-end; 4 | gap: 1rem; 5 | margin-bottom: 1rem; 6 | } 7 | 8 | .stack-number { 9 | color: #777; 10 | } 11 | 12 | .stack-item{ 13 | position: absolute; 14 | transition: .5s; 15 | } 16 | 17 | .slot { 18 | animation: .2s grow forwards; 19 | } 20 | 21 | .move { 22 | color: #777; 23 | transition: .5s; 24 | } 25 | 26 | .active { 27 | color: #fff; 28 | } 29 | 30 | .end { 31 | color: #777; 32 | } 33 | 34 | .end .result { 35 | color: #3498db; 36 | } 37 | 38 | @keyframes grow { 39 | from { 40 | height: 0; 41 | } 42 | 43 | to { 44 | height: 1.5rem; 45 | } 46 | } -------------------------------------------------------------------------------- /2023/src/06/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const t_m = +parser.next()!.replaceAll(" ", "").match(/\d+/gm)!; 6 | 7 | const x = +parser.next()!.replaceAll(" ", "").match(/\d+/gm)!; 8 | 9 | let d = t_m ** 2 - 4 * x; 10 | 11 | let t_1 = (t_m - Math.sqrt(d)) / 2; 12 | let t_2 = (t_m + Math.sqrt(d)) / 2; 13 | 14 | let t_min = Math.ceil(t_1); 15 | let t_max = Math.floor(t_2); 16 | 17 | if (t_min == t_1) t_min++; 18 | if (t_max == t_2) t_max--; 19 | 20 | let possibilites = t_max - t_min + 1; 21 | console.log("Calculated for", t_m, x, "->", t_min, t_max); 22 | 23 | console.log("Number of possibilities:", possibilites); 24 | -------------------------------------------------------------------------------- /2022/src/01/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("src/01/input.txt"); 4 | 5 | const elves = []; 6 | let i = 0; 7 | 8 | while (inputParser.hasNext()) { 9 | const number = inputParser.nextNumber(); 10 | if (!number) { 11 | i++; 12 | } else { 13 | if (!elves[i]) elves[i] = 0; 14 | elves[i] += number; 15 | } 16 | } 17 | 18 | const three_largest = [0, 0, 0]; 19 | 20 | for (const elf of elves) { 21 | if (elf > Math.min(...three_largest)) { 22 | three_largest.push(elf); 23 | three_largest.sort((a, b) => b - a); 24 | three_largest.pop(); 25 | } 26 | } 27 | 28 | console.log(three_largest.reduce((a, b) => a + b, 0)); 29 | -------------------------------------------------------------------------------- /2023/src/04/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | const parser = new InputParser("input.txt"); 3 | 4 | let sum = 0; 5 | 6 | while (parser.hasNext()) { 7 | const line = parser.next()!; 8 | 9 | let score = 0; 10 | 11 | const [, winningStr, inclStr] = line.split(/:|\|/); 12 | const winning = winningStr 13 | .split(" ") 14 | .map((n) => parseInt(n)) 15 | .filter((n) => !isNaN(n)); 16 | const incl = inclStr 17 | .split(" ") 18 | .map((n) => parseInt(n)) 19 | .filter((n) => !isNaN(n)); 20 | 21 | for (let number of winning) { 22 | if (incl.includes(number)) score ? (score *= 2) : (score = 1); 23 | } 24 | 25 | sum += score; 26 | } 27 | 28 | console.log(sum); 29 | -------------------------------------------------------------------------------- /2021/visualizations/09/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Advent Of Code 2021 | Day 09 10 | 11 | 12 |
13 |
14 |
15 | Top besins 16 | 17 |
18 |
19 |
[run]
20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /2021/visualizations/14/styles.css: -------------------------------------------------------------------------------- 1 | .node { 2 | position: absolute; 3 | } 4 | 5 | body { 6 | background-color: #121212; 7 | color: #fff; 8 | font-family: "Consolas", monospace; 9 | overflow: hidden; 10 | } 11 | 12 | .point { 13 | display: inline-block; 14 | transition: 0.5s transform, 0.5s font-size; 15 | } 16 | 17 | #start { 18 | color: #3498db; 19 | cursor: pointer; 20 | } 21 | 22 | .flex { 23 | display: flex; 24 | gap: 2rem; 25 | } 26 | 27 | .chart { 28 | width: 60rem; 29 | } 30 | 31 | .letter { 32 | font-size: 2rem; 33 | } 34 | 35 | .number { 36 | color: #3498db; 37 | } 38 | 39 | .steps { 40 | color: #d35400; 41 | font-size: 2rem; 42 | } 43 | 44 | .dynout { 45 | color: #f1c40f; 46 | } 47 | -------------------------------------------------------------------------------- /2021/07/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const positions = input.getFullInput().split(",").map(Number); 5 | positions.sort((a, b) => a - b); 6 | 7 | const getFuel = (delta: number) => { 8 | let fuel = 0; 9 | for (let i = 1; i < delta + 1; i++) { 10 | fuel += i; 11 | } 12 | return fuel; 13 | }; 14 | 15 | let fuels = []; 16 | 17 | const min = positions[0]; 18 | const max = positions[positions.length - 1]; 19 | 20 | for (let i = min; i <= max; i++) { 21 | let sum = 0; 22 | positions.forEach((position) => { 23 | sum += getFuel(Math.abs(position - i)); 24 | }); 25 | 26 | fuels.push(sum); 27 | } 28 | 29 | fuels.sort((a, b) => a - b); 30 | console.log(fuels[0]); 31 | -------------------------------------------------------------------------------- /2021/06/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const lanterFish = input.getFullInput().split(",").map(Number); 6 | console.log(lanterFish); 7 | 8 | let simulationLength = 80; 9 | 10 | const runSimulation = () => { 11 | let add = 0; 12 | for (let i = 0; i < lanterFish.length; i++) { 13 | const current = lanterFish[i]; 14 | if (current === 0) { 15 | add++; 16 | lanterFish[i] = 6; 17 | } else { 18 | lanterFish[i] = current - 1; 19 | } 20 | } 21 | 22 | for (let i = 0; i < add; i++) { 23 | lanterFish.push(8); 24 | } 25 | }; 26 | 27 | for (let i = 0; i < simulationLength; i++) { 28 | runSimulation(); 29 | } 30 | 31 | console.log(lanterFish.length); 32 | -------------------------------------------------------------------------------- /2021/visualizations/11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Advent Of Code 2021 | Day 10 10 | 11 | 12 |
13 |
14 |
15 |
Steps: 0
16 |
Flashes: 0
17 |
18 |
[run]
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /2021/03/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const data = input.getFullInput().split("\r\n"); 5 | 6 | let gamma = ""; 7 | let epsilon = ""; 8 | 9 | const bin2dec = (bin: string) => { 10 | return parseInt(bin, 2); 11 | }; 12 | 13 | const getMostcommonBitAtColumnd = (col: number) => { 14 | let zeros = 0; 15 | let ones = 0; 16 | 17 | data.forEach((row) => { 18 | if (row[col] === "0") zeros++; 19 | else ones++; 20 | }); 21 | 22 | if (zeros > ones) { 23 | gamma += "0"; 24 | epsilon += "1"; 25 | } else { 26 | gamma += "1"; 27 | epsilon += "0"; 28 | } 29 | }; 30 | 31 | for (let i = 0; i < data[0].length; i++) { 32 | getMostcommonBitAtColumnd(i); 33 | } 34 | 35 | console.log(bin2dec(gamma) * bin2dec(epsilon)); 36 | -------------------------------------------------------------------------------- /2021/visualizations/10/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Advent Of Code 2021 | Day 10 10 | 11 | 12 |
13 |
14 |
15 |
Current Stack
16 |
17 | 18 |
Part 1:
19 |
Part 2:
20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /2022/src/03/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | // "a".charCodeAt(0) // 97 6 | // "z".charCodeAt(0) // 122 7 | // "A".charCodeAt(0) // 65 8 | // "Z".charCodeAt(0) // 90 9 | 10 | let score = 0; 11 | 12 | while (inputParser.hasNext()) { 13 | const group: string[] = []; 14 | 15 | for (let i = 0; i < 3; i++) group.push(inputParser.next()!); 16 | 17 | let charCode = 0; 18 | 19 | for (const char of group[0]) { 20 | if (!group.every((t) => t.includes(char))) continue; 21 | 22 | charCode = char.charCodeAt(0); 23 | break; 24 | } 25 | 26 | if (charCode >= 97 && charCode <= 122) { 27 | score += charCode - 96; 28 | } else if (charCode >= 65 && charCode <= 90) { 29 | score += charCode - 38; 30 | } 31 | } 32 | 33 | console.log(score); 34 | -------------------------------------------------------------------------------- /2021/files.ts: -------------------------------------------------------------------------------- 1 | import fs from "fs"; 2 | 3 | export class InputParser { 4 | private lines: string[]; 5 | private linesRead: number = 0; 6 | 7 | constructor(filename: string) { 8 | console.log(`Loading file ${filename} as input`); 9 | const file = fs.readFileSync(filename, "utf8"); 10 | console.log(`File loaded!`); 11 | this.lines = file.split("\n").filter((line) => line); 12 | } 13 | 14 | public next(): string | null { 15 | if (this.linesRead >= this.lines.length) { 16 | return null; 17 | } 18 | const line = this.lines[this.linesRead]; 19 | this.linesRead++; 20 | return line.replace("\r", ""); 21 | } 22 | 23 | public hasNext(): boolean { 24 | return this.linesRead < this.lines.length; 25 | } 26 | 27 | public getFullInput(): string { 28 | return this.lines.join("\n"); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /2023/src/02/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | let sum = 0; 4 | 5 | const maxConfigurations: { [s: string]: number } = { 6 | red: 12, 7 | green: 13, 8 | blue: 14, 9 | }; 10 | 11 | const parser = new InputParser("input.txt"); 12 | while (parser.hasNext()) { 13 | const string = parser.next()!; 14 | const [gameId, gameStatus] = string.split(": "); 15 | const [, gameIdNumber] = gameId.split(" "); 16 | 17 | const games = gameStatus.split("; "); 18 | 19 | let possible = true; 20 | 21 | for (const game of games) { 22 | const rounds = game.split(", "); 23 | for (const round of rounds) { 24 | const [number, color] = round.split(" "); 25 | if (+number > maxConfigurations[color]) possible = false; 26 | } 27 | } 28 | 29 | if (possible) sum += +gameIdNumber; 30 | } 31 | 32 | console.log(sum); 33 | -------------------------------------------------------------------------------- /2022/src/02/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("in.txt"); 4 | 5 | // X beats C 6 | // Y beats A 7 | // Z beats B 8 | 9 | type PlayerMove = "X" | "Y" | "Z"; 10 | 11 | const gameRules = { 12 | X: { 13 | beats: "C", 14 | draw: "A", 15 | score: 1, 16 | }, 17 | Y: { 18 | beats: "A", 19 | draw: "B", 20 | score: 2, 21 | }, 22 | Z: { 23 | beats: "B", 24 | draw: "C", 25 | score: 3, 26 | }, 27 | }; 28 | 29 | let score = 0; 30 | 31 | while (parser.hasNext()) { 32 | const [opponent, player] = parser.next()!.trim().split(" "); 33 | const movePlayed = gameRules[player as PlayerMove]; 34 | 35 | score += movePlayed.score; 36 | if (movePlayed.beats === opponent) score += 6; 37 | if (movePlayed.draw === opponent) score += 3; 38 | } 39 | 40 | console.log(score); 41 | -------------------------------------------------------------------------------- /2021/08/test.txt: -------------------------------------------------------------------------------- 1 | be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe 2 | edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc 3 | fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg 4 | fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb 5 | aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea 6 | fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb 7 | dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe 8 | bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef 9 | egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb 10 | gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce -------------------------------------------------------------------------------- /2023/src/08/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("test.txt"); 4 | 5 | const instructions = parser.next()!; 6 | 7 | parser.next(); 8 | 9 | const nodes: { [id: string]: [string, string] } = {}; 10 | 11 | while (parser.hasNext()) { 12 | const [id, left, right] = parser.next()!.match(/[A-Z]{3}/gm)!; 13 | nodes[id] = [left, right]; 14 | } 15 | 16 | let currentInstruction = 0; 17 | let currentNode = "AAA"; 18 | let steps = 0; 19 | 20 | while (currentNode !== "ZZZ") { 21 | let instr = instructions[currentInstruction]; 22 | steps++; 23 | 24 | if (instr === "L") currentNode = nodes[currentNode][0]; 25 | else currentNode = nodes[currentNode][1]; 26 | 27 | currentInstruction++; 28 | if (currentInstruction === instructions.length) currentInstruction = 0; 29 | } 30 | 31 | console.log("Number of steps:", steps); 32 | -------------------------------------------------------------------------------- /2022/visualizations/12/12.css: -------------------------------------------------------------------------------- 1 | 2 | .row { 3 | display: flex; 4 | } 5 | 6 | .cell { 7 | width: .9rem; 8 | height: 1.2rem; 9 | 10 | display: flex; 11 | align-items: center; 12 | justify-content: center; 13 | 14 | color: #777; 15 | 16 | transition: .3s; 17 | } 18 | 19 | .cell.start { 20 | color: #fff; 21 | } 22 | 23 | .cell.end { 24 | color: #fff; 25 | } 26 | 27 | .visited{ 28 | animation: visitedAnimation 5s forwards; 29 | } 30 | 31 | .line{ 32 | background-color: #f1c40f; 33 | position: absolute; 34 | height: 2px; 35 | transform-origin: left; 36 | } 37 | 38 | .line-2 { 39 | background-color: #e74c3c; 40 | 41 | } 42 | 43 | .grid-wrapper { 44 | position: relative; 45 | } 46 | 47 | @keyframes visitedAnimation { 48 | 0% { 49 | color: #777; 50 | } 51 | 5% { 52 | color: #fff; 53 | } 54 | 100% { 55 | color: #777; 56 | } 57 | } -------------------------------------------------------------------------------- /2022/visualizations/15/15.css: -------------------------------------------------------------------------------- 1 | .grid-wrapper { 2 | position: relative; 3 | } 4 | 5 | .row { 6 | display: flex; 7 | margin-bottom: .5rem; 8 | } 9 | 10 | .cell { 11 | width: 1.2rem; 12 | height: 1.2rem; 13 | display: flex; 14 | align-items: center; 15 | justify-content: center; 16 | border-radius: .2rem; 17 | 18 | margin-right: .5rem; 19 | color: #777; 20 | } 21 | 22 | .sand { 23 | color: #f1c40f; 24 | position: absolute; 25 | transition: .2s; 26 | 27 | width: 1.2rem; 28 | height: 1.2rem; 29 | display: flex; 30 | align-items: center; 31 | justify-content: center; 32 | } 33 | 34 | .sand.end { 35 | opacity: 0; 36 | } 37 | 38 | span { 39 | color: #f1c40f; 40 | } 41 | 42 | #bounds { 43 | position: absolute; 44 | top: 0; 45 | left: 0; 46 | width: 100%; 47 | height: 100%; 48 | border: 1px solid #fff; 49 | border-radius: .4rem; 50 | } -------------------------------------------------------------------------------- /2021/visualizations/12/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
[start]
17 |
Current path: 0
18 |
Possible paths: 0
19 |
20 |
21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /2022/src/03/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | // "a".charCodeAt(0) // 97 6 | // "z".charCodeAt(0) // 122 7 | // "A".charCodeAt(0) // 65 8 | // "Z".charCodeAt(0) // 90 9 | 10 | let score = 0; 11 | 12 | while (inputParser.hasNext()) { 13 | const line = inputParser.next()!; 14 | 15 | // Parsing the input 16 | const section1 = line.substring(0, line.length / 2); 17 | const section2 = line.substring(line.length / 2); 18 | 19 | let charCode = 0; 20 | 21 | for (let char of section2) { 22 | if (!section1.includes(char)) continue; 23 | 24 | charCode = char.charCodeAt(0); 25 | break; 26 | } 27 | 28 | if (charCode >= 97 && charCode <= 122) { 29 | score += charCode - 96; 30 | } else if (charCode >= 65 && charCode <= 90) { 31 | score += charCode - 38; 32 | } 33 | } 34 | 35 | console.log(score); 36 | -------------------------------------------------------------------------------- /2023/src/14/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const grid = parser.loadAsGrid(); 6 | 7 | let movedRocks = -1; 8 | 9 | while (movedRocks != 0) { 10 | movedRocks = 0; 11 | 12 | for (let y = 0; y < grid.length; y++) { 13 | for (let x = 0; x < grid[y].length; x++) { 14 | let v = grid[y][x]; 15 | 16 | if (v !== "O") continue; 17 | 18 | // check if we can move up 19 | if (y === 0) continue; 20 | 21 | if (grid[y - 1][x] === ".") { 22 | grid[y - 1][x] = "O"; 23 | grid[y][x] = "."; 24 | movedRocks++; 25 | } 26 | } 27 | } 28 | } 29 | 30 | let score = 0; 31 | 32 | for (let y = 0; y < grid.length; y++) { 33 | for (let x = 0; x < grid[y].length; x++) { 34 | if (grid[y][x] === "O") score += grid.length - y; 35 | } 36 | } 37 | 38 | console.log("Total load", score); 39 | -------------------------------------------------------------------------------- /2023/src/02/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | let sum = 0; 4 | 5 | const parser = new InputParser("input.txt"); 6 | while (parser.hasNext()) { 7 | const string = parser.next()!; 8 | const [gameId, gameStatus] = string.split(": "); 9 | const [, gameIdNumber] = gameId.split(" "); 10 | 11 | const maxPossible: { [s: string]: number } = { 12 | red: 0, 13 | green: 0, 14 | blue: 0, 15 | }; 16 | 17 | const games = gameStatus.split("; "); 18 | 19 | let possible = true; 20 | 21 | for (const game of games) { 22 | const rounds = game.split(", "); 23 | for (const round of rounds) { 24 | const [number, color] = round.split(" "); 25 | 26 | if (maxPossible[color] < +number) maxPossible[color] = +number; 27 | } 28 | } 29 | 30 | const gamePower = maxPossible.red * maxPossible.green * maxPossible.blue; 31 | 32 | sum += gamePower; 33 | } 34 | 35 | console.log(sum); 36 | -------------------------------------------------------------------------------- /2023/src/06/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("test.txt"); 4 | 5 | const times = parser 6 | .next()! 7 | .match(/\d+/gm)! 8 | .map((x) => parseInt(x)); 9 | 10 | const distances = parser 11 | .next()! 12 | .match(/\d+/gm)! 13 | .map((x) => parseInt(x)); 14 | 15 | let sum = 1; 16 | 17 | for (let i = 0; i < times.length; i++) { 18 | const t_m = times[i]; 19 | const x = distances[i]; 20 | 21 | let d = t_m ** 2 - 4 * x; 22 | 23 | let t_1 = (t_m - Math.sqrt(d)) / 2; 24 | let t_2 = (t_m + Math.sqrt(d)) / 2; 25 | 26 | let t_min = Math.ceil(t_1); 27 | let t_max = Math.floor(t_2); 28 | 29 | if (t_min == t_1) t_min++; 30 | if (t_max == t_2) t_max--; 31 | 32 | let possibilites = t_max - t_min + 1; 33 | console.log("Calculated for", t_m, x, "->", t_min, t_max, ":", possibilites); 34 | 35 | sum *= possibilites; 36 | } 37 | 38 | console.log("Final score:", sum); 39 | -------------------------------------------------------------------------------- /2023/src/12/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | let wholeSum = 0; 6 | 7 | while (parser.hasNext()) { 8 | const [string, numStr] = parser.next()!.split(" "); 9 | const numbers = numStr.split(",").map(Number); 10 | 11 | const tryCombination = (str: string): number => { 12 | if (!str.includes("?")) { 13 | const s = str.match(/#+/gm); 14 | 15 | if (s?.length !== numbers.length) return 0; 16 | 17 | for (let i = 0; i < s.length; i++) { 18 | if (s[i].length !== numbers[i]) return 0; 19 | } 20 | 21 | return 1; 22 | } 23 | 24 | const version1 = str.replace("?", "#"); 25 | const version2 = str.replace("?", "."); 26 | 27 | return tryCombination(version1) + tryCombination(version2); 28 | }; 29 | 30 | const sum = tryCombination(string); 31 | 32 | wholeSum += sum; 33 | } 34 | 35 | console.log("Answer:", wholeSum); 36 | -------------------------------------------------------------------------------- /2021/visualizations/13/styles.css: -------------------------------------------------------------------------------- 1 | .node { 2 | position: absolute; 3 | } 4 | 5 | body { 6 | background-color: #121212; 7 | color: #fff; 8 | font-family: "Consolas", monospace; 9 | overflow: hidden; 10 | } 11 | 12 | .point { 13 | display: inline-block; 14 | transition: 0.5s transform, 0.5s font-size; 15 | } 16 | 17 | #start { 18 | color: #3498db; 19 | cursor: pointer; 20 | } 21 | 22 | .flex { 23 | display: flex; 24 | gap: 2rem; 25 | } 26 | 27 | .character { 28 | color: grey; 29 | transition: 0.5s transform, 0.5s font-size; 30 | } 31 | 32 | .active { 33 | color: #d35400; 34 | } 35 | 36 | .active-row .character { 37 | color: #c0392b; 38 | } 39 | 40 | .copy-row .character { 41 | color: #f1c40f; 42 | } 43 | 44 | .copy-col.character, 45 | .copy-col.point { 46 | color: #e74c3c; 47 | } 48 | 49 | .active-col.character, 50 | .active-col.point { 51 | color: #c0392b; 52 | } 53 | 54 | .done .point, 55 | .done .character { 56 | font-size: 2rem; 57 | } 58 | -------------------------------------------------------------------------------- /2022/src/21/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | const monkeys: { [key: string]: string | number } = {}; 6 | 7 | while (inputParser.hasNext()) { 8 | const [monkeyId, value] = inputParser 9 | .next()! 10 | .split(": ") 11 | .map((s) => s.trim()); 12 | 13 | let v = isNaN(+value) ? value : +value; 14 | 15 | monkeys[monkeyId] = v; 16 | } 17 | 18 | const getValueOfMonkey = (id: string): number => { 19 | const value = monkeys[id]; 20 | if (typeof value === "number") { 21 | return +value; 22 | } 23 | 24 | const [monkey1, op, monkey2] = value.split(" "); 25 | 26 | const v1 = getValueOfMonkey(monkey1); 27 | const v2 = getValueOfMonkey(monkey2); 28 | 29 | if (op === "+") return v1 + v2; 30 | if (op === "-") return v1 - v2; 31 | if (op === "*") return v1 * v2; 32 | if (op === "/") return v1 / v2; 33 | return 0; 34 | }; 35 | 36 | console.log(getValueOfMonkey("root")); 37 | -------------------------------------------------------------------------------- /2023/src/09/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | let sum = 0; 6 | 7 | while (parser.hasNext()) { 8 | const arr = parser.nextNumberArray()!; 9 | const sequences = [arr]; 10 | 11 | let ind = 0; 12 | 13 | while (!sequences[sequences.length - 1].every((s) => s === 0)) { 14 | let currentSequence = sequences[ind]; 15 | ind++; 16 | 17 | let newSequence: number[] = []; 18 | for (let i = 1; i < currentSequence.length; i++) { 19 | newSequence.push(currentSequence[i] - currentSequence[i - 1]); 20 | } 21 | 22 | sequences.push(newSequence); 23 | } 24 | 25 | // work our way up 26 | sequences[sequences.length - 1].unshift(0); 27 | 28 | for (let i = sequences.length - 2; i >= 0; i--) { 29 | let newNum = sequences[i][0] - sequences[i + 1][0]; 30 | 31 | sequences[i].unshift(newNum); 32 | } 33 | 34 | sum += sequences[0][0]; 35 | } 36 | 37 | console.log("Sum:", sum); 38 | -------------------------------------------------------------------------------- /2021/09/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const grid = input 6 | .getFullInput() 7 | .split("\r\n") 8 | .map((row) => row.split("").map(Number)); 9 | 10 | const getLowPoints = (grid: number[][]) => { 11 | const lowPoints: number[] = []; 12 | 13 | grid.forEach((row, i) => { 14 | row.forEach((point, j) => { 15 | let lowest = true; 16 | 17 | if (i > 0 && grid[i - 1][j] <= point) lowest = false; 18 | if (i < grid.length - 1 && grid[i + 1][j] <= point) lowest = false; 19 | 20 | if (j > 0 && grid[i][j - 1] <= point) lowest = false; 21 | if (j < grid[i].length - 1 && grid[i][j + 1] <= point) lowest = false; 22 | 23 | if (lowest) lowPoints.push(point); 24 | }); 25 | }); 26 | 27 | return lowPoints; 28 | }; 29 | 30 | const lowPoints = getLowPoints(grid); 31 | let risk = 0; 32 | 33 | lowPoints.forEach((val) => { 34 | risk += val + 1; 35 | }); 36 | 37 | console.log(risk); 38 | -------------------------------------------------------------------------------- /2022/src/05/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | const parser = new InputParser("in.txt"); 3 | 4 | const init: string[] = []; 5 | const stacks: string[][] = []; 6 | 7 | // parsing the input 8 | while (parser.hasNext()) { 9 | const line = parser.next(); 10 | if (!line) break; 11 | 12 | init.push(line); 13 | } 14 | 15 | init.reverse(); 16 | 17 | for (let i = 0; i < init[0].length; i++) { 18 | const c = init[0][i]; 19 | if (c == " ") continue; 20 | 21 | const stack = []; 22 | 23 | for (let j = 1; j < init.length; j++) { 24 | if (init[j][i] == " ") break; 25 | stack.push(init[j][i]); 26 | } 27 | 28 | stacks.push(stack); 29 | } 30 | 31 | // doing the actual logic 32 | while (parser.hasNext()) { 33 | var [howMany, from, to] = parser.next()!.match(/\d+/g)!.map(Number); 34 | 35 | for (let i = 0; i < howMany; i++) 36 | stacks[to - 1].push(stacks[from - 1].pop()!); 37 | } 38 | 39 | console.log("Result:", stacks.map((s) => s[s.length - 1]).join("")); 40 | -------------------------------------------------------------------------------- /2023/src/09/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | let sum = 0; 6 | 7 | while (parser.hasNext()) { 8 | const arr = parser.nextNumberArray()!; 9 | const sequences = [arr]; 10 | 11 | let ind = 0; 12 | 13 | while (!sequences[sequences.length - 1].every((s) => s === 0)) { 14 | let currentSequence = sequences[ind]; 15 | ind++; 16 | 17 | let newSequence: number[] = []; 18 | for (let i = 1; i < currentSequence.length; i++) { 19 | newSequence.push(currentSequence[i] - currentSequence[i - 1]); 20 | } 21 | 22 | sequences.push(newSequence); 23 | } 24 | 25 | // work our way up 26 | sequences[sequences.length - 1].push(0); 27 | 28 | for (let i = sequences.length - 2; i >= 0; i--) { 29 | let newNum = sequences[i].at(-1)! + sequences[i + 1].at(-1)!; 30 | 31 | sequences[i].push(newNum); 32 | } 33 | 34 | sum += sequences[0].at(-1)!; 35 | } 36 | 37 | console.log("Sum:", sum); 38 | -------------------------------------------------------------------------------- /2021/visualizations/12/styles.css: -------------------------------------------------------------------------------- 1 | .node { 2 | position: absolute; 3 | } 4 | 5 | body { 6 | background-color: #121212; 7 | color: #fff; 8 | font-family: "Consolas", monospace; 9 | overflow: hidden; 10 | } 11 | 12 | .link { 13 | /* background-color: #ff000011; */ 14 | position: absolute; 15 | display: flex; 16 | align-items: center; 17 | justify-content: center; 18 | } 19 | 20 | .line { 21 | height: 2px; 22 | position: absolute; 23 | background-color: #3498db33; 24 | /* transition: 0.2s; */ 25 | } 26 | 27 | .node { 28 | padding: 0.25rem; 29 | } 30 | 31 | #current { 32 | position: relative; 33 | width: 66%; 34 | height: 90vh; 35 | } 36 | 37 | .number, 38 | .start, 39 | .end { 40 | color: #3498db; 41 | } 42 | 43 | .active { 44 | background-color: #3498db; 45 | } 46 | 47 | .current { 48 | background-color: #16a085; 49 | } 50 | 51 | .success { 52 | background-color: #2ecc71; 53 | } 54 | 55 | .flex { 56 | display: flex; 57 | } 58 | 59 | #start { 60 | color: #3498db; 61 | cursor: pointer; 62 | } 63 | -------------------------------------------------------------------------------- /2022/visualizations/05/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 05 10 | 11 | 12 |
13 |
14 | 21 |
22 | 23 |
24 |
25 | 26 |
27 |
28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /2022/src/05/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | const parser = new InputParser("in.txt"); 3 | 4 | const init: string[] = []; 5 | const stacks: string[][] = []; 6 | 7 | // parsing the input 8 | while (parser.hasNext()) { 9 | const line = parser.next(); 10 | if (!line) break; 11 | 12 | init.push(line); 13 | } 14 | 15 | init.reverse(); 16 | 17 | for (let i = 0; i < init[0].length; i++) { 18 | const c = init[0][i]; 19 | if (c == " ") continue; 20 | 21 | const stack = []; 22 | 23 | for (let j = 1; j < init.length; j++) { 24 | if (init[j][i] == " ") break; 25 | stack.push(init[j][i]); 26 | } 27 | 28 | stacks.push(stack); 29 | } 30 | 31 | // doing the actual logic 32 | while (parser.hasNext()) { 33 | var [howMany, from, to] = parser.next()!.match(/\d+/g)!.map(Number); 34 | 35 | const fromStack = stacks[from - 1]; 36 | const moving = fromStack.splice(fromStack.length - howMany); 37 | stacks[to - 1].push(...moving); 38 | } 39 | 40 | console.log("Result:", stacks.map((s) => s[s.length - 1]).join("")); 41 | -------------------------------------------------------------------------------- /2022/visualizations/09/09.css: -------------------------------------------------------------------------------- 1 | .row { 2 | display: flex; 3 | } 4 | 5 | .grid-wrapper { 6 | position: relative; 7 | } 8 | 9 | .cell { 10 | color: #777; 11 | padding: 0 .3rem; 12 | } 13 | 14 | .rope { 15 | color: #f1c40f; 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | 20 | transition: .2s; 21 | } 22 | 23 | .rope.hidden { 24 | opacity: 0; 25 | } 26 | 27 | .visited-1 { 28 | color: #e74c3c; 29 | } 30 | 31 | .visited-2 { 32 | color: #3498db; 33 | } 34 | 35 | .visited-1.visited-2 { 36 | color: #8e44ad; 37 | } 38 | 39 | .score { 40 | color: #777; 41 | } 42 | 43 | .score span { 44 | color: #f1c40f; 45 | } 46 | 47 | .output { 48 | display: flex; 49 | flex-direction: row; 50 | } 51 | 52 | .text{ 53 | margin-left: 1rem; 54 | } 55 | 56 | #instructions { 57 | margin-top: 1rem; 58 | color: #777; 59 | } 60 | 61 | .instruction { 62 | transition: .2s; 63 | height: 1.1rem; 64 | } 65 | 66 | .instruction.done { 67 | opacity: 0; 68 | height: 0; 69 | color: #777; 70 | } 71 | 72 | .instruction.performing { 73 | color: #fff; 74 | } -------------------------------------------------------------------------------- /2023/src/01/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | let sum = 0; 4 | 5 | const formatNumber = (s: string) => { 6 | if (s === "one") return 1; 7 | if (s === "two") return 2; 8 | if (s === "three") return 3; 9 | if (s === "four") return 4; 10 | if (s === "five") return 5; 11 | if (s === "six") return 6; 12 | if (s === "seven") return 7; 13 | if (s === "eight") return 8; 14 | if (s === "nine") return 9; 15 | return 0; 16 | }; 17 | 18 | var re = /(?=(\d{3}))/g; 19 | / \d{3} /g; 20 | 21 | const parser = new InputParser("input.txt"); 22 | while (parser.hasNext()) { 23 | const string = parser.next()!; 24 | 25 | let number = 0; 26 | 27 | const matches = Array.from( 28 | string.matchAll( 29 | /(?=([0-9]|one|two|three|four|five|six|seven|eight|nine))/g 30 | ), 31 | (x) => x[1] 32 | ); 33 | 34 | const first = matches[0]; 35 | const last = matches[matches.length - 1]; 36 | 37 | number += (isNaN(+first) ? formatNumber(first) : +first) * 10; 38 | number += isNaN(+last) ? formatNumber(last) : +last; 39 | 40 | sum += number; 41 | } 42 | 43 | console.log(sum); 44 | -------------------------------------------------------------------------------- /2021/visualizations/14/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 | 16 |
17 |
18 |
Steps: 0
19 |
Template:
20 |
Part1: calculating
21 |
Part2: calculating
22 |
23 |
24 |
[start]
25 |
26 | 27 | 28 | -------------------------------------------------------------------------------- /2022/src/02/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("in.txt"); 4 | 5 | type Move = "A" | "B" | "C"; 6 | 7 | const gameRules: { 8 | [k in Move]: { 9 | value: number; 10 | beats: Move; 11 | losesTo: Move; 12 | }; 13 | } = { 14 | A: { 15 | value: 1, 16 | beats: "C", 17 | losesTo: "B", 18 | }, 19 | B: { 20 | value: 2, 21 | beats: "A", 22 | losesTo: "C", 23 | }, 24 | C: { 25 | value: 3, 26 | beats: "B", 27 | losesTo: "A", 28 | }, 29 | }; 30 | 31 | console.log(gameRules); 32 | 33 | let score = 0; 34 | 35 | while (parser.hasNext()) { 36 | const [opponent, neededOutcome] = parser.next()!.trim().split(" "); 37 | 38 | const move = gameRules[opponent as Move]; 39 | 40 | switch (neededOutcome) { 41 | case "X": // player should lose 42 | score += gameRules[move.beats].value; 43 | break; 44 | 45 | case "Y": // should end with draw 46 | score += move.value + 3; 47 | break; 48 | 49 | case "Z": // should win 50 | score += gameRules[move.losesTo].value + 6; 51 | break; 52 | } 53 | } 54 | 55 | console.log(score); 56 | -------------------------------------------------------------------------------- /2022/visualizations/10/10.css: -------------------------------------------------------------------------------- 1 | .instruction { 2 | color: #777; 3 | height: 1.2rem; 4 | transition: .2s; 5 | overflow: hidden; 6 | } 7 | 8 | .text-act span{ 9 | color: #f1c40f; 10 | } 11 | 12 | .instruction.current { 13 | color: #fff; 14 | } 15 | 16 | .instruction.done { 17 | color: #fff; 18 | opacity: 0; 19 | height: 0; 20 | } 21 | 22 | .text-act{ 23 | margin-bottom: 1rem; 24 | } 25 | 26 | .row { 27 | display: flex; 28 | } 29 | 30 | .output { 31 | flex-direction: row; 32 | overflow-y: hidden; 33 | } 34 | 35 | .grid-wrapper{ 36 | position: relative; 37 | } 38 | 39 | #sprite{ 40 | position: absolute; 41 | border: 1px solid #fff; 42 | width: fit-content; 43 | height: 100%; 44 | pointer-events: none; 45 | transition: .2s; 46 | } 47 | 48 | #instructions { 49 | transform: translateY(50%); 50 | } 51 | 52 | #crt { 53 | margin-right: 1rem; 54 | color: #777; 55 | } 56 | 57 | .pixel { 58 | transition: .2s; 59 | width: 1rem; 60 | height: 1rem; 61 | display: flex; 62 | justify-content: center; 63 | align-items: center; 64 | } 65 | 66 | .pixel.active { 67 | background-color: #333; 68 | } 69 | 70 | .pixel.on { 71 | background-color: #f1c40f; 72 | } -------------------------------------------------------------------------------- /2023/src/12/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | let wholeSum = 0; 6 | 7 | while (parser.hasNext()) { 8 | const [string, numStr] = parser.next()!.split(" "); 9 | let newString = string; 10 | let newNumbers = numStr; 11 | 12 | for (let i = 0; i < 4; i++) { 13 | newString += "?" + string; 14 | newNumbers += "," + numStr; 15 | } 16 | 17 | const numbers = newNumbers.split(",").map(Number); 18 | 19 | const tryCombination = (str: string): number => { 20 | if (!str.includes("?")) { 21 | const s = str.match(/#+/gm); 22 | 23 | if (s?.length !== numbers.length) return 0; 24 | 25 | for (let i = 0; i < s.length; i++) { 26 | if (s[i].length !== numbers[i]) return 0; 27 | } 28 | 29 | return 1; 30 | } 31 | 32 | const version1 = str.replace("?", "#"); 33 | const version2 = str.replace("?", "."); 34 | 35 | return tryCombination(version1) + tryCombination(version2); 36 | }; 37 | 38 | const sum = tryCombination(newString); 39 | 40 | console.log("Done with this", sum); 41 | 42 | wholeSum += sum; 43 | } 44 | 45 | console.log("Answer:", wholeSum); 46 | -------------------------------------------------------------------------------- /2021/06/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const lanterFish = input.getFullInput().split(",").map(Number); 6 | console.log(lanterFish); 7 | 8 | let simulationLength = 256; 9 | 10 | const runSimulation = () => { 11 | var initial = lanterFish.slice(); 12 | var count: { [n: number]: number } = {}; 13 | for (var fish of initial) { 14 | if (count[fish] === undefined) count[fish] = 0; 15 | count[fish] += 1; 16 | } 17 | for (var day = 0; day < simulationLength; day++) { 18 | var new_count: { [n: number]: number } = {}; 19 | for (const k in count) { 20 | const v = count[k]; 21 | if (+k > 0) { 22 | if (new_count[+k - 1] === undefined) new_count[+k - 1] = 0; 23 | new_count[+k - 1] += v; 24 | } else { 25 | if (new_count[6] === undefined) new_count[6] = 0; 26 | if (new_count[8] === undefined) new_count[8] = 0; 27 | new_count[6] += v; 28 | new_count[8] += v; 29 | } 30 | } 31 | count = new_count; 32 | } 33 | return Object.values(count).reduce(function (a, b) { 34 | return a + b; 35 | }); 36 | }; 37 | 38 | console.log(runSimulation()); 39 | -------------------------------------------------------------------------------- /2023/src/04/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | const parser = new InputParser("input.txt"); 3 | 4 | const scoreMap = new Map(); 5 | 6 | let i = 0; 7 | 8 | while (parser.hasNext()) { 9 | const line = parser.next()!; 10 | i++; 11 | 12 | let score = 0; 13 | 14 | const [, winningStr, inclStr] = line.split(/:|\|/); 15 | const winning = winningStr 16 | .split(" ") 17 | .map((n) => parseInt(n)) 18 | .filter((n) => !isNaN(n)); 19 | const incl = inclStr 20 | .split(" ") 21 | .map((n) => parseInt(n)) 22 | .filter((n) => !isNaN(n)); 23 | 24 | for (let number of winning) if (incl.includes(number)) score++; 25 | 26 | scoreMap.set(i, score); 27 | } 28 | 29 | console.log(scoreMap); 30 | 31 | let totalCards = 0; 32 | 33 | const getNumberOfCards = (cardId: number, k = 0): number => { 34 | let allNextCards = scoreMap.get(cardId); 35 | 36 | if (!allNextCards) return 0; 37 | totalCards += allNextCards; 38 | 39 | for (let i = cardId + 1; i <= cardId + allNextCards; i++) { 40 | getNumberOfCards(i, k + 1); 41 | } 42 | 43 | return 0; 44 | }; 45 | 46 | for (let k of scoreMap.keys()) { 47 | totalCards++; 48 | getNumberOfCards(k); 49 | } 50 | 51 | console.log(totalCards); 52 | -------------------------------------------------------------------------------- /2022/src/08/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | const grid: number[][] = []; 6 | const visibleTrees = new Set(); 7 | 8 | while (inputParser.hasNext()) { 9 | grid.push(inputParser.next()!.split("").map(Number)); 10 | } 11 | 12 | for (let y = 0; y < grid.length; y++) { 13 | const row = grid[y]; 14 | let max = -1; 15 | for (let x = 0; x < row.length; x++) { 16 | if (row[x] > max) { 17 | visibleTrees.add(`${x},${y}`); 18 | max = row[x]; 19 | } 20 | } 21 | 22 | max = -1; 23 | for (let x = row.length - 1; x >= 0; x--) { 24 | if (row[x] > max) { 25 | visibleTrees.add(`${x},${y}`); 26 | max = row[x]; 27 | } 28 | } 29 | } 30 | 31 | for (let x = 0; x < grid[0].length; x++) { 32 | let max = -1; 33 | for (let y = 0; y < grid.length; y++) { 34 | if (grid[y][x] > max) { 35 | visibleTrees.add(`${x},${y}`); 36 | max = grid[y][x]; 37 | } 38 | } 39 | 40 | max = -1; 41 | for (let y = grid.length - 1; y >= 0; y--) { 42 | if (grid[y][x] > max) { 43 | visibleTrees.add(`${x},${y}`); 44 | max = grid[y][x]; 45 | } 46 | } 47 | } 48 | 49 | console.log("Visible trees: ", visibleTrees.size); 50 | -------------------------------------------------------------------------------- /2021/visualizations/16/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: consolas; 3 | src: url("../font/Consolas.ttf"); 4 | } 5 | 6 | body { 7 | font-family: consolas, "consolas", "Roboto Mono", monospace; 8 | color: #fff; 9 | background-color: #121212; 10 | white-space: nowrap; 11 | } 12 | 13 | #transmitted-data, 14 | #markers { 15 | color: grey; 16 | } 17 | 18 | .label { 19 | color: #fff; 20 | } 21 | 22 | .version { 23 | color: #d35400; 24 | } 25 | 26 | .type { 27 | color: #f1c40f; 28 | } 29 | 30 | .lengthfactor { 31 | color: #3498db; 32 | } 33 | 34 | .lengthtype { 35 | color: #9b59b6; 36 | } 37 | 38 | .value { 39 | color: #fff; 40 | } 41 | 42 | .endbit { 43 | color: #2ecc71; 44 | } 45 | 46 | .flex { 47 | display: flex; 48 | gap: 2rem; 49 | } 50 | 51 | .input { 52 | margin-bottom: 1rem; 53 | } 54 | 55 | input { 56 | background-color: rgba(255, 255, 255, 0.1); 57 | transition: 0.2s; 58 | border: 0; 59 | padding: 0.3rem; 60 | outline: 0; 61 | border: transparent solid 1px; 62 | 63 | color: #fff; 64 | } 65 | 66 | input:focus { 67 | border: rgba(255, 255, 255, 0.2) solid 1px; 68 | } 69 | 70 | #run { 71 | cursor: pointer; 72 | transition: 0.2s; 73 | } 74 | 75 | #run:hover { 76 | color: #3498db; 77 | } 78 | -------------------------------------------------------------------------------- /2021/05/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let data = input 5 | .getFullInput() 6 | .split("\r\n") 7 | .map((s) => s.split(" -> ").map((s) => s.split(",").map(Number))); 8 | 9 | data = data.filter((d) => d[0][0] === d[1][0] || d[0][1] === d[1][1]); 10 | 11 | let grid: string[][] = []; 12 | 13 | const maxX = Math.max( 14 | ...data.map((d) => (d[0][0] > d[0][1] ? d[0][0] : d[0][1])) 15 | ); 16 | 17 | const maxY = Math.max( 18 | ...data.map((d) => (d[1][0] > d[1][1] ? d[1][0] : d[1][1])) 19 | ); 20 | 21 | grid = new Array(maxX + 1).fill(0).map(() => new Array(maxY + 1).fill(".")); 22 | data.forEach((record, i) => { 23 | const [[x1, y1], [x2, y2]] = record; 24 | for (let x = x1 < x2 ? x1 : x2; x2 > x1 ? x <= x2 : x <= x1; x++) { 25 | for (let y = y1 < y2 ? y1 : y2; y2 > y1 ? y <= y2 : y <= y1; y++) { 26 | if (grid[y][x] === "x" || grid[y][x] === "I") { 27 | grid[y][x] = "I"; 28 | continue; 29 | } 30 | grid[y][x] = "x"; 31 | } 32 | } 33 | }); 34 | 35 | const Is = grid.reduce((acc, row) => { 36 | return ( 37 | acc + 38 | row.reduce((acc, cell) => { 39 | return acc + (cell === "I" ? 1 : 0); 40 | }, 0) 41 | ); 42 | }, 0); 43 | 44 | console.log(Is); 45 | -------------------------------------------------------------------------------- /2021/15/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const grid = input 6 | .getFullInput() 7 | .split("\r\n") 8 | .map((row) => row.split("").map(Number)); 9 | 10 | grid[0][0] = 0; 11 | console.log(grid); 12 | 13 | const getNeighbors = (x: number, y: number) => { 14 | const neighbors: number[][] = []; 15 | if (x > 0) neighbors.push([x - 1, y]); 16 | if (x < grid.length - 1) neighbors.push([x + 1, y]); 17 | if (y > 0) neighbors.push([x, y - 1]); 18 | if (y < grid[0].length - 1) neighbors.push([x, y + 1]); 19 | return neighbors; 20 | }; 21 | 22 | const cost = grid.map((row) => row.map(() => Infinity)); 23 | cost[0][0] = 0; 24 | 25 | const queue = [[0, 0]]; 26 | while (queue.length) { 27 | const current = queue.shift()!; 28 | const neighbors = getNeighbors(current[0], current[1]); 29 | 30 | for (const neighbor of neighbors) { 31 | const neighborCost = cost[neighbor[0]][neighbor[1]]; 32 | const costToNeighbor = cost[current[0]][current[1]] + grid[neighbor[0]][neighbor[1]]; 33 | if (neighborCost > costToNeighbor) { 34 | cost[neighbor[0]][neighbor[1]] = costToNeighbor; 35 | queue.push(neighbor); 36 | } 37 | } 38 | } 39 | 40 | console.log(cost[grid.length - 1][grid[0].length - 1]); 41 | -------------------------------------------------------------------------------- /2021/16/in.txt: -------------------------------------------------------------------------------- 1 | 420D50000B318100415919B24E72D6509AE67F87195A3CCC518CC01197D538C3E00BC9A349A09802D258CC16FC016100660DC4283200087C6485F1C8C015A00A5A5FB19C363F2FD8CE1B1B99DE81D00C9D3002100B58002AB5400D50038008DA2020A9C00F300248065A4016B4C00810028003D9600CA4C0084007B8400A0002AA6F68440274080331D20C4300004323CC32830200D42A85D1BE4F1C1440072E4630F2CCD624206008CC5B3E3AB00580010E8710862F0803D06E10C65000946442A631EC2EC30926A600D2A583653BE2D98BFE3820975787C600A680252AC9354FFE8CD23BE1E180253548D057002429794BD4759794BD4709AEDAFF0530043003511006E24C4685A00087C428811EE7FD8BBC1805D28C73C93262526CB36AC600DCB9649334A23900AA9257963FEF17D8028200DC608A71B80010A8D50C23E9802B37AA40EA801CD96EDA25B39593BB002A33F72D9AD959802525BCD6D36CC00D580010A86D1761F080311AE32C73500224E3BCD6D0AE5600024F92F654E5F6132B49979802129DC6593401591389CA62A4840101C9064A34499E4A1B180276008CDEFA0D37BE834F6F11B13900923E008CF6611BC65BCB2CB46B3A779D4C998A848DED30F0014288010A8451062B980311C21BC7C20042A2846782A400834916CFA5B8013374F6A33973C532F071000B565F47F15A526273BB129B6D9985680680111C728FD339BDBD8F03980230A6C0119774999A09001093E34600A60052B2B1D7EF60C958EBF7B074D7AF4928CD6BA5A40208E002F935E855AE68EE56F3ED271E6B44460084AB55002572F3289B78600A6647D1E5F6871BE5E598099006512207600BCDCBCFD23CE463678100467680D27BAE920804119DBFA96E05F00431269D255DDA528D83A577285B91BCCB4802AB95A5C9B001299793FCD24C5D600BC652523D82D3FCB56EF737F045008E0FCDC7DAE40B64F7F799F3981F2490 -------------------------------------------------------------------------------- /2022/src/10/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | let clockCycle = 0; 6 | let currentOperation: string = ""; 7 | let currentOperationDuration: number = -1; 8 | let registerValue = 1; 9 | 10 | const crt = ["", "", "", "", "", ""]; 11 | 12 | while (inputParser.hasNext()) { 13 | if (clockCycle >= 240) break; 14 | const crtRow = Math.floor(clockCycle / 40); 15 | if (Math.abs(registerValue - (clockCycle % 40)) <= 1) crt[crtRow] += "#"; 16 | else crt[crtRow] += "."; 17 | 18 | clockCycle++; 19 | 20 | if ( 21 | currentOperation == "noop" || 22 | (currentOperation.startsWith("addx") && currentOperationDuration == 1) || 23 | !currentOperation 24 | ) { 25 | currentOperation = inputParser.next()!; 26 | if (currentOperation.startsWith("addx")) currentOperationDuration = 0; 27 | } else { 28 | // current operation is addx but it hasnt finished yet 29 | currentOperationDuration += 1; 30 | 31 | const number = +currentOperation.split(" ")[1]; 32 | registerValue += number; 33 | } 34 | } 35 | 36 | if (currentOperation.startsWith("addx")) { 37 | const number = +currentOperation.split(" ")[1]; 38 | registerValue += number; 39 | } 40 | 41 | console.log("Rendered image: "); 42 | console.log( 43 | crt.map((s) => s.replaceAll("#", "██").replaceAll(".", " ")).join("\n") 44 | ); 45 | -------------------------------------------------------------------------------- /2021/14/in.txt: -------------------------------------------------------------------------------- 1 | CNBPHFBOPCSPKOFNHVKV 2 | 3 | CS -> S 4 | FB -> F 5 | VK -> V 6 | HO -> F 7 | SO -> K 8 | FK -> B 9 | VS -> C 10 | PS -> H 11 | HH -> P 12 | KH -> V 13 | PV -> V 14 | CB -> N 15 | BB -> N 16 | HB -> B 17 | HV -> O 18 | NC -> H 19 | NF -> B 20 | HP -> B 21 | HK -> S 22 | SF -> O 23 | ON -> K 24 | VN -> V 25 | SB -> H 26 | SK -> H 27 | VH -> N 28 | KN -> C 29 | CC -> N 30 | BF -> H 31 | SN -> N 32 | KP -> B 33 | FO -> N 34 | KO -> V 35 | BP -> O 36 | OK -> F 37 | HC -> B 38 | NH -> O 39 | SP -> O 40 | OO -> S 41 | VC -> O 42 | PC -> F 43 | VB -> O 44 | FF -> S 45 | BS -> F 46 | KS -> F 47 | OV -> P 48 | NB -> O 49 | CF -> F 50 | SS -> V 51 | KV -> K 52 | FP -> F 53 | KC -> C 54 | PF -> C 55 | OS -> C 56 | PN -> B 57 | OP -> C 58 | FN -> F 59 | OF -> C 60 | NP -> C 61 | CK -> N 62 | BN -> K 63 | BO -> K 64 | OH -> S 65 | BH -> O 66 | SH -> N 67 | CH -> K 68 | PO -> V 69 | CN -> N 70 | BV -> F 71 | FV -> B 72 | VP -> V 73 | FS -> O 74 | NV -> P 75 | PH -> C 76 | HN -> P 77 | VV -> C 78 | NK -> K 79 | CO -> N 80 | NS -> P 81 | VO -> P 82 | CP -> V 83 | OC -> S 84 | PK -> V 85 | NN -> F 86 | SC -> P 87 | BK -> F 88 | BC -> P 89 | FH -> B 90 | OB -> O 91 | FC -> N 92 | PB -> N 93 | VF -> N 94 | PP -> S 95 | HS -> O 96 | HF -> N 97 | KK -> C 98 | KB -> N 99 | SV -> N 100 | KF -> K 101 | CV -> N 102 | NO -> P -------------------------------------------------------------------------------- /2021/21/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const data = input 5 | .getFullInput() 6 | .replaceAll("\r", "") 7 | .split("\n") 8 | .map((x) => x.substring(x.length - 1)) 9 | .map(Number); 10 | 11 | interface Player { 12 | position: number; 13 | score: number; 14 | } 15 | 16 | const players: Player[] = data.map((x) => ({ position: x, score: 0 })); 17 | 18 | let dice = 1; 19 | 20 | const incrementPositionByScore = (player: Player, moveBy: number) => { 21 | let newPosition = (player.position + moveBy) % 10; 22 | if (newPosition === 0) newPosition = 10; 23 | 24 | player.position = newPosition; 25 | player.score += newPosition; 26 | }; 27 | 28 | let end = false; 29 | let rolls = 0; 30 | let result = 0; 31 | 32 | while (!end) { 33 | players.forEach((player, i) => { 34 | if (end) return; 35 | let sum = 0; 36 | for (let i = 0; i < 3; i++) { 37 | if (dice === 101) dice = 1; 38 | sum += dice; 39 | rolls++; 40 | console.log(dice); 41 | dice++; 42 | } 43 | 44 | incrementPositionByScore(player, sum); 45 | console.log("Player", i, "moved by", sum, "to", player.position, "score:", player.score); 46 | 47 | if (player.score >= 1000) { 48 | end = true; 49 | result = players[1 - i].score; 50 | } 51 | }); 52 | } 53 | 54 | console.log(result * rolls, result, rolls); 55 | -------------------------------------------------------------------------------- /2022/visualizations/main.css: -------------------------------------------------------------------------------- 1 | .command-line { 2 | color: #777; 3 | } 4 | 5 | .command-line span { 6 | color: #f1c40f; 7 | } 8 | 9 | .command-line .dollar-sign{ 10 | color: #fff; 11 | } 12 | 13 | .terminal { 14 | background-color: #121212; 15 | border-radius: .5rem; 16 | min-width: 30rem; 17 | } 18 | 19 | .grid-select{ 20 | display: grid; 21 | width: fit-content; 22 | grid-template-rows: repeat(4, auto); 23 | grid-auto-flow: column; 24 | margin-bottom: 1rem; 25 | gap: 0 1rem 26 | } 27 | 28 | body { 29 | display: flex; 30 | align-items: center; 31 | justify-content: center; 32 | background: linear-gradient(to top right, #c0392b, #d35400); 33 | } 34 | 35 | .terminal-content { 36 | padding : 1rem; 37 | padding-top: 0; 38 | } 39 | 40 | .terminal-heading { 41 | display: flex; 42 | align-items: center; 43 | padding: 1rem 1rem; 44 | } 45 | 46 | .terminal-heading-name{ 47 | flex-grow: 1; 48 | } 49 | 50 | .terminal-heading-button{ 51 | width: .6rem; 52 | height: .6rem; 53 | border-radius: 50%; 54 | margin-left: .5rem; 55 | } 56 | 57 | .terminal-heading-button.g { 58 | background-color: #2ecc71; 59 | } 60 | 61 | .terminal-heading-button.y { 62 | background-color: #f1c40f; 63 | } 64 | 65 | .terminal-heading-button.r { 66 | background-color: #e74c3c; 67 | } 68 | 69 | #t-name { 70 | color: #f1c40f; 71 | } 72 | #loading { 73 | margin-top: 1rem; 74 | } 75 | 76 | -------------------------------------------------------------------------------- /2021/visualizations/14/data.txt: -------------------------------------------------------------------------------- 1 | CNBPHFBOPCSPKOFNHVKV 2 | 3 | CS -> S 4 | FB -> F 5 | VK -> V 6 | HO -> F 7 | SO -> K 8 | FK -> B 9 | VS -> C 10 | PS -> H 11 | HH -> P 12 | KH -> V 13 | PV -> V 14 | CB -> N 15 | BB -> N 16 | HB -> B 17 | HV -> O 18 | NC -> H 19 | NF -> B 20 | HP -> B 21 | HK -> S 22 | SF -> O 23 | ON -> K 24 | VN -> V 25 | SB -> H 26 | SK -> H 27 | VH -> N 28 | KN -> C 29 | CC -> N 30 | BF -> H 31 | SN -> N 32 | KP -> B 33 | FO -> N 34 | KO -> V 35 | BP -> O 36 | OK -> F 37 | HC -> B 38 | NH -> O 39 | SP -> O 40 | OO -> S 41 | VC -> O 42 | PC -> F 43 | VB -> O 44 | FF -> S 45 | BS -> F 46 | KS -> F 47 | OV -> P 48 | NB -> O 49 | CF -> F 50 | SS -> V 51 | KV -> K 52 | FP -> F 53 | KC -> C 54 | PF -> C 55 | OS -> C 56 | PN -> B 57 | OP -> C 58 | FN -> F 59 | OF -> C 60 | NP -> C 61 | CK -> N 62 | BN -> K 63 | BO -> K 64 | OH -> S 65 | BH -> O 66 | SH -> N 67 | CH -> K 68 | PO -> V 69 | CN -> N 70 | BV -> F 71 | FV -> B 72 | VP -> V 73 | FS -> O 74 | NV -> P 75 | PH -> C 76 | HN -> P 77 | VV -> C 78 | NK -> K 79 | CO -> N 80 | NS -> P 81 | VO -> P 82 | CP -> V 83 | OC -> S 84 | PK -> V 85 | NN -> F 86 | SC -> P 87 | BK -> F 88 | BC -> P 89 | FH -> B 90 | OB -> O 91 | FC -> N 92 | PB -> N 93 | VF -> N 94 | PP -> S 95 | HS -> O 96 | HF -> N 97 | KK -> C 98 | KB -> N 99 | SV -> N 100 | KF -> K 101 | CV -> N 102 | NO -> P -------------------------------------------------------------------------------- /2021/14/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const [template, rawInstructions] = input.getFullInput().split("\r\n\r\n"); 6 | 7 | const instructions = rawInstructions.split("\r\n").map((instruction) => { 8 | const [from, to] = instruction.split(" -> "); 9 | return { from, to }; 10 | }); 11 | 12 | const n = 10; 13 | let string = template; 14 | 15 | for (let i = 0; i < n; i++) { 16 | let toReplace = string[0]; 17 | 18 | for (let i = 0; i < string.length - 1; i++) { 19 | const momentaryString = string.substring(i, i + 2); 20 | const [_, b] = momentaryString.split(""); 21 | const add = instructions.find((instruction) => instruction.from === momentaryString); 22 | toReplace += add!.to + b; 23 | } 24 | 25 | string = toReplace; 26 | } 27 | 28 | const countLetters = (string: string) => { 29 | const letters: { [k: string]: number } = {}; 30 | 31 | for (const letter of string) { 32 | if (letters[letter]) { 33 | letters[letter]++; 34 | } else { 35 | letters[letter] = 1; 36 | } 37 | } 38 | return letters; 39 | }; 40 | 41 | let max = 0; 42 | let min = Infinity; 43 | 44 | const letters = countLetters(string); 45 | for (const key of Object.keys(letters)) { 46 | if (letters[key] > max) { 47 | max = letters[key]; 48 | } 49 | if (letters[key] < min) { 50 | min = letters[key]; 51 | } 52 | } 53 | 54 | console.log(max - min); 55 | -------------------------------------------------------------------------------- /2022/src/13/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | type ArrayType = (ArrayType | number)[]; 6 | 7 | const compareObjects = (a: ArrayType, b: ArrayType): number => { 8 | const minLen = Math.min(a.length, b.length); 9 | for (let i = 0; i < minLen; i++) { 10 | if (typeof a[i] == "number" && typeof b[i] == "number") { 11 | if (a[i] < b[i]) return 1; 12 | if (a[i] > b[i]) return 0; 13 | } 14 | let r; 15 | if (typeof a[i] == "object" && typeof b[i] == "object") { 16 | r = compareObjects(a[i] as ArrayType, b[i] as ArrayType); 17 | } 18 | 19 | if (typeof a[i] == "number" && typeof b[i] == "object") { 20 | r = compareObjects([a[i]], b[i] as ArrayType); 21 | } 22 | 23 | if (typeof a[i] == "object" && typeof b[i] == "number") { 24 | r = compareObjects(a[i] as ArrayType, [b[i]]); 25 | } 26 | 27 | if (r == 1) return 1; 28 | if (r == 0) return 0; 29 | } 30 | 31 | if (a.length < b.length) return 1; 32 | else if (a.length > b.length) return 0; 33 | else return 2; 34 | }; 35 | 36 | let i = 0; 37 | let sum = 0; 38 | 39 | while (inputParser.hasNext()) { 40 | const [arr1, arr2] = inputParser 41 | .nextUntilEmptyLine()! 42 | .map((s) => eval(s)) as [ArrayType, ArrayType]; 43 | 44 | i++; 45 | const r = compareObjects(arr1, arr2); 46 | 47 | if (r == 1) sum += i; 48 | } 49 | 50 | console.log(sum); 51 | -------------------------------------------------------------------------------- /2022/visualizations/07/07.css: -------------------------------------------------------------------------------- 1 | .output { 2 | margin: 1rem 0; 3 | width: 100%; 4 | } 5 | 6 | .file-controls{ 7 | display: flex; 8 | height: 2rem; 9 | margin-left: 1rem; 10 | } 11 | 12 | #path { 13 | color: #777; 14 | min-width: 15rem; 15 | margin-left: 1rem; 16 | padding: .5rem 1rem; 17 | } 18 | 19 | table { 20 | border-collapse: collapse; 21 | margin-top: 1rem; 22 | } 23 | 24 | .file-row.folder { 25 | cursor: pointer; 26 | transition: .2s; 27 | } 28 | 29 | .file-row.folder:hover { 30 | background-color: #333; 31 | } 32 | 33 | .file-row.folder:active { 34 | background-color: #555; 35 | } 36 | 37 | .file-row.selected { 38 | background-color: #555; 39 | } 40 | 41 | td { 42 | padding: .5rem 0; 43 | padding-right: 2rem; 44 | } 45 | 46 | .type { 47 | color: #777; 48 | } 49 | 50 | .size { 51 | color: #f1c40f; 52 | text-align: right; 53 | } 54 | 55 | td:nth-child(2) { 56 | min-width: 10rem; 57 | } 58 | 59 | td:first-child { 60 | padding-left: 1rem; 61 | } 62 | 63 | td:last-child { 64 | padding-right: 1rem; 65 | } 66 | 67 | #progress { 68 | margin-left: 1rem; 69 | margin-top: 1rem; 70 | color: #777; 71 | } 72 | 73 | #progress-bar { 74 | background-color: #555; 75 | height: 2px; 76 | width: 100%; 77 | margin-bottom: .5rem; 78 | } 79 | 80 | #progress-bar-inner { 81 | background-color: #f1c40f; 82 | height: 2px; 83 | width: 0; 84 | transition: .2s; 85 | } 86 | 87 | #progress span { 88 | color: #f1c40f; 89 | } -------------------------------------------------------------------------------- /2021/visualizations/18/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Advent of code 2021 | Day 18 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | [process] 19 |
20 | 21 |
22 |
23 |
24 |
Press next step button to start the proccess
25 |
26 |
27 | [next step] 28 | [ ] Auto 29 |
30 | 31 |
Addition stack:
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /2022/visualizations/06/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 06 10 | 11 | 14 | 15 | 16 |
17 |
18 | 25 |
26 | 27 |
28 |
29 | 30 |
31 |
32 |
0
33 |
34 |
35 |
36 | Part 1: 37 | 0 38 | x 39 |
40 |
41 | Part 2: 42 | 0 43 | x 44 |
45 |
46 |
47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /2022/visualizations/07/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 07 10 | 11 | 14 | 15 | 16 |
17 |
18 | 25 |
26 | 27 |
28 |
29 | 30 |
31 |
32 | 33 |
34 |
35 |
36 | 43 |
44 |
45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /2022/visualizations/11/11.css: -------------------------------------------------------------------------------- 1 | .output { 2 | position: relative; 3 | } 4 | 5 | #monkeys { 6 | flex: 1; 7 | height: 100%; 8 | width: 100%; 9 | position: relative; 10 | } 11 | 12 | .monkey { 13 | position: absolute; 14 | transform: translateX(-50%); 15 | } 16 | 17 | .monkey-id { 18 | color: #777; 19 | transition: .2s; 20 | } 21 | 22 | .monkey-id.active { 23 | color: #fff; 24 | } 25 | 26 | .monkey-op{ 27 | color: #777; 28 | } 29 | 30 | .monkey-test { 31 | color: #777; 32 | } 33 | 34 | .monkey-items{ 35 | display: flex; 36 | gap: .5rem; 37 | flex-wrap: wrap; 38 | width: 10rem; 39 | } 40 | 41 | .item { 42 | color: #f1c40f; 43 | position: absolute; 44 | transition: .35s; 45 | } 46 | 47 | .monkey-item-slot{ 48 | width: 1rem; 49 | height: 1.2rem; 50 | } 51 | 52 | .arrow { 53 | position: absolute; 54 | width: 2px; 55 | height: 40%; 56 | top: 50%; 57 | left: 50%; 58 | transform: translate(-50%, -50%); 59 | transition: .6s; 60 | } 61 | 62 | .arrow.s .arrow-head{ 63 | background-color: #777; 64 | } 65 | 66 | #arrow-1 .arrow-head{ 67 | background-color: #27ae60; 68 | opacity: .3; 69 | } 70 | 71 | #arrow-2 .arrow-head{ 72 | background-color: #e74c3c; 73 | opacity: .3; 74 | } 75 | 76 | .arrow-head { 77 | width: 100%; 78 | height: 50%; 79 | background-color: #f1c40f; 80 | } 81 | 82 | #info { 83 | position: absolute; 84 | bottom: 1rem; 85 | left: 1rem; 86 | color: #777; 87 | } 88 | 89 | #info span { 90 | color: #f1c40f; 91 | } -------------------------------------------------------------------------------- /2022/visualizations/12/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 12 10 | 11 | 14 | 15 | 16 |
17 |
18 | 26 |
27 | 28 | 39 |
40 |
41 | 42 |
43 |
44 |
45 |
46 |
47 |
48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /2021/visualizations/11/data.txt: -------------------------------------------------------------------------------- 1 | 784304459131808911509115713818422592413142528 2 | 119347560475207771813212946032272214045795212 3 | 586027685353617609978812866511324552641763783 4 | 517547057691812295137219613541661257981802379 5 | 227389416959994515648221342730996765740668989 6 | 419724043348730973908923106214249138519669020 7 | 059374240108267955840698639760265489622525886 8 | 250561412510974491562072766666411627913292123 9 | 328000467244329627374348758917511178048226736 10 | 741558384251980448821565277023487431732350935 11 | 816796088818197629747123846179320707213271293 12 | 637625336119753840681829136175367598788333010 13 | 120485073968271336262143698576064056657065407 14 | 255705465824224162381030814483211389239296286 15 | 293308375895198578686063917235835565883110605 16 | 252485687480650316543117566926104282890922697 17 | 513813335071253738628164457511892372016956983 18 | 656659675972293590487428902612576471599189989 19 | 162195805320858957008157471692879188117039032 20 | 765561952777655587215342374277650277003091007 21 | 466246392695105878893393170292785762621766603 22 | 839330119284437573451086348371772255561058500 23 | 022586745551656840163686955095616300879734443 24 | 731092831768640720569686334114024773158213273 25 | 901761637847526382642796891171569696176505169 26 | 585197992160960342826270302153803024933973375 27 | 842475770962042106721364402524324639415399548 28 | 635133997163549517707055390032891155126539089 29 | 926326534398642063180607466702921188771964461 30 | 239935705424303682782274971536671664562341367 -------------------------------------------------------------------------------- /2023/src/05/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | type ConversionObj = { 6 | min: number; 7 | max: number; 8 | shift: number; 9 | }[]; 10 | 11 | let seedNumbers = parser 12 | .next()! 13 | .match(/\d+/gm)! 14 | .map((x) => parseInt(x)); 15 | 16 | parser.next(); 17 | 18 | const shiftNumber = (co: ConversionObj, number: number) => { 19 | for (const record of co) { 20 | if (number >= record.min && number <= record.max) { 21 | return number + record.shift; 22 | } 23 | } 24 | 25 | return number; 26 | }; 27 | 28 | console.log("original", seedNumbers); 29 | 30 | while (parser.hasNext()) { 31 | const groupName = parser.next(); // skip group name 32 | 33 | const groupData = parser.nextUntilEmptyLine()!; 34 | 35 | const conversionObj: ConversionObj = []; 36 | 37 | for (const record of groupData) { 38 | const [destinationRangeStart, sourceRangeStart, rangeLength] = record 39 | .split(" ") 40 | .map((x) => +x); 41 | 42 | conversionObj.push({ 43 | min: sourceRangeStart, 44 | max: sourceRangeStart + rangeLength - 1, 45 | shift: destinationRangeStart - sourceRangeStart, 46 | }); 47 | } 48 | 49 | const newSeedNumbers = []; 50 | 51 | for (const number of seedNumbers) { 52 | newSeedNumbers.push(shiftNumber(conversionObj, number)); 53 | } 54 | 55 | seedNumbers = newSeedNumbers; 56 | 57 | console.log(groupName, newSeedNumbers); 58 | } 59 | 60 | console.log("minimum:", Math.min(...seedNumbers)); 61 | -------------------------------------------------------------------------------- /2022/src/08/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | const grid: number[][] = []; 6 | 7 | while (inputParser.hasNext()) { 8 | grid.push(inputParser.next()!.split("").map(Number)); 9 | } 10 | 11 | const getTreeViewScore = (x: number, y: number) => { 12 | const treeValue = grid[y][x]; 13 | 14 | let scoreTop = 0; 15 | for (let i = y - 1; i >= 0; i--) { 16 | if (treeValue > grid[i][x]) scoreTop++; 17 | else { 18 | scoreTop++; 19 | break; 20 | } 21 | } 22 | 23 | let scoreBottom = 0; 24 | for (let i = y + 1; i < grid.length; i++) { 25 | if (treeValue > grid[i][x]) scoreBottom++; 26 | else { 27 | scoreBottom++; 28 | break; 29 | } 30 | } 31 | 32 | let scoreLeft = 0; 33 | for (let i = x - 1; i >= 0; i--) { 34 | if (treeValue > grid[y][i]) scoreLeft++; 35 | else { 36 | scoreLeft++; 37 | break; 38 | } 39 | } 40 | 41 | let scoreRight = 0; 42 | for (let i = x + 1; i < grid[y].length; i++) { 43 | if (treeValue > grid[y][i]) scoreRight++; 44 | else { 45 | scoreRight++; 46 | break; 47 | } 48 | } 49 | 50 | return scoreTop * scoreBottom * scoreLeft * scoreRight; 51 | }; 52 | 53 | let max = 0; 54 | 55 | // loop through all trees 56 | for (let y = 0; y < grid.length; y++) { 57 | for (let x = 0; x < grid[y].length; x++) { 58 | const score = getTreeViewScore(x, y); 59 | if (score > max) max = score; 60 | } 61 | } 62 | 63 | console.log("Max veiwing distance: ", max); 64 | -------------------------------------------------------------------------------- /2022/src/15/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | let filename = "in.txt"; 4 | const inputParser = new InputParser(filename); 5 | 6 | interface Sensor { 7 | x: number; 8 | y: number; 9 | range: number; 10 | closestBeacon: { 11 | x: number; 12 | y: number; 13 | }; 14 | } 15 | 16 | let minX = Infinity; 17 | let maxX = -Infinity; 18 | 19 | const sensors: Sensor[] = []; 20 | 21 | while (inputParser.hasNext()) { 22 | const [x, y, xb, yb] = 23 | inputParser 24 | .next() 25 | ?.match(/(-)*\d+/g) 26 | ?.map(Number) ?? []; 27 | 28 | minX = Math.min(minX, x, xb); 29 | maxX = Math.max(maxX, x, xb); 30 | 31 | sensors.push({ 32 | x, 33 | y, 34 | range: Math.abs(x - xb) + Math.abs(y - yb), 35 | closestBeacon: { 36 | x: xb, 37 | y: yb, 38 | }, 39 | }); 40 | } 41 | 42 | let y = filename === "test.txt" ? 10 : 2000000; 43 | let avalPos = 0; 44 | 45 | let maxRange = Math.max(...sensors.map((s) => s.range)); 46 | 47 | for (let x = minX - maxRange * 2; x <= maxX + maxRange * 2; x++) { 48 | let skip = false; 49 | for (const sensor of sensors) { 50 | if (x === sensor.closestBeacon.x && y === sensor.closestBeacon.y) { 51 | skip = true; 52 | break; 53 | } 54 | } 55 | 56 | if (skip) { 57 | continue; 58 | } 59 | 60 | for (const sensor of sensors) { 61 | if (Math.abs(x - sensor.x) + Math.abs(y - sensor.y) <= sensor.range) { 62 | avalPos++; 63 | break; 64 | } 65 | } 66 | } 67 | 68 | console.log("positions not available:", avalPos); 69 | -------------------------------------------------------------------------------- /2022/visualizations/13/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 13 10 | 11 | 14 | 15 | 16 |
17 |
18 | 26 |
27 | 28 | 39 |
40 |
41 | 42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /2021/visualizations/17/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Advent of code 2021 | Day 17 11 | 12 | 13 | 14 | 15 |
16 | 17 |
18 | 19 | 20 |
21 | 22 | [visualize] 23 |
24 |
25 |
26 |
27 |
Current velocity:
28 |
Velocity:
29 |
Hits:
30 |
Trajectory length:
31 |
Max y:
32 |
33 |
34 | 35 | 36 | -------------------------------------------------------------------------------- /2021/09/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const grid = input 6 | .getFullInput() 7 | .split("\r\n") 8 | .map((row) => row.split("").map(Number)); 9 | 10 | const getBesins = (grid: number[][]) => { 11 | const besins: number[] = []; 12 | 13 | grid.forEach((row, i) => { 14 | row.forEach((point, j) => { 15 | let lowest = true; 16 | 17 | if (i > 0 && grid[i - 1][j] <= point) lowest = false; 18 | if (i < grid.length - 1 && grid[i + 1][j] <= point) lowest = false; 19 | 20 | if (j > 0 && grid[i][j - 1] <= point) lowest = false; 21 | if (j < grid[i].length - 1 && grid[i][j + 1] <= point) lowest = false; 22 | 23 | if (!lowest) return; 24 | 25 | const visited = new Set(); 26 | 27 | const directions = [ 28 | [0, 1], 29 | [0, -1], 30 | [1, 0], 31 | [-1, 0], 32 | ]; 33 | 34 | const toCheck = [[i, j]]; 35 | 36 | while (toCheck.length) { 37 | const [i, j] = toCheck.shift()!; 38 | 39 | if (visited.has(`${i}-${j}`)) continue; 40 | if (i < 0 || j < 0 || i >= grid.length || j >= grid[i].length) continue; 41 | if (grid[i][j] === 9) continue; 42 | 43 | visited.add(`${i}-${j}`); 44 | toCheck.push(...directions.map(([x, y]) => [i + x, j + y])); 45 | } 46 | 47 | besins.push(visited.size); 48 | }); 49 | }); 50 | 51 | return besins; 52 | }; 53 | 54 | const sorted = getBesins(grid).sort((a, b) => b - a); 55 | 56 | console.log(sorted[0] * sorted[1] * sorted[2]); 57 | -------------------------------------------------------------------------------- /2021/12/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | interface Node { 6 | id: string; 7 | goTo: number[]; 8 | links: string[]; 9 | } 10 | 11 | const nodes: Node[] = []; 12 | 13 | while (input.hasNext()) { 14 | const line = input.next()!; 15 | const [nodeA, nodeB] = line.split("-"); 16 | 17 | console.log(nodeA, nodeB); 18 | 19 | const nodeAIndex = nodes.findIndex((n) => n.id === nodeA); 20 | const nodeBIndex = nodes.findIndex((n) => n.id === nodeB); 21 | 22 | console.log(nodeAIndex, nodeBIndex); 23 | 24 | if (nodeAIndex === -1) { 25 | nodes.push({ 26 | id: nodeA, 27 | goTo: [0], 28 | links: [nodeB], 29 | }); 30 | } 31 | if (nodeBIndex === -1) { 32 | nodes.push({ 33 | id: nodeB, 34 | goTo: [0], 35 | links: [nodeA], 36 | }); 37 | } 38 | 39 | if (nodeAIndex !== -1) { 40 | nodes[nodeAIndex].links.push(nodeB); 41 | } 42 | 43 | if (nodeBIndex !== -1) { 44 | nodes[nodeBIndex].links.push(nodeA); 45 | } 46 | } 47 | 48 | console.log(nodes); 49 | 50 | const paths: string[][] = []; 51 | paths.push(["start"]); 52 | const completes: string[][] = []; 53 | 54 | while (paths.length) { 55 | const p0 = paths.shift()!; 56 | for (let s of nodes.find((n) => n.id === p0[p0.length - 1])!.links) { 57 | if (s.toLowerCase() === s && p0.includes(s)) continue; 58 | 59 | const p1 = [...p0, s]; 60 | 61 | if (s === "end") { 62 | completes.push(p1); 63 | } else { 64 | paths.push(p1); 65 | } 66 | } 67 | } 68 | 69 | console.log(completes.length); 70 | -------------------------------------------------------------------------------- /2022/visualizations/15/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 15 10 | 11 | 14 | 15 | 16 |
17 |
18 | 26 |
27 | 28 | 39 | 40 | 41 |
42 |
43 | 44 |
45 |
46 |
47 | 48 |
49 |
50 |
51 |
52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /2021/17/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const data = input 5 | .getFullInput() 6 | .replaceAll("..", ",") 7 | .replaceAll("target area: x=", "") 8 | .replaceAll(" ", "") 9 | .replaceAll("y=", "") 10 | .split(",") 11 | .map(Number); 12 | 13 | const targetStart = [data[0], data[2]]; 14 | const targetEnd = [data[1], data[3]]; 15 | 16 | const doesTrajectoryCrossTarget = (vX: number, vY: number): [boolean, number, boolean, boolean] => { 17 | let x = 0; 18 | let y = 0; 19 | let result = undefined; 20 | let maxY = 0; 21 | 22 | let failsX = false; 23 | let failsY = false; 24 | 25 | let velY = vY; 26 | let velX = vX; 27 | 28 | while (result === undefined) { 29 | x += velX; 30 | y += velY; 31 | 32 | if (velX > 0) velX--; 33 | if (velX < 0) velX++; 34 | 35 | if (y > maxY) maxY = y; 36 | 37 | velY--; 38 | 39 | if (x >= targetStart[0] && x <= targetEnd[0] && y >= targetStart[1] && y <= targetEnd[1]) { 40 | result = true; 41 | } else if (x > targetEnd[0]) { 42 | failsX = true; 43 | result = false; 44 | } else if (y < targetStart[1]) { 45 | failsY = true; 46 | result = false; 47 | } 48 | } 49 | 50 | return [result, maxY, failsY, failsX]; 51 | }; 52 | 53 | let count = 0; 54 | let end = false; 55 | 56 | for (let i = 0; i < 1000; i++) { 57 | for (let j = -1000; j < 1000; j++) { 58 | const [crosses, y, failsY, failsX] = doesTrajectoryCrossTarget(i, j); 59 | if (crosses) { 60 | count++; 61 | } 62 | } 63 | } 64 | 65 | console.log("Count:", count); 66 | -------------------------------------------------------------------------------- /2022/src/10/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | let clockCycle = 0; 6 | let currentOperation: string = ""; 7 | let currentOperationDuration: number = -1; 8 | let registerValue = 1; 9 | 10 | const signalStrengths = [20, 60, 100, 140, 180, 220]; 11 | let score = 0; 12 | 13 | while (inputParser.hasNext() || currentOperationDuration != 1) { 14 | clockCycle++; 15 | if ( 16 | currentOperation == "noop" || 17 | (currentOperation.startsWith("addx") && currentOperationDuration == 1) || 18 | !currentOperation 19 | ) { 20 | // if operation was addx, add the number to register 21 | if (currentOperation.startsWith("addx")) { 22 | const number = +currentOperation.split(" ")[1]; 23 | registerValue += number; 24 | } 25 | 26 | // console.log("Cycle", clockCycle, "- reading next op"); 27 | 28 | currentOperation = inputParser.next()!; 29 | if (currentOperation.startsWith("addx")) currentOperationDuration = 0; 30 | } else { 31 | // console.log("Cycle", clockCycle, "continuing addx"); 32 | // current operation is addx but it hasnt finished yet 33 | currentOperationDuration += 1; 34 | } 35 | 36 | if (signalStrengths.includes(clockCycle)) { 37 | console.log("Adding", registerValue, "to score"); 38 | score += registerValue * clockCycle; 39 | } 40 | } 41 | 42 | if (currentOperation.startsWith("addx")) { 43 | const number = +currentOperation.split(" ")[1]; 44 | registerValue += number; 45 | } 46 | 47 | console.log("Register value: ", registerValue); 48 | console.log("Final score:", score); 49 | -------------------------------------------------------------------------------- /2021/visualizations/18/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: consolas; 3 | src: url("../font/Consolas.ttf"); 4 | } 5 | 6 | * { 7 | font-family: consolas, "consolas", "Roboto Mono", monospace; 8 | } 9 | 10 | body { 11 | color: #fff; 12 | background-color: #121212; 13 | white-space: nowrap; 14 | } 15 | 16 | .input { 17 | margin-bottom: 1rem; 18 | display: flex; 19 | align-items: center; 20 | gap: 1rem; 21 | } 22 | 23 | #container { 24 | display: none; 25 | } 26 | 27 | #container.shown { 28 | display: block; 29 | } 30 | 31 | label { 32 | user-select: none; 33 | cursor: pointer; 34 | } 35 | 36 | textarea { 37 | background-color: rgba(255, 255, 255, 0.1); 38 | transition: 0.2s background-color, 0.2s border; 39 | border: 0; 40 | padding: 0.3rem; 41 | outline: 0; 42 | border: transparent solid 1px; 43 | min-width: 20rem; 44 | color: #fff; 45 | } 46 | 47 | textarea:focus { 48 | border: rgba(255, 255, 255, 0.2) solid 1px; 49 | } 50 | 51 | .button { 52 | cursor: pointer; 53 | transition: 0.2s; 54 | color: #3498db; 55 | user-select: none; 56 | } 57 | 58 | .button:hover { 59 | color: #3498db; 60 | opacity: 0.8; 61 | } 62 | 63 | .button:active { 64 | color: #3498db; 65 | opacity: 0.5; 66 | } 67 | 68 | .addition-stack-item { 69 | color: grey; 70 | } 71 | 72 | .bracket { 73 | color: grey; 74 | } 75 | 76 | .note { 77 | color: grey; 78 | } 79 | 80 | .main { 81 | display: flex; 82 | gap: 2rem; 83 | margin-bottom: 1rem; 84 | } 85 | 86 | .explode { 87 | color: #e74c3c; 88 | } 89 | 90 | .big { 91 | color: #f1c40f; 92 | } 93 | 94 | .string { 95 | flex-grow: 1; 96 | } 97 | -------------------------------------------------------------------------------- /2023/src/15/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const steps = parser.next()!.split(","); 6 | 7 | const boxes = new Map(); 8 | 9 | for (const step of steps) { 10 | let boxIndex = 0; 11 | 12 | let label: string; 13 | let operation; 14 | let focalLength: string = ""; 15 | 16 | if (step.includes("-")) { 17 | label = step.substring(0, step.length - 1); 18 | operation = "-"; 19 | } else { 20 | [label, focalLength] = step.split("="); 21 | operation = "="; 22 | } 23 | 24 | for (const char of label) { 25 | boxIndex += char.charCodeAt(0); 26 | boxIndex *= 17; 27 | boxIndex %= 256; 28 | } 29 | 30 | let lens: string[] = []; 31 | if (boxes.has(boxIndex)) lens = boxes.get(boxIndex)!; 32 | 33 | if (operation == "-") { 34 | // remove the lens 35 | lens = lens.filter((s) => s.split(" ")[0] != label); 36 | } else { 37 | // if there is already lens in this box with the same label 38 | let index = lens.findIndex((l) => l.split(" ")[0] === label); 39 | if (index !== -1) { 40 | lens.splice(index, 1, `${label} ${focalLength}`); 41 | } else { 42 | lens.push(`${label} ${focalLength}`); 43 | } 44 | } 45 | 46 | boxes.set(boxIndex, lens); 47 | } 48 | 49 | let sum = 0; 50 | 51 | for (const i of boxes.keys()) { 52 | let lenses = boxes.get(i)!; 53 | 54 | for (let j = 0; j < lenses.length; j++) { 55 | const lens = lenses[j]; 56 | const [, focalLength] = lens.split(" "); 57 | sum += (i + 1) * +focalLength * (j + 1); 58 | } 59 | } 60 | 61 | console.log("Sum", sum); 62 | -------------------------------------------------------------------------------- /2022/visualizations/14/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 14 10 | 11 | 14 | 15 | 16 |
17 |
18 | 26 |
27 | 28 | 39 |
40 |
41 | 42 |
43 |
44 |
45 |
46 |
47 |
48 | Number of sand units: 0 49 |
50 |
51 |
52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /2022/src/09/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | const headPosition = [0, 0]; 6 | const tailPosition = [0, 0]; 7 | const visited = new Set(); 8 | 9 | const updateTailPosition = () => { 10 | const [x, y] = tailPosition; 11 | const [xh, yh] = headPosition; 12 | 13 | if (xh == x && Math.abs(y - yh) > 1) { 14 | if (yh > y) tailPosition[1]++; 15 | else tailPosition[1]--; 16 | } 17 | 18 | if (yh == y && Math.abs(x - xh) > 1) { 19 | if (xh > x) tailPosition[0]++; 20 | else tailPosition[0]--; 21 | } 22 | 23 | if (xh != x && yh != y && !(Math.abs(x - xh) == 1 && Math.abs(y - yh) == 1)) { 24 | if (Math.abs(y - yh) == 1) { 25 | if (xh > x) tailPosition[0]++; 26 | else tailPosition[0]--; 27 | tailPosition[1] = yh; 28 | } 29 | 30 | if (Math.abs(x - xh) == 1) { 31 | if (yh > y) tailPosition[1]++; 32 | else tailPosition[1]--; 33 | tailPosition[0] = xh; 34 | } 35 | } 36 | 37 | visited.add(tailPosition.join(",")); 38 | }; 39 | 40 | while (inputParser.hasNext()) { 41 | const [direction, distance] = inputParser.next()!.split(" "); 42 | 43 | for (let c = 0; c < +distance; c++) { 44 | switch (direction) { 45 | case "R": 46 | headPosition[0]++; 47 | break; 48 | case "L": 49 | headPosition[0]--; 50 | break; 51 | case "U": 52 | headPosition[1]++; 53 | break; 54 | case "D": 55 | headPosition[1]--; 56 | break; 57 | } 58 | 59 | updateTailPosition(); 60 | } 61 | } 62 | 63 | console.log("Amount of visited positions: " + visited.size); 64 | -------------------------------------------------------------------------------- /2022/src/13/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("test.txt"); 4 | 5 | type ArrayType = (ArrayType | number)[]; 6 | 7 | const compareObjects = (a: ArrayType, b: ArrayType): number => { 8 | const minLen = Math.min(a.length, b.length); 9 | for (let i = 0; i < minLen; i++) { 10 | if (typeof a[i] == "number" && typeof b[i] == "number") { 11 | if (a[i] < b[i]) return 1; 12 | if (a[i] > b[i]) return -1; 13 | } 14 | let r; 15 | if (typeof a[i] == "object" && typeof b[i] == "object") { 16 | r = compareObjects(a[i] as ArrayType, b[i] as ArrayType); 17 | } 18 | 19 | if (typeof a[i] == "number" && typeof b[i] == "object") { 20 | r = compareObjects([a[i]], b[i] as ArrayType); 21 | } 22 | 23 | if (typeof a[i] == "object" && typeof b[i] == "number") { 24 | r = compareObjects(a[i] as ArrayType, [b[i]]); 25 | } 26 | 27 | if (r == 1) return 1; 28 | if (r == -1) return -1; 29 | } 30 | 31 | if (a.length < b.length) return 1; 32 | else if (a.length > b.length) return -1; 33 | else return 0; 34 | }; 35 | 36 | let i = 0; 37 | 38 | const ds1 = [[2]]; 39 | const ds2 = [[6]]; 40 | const packets = [ds1, ds2] as ArrayType[]; 41 | 42 | while (inputParser.hasNext()) { 43 | const [arr1, arr2] = inputParser 44 | .nextUntilEmptyLine()! 45 | .map((s) => eval(s)) as [ArrayType, ArrayType]; 46 | 47 | packets.push(arr1, arr2); 48 | } 49 | 50 | packets.sort((a, b) => -compareObjects(a, b)); 51 | 52 | console.log(compareObjects([1, 1, 5, 1, 1], [1, 1, 3, 1, 1])); 53 | console.log(packets); 54 | 55 | console.log((packets.indexOf(ds1) + 1) * (packets.indexOf(ds2) + 1)); 56 | -------------------------------------------------------------------------------- /2022/visualizations/index.ts: -------------------------------------------------------------------------------- 1 | import { join } from "path"; 2 | 3 | const elements = document.querySelectorAll( 4 | ".day-select" 5 | ) as NodeListOf; 6 | 7 | const options = document.querySelectorAll( 8 | ".option-select" 9 | ) as NodeListOf; 10 | 11 | const span = document.getElementById("t-name"); 12 | const methodSelect = document.getElementById("method-select"); 13 | 14 | let selectedDay; 15 | 16 | elements.forEach((e) => { 17 | const handleHover = () => { 18 | const day = e.getAttribute("x-attr-name"); 19 | span.textContent = day; 20 | }; 21 | 22 | e.addEventListener("mouseover", handleHover); 23 | e.addEventListener("focus", handleHover); 24 | e.addEventListener("click", () => { 25 | selectedDay = e.getAttribute("x-attr-data"); 26 | methodSelect.style.display = "block"; 27 | e.classList.add("selected"); 28 | options[0].focus(); 29 | elements.forEach((e) => (e.disabled = true)); 30 | }); 31 | }); 32 | 33 | options.forEach((o) => { 34 | o.addEventListener("click", async () => { 35 | const url = o.getAttribute("x-attr-data").replace("{day}", selectedDay); 36 | document.getElementById("loading")!.style.display = "block"; 37 | console.log(url); 38 | 39 | let str = ""; 40 | 41 | for (let i = 0; i < 20; i++) { 42 | await new Promise((r) => setTimeout(r, 50)); 43 | str += "#"; 44 | const fill = new Array(19 - i).fill(" ").join(""); 45 | console.log(fill); 46 | 47 | document.getElementById("loading")!.textContent = 48 | "Loading [" + str + fill + "]"; 49 | } 50 | 51 | window.location.href = url; 52 | }); 53 | }); 54 | 55 | elements[0].focus(); 56 | -------------------------------------------------------------------------------- /2021/17/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const data = input 5 | .getFullInput() 6 | .replaceAll("..", ",") 7 | .replaceAll("target area: x=", "") 8 | .replaceAll(" ", "") 9 | .replaceAll("y=", "") 10 | .split(",") 11 | .map(Number); 12 | 13 | const targetStart = [data[0], data[2]]; 14 | const targetEnd = [data[1], data[3]]; 15 | 16 | const doesTrajectoryCrossTarget = (vX: number, vY: number): [boolean, number, boolean, boolean] => { 17 | let x = 0; 18 | let y = 0; 19 | let result = undefined; 20 | let maxY = 0; 21 | 22 | let failsX = false; 23 | let failsY = false; 24 | 25 | let velY = vY; 26 | let velX = vX; 27 | 28 | while (result === undefined) { 29 | x += velX; 30 | y += velY; 31 | 32 | if (velX > 0) velX--; 33 | if (velX < 0) velX++; 34 | 35 | if (y > maxY) maxY = y; 36 | 37 | velY--; 38 | 39 | if (x >= targetStart[0] && x <= targetEnd[0] && y >= targetStart[1] && y <= targetEnd[1]) { 40 | result = true; 41 | } else if (x > targetEnd[0]) { 42 | failsX = true; 43 | result = false; 44 | } else if (y < targetStart[1]) { 45 | failsY = true; 46 | result = false; 47 | } 48 | } 49 | 50 | return [result, maxY, failsY, failsX]; 51 | }; 52 | 53 | // Yep, just bruteforce 54 | 55 | let maxY = 0; 56 | let end = false; 57 | 58 | for (let i = 0; i < 1000; i++) { 59 | for (let j = 0; j < 1000; j++) { 60 | const [crosses, y, failsY, failsX] = doesTrajectoryCrossTarget(i, j); 61 | if (crosses) { 62 | console.log(i, j, "hits!", y); 63 | if (y > maxY) maxY = y; 64 | } 65 | } 66 | } 67 | 68 | console.log("Max Y:", maxY); 69 | -------------------------------------------------------------------------------- /2021/visualizations/20/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: consolas; 3 | src: url("../font/Consolas.ttf"); 4 | } 5 | 6 | * { 7 | font-family: consolas, "consolas", "Roboto Mono", monospace; 8 | } 9 | 10 | .grids { 11 | display: flex; 12 | gap: 1rem; 13 | align-items: center; 14 | } 15 | 16 | body { 17 | color: #fff; 18 | background-color: #121212; 19 | white-space: nowrap; 20 | } 21 | 22 | .input { 23 | margin-bottom: 1rem; 24 | display: flex; 25 | align-items: center; 26 | gap: 1rem; 27 | } 28 | 29 | label { 30 | user-select: none; 31 | cursor: pointer; 32 | } 33 | 34 | textarea { 35 | background-color: rgba(255, 255, 255, 0.1); 36 | transition: 0.2s background-color, 0.2s border; 37 | border: 0; 38 | padding: 0.3rem; 39 | outline: 0; 40 | border: transparent solid 1px; 41 | min-width: 40rem; 42 | min-height: 8rem; 43 | color: #fff; 44 | } 45 | 46 | textarea:focus { 47 | border: rgba(255, 255, 255, 0.2) solid 1px; 48 | } 49 | 50 | .button { 51 | font-size: 1rem; 52 | background: 0; 53 | padding: 0; 54 | border: 0; 55 | display: block; 56 | cursor: pointer; 57 | transition: 0.2s; 58 | color: #3498db; 59 | user-select: none; 60 | } 61 | 62 | .button:hover { 63 | color: #3498db; 64 | opacity: 0.8; 65 | } 66 | 67 | .button:active { 68 | color: #3498db; 69 | opacity: 0.5; 70 | } 71 | 72 | .button:disabled { 73 | opacity: 0.2; 74 | cursor: not-allowed; 75 | } 76 | 77 | .grey { 78 | color: grey; 79 | } 80 | 81 | .active { 82 | color: #c0392b; 83 | } 84 | 85 | .main { 86 | display: flex; 87 | gap: 1rem; 88 | } 89 | 90 | .n { 91 | color: #3498db; 92 | } 93 | 94 | .dn { 95 | display: flex; 96 | gap: 0.5rem; 97 | } 98 | -------------------------------------------------------------------------------- /2022/src/18/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | const cubes = new Set(); 5 | const cubesUnvisited = new Set(); 6 | 7 | while (inputParser.hasNext()) { 8 | const [x, y, z] = inputParser.nextNumberArray(",")!; 9 | 10 | cubes.add(`${x},${y},${z}`); 11 | cubesUnvisited.add(`${x},${y},${z}`); 12 | } 13 | 14 | let surface = cubes.size * 6; 15 | 16 | const queue = [[...cubes.values()][0]]; 17 | 18 | const str = (x: number, y: number, z: number) => { 19 | return `${x},${y},${z}`; 20 | }; 21 | 22 | while (cubesUnvisited.size) { 23 | if (queue.length) { 24 | const cube = queue.shift()!; 25 | 26 | if (!cubesUnvisited.has(cube)) continue; 27 | cubesUnvisited.delete(cube); 28 | 29 | const [x, y, z] = cube.split(",").map(Number); 30 | 31 | if (cubes.has(str(x - 1, y, z))) { 32 | surface -= 1; 33 | queue.push(str(x - 1, y, z)); 34 | } 35 | 36 | if (cubes.has(str(x + 1, y, z))) { 37 | surface -= 1; 38 | queue.push(str(x + 1, y, z)); 39 | } 40 | 41 | if (cubes.has(str(x, y - 1, z))) { 42 | surface -= 1; 43 | queue.push(str(x, y - 1, z)); 44 | } 45 | 46 | if (cubes.has(str(x, y + 1, z))) { 47 | surface -= 1; 48 | queue.push(str(x, y + 1, z)); 49 | } 50 | 51 | if (cubes.has(str(x, y, z - 1))) { 52 | surface -= 1; 53 | queue.push(str(x, y, z - 1)); 54 | } 55 | 56 | if (cubes.has(str(x, y, z + 1))) { 57 | surface -= 1; 58 | queue.push(str(x, y, z + 1)); 59 | } 60 | } else { 61 | queue.push([...cubesUnvisited.values()][0]); 62 | } 63 | } 64 | 65 | console.log("Total surface area:", surface); 66 | -------------------------------------------------------------------------------- /2022/visualizations/09/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 09 10 | 11 | 14 | 15 | 16 |
17 |
18 | 25 |
26 | 27 | 38 |
39 |
40 | 41 |
42 |
43 |

44 |           
45 |
46 | 47 |
48 |
49 |
Part 1: 0
50 |
Part 2: 0
51 |
52 |
53 |
54 |
55 |
56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /2021/visualizations/15/data.txt: -------------------------------------------------------------------------------- 1 | 11637517422274862853338597396444961 2 | 13813736722492484783351359589446246 3 | 21365113283247622439435873354154698 4 | 36949315694715142671582625378269373 5 | 74634171118574528222968563933317967 6 | 13191281372421239248353234135946434 7 | 13599124212461123532357223464346833 8 | 31254216394236532741534764385264587 9 | 12931385212314249632342535174345364 10 | 23119445813422155692453326671356443 11 | 22748628533385973964449618417555172 12 | 24924847833513595894462461691557357 13 | 32476224394358733541546984465265719 14 | 47151426715826253782693736489371484 15 | 85745282229685639333179674144428178 16 | 24212392483532341359464345246157545 17 | 24611235323572234643468334575457944 18 | 42365327415347643852645875496375698 19 | 23142496323425351743453646285456475 20 | 34221556924533266713564437782467554 21 | 33859739644496184175551729528666283 22 | 35135958944624616915573572712668468 23 | 43587335415469844652657195576376821 24 | 58262537826937364893714847591482595 25 | 96856393331796741444281785255539289 26 | 35323413594643452461575456357268656 27 | 35722346434683345754579445686568155 28 | 53476438526458754963756986517486719 29 | 34253517434536462854564757396567586 30 | 45332667135644377824675548893578665 31 | 44961841755517295286662831639777394 32 | 46246169155735727126684683823779579 33 | 54698446526571955763768216687487932 34 | 69373648937148475914825958612593616 35 | 17967414442817852555392896366641391 36 | 46434524615754563572686567468379767 37 | 46833457545794456865681556797679266 38 | 64587549637569865174867197628597821 39 | 45364628545647573965675868417678697 40 | 56443778246755488935786659914689776 41 | 55172952866628316397773942741888415 42 | 57357271266846838237795794934881681 43 | 65719557637682166874879327798598143 44 | 71484759148259586125936169723614727 -------------------------------------------------------------------------------- /2023/src/08/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const instructions = parser.next()!; 6 | 7 | parser.next(); 8 | 9 | const nodes: { [id: string]: [string, string] } = {}; 10 | 11 | while (parser.hasNext()) { 12 | const [id, left, right] = parser.next()!.match(/[A-Z0-9]{3}/gm)!; 13 | nodes[id] = [left, right]; 14 | } 15 | 16 | let startPoints = Object.keys(nodes).filter((s) => s.endsWith("A")); 17 | 18 | console.log(startPoints); 19 | 20 | let loopSizes: number[] = []; 21 | let cyclesUntilZ = []; 22 | 23 | for (const start of startPoints) { 24 | let currentNode = start; 25 | let currInstr = 0; 26 | let zInterval = 0; 27 | let zFoundAt = 0; 28 | let counter = 0; 29 | 30 | while (1) { 31 | let instr = instructions[currInstr]; 32 | 33 | if (currentNode.endsWith("Z")) { 34 | if (zFoundAt) { 35 | zInterval = counter - zFoundAt; 36 | break; 37 | } else zFoundAt = counter; 38 | } 39 | 40 | // increment node 41 | if (instr === "L") currentNode = nodes[currentNode][0]; 42 | else currentNode = nodes[currentNode][1]; 43 | currInstr++; 44 | if (currInstr === instructions.length) currInstr = 0; 45 | counter++; 46 | } 47 | 48 | cyclesUntilZ.push(zInterval); 49 | } 50 | 51 | let gcf = (a: number, b: number) => { 52 | while (b != 0) { 53 | let temp = b; 54 | b = a % b; 55 | a = temp; 56 | } 57 | 58 | return a; 59 | }; 60 | 61 | let lcm = (a: number, b: number) => { 62 | return (a / gcf(a, b)) * b; 63 | }; 64 | 65 | let currentLcm = cyclesUntilZ[0]; 66 | 67 | for (let i = 1; i < cyclesUntilZ.length; i++) { 68 | currentLcm = lcm(currentLcm, cyclesUntilZ[i]); 69 | } 70 | 71 | console.log("Answer", currentLcm); 72 | -------------------------------------------------------------------------------- /2021/22/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | // ["off", [0, 0, 0], [52, 12, 30]] 5 | 6 | const rows: ["on" | "off", [number, number, number], [number, number, number]][] = input 7 | .getFullInput() 8 | .replaceAll("\r", "") 9 | .split("\n") 10 | .map((row) => { 11 | const [state, xVals, yValy, zVals] = row 12 | .replaceAll(",", " ") 13 | .replaceAll("x", "") 14 | .replaceAll("y", "") 15 | .replaceAll("z", "") 16 | .replaceAll("=", "") 17 | .split(" "); 18 | const x = xVals.split("..").map(Number); 19 | const y = yValy.split("..").map(Number); 20 | const z = zVals.split("..").map(Number); 21 | 22 | return [state as "on" | "off", [x[0] + 50, y[0] + 50, z[0] + 50], [x[1] + 50, y[1] + 50, z[1] + 50]]; 23 | }); 24 | 25 | const array: number[][][] = []; 26 | for (let x = 0; x < 101; x++) { 27 | array[x] = []; 28 | for (let y = 0; y < 101; y++) { 29 | array[x][y] = []; 30 | for (let z = 0; z < 101; z++) { 31 | array[x][y][z] = 0; 32 | } 33 | } 34 | } 35 | 36 | rows.forEach(([state, [x1, y1, z1], [x2, y2, z2]]) => { 37 | if (x1 < 0 || x2 > 100 || y1 < 0 || y2 > 100 || z1 < 0 || z2 > 100) return; 38 | for (let i = x1; i <= x2; i++) { 39 | for (let j = y1; j <= y2; j++) { 40 | for (let k = z1; k <= z2; k++) { 41 | array[i][j][k] = state === "on" ? 1 : 0; 42 | } 43 | } 44 | } 45 | }); 46 | 47 | const count = array.reduce((acc, row) => { 48 | return ( 49 | acc + 50 | row.reduce((acc2, row2) => { 51 | return ( 52 | acc2 + 53 | row2.reduce((acc3, row3) => { 54 | return acc3 + row3; 55 | }, 0) 56 | ); 57 | }, 0) 58 | ); 59 | }, 0); 60 | 61 | console.log(count); 62 | -------------------------------------------------------------------------------- /2021/visualizations/20/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Advent of code 2021 | Day 20 11 | 12 | 13 | 14 | 15 |
16 | 27 | 28 | 29 |
30 | 31 |
32 |
33 | 34 |
35 |
Binary: 0
36 |
Surroundings: ...
37 |
Pixels active: 0
38 |
Enhanced: 0
39 |
40 |
41 |
42 |
43 |
->
44 |
45 |
46 |
47 | 48 | 49 | -------------------------------------------------------------------------------- /2022/src/10/test.txt: -------------------------------------------------------------------------------- 1 | addx 15 2 | addx -11 3 | addx 6 4 | addx -3 5 | addx 5 6 | addx -1 7 | addx -8 8 | addx 13 9 | addx 4 10 | noop 11 | addx -1 12 | addx 5 13 | addx -1 14 | addx 5 15 | addx -1 16 | addx 5 17 | addx -1 18 | addx 5 19 | addx -1 20 | addx -35 21 | addx 1 22 | addx 24 23 | addx -19 24 | addx 1 25 | addx 16 26 | addx -11 27 | noop 28 | noop 29 | addx 21 30 | addx -15 31 | noop 32 | noop 33 | addx -3 34 | addx 9 35 | addx 1 36 | addx -3 37 | addx 8 38 | addx 1 39 | addx 5 40 | noop 41 | noop 42 | noop 43 | noop 44 | noop 45 | addx -36 46 | noop 47 | addx 1 48 | addx 7 49 | noop 50 | noop 51 | noop 52 | addx 2 53 | addx 6 54 | noop 55 | noop 56 | noop 57 | noop 58 | noop 59 | addx 1 60 | noop 61 | noop 62 | addx 7 63 | addx 1 64 | noop 65 | addx -13 66 | addx 13 67 | addx 7 68 | noop 69 | addx 1 70 | addx -33 71 | noop 72 | noop 73 | noop 74 | addx 2 75 | noop 76 | noop 77 | noop 78 | addx 8 79 | noop 80 | addx -1 81 | addx 2 82 | addx 1 83 | noop 84 | addx 17 85 | addx -9 86 | addx 1 87 | addx 1 88 | addx -3 89 | addx 11 90 | noop 91 | noop 92 | addx 1 93 | noop 94 | addx 1 95 | noop 96 | noop 97 | addx -13 98 | addx -19 99 | addx 1 100 | addx 3 101 | addx 26 102 | addx -30 103 | addx 12 104 | addx -1 105 | addx 3 106 | addx 1 107 | noop 108 | noop 109 | noop 110 | addx -9 111 | addx 18 112 | addx 1 113 | addx 2 114 | noop 115 | noop 116 | addx 9 117 | noop 118 | noop 119 | noop 120 | addx -1 121 | addx 2 122 | addx -37 123 | addx 1 124 | addx 3 125 | noop 126 | addx 15 127 | addx -21 128 | addx 22 129 | addx -6 130 | addx 1 131 | noop 132 | addx 2 133 | addx 1 134 | noop 135 | addx -10 136 | noop 137 | noop 138 | addx 20 139 | addx 1 140 | addx 2 141 | addx 2 142 | addx -6 143 | addx -11 144 | noop 145 | noop 146 | noop -------------------------------------------------------------------------------- /2022/visualizations/10/default.txt: -------------------------------------------------------------------------------- 1 | addx 15 2 | addx -11 3 | addx 6 4 | addx -3 5 | addx 5 6 | addx -1 7 | addx -8 8 | addx 13 9 | addx 4 10 | noop 11 | addx -1 12 | addx 5 13 | addx -1 14 | addx 5 15 | addx -1 16 | addx 5 17 | addx -1 18 | addx 5 19 | addx -1 20 | addx -35 21 | addx 1 22 | addx 24 23 | addx -19 24 | addx 1 25 | addx 16 26 | addx -11 27 | noop 28 | noop 29 | addx 21 30 | addx -15 31 | noop 32 | noop 33 | addx -3 34 | addx 9 35 | addx 1 36 | addx -3 37 | addx 8 38 | addx 1 39 | addx 5 40 | noop 41 | noop 42 | noop 43 | noop 44 | noop 45 | addx -36 46 | noop 47 | addx 1 48 | addx 7 49 | noop 50 | noop 51 | noop 52 | addx 2 53 | addx 6 54 | noop 55 | noop 56 | noop 57 | noop 58 | noop 59 | addx 1 60 | noop 61 | noop 62 | addx 7 63 | addx 1 64 | noop 65 | addx -13 66 | addx 13 67 | addx 7 68 | noop 69 | addx 1 70 | addx -33 71 | noop 72 | noop 73 | noop 74 | addx 2 75 | noop 76 | noop 77 | noop 78 | addx 8 79 | noop 80 | addx -1 81 | addx 2 82 | addx 1 83 | noop 84 | addx 17 85 | addx -9 86 | addx 1 87 | addx 1 88 | addx -3 89 | addx 11 90 | noop 91 | noop 92 | addx 1 93 | noop 94 | addx 1 95 | noop 96 | noop 97 | addx -13 98 | addx -19 99 | addx 1 100 | addx 3 101 | addx 26 102 | addx -30 103 | addx 12 104 | addx -1 105 | addx 3 106 | addx 1 107 | noop 108 | noop 109 | noop 110 | addx -9 111 | addx 18 112 | addx 1 113 | addx 2 114 | noop 115 | noop 116 | addx 9 117 | noop 118 | noop 119 | noop 120 | addx -1 121 | addx 2 122 | addx -37 123 | addx 1 124 | addx 3 125 | noop 126 | addx 15 127 | addx -21 128 | addx 22 129 | addx -6 130 | addx 1 131 | noop 132 | addx 2 133 | addx 1 134 | noop 135 | addx -10 136 | noop 137 | noop 138 | addx 20 139 | addx 1 140 | addx 2 141 | addx 2 142 | addx -6 143 | addx -11 144 | noop 145 | noop 146 | noop -------------------------------------------------------------------------------- /2023/src/07/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const cardData: { 6 | hand: string; 7 | handRank: number; 8 | bid: number; 9 | }[] = []; 10 | 11 | const getHandRank = (hand: string) => { 12 | const cardNumbering: { [card: string]: number } = {}; 13 | 14 | for (const card of hand) { 15 | if (cardNumbering[card]) cardNumbering[card]++; 16 | else cardNumbering[card] = 1; 17 | } 18 | 19 | const values = Object.values(cardNumbering); 20 | 21 | if (values.includes(5)) return 7; 22 | if (values.includes(4)) return 6; 23 | if (values.includes(3) && values.includes(2)) return 5; 24 | if (values.includes(3)) return 4; 25 | if (values.filter((s) => s == 2).length == 2) return 3; 26 | if (values.filter((s) => s == 1).length == 3) return 2; 27 | if (values.filter((s) => s == 1).length == 5) return 1; 28 | return 0; 29 | }; 30 | 31 | const cards = " 23456789TJQKA"; 32 | const getCardValue = (card: string) => { 33 | return cards.indexOf(card); 34 | }; 35 | 36 | while (parser.hasNext()) { 37 | const [hand, bidStr] = parser.next()!.split(" "); 38 | 39 | const cardRank = getHandRank(hand); 40 | 41 | cardData.push({ 42 | handRank: cardRank, 43 | bid: +bidStr, 44 | hand: hand, 45 | }); 46 | } 47 | 48 | cardData.sort((a, b) => { 49 | if (a.handRank !== b.handRank) return a.handRank - b.handRank; 50 | 51 | let cardIndex = 0; 52 | 53 | while (a.hand[cardIndex] == b.hand[cardIndex]) { 54 | cardIndex++; 55 | } 56 | 57 | return getCardValue(a.hand[cardIndex]) - getCardValue(b.hand[cardIndex]); 58 | }); 59 | 60 | console.log(cardData); 61 | 62 | let sum = 0; 63 | let i = 1; 64 | 65 | for (const record of cardData) { 66 | sum += i * record.bid; 67 | i++; 68 | } 69 | 70 | console.log("Answer:", sum); 71 | -------------------------------------------------------------------------------- /2021/10/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const pointTable = { 6 | ")": 3, 7 | "]": 57, 8 | "}": 1197, 9 | ">": 25137, 10 | }; 11 | 12 | let sum = 0; 13 | 14 | while (input.hasNext()) { 15 | const line = input.next()?.split("")!; 16 | const nested = []; 17 | let currentLevel = 0; 18 | const charStack: ("[" | "{" | "<" | "(")[] = []; 19 | 20 | console.log("READING", line.join("")); 21 | 22 | let wrongFound = false; 23 | 24 | line.forEach((char) => { 25 | if (wrongFound) return; 26 | if (char === "[" || char === "{" || char === "<" || char === "(") { 27 | charStack.push(char); 28 | currentLevel++; 29 | nested.push(currentLevel); 30 | } 31 | 32 | if (char === "]") { 33 | if (charStack[charStack.length - 1] === "[") { 34 | charStack.pop(); 35 | currentLevel--; 36 | } else { 37 | sum += pointTable[char]; 38 | wrongFound = true; 39 | } 40 | } 41 | 42 | if (char === "}") { 43 | if (charStack[charStack.length - 1] === "{") { 44 | charStack.pop(); 45 | currentLevel--; 46 | } else { 47 | sum += pointTable[char]; 48 | wrongFound = true; 49 | } 50 | } 51 | 52 | if (char === ">") { 53 | if (charStack[charStack.length - 1] === "<") { 54 | charStack.pop(); 55 | currentLevel--; 56 | } else { 57 | sum += pointTable[char]; 58 | wrongFound = true; 59 | } 60 | } 61 | 62 | if (char === ")") { 63 | if (charStack[charStack.length - 1] === "(") { 64 | charStack.pop(); 65 | currentLevel--; 66 | } else { 67 | sum += pointTable[char]; 68 | wrongFound = true; 69 | } 70 | } 71 | }); 72 | } 73 | 74 | console.log(sum); 75 | -------------------------------------------------------------------------------- /2022/src/10/in.txt: -------------------------------------------------------------------------------- 1 | addx 1 2 | noop 3 | addx 2 4 | addx 11 5 | addx -4 6 | noop 7 | noop 8 | noop 9 | noop 10 | addx 3 11 | addx -3 12 | addx 10 13 | addx 1 14 | noop 15 | addx 12 16 | addx -8 17 | addx 5 18 | noop 19 | noop 20 | addx 1 21 | addx 4 22 | addx -12 23 | noop 24 | addx -25 25 | addx 14 26 | addx -7 27 | noop 28 | addx 11 29 | noop 30 | addx -6 31 | addx 3 32 | noop 33 | addx 2 34 | addx 22 35 | addx -12 36 | addx -17 37 | addx 15 38 | addx 2 39 | addx 10 40 | addx -9 41 | noop 42 | noop 43 | noop 44 | addx 5 45 | addx 2 46 | addx -33 47 | noop 48 | noop 49 | noop 50 | noop 51 | addx 12 52 | addx -9 53 | addx 7 54 | noop 55 | noop 56 | addx 3 57 | addx -2 58 | addx 2 59 | addx 26 60 | addx -31 61 | addx 14 62 | addx 3 63 | noop 64 | addx 13 65 | addx -1 66 | noop 67 | addx -5 68 | addx -13 69 | addx 14 70 | noop 71 | addx -20 72 | addx -15 73 | noop 74 | addx 7 75 | noop 76 | addx 31 77 | noop 78 | addx -26 79 | noop 80 | noop 81 | noop 82 | addx 5 83 | addx 20 84 | addx -11 85 | addx -3 86 | addx 9 87 | addx -5 88 | addx 2 89 | noop 90 | addx 4 91 | noop 92 | addx 4 93 | noop 94 | noop 95 | addx -7 96 | addx -30 97 | noop 98 | addx 7 99 | noop 100 | noop 101 | addx -2 102 | addx -4 103 | addx 11 104 | addx 14 105 | addx -9 106 | addx -2 107 | noop 108 | addx 7 109 | noop 110 | addx -11 111 | addx -5 112 | addx 19 113 | addx 5 114 | addx 2 115 | addx 5 116 | noop 117 | noop 118 | addx -2 119 | addx -27 120 | addx -6 121 | addx 1 122 | noop 123 | noop 124 | addx 4 125 | addx 1 126 | addx 4 127 | addx 5 128 | noop 129 | noop 130 | noop 131 | addx 1 132 | noop 133 | addx 4 134 | addx 1 135 | noop 136 | noop 137 | addx 5 138 | noop 139 | noop 140 | addx 4 141 | addx 1 142 | noop 143 | addx 4 144 | addx 1 145 | noop 146 | noop 147 | noop 148 | noop -------------------------------------------------------------------------------- /2022/visualizations/11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 11 10 | 11 | 14 | 15 | 16 |
17 |
18 | 25 |
26 | 27 | 38 |
39 |
40 | 41 |
42 |
43 |
44 |
45 |
46 | 47 |
48 |
49 |
50 | 51 |
52 |
53 |
54 |
Round: 0
55 |
56 |
57 |
58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /2021/13/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const [data, folds] = input.getFullInput().split("\r\n\r\n"); 6 | const cords = data.split("\r\n").map((cord) => cord.split(",").map(Number)); 7 | 8 | const xArray = data.split("\r\n").map((x) => +x.split(",")[0]); 9 | const yArray = data.split("\r\n").map((x) => +x.split(",")[1]); 10 | 11 | const xMax = Math.max(...xArray); 12 | const yMax = Math.max(...yArray); 13 | 14 | const grid = new Array(yMax + 1).fill(".").map(() => new Array(xMax + 1).fill(".")); 15 | 16 | for (const cord of cords) { 17 | const [x, y] = cord; 18 | grid[y][x] = "#"; 19 | } 20 | 21 | const removeRows = (from: number, to: number) => { 22 | grid.splice(from, to + 1); 23 | }; 24 | 25 | const removeCols = (from: number, to: number) => { 26 | grid.forEach((row) => row.splice(from, to + 1)); 27 | }; 28 | 29 | for (const fold of folds.split("\r\n")) { 30 | const [line, value] = fold.split("="); 31 | 32 | if (line.includes("x")) { 33 | for (let i in grid) { 34 | for (let j = +value + 1; j < grid[i].length; j++) { 35 | if (grid[i][j] === "#") { 36 | grid[i][j] = "."; 37 | grid[i][+value - (j - +value)] = "#"; 38 | } 39 | } 40 | } 41 | 42 | removeCols(+value, grid[0].length - 1); 43 | } else { 44 | for (let i = +value + 1; i <= grid.length - 1; i++) { 45 | for (let j = 0; j < grid[i].length; j++) { 46 | if (grid[i][j] === "#") { 47 | grid[i][j] = "."; 48 | grid[+value - (i - +value)][j] = "#"; 49 | } 50 | } 51 | } 52 | 53 | removeRows(+value, grid.length - 1); 54 | } 55 | } 56 | 57 | const printReadable = () => { 58 | console.log(grid.map((row) => row.join("").replaceAll(".", " ").replaceAll("#", "██")).join("\r\n")); 59 | }; 60 | 61 | printReadable(); 62 | -------------------------------------------------------------------------------- /2021/visualizations/17/style.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: consolas; 3 | src: url("../font/Consolas.ttf"); 4 | } 5 | 6 | * { 7 | font-family: consolas, "consolas", "Roboto Mono", monospace; 8 | } 9 | 10 | body { 11 | color: #fff; 12 | background-color: #121212; 13 | white-space: nowrap; 14 | } 15 | 16 | .ckeckbox { 17 | display: flex; 18 | align-items: center; 19 | gap: 0.2rem; 20 | } 21 | 22 | .input { 23 | margin-bottom: 1rem; 24 | display: flex; 25 | align-items: center; 26 | gap: 1rem; 27 | } 28 | 29 | label { 30 | user-select: none; 31 | cursor: pointer; 32 | } 33 | 34 | input { 35 | background-color: rgba(255, 255, 255, 0.1); 36 | transition: 0.2s; 37 | border: 0; 38 | padding: 0.3rem; 39 | outline: 0; 40 | border: transparent solid 1px; 41 | 42 | color: #fff; 43 | } 44 | 45 | input:focus { 46 | border: rgba(255, 255, 255, 0.2) solid 1px; 47 | } 48 | 49 | #run { 50 | cursor: pointer; 51 | transition: 0.2s; 52 | } 53 | 54 | #run:hover { 55 | color: #3498db; 56 | } 57 | 58 | .nothing { 59 | color: grey; 60 | cursor: context-menu; 61 | } 62 | 63 | .submarine { 64 | color: #3498db; 65 | } 66 | 67 | .trajectory { 68 | color: #e74c3c; 69 | cursor: context-menu; 70 | } 71 | 72 | .success { 73 | color: #27ae60; 74 | } 75 | 76 | .flex { 77 | display: flex; 78 | gap: 2rem; 79 | align-items: flex-start; 80 | } 81 | 82 | .title { 83 | font-size: 1.5rem; 84 | margin-bottom: 0.5rem; 85 | } 86 | 87 | .n { 88 | color: #3498db; 89 | } 90 | 91 | .data { 92 | position: sticky; 93 | top: 0; 94 | } 95 | 96 | .row-label { 97 | display: inline-block; 98 | width: 2rem; 99 | text-align: right; 100 | margin-right: 1rem; 101 | color: grey; 102 | } 103 | 104 | .row:hover .row-label { 105 | color: #fff; 106 | } 107 | -------------------------------------------------------------------------------- /2022/visualizations/10/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 10 10 | 11 | 14 | 15 | 16 |
17 |
18 | 25 |
26 | 27 | 38 |
39 |
40 | 41 |
42 |
43 |
44 | Sprite position:
45 | Clock cycle:
46 |
47 | 48 |
49 |

50 |             

51 |           
52 |
53 | 54 |
55 |
56 |
57 |
58 |
59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /2021/04/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const boards = input 5 | .getFullInput() 6 | .replaceAll(" ", " ") 7 | .split("\r\n\r\n") 8 | .map((x) => x.split("\r\n").map((y) => y.split(" ").filter((z) => z !== ""))); 9 | 10 | const numbers = boards.shift()![0][0].split(","); 11 | 12 | const checkNumbers = (num: string) => { 13 | boards.forEach((board, bs) => { 14 | board.forEach((row, i) => { 15 | row.forEach((number, k) => { 16 | if (number === num) { 17 | boards[bs][i][k] = "x"; 18 | } 19 | }); 20 | }); 21 | }); 22 | }; 23 | 24 | const checkForWin = (board: string[][]) => { 25 | let win = false; 26 | 27 | board.forEach((row, i) => { 28 | if (row.every((x) => x === "x")) { 29 | win = true; 30 | } 31 | }); 32 | 33 | for (let i = 0; i < board[0].length; i++) { 34 | let col = []; 35 | for (let row of board) { 36 | col.push(row[i]); 37 | } 38 | if (col.every((x) => x === "x")) { 39 | win = true; 40 | } 41 | } 42 | 43 | return win; 44 | }; 45 | 46 | const getSum = (board: string[][]) => { 47 | let sum = 0; 48 | board.forEach((row) => { 49 | row.forEach((num) => { 50 | if (num !== "x") sum += parseInt(num, 10); 51 | }); 52 | }); 53 | return sum; 54 | }; 55 | 56 | let boardsThatWon: string[][][] = []; 57 | let rounds = 0; 58 | for (let number of numbers) { 59 | rounds++; 60 | checkNumbers(number); 61 | 62 | let end = false; 63 | 64 | for (let board of boards) { 65 | if (!boardsThatWon.includes(board) && checkForWin(board)) { 66 | boardsThatWon.push(board); 67 | } 68 | 69 | if (boardsThatWon.length === boards.length) { 70 | console.log(getSum(boardsThatWon[boardsThatWon.length - 1]) * +number); 71 | end = true; 72 | break; 73 | } 74 | } 75 | 76 | if (end) break; 77 | } 78 | -------------------------------------------------------------------------------- /2023/src/11/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | let grid = parser.loadAsGrid(); 5 | 6 | // expand the universe 7 | let newGrid: string[][] = []; 8 | 9 | // start with rows 10 | for (let y = 0; y < grid.length; y++) { 11 | newGrid.push([...grid[y]]); 12 | if (grid[y].every((r) => r === ".")) { 13 | newGrid.push(new Array(grid[y].length).fill(".")); 14 | } 15 | } 16 | 17 | grid = newGrid; 18 | newGrid = []; 19 | 20 | for (let i = 0; i < grid.length; i++) newGrid.push([]); 21 | 22 | // expand columns 23 | for (let x = 0; x < grid[0].length; x++) { 24 | let addNew = grid.every((r) => r[x] === "."); 25 | 26 | for (let y = 0; y < grid.length; y++) { 27 | newGrid[y].push(grid[y][x]); 28 | if (addNew) newGrid[y].push("."); 29 | } 30 | } 31 | 32 | grid = newGrid; 33 | newGrid = []; 34 | 35 | // expanding complete, create pair and measure distances 36 | const galaxies: [number, number][] = []; 37 | 38 | for (let y = 0; y < grid.length; y++) { 39 | for (let x = 0; x < grid[y].length; x++) { 40 | if (grid[y][x] === "#") galaxies.push([y, x]); 41 | } 42 | } 43 | 44 | const distances = new Map(); 45 | 46 | // match every with every 47 | for (const g1 of galaxies) { 48 | for (const g2 of galaxies) { 49 | if (g1[0] == g2[0] && g1[1] == g2[1]) continue; 50 | 51 | let key = ""; 52 | if (g1[0] > g2[0]) key = `${g1.join()};${g2.join()}`; 53 | else if (g2[0] > g1[0]) key = `${g2.join()};${g1.join()}`; 54 | else { 55 | if (g1[1] > g2[1]) key = `${g1.join()};${g2.join()}`; 56 | else key = `${g2.join()};${g1.join()}`; 57 | } 58 | 59 | if (distances.has(key)) continue; 60 | 61 | distances.set(key, Math.abs(g1[0] - g2[0]) + Math.abs(g1[1] - g2[1])); 62 | } 63 | } 64 | 65 | let sum = 0; 66 | 67 | for (const v of distances.values()) { 68 | sum += v; 69 | } 70 | 71 | console.log(sum); 72 | -------------------------------------------------------------------------------- /2021/13/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const [data, folds] = input.getFullInput().split("\r\n\r\n"); 6 | const cords = data.split("\r\n").map((cord) => cord.split(",").map(Number)); 7 | 8 | const xArray = data.split("\r\n").map((x) => +x.split(",")[0]); 9 | const yArray = data.split("\r\n").map((x) => +x.split(",")[1]); 10 | 11 | const xMax = Math.max(...xArray); 12 | const yMax = Math.max(...yArray); 13 | 14 | const grid = new Array(yMax + 1) 15 | .fill(".") 16 | .map(() => new Array(xMax + 1).fill(".")); 17 | 18 | for (const cord of cords) { 19 | const [x, y] = cord; 20 | grid[y][x] = "#"; 21 | } 22 | 23 | const [line, value] = folds.split("\r\n")[0].split("="); 24 | 25 | const removeRows = (from: number, to: number) => { 26 | grid.splice(from, to + 1); 27 | }; 28 | 29 | const removeCols = (from: number, to: number) => { 30 | grid.forEach((row) => row.splice(from, to + 1)); 31 | }; 32 | 33 | const countPoints = () => { 34 | let count = 0; 35 | for (const row of grid) { 36 | for (const point of row) { 37 | if (point === "#") { 38 | count++; 39 | } 40 | } 41 | } 42 | return count; 43 | }; 44 | 45 | if (line.includes("x")) { 46 | for (let i in grid) { 47 | for (let j = +value + 1; j < grid[i].length; j++) { 48 | if (grid[i][j] === "#") { 49 | grid[i][j] = "."; 50 | grid[i][+value - (j - +value)] = "#"; 51 | } 52 | } 53 | } 54 | 55 | removeCols(+value, grid[0].length - 1); 56 | } else { 57 | for (let i = +value + 1; i <= grid.length - 1; i++) { 58 | console.log("working on", grid[i]); 59 | for (let j = 0; j < grid[i].length; j++) { 60 | if (grid[i][j] === "#") { 61 | grid[i][j] = "."; 62 | grid[+value - (i - +value)][j] = "#"; 63 | } 64 | } 65 | } 66 | 67 | removeRows(+value, grid.length - 1); 68 | } 69 | 70 | console.log(countPoints()); 71 | -------------------------------------------------------------------------------- /2023/src/03/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const grid = parser.nextUntilEmptyLine()!.map((s) => { 6 | const arr = s.split(""); 7 | arr.push("."); 8 | return arr; 9 | }); 10 | 11 | console.log(grid); 12 | 13 | const checkForSymbolsInArea = ( 14 | x1: number, 15 | x2: number, 16 | y1: number, 17 | y2: number 18 | ) => { 19 | if (x1 < 0) x1 = 0; 20 | if (x2 >= grid[0].length) x2 = grid[0].length - 1; 21 | if (y1 < 0) y1 = 0; 22 | if (y2 >= grid.length) y2 = grid.length - 1; 23 | 24 | for (let y = y1; y <= y2; y++) { 25 | for (let x = x1; x <= x2; x++) { 26 | const value = grid[y][x]; 27 | 28 | if (isNaN(+value) && value != ".") return true; 29 | } 30 | } 31 | 32 | return false; 33 | }; 34 | 35 | let sum = 0; 36 | 37 | let currentNumber = ""; 38 | let currentlyInNumber = false; 39 | let numberCoords = { 40 | x1: 0, 41 | y1: 0, 42 | x2: 0, 43 | y2: 0, 44 | }; 45 | 46 | for (let y = 0; y < grid.length; y++) { 47 | for (let x = 0; x < grid[y].length; x++) { 48 | const value = grid[y][x]; 49 | 50 | if (!isNaN(+value) && !currentlyInNumber) { 51 | currentlyInNumber = true; 52 | numberCoords.x1 = x; 53 | numberCoords.y1 = y; 54 | } 55 | 56 | if (isNaN(+value) && currentlyInNumber) { 57 | // number ended 58 | currentlyInNumber = false; 59 | 60 | numberCoords.y2 = y; 61 | numberCoords.x2 = x - 1; 62 | 63 | let hasSymbol = checkForSymbolsInArea( 64 | numberCoords.x1 - 1, 65 | numberCoords.x2 + 1, 66 | numberCoords.y1 - 1, 67 | numberCoords.y2 + 1 68 | ); 69 | 70 | console.log("Found number", +currentNumber, hasSymbol); 71 | if (hasSymbol) sum += +currentNumber; 72 | currentNumber = ""; 73 | } 74 | 75 | if (currentlyInNumber) currentNumber += value; 76 | } 77 | } 78 | 79 | console.log(sum); 80 | -------------------------------------------------------------------------------- /2021/04/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const boards = input 5 | .getFullInput() 6 | .replaceAll(" ", " ") 7 | .split("\r\n\r\n") 8 | .map((x) => x.split("\r\n").map((y) => y.split(" ").filter((z) => z !== ""))); 9 | 10 | const numbers = boards.shift()![0][0].split(","); 11 | 12 | const checkNumbers = (num: string) => { 13 | boards.forEach((board, bs) => { 14 | board.forEach((row, i) => { 15 | row.forEach((number, k) => { 16 | if (number === num) { 17 | boards[bs][i][k] = "x"; 18 | } 19 | }); 20 | }); 21 | }); 22 | }; 23 | 24 | const checkForWin = (board: string[][]) => { 25 | let win = false; 26 | 27 | board.forEach((row, i) => { 28 | if (row.every((x) => x === "x")) { 29 | win = true; 30 | } 31 | }); 32 | 33 | for (let i = 0; i < board[0].length; i++) { 34 | let col = []; 35 | for (let row of board) { 36 | col.push(row[i]); 37 | } 38 | if (col.every((x) => x === "x")) { 39 | win = true; 40 | } 41 | } 42 | 43 | return win; 44 | }; 45 | 46 | const getSum = (board: string[][]) => { 47 | let sum = 0; 48 | board.forEach((row) => { 49 | row.forEach((num) => { 50 | if (num !== "x") sum += parseInt(num, 10); 51 | }); 52 | }); 53 | return sum; 54 | }; 55 | 56 | let rounds = 0; 57 | for (let number of numbers) { 58 | rounds++; 59 | checkNumbers(number); 60 | 61 | let won = false; 62 | 63 | for (let board of boards) { 64 | if (checkForWin(board)) { 65 | const sum = getSum(board); 66 | console.log(sum * +number); 67 | won = true; 68 | } 69 | } 70 | 71 | if (won) break; 72 | } 73 | 74 | 75 | const secondsToTime = (s: number) => { 76 | const hours = Math.floor(s / 3600); 77 | const minutes = Math.floor((s - hours * 3600) / 60); 78 | const seconds = s - hours * 3600 - minutes * 60; 79 | 80 | return `${hours}:${minutes}:${seconds}`; 81 | } -------------------------------------------------------------------------------- /2022/src/lib/files.ts: -------------------------------------------------------------------------------- 1 | import * as fs from "fs"; 2 | 3 | export class InputParser { 4 | private lines: string[]; 5 | private linesRead: number = 0; 6 | 7 | constructor(filename: string, private outputname?: string) { 8 | console.log(`Loading file ${filename} as input`); 9 | const file = fs.readFileSync(filename, "utf8"); 10 | console.log(`File loaded!`); 11 | this.lines = file.split("\n").filter((line) => line); 12 | 13 | if (outputname) { 14 | console.log(`Output file: ${outputname}`); 15 | // Clear the file 16 | fs.writeFileSync(outputname, "", { flag: "w" }); 17 | } 18 | } 19 | 20 | public appendOutput(output: string) { 21 | if (this.outputname) { 22 | fs.appendFileSync(this.outputname, output + "\n"); 23 | } 24 | } 25 | 26 | public next(moveSelector = true): string | null { 27 | if (this.linesRead >= this.lines.length) { 28 | return null; 29 | } 30 | const line = this.lines[this.linesRead]; 31 | 32 | if (moveSelector) this.linesRead++; 33 | 34 | return line.replace("\r", ""); 35 | } 36 | 37 | public nextUntilEmptyLine(): string[] | null { 38 | const lines: string[] = []; 39 | let line = this.next(); 40 | while (line !== null && line !== "") { 41 | lines.push(line); 42 | line = this.next(); 43 | } 44 | return lines; 45 | } 46 | 47 | public nextNumber(): number | null { 48 | const line = this.next(); 49 | if (line === null) { 50 | return null; 51 | } 52 | return parseInt(line); 53 | } 54 | 55 | public nextNumberArray(spearator = " "): number[] | null { 56 | const line = this.next(); 57 | if (line === null) { 58 | return null; 59 | } 60 | return line.trim().split(spearator).map(Number); 61 | } 62 | 63 | public hasNext(): boolean { 64 | return this.linesRead < this.lines.length; 65 | } 66 | 67 | public getFullInput(): string { 68 | return this.lines.join("\n"); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /2022/src/14/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | const rockPositions = new Set(); 6 | 7 | let maxY = 0; 8 | 9 | while (inputParser.hasNext()) { 10 | const pathPoints = inputParser.next()!.split(" -> "); 11 | 12 | for (let i = 0; i < pathPoints.length - 1; i++) { 13 | const [x1, y1] = pathPoints[i].split(",").map(Number); 14 | const [x2, y2] = pathPoints[i + 1].split(",").map(Number); 15 | 16 | maxY = Math.max(maxY, y1, y2); 17 | 18 | if (x1 == x2) { 19 | const minY = Math.min(y1, y2); 20 | const maxY = Math.max(y1, y2); 21 | for (let y = minY; y <= maxY; y++) { 22 | rockPositions.add(`${x1},${y}`); 23 | } 24 | } else { 25 | const minX = Math.min(x1, x2); 26 | const maxX = Math.max(x1, x2); 27 | for (let x = minX; x <= maxX; x++) { 28 | rockPositions.add(`${x},${y1}`); 29 | } 30 | } 31 | } 32 | } 33 | 34 | const sandPositions = new Set(); 35 | 36 | let end = false; 37 | 38 | while (!end) { 39 | const sand = [500, 0]; 40 | 41 | // move sand 42 | while (!end) { 43 | const [x, y] = sand; 44 | if (y > maxY) { 45 | end = true; 46 | continue; 47 | } 48 | 49 | if ( 50 | !rockPositions.has(`${x},${y + 1}`) && 51 | !sandPositions.has(`${x},${y + 1}`) 52 | ) { 53 | sand[1] += 1; 54 | continue; 55 | } 56 | 57 | if ( 58 | !rockPositions.has(`${x - 1},${y + 1}`) && 59 | !sandPositions.has(`${x - 1},${y + 1}`) 60 | ) { 61 | sand[0] -= 1; 62 | sand[1] += 1; 63 | continue; 64 | } 65 | 66 | if ( 67 | !rockPositions.has(`${x + 1},${y + 1}`) && 68 | !sandPositions.has(`${x + 1},${y + 1}`) 69 | ) { 70 | sand[0] += 1; 71 | sand[1] += 1; 72 | continue; 73 | } 74 | 75 | sandPositions.add(`${x},${y}`); 76 | break; 77 | } 78 | } 79 | 80 | console.log(sandPositions.size); 81 | -------------------------------------------------------------------------------- /2021/05/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let data = input 5 | .getFullInput() 6 | .split("\r\n") 7 | .map((s) => s.split(" -> ").map((s) => s.split(",").map(Number))); 8 | 9 | const maxX = Math.max( 10 | ...data.map((d) => (d[0][0] > d[0][1] ? d[0][0] : d[0][1])) 11 | ); 12 | 13 | const maxY = Math.max( 14 | ...data.map((d) => (d[1][0] > d[1][1] ? d[1][0] : d[1][1])) 15 | ); 16 | 17 | const diagonals = data.filter( 18 | (d) => d[0][0] !== d[1][0] && d[0][1] !== d[1][1] 19 | ); 20 | data = data.filter((d) => d[0][0] === d[1][0] || d[0][1] === d[1][1]); 21 | 22 | let grid: string[][] = []; 23 | 24 | grid = new Array(maxY + 1).fill(0).map(() => new Array(maxX + 1).fill(".")); 25 | data.forEach((record, i) => { 26 | const [[x1, y1], [x2, y2]] = record; 27 | for (let x = x1 < x2 ? x1 : x2; x2 > x1 ? x <= x2 : x <= x1; x++) { 28 | for (let y = y1 < y2 ? y1 : y2; y2 > y1 ? y <= y2 : y <= y1; y++) { 29 | if (grid[y][x] === "x" || grid[y][x] === "I") { 30 | grid[y][x] = "I"; 31 | continue; 32 | } 33 | grid[y][x] = "x"; 34 | } 35 | } 36 | }); 37 | 38 | diagonals.forEach((record, i) => { 39 | const [[x1, y1], [x2, y2]] = record; 40 | let y = x1 < x2 ? y1 : y2; 41 | const selected = x1 < x2 ? "y1" : "y2"; 42 | for (let x = x1 < x2 ? x1 : x2; x2 > x1 ? x <= x2 : x <= x1; x++) { 43 | // console.log("Doin", x, y, grid.length, grid[0].length, maxY, maxX); 44 | 45 | if (grid[y][x] === "x" || grid[y][x] === "I") { 46 | grid[y][x] = "I"; 47 | } else { 48 | grid[y][x] = "x"; 49 | } 50 | 51 | if (selected === "y1") { 52 | y1 > y2 ? y-- : y++; 53 | } else { 54 | y1 > y2 ? y++ : y--; 55 | } 56 | } 57 | }); 58 | 59 | const Is = grid.reduce((acc, row) => { 60 | return ( 61 | acc + 62 | row.reduce((acc, cell) => { 63 | return acc + (cell === "I" ? 1 : 0); 64 | }, 0) 65 | ); 66 | }, 0); 67 | 68 | console.log(Is); 69 | -------------------------------------------------------------------------------- /2021/12/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | interface Node { 6 | id: string; 7 | goTo: number[]; 8 | links: string[]; 9 | } 10 | 11 | const nodes: Node[] = []; 12 | 13 | while (input.hasNext()) { 14 | const line = input.next()!; 15 | const [nodeA, nodeB] = line.split("-"); 16 | 17 | const nodeAIndex = nodes.findIndex((n) => n.id === nodeA); 18 | const nodeBIndex = nodes.findIndex((n) => n.id === nodeB); 19 | 20 | console.log(nodeAIndex, nodeBIndex); 21 | 22 | if (nodeAIndex === -1) { 23 | nodes.push({ 24 | id: nodeA, 25 | goTo: [0], 26 | links: [nodeB], 27 | }); 28 | } 29 | if (nodeBIndex === -1) { 30 | nodes.push({ 31 | id: nodeB, 32 | goTo: [0], 33 | links: [nodeA], 34 | }); 35 | } 36 | 37 | if (nodeAIndex !== -1) { 38 | nodes[nodeAIndex].links.push(nodeB); 39 | } 40 | 41 | if (nodeBIndex !== -1) { 42 | nodes[nodeBIndex].links.push(nodeA); 43 | } 44 | } 45 | 46 | const count = (array: any[]) => { 47 | const elements: { [k: string]: number } = {}; 48 | for (const element of array) { 49 | if (!elements[element]) { 50 | elements[element] = 0; 51 | } 52 | elements[element]++; 53 | } 54 | 55 | return elements; 56 | }; 57 | 58 | const paths: string[][] = []; 59 | paths.push(["start"]); 60 | const completes: string[][] = []; 61 | 62 | while (paths.length) { 63 | const p0 = paths.shift()!; 64 | for (let s of nodes.find((n) => n.id === p0[p0.length - 1])!.links) { 65 | if (s === "start") continue; 66 | 67 | if (s.toLowerCase() === s) { 68 | const c = p0.filter((id) => id.toLowerCase() === id); 69 | if (Object.values(count(c)).includes(2) && p0.includes(s)) continue; 70 | } 71 | 72 | const p1 = [...p0, s]; 73 | 74 | if (s === "end") { 75 | completes.push(p1); 76 | } else { 77 | paths.push(p1); 78 | } 79 | } 80 | } 81 | 82 | console.log(completes.length); 83 | -------------------------------------------------------------------------------- /2022/visualizations/08/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | AOC 2022 / Day 08 10 | 11 | 14 | 15 | 16 |
17 |
18 | 25 |
26 | 27 |
30 | 31 | 42 |
43 |
44 | 45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | 53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /2021/03/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let data = input.getFullInput().split("\r\n"); 5 | 6 | let gamma = ""; 7 | let epsilon = ""; 8 | 9 | const bin2dec = (bin: string) => { 10 | return parseInt(bin, 2); 11 | }; 12 | 13 | const getMostcommonBitAtColumnd = (col: number) => { 14 | let zeros = 0; 15 | let ones = 0; 16 | 17 | data.forEach((row) => { 18 | if (row[col] === "0") zeros++; 19 | else ones++; 20 | }); 21 | 22 | return [zeros, ones]; 23 | }; 24 | 25 | const deleteDataWithBitOnPosition = (bit: string, position: number) => { 26 | const to_remove: number[] = []; 27 | data.forEach((row, index) => { 28 | if (row[position] === bit) { 29 | to_remove.push(index); 30 | } 31 | }); 32 | 33 | to_remove.sort((a, b) => b - a); 34 | 35 | to_remove.forEach((index) => { 36 | if (data.length === 1) return; 37 | data.splice(index, 1); 38 | }); 39 | }; 40 | 41 | const findOxygenRating = () => { 42 | const len = data[0].length; 43 | for (let i = 0; i < len; i++) { 44 | const [zeroes, ones] = getMostcommonBitAtColumnd(i); 45 | 46 | if (zeroes > ones) { 47 | deleteDataWithBitOnPosition("1", i); 48 | } 49 | 50 | if (ones > zeroes || zeroes === ones) { 51 | deleteDataWithBitOnPosition("0", i); 52 | } 53 | } 54 | }; 55 | 56 | const findLifeSupportRating = () => { 57 | const len = data[0].length; 58 | for (let i = 0; i < len; i++) { 59 | const [zeroes, ones] = getMostcommonBitAtColumnd(i); 60 | 61 | if (zeroes < ones || zeroes === ones) { 62 | deleteDataWithBitOnPosition("1", i); 63 | } 64 | 65 | if (ones < zeroes) { 66 | deleteDataWithBitOnPosition("0", i); 67 | } 68 | } 69 | }; 70 | 71 | findOxygenRating(); 72 | let oxygen_rating = data[0]; 73 | 74 | data = input.getFullInput().split("\r\n"); 75 | 76 | findLifeSupportRating(); 77 | let life_support_rating = data[0]; 78 | 79 | console.log(bin2dec(oxygen_rating) * bin2dec(life_support_rating)); 80 | -------------------------------------------------------------------------------- /2021/visualizations/16/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Advent of code 2021 | Day 16 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | [visualize] 19 |
20 |
21 |
22 |
23 |
24 |
25 |
██ Version
26 |
██ Type
27 |
██ Literal value
28 |
██ Ending mark bit
29 |
██ Type of length of operator
30 |
██ Length of operator
31 |
32 |
33 |
+   Addition
34 |
*   Multiplication
35 |
min Minimum
36 |
max Maximum
37 |
ltr Literal value
38 |
>   Is less than
39 |
<   Is greater than
40 |
==  Are equal
41 |
42 |
43 | 44 | 45 | -------------------------------------------------------------------------------- /2023/src/13/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const grids = []; 6 | let grid: string[][] = []; 7 | 8 | while (parser.hasNext()) { 9 | const line = parser.next(); 10 | if (line === "") { 11 | grids.push(grid); 12 | grid = []; 13 | } else { 14 | grid.push(line!.split("")); 15 | } 16 | } 17 | 18 | grids.push(grid); 19 | 20 | let sum = 0; 21 | 22 | for (const grid of grids) { 23 | // go iteratively htrough every option 24 | for (let x = 0; x < grid[0].length - 1; x++) { 25 | let maxIter = Math.min(x, grid[0].length - x) + 1; 26 | let rs = 0; 27 | 28 | if (x == 0) maxIter++; 29 | 30 | for (let i = 0; i < maxIter; i++) { 31 | let c1 = x - i; 32 | let c2 = x + 1 + i; 33 | 34 | // console.log("Checking column", c1, c2); 35 | 36 | if (c1 < 0 || c2 >= grid[0].length) { 37 | // console.log("- out of bounds, continue"); 38 | continue; 39 | } 40 | 41 | // check if two adjecent columns compare 42 | 43 | for (let y = 0; y < grid.length; y++) { 44 | if (grid[y][c1] !== grid[y][c2]) { 45 | rs++; 46 | } 47 | } 48 | } 49 | 50 | if (rs === 1) { 51 | sum += x + 1; 52 | } 53 | } 54 | 55 | // go iteratively htrough every option 56 | for (let y = 0; y < grid.length - 1; y++) { 57 | let maxIter = Math.min(y, grid.length - y) + 1; 58 | let rs = 0; 59 | 60 | if (y == 0) maxIter++; 61 | 62 | let rFound = true; 63 | for (let i = 0; i < maxIter; i++) { 64 | let r1 = y - i; 65 | let r2 = y + 1 + i; 66 | 67 | if (r1 < 0 || r2 >= grid.length) continue; 68 | 69 | if (!rFound) break; 70 | // check if two adjecent columns compare 71 | 72 | for (let x = 0; x < grid[0].length; x++) { 73 | if (grid[r1][x] !== grid[r2][x]) { 74 | rs++; 75 | } 76 | } 77 | } 78 | 79 | if (rs === 1) { 80 | sum += (y + 1) * 100; 81 | } 82 | } 83 | } 84 | 85 | console.log(sum); 86 | -------------------------------------------------------------------------------- /2021/10/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const pointTable = { 6 | ")": 1, 7 | "]": 2, 8 | "}": 3, 9 | ">": 4, 10 | }; 11 | 12 | let sums = []; 13 | 14 | const getSum = (chars: ("]" | "}" | ">" | ")")[]) => { 15 | let sum = 0; 16 | chars.forEach((char) => { 17 | sum *= 5; 18 | sum += pointTable[char]; 19 | }); 20 | 21 | return sum; 22 | }; 23 | 24 | while (input.hasNext()) { 25 | const line = input.next()?.split("")!; 26 | const charStack: ("[" | "{" | "<" | "(")[] = []; 27 | 28 | console.log("READING", line.join("")); 29 | 30 | let wrongFound = false; 31 | 32 | line.forEach((char) => { 33 | if (wrongFound) return; 34 | if (char === "[" || char === "{" || char === "<" || char === "(") { 35 | charStack.push(char); 36 | } 37 | 38 | if (char === "]") { 39 | if (charStack[charStack.length - 1] === "[") { 40 | charStack.pop(); 41 | } else { 42 | wrongFound = true; 43 | } 44 | } 45 | 46 | if (char === "}") { 47 | if (charStack[charStack.length - 1] === "{") { 48 | charStack.pop(); 49 | } else { 50 | wrongFound = true; 51 | } 52 | } 53 | 54 | if (char === ">") { 55 | if (charStack[charStack.length - 1] === "<") { 56 | charStack.pop(); 57 | } else { 58 | wrongFound = true; 59 | } 60 | } 61 | 62 | if (char === ")") { 63 | if (charStack[charStack.length - 1] === "(") { 64 | charStack.pop(); 65 | } else { 66 | wrongFound = true; 67 | } 68 | } 69 | }); 70 | 71 | if (wrongFound) continue; 72 | 73 | const toComplete = charStack.reverse().map((c) => { 74 | if (c === "[") return "]"; 75 | if (c === "{") return "}"; 76 | if (c === "<") return ">"; 77 | if (c === "(") return ")"; 78 | return ")"; 79 | }); 80 | 81 | const sum = getSum(toComplete); 82 | sums.push(sum); 83 | } 84 | 85 | sums.sort((a, b) => a - b); 86 | console.log(sums[Math.floor(sums.length / 2)]); 87 | -------------------------------------------------------------------------------- /2021/11/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const data = input 5 | .getFullInput() 6 | .split("\r\n") 7 | .map((x) => x.split("").map(Number)); 8 | 9 | const increaseGrid = () => { 10 | for (let i in data) { 11 | for (let j in data[i]) { 12 | // if (data[i][j] === 9) continue; 13 | data[i][j]++; 14 | } 15 | } 16 | }; 17 | 18 | const directions = [ 19 | [0, 1], 20 | [1, 0], 21 | [0, -1], 22 | [-1, 0], 23 | [1, 1], 24 | [1, -1], 25 | [-1, 1], 26 | [-1, -1], 27 | ]; 28 | 29 | const visitedInRound = new Set(); 30 | 31 | const countNines = () => { 32 | let count = 0; 33 | for (let i in data) { 34 | for (let j in data[i]) { 35 | if (visitedInRound.has(`${i}-${j}`)) continue; 36 | if (data[i][j] === 9) count++; 37 | } 38 | } 39 | return count; 40 | }; 41 | 42 | let flashes = 0; 43 | 44 | const checkForFlashes = () => { 45 | while (countNines()) { 46 | for (let i in data) { 47 | for (let j in data[i]) { 48 | const number = data[i][j]; 49 | if (number === 9) { 50 | if (visitedInRound.has(`${i}-${j}`)) continue; 51 | const toCheck = [...directions.map((x) => [x[0] + +i, x[1] + +j])]; 52 | visitedInRound.add(`${i}-${j}`); 53 | data[i][j] = -1; 54 | flashes++; 55 | for (let i in toCheck) { 56 | const [x, y] = toCheck[i]; 57 | if (!data[x] || data[x][y] === undefined) continue; 58 | 59 | if (visitedInRound.has(`${x}-${y}`)) continue; 60 | 61 | if (data[x][y] === 9) continue; 62 | if (data[x][y] === -1) continue; 63 | 64 | data[x][y]++; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | visitedInRound.clear(); 72 | }; 73 | 74 | // increaseGrid(); 75 | 76 | for (let i = 0; i < 100; i++) { 77 | checkForFlashes(); 78 | increaseGrid(); 79 | } 80 | 81 | console.log(); 82 | console.log(data.map((x) => x.join("")).join("\n")); 83 | console.log("Flashes", flashes); 84 | -------------------------------------------------------------------------------- /2022/src/14/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | const rockPositions = new Set(); 6 | 7 | let maxY = 0; 8 | 9 | while (inputParser.hasNext()) { 10 | const pathPoints = inputParser.next()!.split(" -> "); 11 | 12 | for (let i = 0; i < pathPoints.length - 1; i++) { 13 | const [x1, y1] = pathPoints[i].split(",").map(Number); 14 | const [x2, y2] = pathPoints[i + 1].split(",").map(Number); 15 | 16 | maxY = Math.max(maxY, y1, y2); 17 | 18 | if (x1 == x2) { 19 | const minY = Math.min(y1, y2); 20 | const maxY = Math.max(y1, y2); 21 | for (let y = minY; y <= maxY; y++) { 22 | rockPositions.add(`${x1},${y}`); 23 | } 24 | } else { 25 | const minX = Math.min(x1, x2); 26 | const maxX = Math.max(x1, x2); 27 | for (let x = minX; x <= maxX; x++) { 28 | rockPositions.add(`${x},${y1}`); 29 | } 30 | } 31 | } 32 | } 33 | 34 | const sandPositions = new Set(); 35 | 36 | let end = false; 37 | 38 | while (!end) { 39 | const sand = [500, 0]; 40 | 41 | // move sand 42 | while (!end) { 43 | const [x, y] = sand; 44 | 45 | if ( 46 | !rockPositions.has(`${x},${y + 1}`) && 47 | !sandPositions.has(`${x},${y + 1}`) && 48 | y < maxY + 1 49 | ) { 50 | sand[1] += 1; 51 | continue; 52 | } 53 | 54 | if ( 55 | !rockPositions.has(`${x - 1},${y + 1}`) && 56 | !sandPositions.has(`${x - 1},${y + 1}`) && 57 | y < maxY + 1 58 | ) { 59 | sand[0] -= 1; 60 | sand[1] += 1; 61 | continue; 62 | } 63 | 64 | if ( 65 | !rockPositions.has(`${x + 1},${y + 1}`) && 66 | !sandPositions.has(`${x + 1},${y + 1}`) && 67 | y < maxY + 1 68 | ) { 69 | sand[0] += 1; 70 | sand[1] += 1; 71 | continue; 72 | } 73 | 74 | sandPositions.add(`${x},${y}`); 75 | break; 76 | } 77 | 78 | if (sand[0] == 500 && sand[1] == 0) { 79 | end = true; 80 | } 81 | } 82 | 83 | console.log(sandPositions.size); 84 | -------------------------------------------------------------------------------- /2023/src/10/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | // connections in y x format 6 | const connections: { [k: string]: [number, number][] } = { 7 | "|": [ 8 | [-1, 0], 9 | [1, 0], 10 | ], 11 | "-": [ 12 | [0, -1], 13 | [0, 1], 14 | ], 15 | L: [ 16 | [-1, 0], 17 | [0, 1], 18 | ], 19 | "7": [ 20 | [0, -1], 21 | [1, 0], 22 | ], 23 | F: [ 24 | [1, 0], 25 | [0, 1], 26 | ], 27 | J: [ 28 | [0, -1], 29 | [-1, 0], 30 | ], 31 | }; 32 | 33 | const grid: string[][] = []; 34 | while (parser.hasNext()) grid.push(parser.next()!.split("")); 35 | 36 | const connectionMap = new Map(); 37 | 38 | let sPosition: [number, number]; 39 | 40 | for (let y = 0; y < grid.length; y++) { 41 | for (let x = 0; x < grid[y].length; x++) { 42 | let val = grid[y][x]; 43 | if (val === ".") continue; 44 | 45 | if (val === "S") { 46 | sPosition = [y, x]; 47 | continue; 48 | } 49 | 50 | let c = connections[val]; 51 | 52 | let pieceConnections = c.map((s) => [s[0] + y, s[1] + x]) as [ 53 | number, 54 | number, 55 | ][]; 56 | connectionMap.set(`${y};${x}`, pieceConnections); 57 | } 58 | } 59 | 60 | const visited = new Map(); 61 | visited.set(`${sPosition![0]};${sPosition![1]}`, 0); 62 | const queue: string[] = []; 63 | 64 | // find the two pipes that connect to S 65 | for (const [key, value] of connectionMap) { 66 | if (value.find((c) => c[0] == sPosition[0] && c[1] == sPosition[1])) { 67 | queue.push(key); 68 | visited.set(key, 1); 69 | } 70 | } 71 | 72 | while (queue.length) { 73 | const toCheck = queue.shift()!; 74 | const currentDistance = visited.get(toCheck)!; 75 | 76 | const connections = connectionMap.get(toCheck)!; 77 | 78 | for (const c of connections) { 79 | const str = `${c[0]};${c[1]}`; 80 | if (visited.has(str)) continue; 81 | 82 | queue.push(str); 83 | visited.set(str, currentDistance + 1); 84 | } 85 | } 86 | 87 | console.log("Max distance: ", Math.max(...visited.values())); 88 | -------------------------------------------------------------------------------- /2021/25/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | let grid = input 5 | .getFullInput() 6 | .replaceAll("\r", "") 7 | .split("\n") 8 | .map((row) => row.split("")); 9 | 10 | const moveEast = () => { 11 | let newGrid = grid.map((row) => row.slice()); 12 | 13 | for (let i = 0; i < grid.length; i++) { 14 | for (let j = 0; j < grid[i].length; j++) { 15 | if (j === grid[i].length - 1) { 16 | if (grid[i][j] === ">" && grid[i][0] === ".") { 17 | newGrid[i][j] = "."; 18 | newGrid[i][0] = ">"; 19 | } 20 | continue; 21 | } 22 | 23 | if (grid[i][j] === "." || grid[i][j] === "v") continue; 24 | 25 | if (grid[i][j + 1] === ">" || grid[i][j + 1] === "v") { 26 | continue; 27 | } 28 | 29 | newGrid[i][j] = "."; 30 | newGrid[i][j + 1] = ">"; 31 | } 32 | } 33 | 34 | grid = newGrid; 35 | }; 36 | 37 | const moveSouth = () => { 38 | let newGrid = grid.map((row) => row.slice()); 39 | 40 | for (let i = 0; i < grid.length; i++) { 41 | for (let j = 0; j < grid[i].length; j++) { 42 | if (i === grid.length - 1) { 43 | if (grid[i][j] === "v" && grid[0][j] === ".") { 44 | newGrid[0][j] = "v"; 45 | newGrid[i][j] = "."; 46 | } 47 | continue; 48 | } 49 | 50 | if (grid[i][j] === "." || grid[i][j] === ">") continue; 51 | 52 | if (grid[i + 1][j] === "v" || grid[i + 1][j] === ">") { 53 | continue; 54 | } 55 | 56 | newGrid[i][j] = "."; 57 | newGrid[i + 1][j] = "v"; 58 | } 59 | } 60 | 61 | grid = newGrid; 62 | }; 63 | 64 | const areSame = (oldGrid: string[][], newGrid: string[][]) => { 65 | for (let i = 0; i < oldGrid.length; i++) { 66 | for (let j = 0; j < oldGrid[i].length; j++) { 67 | if (oldGrid[i][j] !== newGrid[i][j]) return false; 68 | } 69 | } 70 | return true; 71 | }; 72 | 73 | let end = false; 74 | let i = 0; 75 | 76 | while (!end) { 77 | i++; 78 | let oldGrid = grid.map((row) => row.slice()); 79 | moveEast(); 80 | moveSouth(); 81 | if (areSame(oldGrid, grid)) end = true; 82 | } 83 | 84 | console.log(i); 85 | -------------------------------------------------------------------------------- /2021/15/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | let grid = input 6 | .getFullInput() 7 | .split("\r\n") 8 | .map((row) => row.split("").map(Number)); 9 | 10 | // grid[0][0] = 0; 11 | const enlargeGrid = () => { 12 | let newGrid: number[][] = []; 13 | 14 | for (const row of grid) { 15 | const newRow: number[] = []; 16 | for (let i = 0; i < 5; i++) { 17 | row.forEach((cell) => { 18 | const newCell = cell + i > 9 ? +(cell + i + 1).toString()[(cell + i + 1).toString().length - 1] : cell + i; 19 | newRow.push(newCell); 20 | }); 21 | } 22 | newGrid.push(newRow); 23 | } 24 | 25 | for (let i = 1; i < 5; i++) { 26 | for (let j = 0; j < grid.length; j++) { 27 | const row = newGrid[j]; 28 | const newRow: number[] = []; 29 | 30 | row.forEach((cell) => { 31 | const newCell = cell + i > 9 ? +(cell + i + 1).toString()[(cell + i + 1).toString().length - 1] : cell + i; 32 | newRow.push(newCell); 33 | }); 34 | 35 | newGrid.push(newRow); 36 | } 37 | } 38 | 39 | return newGrid; 40 | }; 41 | 42 | grid = enlargeGrid(); 43 | 44 | const getNeighbors = (x: number, y: number) => { 45 | const neighbors: number[][] = []; 46 | if (x > 0) neighbors.push([x - 1, y]); 47 | if (x < grid.length - 1) neighbors.push([x + 1, y]); 48 | if (y > 0) neighbors.push([x, y - 1]); 49 | if (y < grid[0].length - 1) neighbors.push([x, y + 1]); 50 | return neighbors; 51 | }; 52 | 53 | const cost = grid.map((row) => row.map(() => Infinity)); 54 | cost[0][0] = 0; 55 | 56 | const queue = [[0, 0]]; 57 | while (queue.length) { 58 | const current = queue.shift()!; 59 | const neighbors = getNeighbors(current[0], current[1]); 60 | 61 | for (const neighbor of neighbors) { 62 | const neighborCost = cost[neighbor[0]][neighbor[1]]; 63 | const costToNeighbor = cost[current[0]][current[1]] + grid[neighbor[0]][neighbor[1]]; 64 | if (neighborCost > costToNeighbor) { 65 | cost[neighbor[0]][neighbor[1]] = costToNeighbor; 66 | queue.push(neighbor); 67 | } 68 | } 69 | } 70 | 71 | console.log(cost[grid.length - 1][grid[0].length - 1]); 72 | -------------------------------------------------------------------------------- /2021/14/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | 5 | const [template, rawInstructions] = input.getFullInput().split("\r\n\r\n"); 6 | 7 | const instructions = rawInstructions.split("\r\n").map((instruction) => { 8 | const [from, to] = instruction.split(" -> "); 9 | return { from, to }; 10 | }); 11 | 12 | const countLetters = (string: string) => { 13 | const letters: { [k: string]: number } = {}; 14 | for (const letter of string) { 15 | if (letters[letter]) { 16 | letters[letter]++; 17 | } else { 18 | letters[letter] = 1; 19 | } 20 | } 21 | return letters; 22 | }; 23 | 24 | const n = 40; 25 | 26 | let pairs: { [k: string]: number } = {}; 27 | const letters: { [k: string]: number } = countLetters(template); 28 | 29 | // Prepare pairs from template 30 | for (let i = 0; i < template.length - 1; i++) { 31 | const momentaryString = template.substring(i, i + 2); 32 | if (pairs[momentaryString]) pairs[momentaryString]++; 33 | else pairs[momentaryString] = 1; 34 | } 35 | 36 | console.log(pairs); 37 | 38 | for (let i = 0; i < n; i++) { 39 | const newPairs: { [k: string]: number } = {}; 40 | 41 | for (const pair of Object.keys(pairs)) { 42 | const count = pairs[pair]; 43 | 44 | const to = instructions.find((instruction) => instruction.from === pair)!; 45 | 46 | const [a, b] = pair.split(""); 47 | 48 | if (newPairs[a + to.to]) { 49 | newPairs[a + to.to] += count; 50 | } else { 51 | newPairs[a + to.to] = count; 52 | } 53 | 54 | if (newPairs[to.to + b]) { 55 | newPairs[to.to + b] += count; 56 | } else { 57 | newPairs[to.to + b] = count; 58 | } 59 | 60 | if (letters[to.to]) { 61 | letters[to.to] += count; 62 | } else { 63 | letters[to.to] = count; 64 | } 65 | } 66 | 67 | console.log(i, "calculated"); 68 | 69 | pairs = newPairs; 70 | } 71 | 72 | let max = 0; 73 | let min = Infinity; 74 | 75 | console.log(letters); 76 | 77 | for (const key of Object.keys(letters)) { 78 | if (letters[key] > max) { 79 | max = letters[key]; 80 | } 81 | if (letters[key] < min) { 82 | min = letters[key]; 83 | } 84 | } 85 | 86 | console.log(max - min); 87 | -------------------------------------------------------------------------------- /2023/src/11/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | let expansionFactor = 1_000_000; 5 | let grid = parser.loadAsGrid(); 6 | 7 | const galaxies: [number, number][] = []; 8 | 9 | for (let y = 0; y < grid.length; y++) { 10 | for (let x = 0; x < grid[y].length; x++) { 11 | if (grid[y][x] === "#") galaxies.push([y, x]); 12 | } 13 | } 14 | 15 | let maxY = Math.max(...galaxies.map((g) => g[0])); 16 | let maxX = Math.max(...galaxies.map((g) => g[1])); 17 | 18 | // decrease expansionFactor - 1 because it the space there already stays 19 | expansionFactor--; 20 | 21 | // expanding universe just by working with galaxies like this; 22 | for (let y = 0; y < maxY; y++) { 23 | // if there are galaxies in this row, continue; 24 | if (galaxies.find((g) => g[0] == y)) continue; 25 | 26 | // if not, push all galaxies after this point {expansionFactor} down 27 | // update maxY as well 28 | 29 | for (const galaxy of galaxies) { 30 | if (galaxy[0] > y) galaxy[0] += expansionFactor; 31 | } 32 | 33 | maxY += expansionFactor; 34 | 35 | // skip all the new created space 36 | y += expansionFactor; 37 | } 38 | 39 | // do the same thing with x 40 | for (let x = 0; x < maxX; x++) { 41 | if (galaxies.find((g) => g[1] == x)) continue; 42 | 43 | for (const galaxy of galaxies) { 44 | if (galaxy[1] > x) galaxy[1] += expansionFactor; 45 | } 46 | 47 | maxX += expansionFactor; 48 | x += expansionFactor; 49 | } 50 | 51 | const distances = new Map(); 52 | 53 | // match every with every 54 | for (const g1 of galaxies) { 55 | for (const g2 of galaxies) { 56 | if (g1[0] == g2[0] && g1[1] == g2[1]) continue; 57 | 58 | let key = ""; 59 | if (g1[0] > g2[0]) key = `${g1.join()};${g2.join()}`; 60 | else if (g2[0] > g1[0]) key = `${g2.join()};${g1.join()}`; 61 | else { 62 | if (g1[1] > g2[1]) key = `${g1.join()};${g2.join()}`; 63 | else key = `${g2.join()};${g1.join()}`; 64 | } 65 | 66 | if (distances.has(key)) continue; 67 | 68 | distances.set(key, Math.abs(g1[0] - g2[0]) + Math.abs(g1[1] - g2[1])); 69 | } 70 | } 71 | 72 | let sum = 0; 73 | 74 | for (const v of distances.values()) { 75 | sum += v; 76 | } 77 | 78 | console.log(sum, distances.size); 79 | -------------------------------------------------------------------------------- /2023/src/05/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | type ConversionObj = { 6 | min: number; 7 | max: number; 8 | shift: number; 9 | }[]; 10 | 11 | const start = Date.now(); 12 | 13 | let seedNumbers = parser 14 | .next()! 15 | .match(/\d+/gm)! 16 | .map((x) => parseInt(x)); 17 | 18 | parser.next(); 19 | 20 | let ranges: number[][] = []; 21 | 22 | let currentRange: number[] = []; 23 | for (const n of seedNumbers) { 24 | if (currentRange.length === 1) { 25 | currentRange.push(n + currentRange[0] - 1); 26 | } else { 27 | currentRange.push(n); 28 | } 29 | 30 | if (currentRange.length == 2) { 31 | ranges.push([...currentRange]); 32 | currentRange = []; 33 | } 34 | } 35 | 36 | const conversionObjects: ConversionObj[] = []; 37 | 38 | console.log(ranges); 39 | 40 | while (parser.hasNext()) { 41 | parser.next(); // skip group name 42 | 43 | const groupData = parser.nextUntilEmptyLine()!; 44 | 45 | const conversionObj: ConversionObj = []; 46 | 47 | for (const record of groupData) { 48 | const [destinationRangeStart, sourceRangeStart, rangeLength] = record 49 | .split(" ") 50 | .map((x) => +x); 51 | 52 | conversionObj.push({ 53 | min: destinationRangeStart, 54 | max: destinationRangeStart + rangeLength - 1, 55 | shift: sourceRangeStart - destinationRangeStart, 56 | }); 57 | } 58 | 59 | conversionObjects.unshift(conversionObj); 60 | } 61 | 62 | // console.log(conversionObjects); 63 | 64 | let solved = false; 65 | let testedNumber = 0; 66 | 67 | while (!solved) { 68 | let currentValue = testedNumber; 69 | 70 | if (testedNumber % 1_000_000 === 0) 71 | console.log("Checked", testedNumber, "cases..."); 72 | 73 | for (const COs of conversionObjects) { 74 | for (const co of COs) { 75 | if (currentValue >= co.min && currentValue <= co.max) { 76 | currentValue += co.shift; 77 | break; 78 | } 79 | } 80 | } 81 | 82 | for (const range of ranges) { 83 | if (currentValue >= range[0] && currentValue <= range[1]) { 84 | solved = true; 85 | console.log("Finally here:", testedNumber); 86 | } 87 | } 88 | 89 | testedNumber++; 90 | } 91 | 92 | console.log("Finished in", Date.now() - start, "ms"); 93 | -------------------------------------------------------------------------------- /2021/11/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | const data = input 5 | .getFullInput() 6 | .split("\r\n") 7 | .map((x) => x.split("").map(Number)); 8 | 9 | const increaseGrid = () => { 10 | for (let i in data) { 11 | for (let j in data[i]) { 12 | // if (data[i][j] === 9) continue; 13 | data[i][j]++; 14 | } 15 | } 16 | }; 17 | 18 | const directions = [ 19 | [0, 1], 20 | [1, 0], 21 | [0, -1], 22 | [-1, 0], 23 | [1, 1], 24 | [1, -1], 25 | [-1, 1], 26 | [-1, -1], 27 | ]; 28 | 29 | const visitedInRound = new Set(); 30 | 31 | const countNines = () => { 32 | let count = 0; 33 | for (let i in data) { 34 | for (let j in data[i]) { 35 | if (visitedInRound.has(`${i}-${j}`)) continue; 36 | if (data[i][j] === 9) count++; 37 | } 38 | } 39 | return count; 40 | }; 41 | 42 | let flashes = 0; 43 | 44 | const checkForFlashes = () => { 45 | while (countNines()) { 46 | for (let i in data) { 47 | for (let j in data[i]) { 48 | const number = data[i][j]; 49 | if (number === 9) { 50 | if (visitedInRound.has(`${i}-${j}`)) continue; 51 | const toCheck = [...directions.map((x) => [x[0] + +i, x[1] + +j])]; 52 | visitedInRound.add(`${i}-${j}`); 53 | data[i][j] = -1; 54 | flashes++; 55 | for (let i in toCheck) { 56 | const [x, y] = toCheck[i]; 57 | if (!data[x] || data[x][y] === undefined) continue; 58 | 59 | if (visitedInRound.has(`${x}-${y}`)) continue; 60 | 61 | if (data[x][y] === 9) continue; 62 | if (data[x][y] === -1) continue; 63 | 64 | data[x][y]++; 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | visitedInRound.clear(); 72 | }; 73 | 74 | const allZeroes = () => { 75 | for (let i in data) { 76 | for (let j in data[i]) { 77 | if (data[i][j] !== 0) return false; 78 | } 79 | } 80 | return true; 81 | }; 82 | 83 | // increaseGrid(); 84 | 85 | let i = 0; 86 | while (true) { 87 | checkForFlashes(); 88 | increaseGrid(); 89 | i++; 90 | if (allZeroes()) break; 91 | } 92 | 93 | console.log(); 94 | console.log(data.map((x) => x.join("")).join("\n")); 95 | console.log("Flashes", flashes); 96 | console.log("All zeroes at", i); 97 | -------------------------------------------------------------------------------- /2021/22/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | const input = new InputParser("in.txt"); 4 | // ["off", [0, 0, 0], [52, 12, 30]] 5 | 6 | interface Box { 7 | x1: number; 8 | x2: number; 9 | y1: number; 10 | y2: number; 11 | z1: number; 12 | z2: number; 13 | } 14 | 15 | const rows: ["on" | "off", [number, number, number], [number, number, number]][] = input 16 | .getFullInput() 17 | .replaceAll("\r", "") 18 | .split("\n") 19 | .map((row) => { 20 | const [state, xVals, yValy, zVals] = row 21 | .replaceAll(",", " ") 22 | .replaceAll("x", "") 23 | .replaceAll("y", "") 24 | .replaceAll("z", "") 25 | .replaceAll("=", "") 26 | .split(" "); 27 | const x = xVals.split("..").map(Number); 28 | const y = yValy.split("..").map(Number); 29 | const z = zVals.split("..").map(Number); 30 | 31 | return [state as "on" | "off", [x[0], y[0], z[0]], [x[1], y[1], z[1]]]; 32 | }); 33 | 34 | const lineOverlap = (x1: number, x2: number, x1_: number, x2_: number) => [Math.max(x1, x1_), Math.min(x2, x2_)]; 35 | const volume = (b: Box) => (b.x2 - b.x1 + 1) * (b.y2 - b.y1 + 1) * (b.z2 - b.z1 + 1); 36 | const newBox = (x1: number, x2: number, y1: number, y2: number, z1: number, z2: number): Box => ({ 37 | x1, 38 | x2, 39 | y1, 40 | y2, 41 | z1, 42 | z2, 43 | }); 44 | 45 | const overlap = (box: Box, boxes: Box[]): number => { 46 | return boxes 47 | .map((b) => { 48 | const [minX, maxX] = lineOverlap(box.x1, box.x2, b.x1, b.x2); 49 | const [minY, maxY] = lineOverlap(box.y1, box.y2, b.y1, b.y2); 50 | const [minZ, maxZ] = lineOverlap(box.z1, box.z2, b.z1, b.z2); 51 | 52 | if (maxX - minX >= 0 && maxY - minY >= 0 && maxZ - minZ >= 0) { 53 | const temp_box = newBox(minX, maxX, minY, maxY, minZ, maxZ); 54 | return volume(temp_box) - overlap(temp_box, boxes.slice(1 + boxes.indexOf(b))); 55 | } else { 56 | return 0; 57 | } 58 | }) 59 | .reduce((acc, curr) => acc + curr, 0); 60 | }; 61 | 62 | let totalOn = 0; 63 | const boxes: Box[] = []; 64 | rows.reverse(); 65 | rows.forEach((row) => { 66 | const box = newBox(row[1][0], row[2][0], row[1][1], row[2][1], row[1][2], row[2][2]); 67 | if (row[0] === "on") totalOn += volume(box) - overlap(box, boxes); 68 | boxes.push(box); 69 | }); 70 | 71 | console.log(totalOn); 72 | -------------------------------------------------------------------------------- /2021/20/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | // Parse the input 4 | const input = new InputParser("in.txt"); 5 | const [algorithm, data] = input.getFullInput().replaceAll("\r", "").split("\n\n"); 6 | 7 | let grid = data.split("\n").map((row) => row.split("")); 8 | let environment = "."; 9 | 10 | const enlargeGrid = () => { 11 | grid = [ 12 | [environment, ...new Array(grid[0].length + 1).fill(environment)], 13 | ...grid.map((row) => [environment, ...row, environment]), 14 | [environment, ...new Array(grid[0].length + 1).fill(environment)], 15 | ]; 16 | }; 17 | 18 | let newGrid: string[][] = []; 19 | 20 | for (let i = 0; i < 50; i++) { 21 | enlargeGrid(); 22 | 23 | grid.forEach((row, y) => { 24 | newGrid[y] = []; 25 | row.forEach((cell, x) => { 26 | let string = ""; 27 | if (y <= 0 || x <= 0) string += environment; 28 | else string += grid[y - 1][x - 1]; 29 | 30 | if (y <= 0) string += environment; 31 | else string += grid[y - 1][x]; 32 | 33 | if (y <= 0 || x >= grid[0].length - 1) string += environment; 34 | else string += grid[y - 1][x + 1]; 35 | 36 | if (x <= 0) string += environment; 37 | else string += grid[y][x - 1]; 38 | 39 | string += cell; 40 | 41 | if (x >= grid[0].length - 1) string += environment; 42 | else string += grid[y][x + 1]; 43 | 44 | if (y >= grid.length - 1 || x <= 0) string += environment; 45 | else string += grid[y + 1][x - 1]; 46 | 47 | if (y >= grid.length - 1) string += environment; 48 | else string += grid[y + 1][x]; 49 | 50 | if (y >= grid.length - 1 || x >= grid[0].length - 1) string += environment; 51 | else string += grid[y + 1][x + 1]; 52 | 53 | newGrid[y].push(algorithm[parseInt(string.replaceAll(".", "0").replaceAll("#", "1"), 2)]); 54 | }); 55 | }); 56 | 57 | grid = newGrid; 58 | 59 | if (environment === "." && algorithm[0] === "#") environment = "#"; 60 | else if (environment === "#" && algorithm[511] === ".") environment = "."; 61 | } 62 | 63 | const countLights = () => { 64 | let count = 0; 65 | grid.forEach((row) => { 66 | row.forEach((cell) => { 67 | if (cell === "#") count++; 68 | }); 69 | }); 70 | return count; 71 | }; 72 | 73 | // console.log(algorithm); 74 | console.log("Light pixels:", countLights()); 75 | console.log(""); 76 | -------------------------------------------------------------------------------- /2022/src/07/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const inputParser = new InputParser("in.txt"); 4 | 5 | interface File { 6 | type: "file"; 7 | name: string; 8 | size: number; 9 | } 10 | 11 | interface Folder { 12 | type: "folder"; 13 | name: string; 14 | children: { [fname: string]: Folder | File }; 15 | parent: Folder | null; 16 | size: number; 17 | } 18 | 19 | const root: Folder = { 20 | type: "folder", 21 | name: "/", 22 | children: {}, 23 | size: 0, 24 | parent: null, 25 | }; 26 | 27 | let currentPath: Folder = root; 28 | 29 | while (inputParser.hasNext()) { 30 | const [, command, args] = inputParser.next()!.split(" "); 31 | 32 | if (command === "cd") { 33 | if (args === "..") { 34 | if (currentPath.parent) { 35 | currentPath = currentPath.parent; 36 | } 37 | } else if (args === "/") { 38 | currentPath = root; 39 | } else { 40 | currentPath = currentPath.children[args] as Folder; 41 | } 42 | 43 | continue; 44 | } 45 | 46 | const nextLine = inputParser.next(false); 47 | while (inputParser.next(false) && !inputParser.next(false)?.startsWith("$")) { 48 | const [sizeOrDir, name] = inputParser.next()!.split(" "); 49 | 50 | if (sizeOrDir === "dir") { 51 | // Create folder 52 | const folder: Folder = { 53 | type: "folder", 54 | name, 55 | children: {}, 56 | size: 0, 57 | parent: currentPath, 58 | }; 59 | 60 | currentPath.children[name] = folder; 61 | } else { 62 | // Create file 63 | const file: File = { 64 | type: "file", 65 | name, 66 | size: parseInt(sizeOrDir), 67 | }; 68 | 69 | currentPath.children[name] = file; 70 | } 71 | } 72 | } 73 | 74 | const folderSizes: number[] = []; 75 | 76 | const calculateFolderSize = (folder: Folder): number => { 77 | let size = 0; 78 | for (const child of Object.values(folder.children)) { 79 | if (child.type === "file") { 80 | size += child.size; 81 | } else { 82 | size += calculateFolderSize(child); 83 | } 84 | } 85 | 86 | folder.size = size; 87 | folderSizes.push(size); 88 | return size; 89 | }; 90 | 91 | calculateFolderSize(root); 92 | 93 | console.log( 94 | "Total:", 95 | folderSizes.filter((size) => size <= 100000).reduce((a, b) => a + b, 0) 96 | ); 97 | -------------------------------------------------------------------------------- /2021/20/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../files"; 2 | 3 | // Parse the input 4 | const input = new InputParser("in.txt"); 5 | const [algorithm, data] = input.getFullInput().replaceAll("\r", "").split("\n\n"); 6 | 7 | let grid = data.split("\n").map((row) => row.split("")); 8 | let environment = "."; 9 | 10 | const enlargeGrid = () => { 11 | grid = [ 12 | [environment, ...new Array(grid[0].length + 1).fill(environment)], 13 | ...grid.map((row) => [environment, ...row, environment]), 14 | [environment, ...new Array(grid[0].length + 1).fill(environment)], 15 | ]; 16 | }; 17 | 18 | let newGrid: string[][] = []; 19 | 20 | for (let i = 0; i < 2; i++) { 21 | enlargeGrid(); 22 | 23 | grid.forEach((row, y) => { 24 | newGrid[y] = []; 25 | row.forEach((cell, x) => { 26 | let string = ""; 27 | if (y <= 0 || x <= 0) string += environment; 28 | else string += grid[y - 1][x - 1]; 29 | 30 | if (y <= 0) string += environment; 31 | else string += grid[y - 1][x]; 32 | 33 | if (y <= 0 || x >= grid[0].length - 1) string += environment; 34 | else string += grid[y - 1][x + 1]; 35 | 36 | if (x <= 0) string += environment; 37 | else string += grid[y][x - 1]; 38 | 39 | string += cell; 40 | 41 | if (x >= grid[0].length - 1) string += environment; 42 | else string += grid[y][x + 1]; 43 | 44 | if (y >= grid.length - 1 || x <= 0) string += environment; 45 | else string += grid[y + 1][x - 1]; 46 | 47 | if (y >= grid.length - 1) string += environment; 48 | else string += grid[y + 1][x]; 49 | 50 | if (y >= grid.length - 1 || x >= grid[0].length - 1) string += environment; 51 | else string += grid[y + 1][x + 1]; 52 | 53 | newGrid[y].push(algorithm[parseInt(string.replaceAll(".", "0").replaceAll("#", "1"), 2)]); 54 | }); 55 | }); 56 | 57 | grid = newGrid; 58 | 59 | if (environment === "." && algorithm[0] === "#") environment = "#"; 60 | else if (environment === "#" && algorithm[511] === ".") environment = "."; 61 | 62 | console.log(environment); 63 | } 64 | 65 | const countLights = () => { 66 | let count = 0; 67 | grid.forEach((row) => { 68 | row.forEach((cell) => { 69 | if (cell === "#") count++; 70 | }); 71 | }); 72 | return count; 73 | }; 74 | 75 | // console.log(algorithm); 76 | console.log("Light pixels:", countLights()); 77 | -------------------------------------------------------------------------------- /2022/src/11/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | interface Monkey { 4 | items: number[]; 5 | operation: { 6 | operation: string; 7 | value1: string; 8 | value2: string; 9 | }; 10 | test: { 11 | divisbleBy: number; 12 | ifYes: number; 13 | ifNo: number; 14 | }; 15 | activity: number; 16 | } 17 | 18 | const inputParser = new InputParser("in.txt"); 19 | 20 | const monkeys: Monkey[] = []; 21 | 22 | while (inputParser.hasNext()) { 23 | const monkeyString = inputParser.nextUntilEmptyLine()!; 24 | const startingItems = monkeyString[1].match(/\d+/g)!.map(Number); 25 | const operation = monkeyString[2] 26 | .match(/(\d+|old)\ .\ (\d+|old)/)![0] 27 | .split(" "); 28 | 29 | const test = monkeyString[3].match(/\d+/g)!; 30 | const ifYes = monkeyString[4].match(/\d+/g)!; 31 | const ifNo = monkeyString[5].match(/\d+/g)!; 32 | 33 | monkeys.push({ 34 | items: startingItems, 35 | operation: { 36 | operation: operation[1], 37 | value1: operation[0], 38 | value2: operation[2], 39 | }, 40 | test: { 41 | divisbleBy: Number(test[0]), 42 | ifYes: Number(ifYes[0]), 43 | ifNo: Number(ifNo[0]), 44 | }, 45 | activity: 0, 46 | }); 47 | } 48 | 49 | console.log(monkeys); 50 | for (let i = 0; i < 20; i++) { 51 | for (const monkey of monkeys) { 52 | while (monkey.items.length) { 53 | const item = monkey.items.shift()!; 54 | 55 | let newValue = 0; 56 | let value1 = 57 | monkey.operation.value1 === "old" 58 | ? item 59 | : Number(monkey.operation.value1); 60 | let value2 = 61 | monkey.operation.value2 === "old" 62 | ? item 63 | : Number(monkey.operation.value2); 64 | 65 | switch (monkey.operation.operation) { 66 | case "+": 67 | newValue = value1 + value2; 68 | break; 69 | case "*": 70 | newValue = value1 * value2; 71 | } 72 | 73 | newValue = Math.floor(newValue / 3); 74 | 75 | if (newValue % monkey.test.divisbleBy == 0) 76 | monkeys[monkey.test.ifYes].items.push(newValue); 77 | else monkeys[monkey.test.ifNo].items.push(newValue); 78 | 79 | monkey.activity++; 80 | } 81 | } 82 | } 83 | 84 | monkeys.sort((a, b) => b.activity - a.activity); 85 | console.log("Business level: ", monkeys[0].activity * monkeys[1].activity); 86 | -------------------------------------------------------------------------------- /2022/src/11/b.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | interface Monkey { 4 | items: number[]; 5 | operation: { 6 | operation: string; 7 | value1: string; 8 | value2: string; 9 | }; 10 | test: { 11 | divisbleBy: number; 12 | ifYes: number; 13 | ifNo: number; 14 | }; 15 | activity: number; 16 | } 17 | 18 | const inputParser = new InputParser("in.txt"); 19 | 20 | const monkeys: Monkey[] = []; 21 | 22 | while (inputParser.hasNext()) { 23 | const monkeyString = inputParser.nextUntilEmptyLine()!; 24 | const startingItems = monkeyString[1].match(/\d+/g)!.map(Number); 25 | const operation = monkeyString[2] 26 | .match(/(\d+|old)\ .\ (\d+|old)/)![0] 27 | .split(" "); 28 | 29 | const test = monkeyString[3].match(/\d+/g)!; 30 | const ifYes = monkeyString[4].match(/\d+/g)!; 31 | const ifNo = monkeyString[5].match(/\d+/g)!; 32 | 33 | monkeys.push({ 34 | items: startingItems, 35 | operation: { 36 | operation: operation[1], 37 | value1: operation[0], 38 | value2: operation[2], 39 | }, 40 | test: { 41 | divisbleBy: Number(test[0]), 42 | ifYes: Number(ifYes[0]), 43 | ifNo: Number(ifNo[0]), 44 | }, 45 | activity: 0, 46 | }); 47 | } 48 | 49 | const superModulo = monkeys.reduce( 50 | (prev, monkey) => monkey.test.divisbleBy * prev, 51 | 1 52 | ); 53 | 54 | for (let i = 0; i < 10000; i++) { 55 | for (const monkey of monkeys) { 56 | while (monkey.items.length) { 57 | const item = monkey.items.shift()!; 58 | 59 | let newValue = 0; 60 | let value1 = 61 | monkey.operation.value1 === "old" 62 | ? item 63 | : Number(monkey.operation.value1); 64 | let value2 = 65 | monkey.operation.value2 === "old" 66 | ? item 67 | : Number(monkey.operation.value2); 68 | 69 | switch (monkey.operation.operation) { 70 | case "+": 71 | newValue = value1 + value2; 72 | break; 73 | case "*": 74 | newValue = value1 * value2; 75 | } 76 | newValue = newValue % superModulo; 77 | 78 | if (newValue % monkey.test.divisbleBy == 0) 79 | monkeys[monkey.test.ifYes].items.push(newValue); 80 | else monkeys[monkey.test.ifNo].items.push(newValue); 81 | 82 | monkey.activity++; 83 | } 84 | } 85 | } 86 | 87 | monkeys.sort((a, b) => b.activity - a.activity); 88 | console.log("Business level: ", monkeys[0].activity * monkeys[1].activity); 89 | -------------------------------------------------------------------------------- /2023/src/13/a.ts: -------------------------------------------------------------------------------- 1 | import { InputParser } from "../lib/files"; 2 | 3 | const parser = new InputParser("input.txt"); 4 | 5 | const grids = []; 6 | let grid: string[][] = []; 7 | 8 | while (parser.hasNext()) { 9 | const line = parser.next(); 10 | console.log(line); 11 | if (line === "") { 12 | grids.push(grid); 13 | grid = []; 14 | } else { 15 | grid.push(line!.split("")); 16 | } 17 | } 18 | 19 | grids.push(grid); 20 | 21 | let sum = 0; 22 | 23 | for (const grid of grids) { 24 | let reflectionFound = false; 25 | 26 | console.log(""); 27 | 28 | // go iteratively htrough every option 29 | for (let x = 0; x < grid[0].length - 1; x++) { 30 | let maxIter = Math.min(x, grid[0].length - x) + 1; 31 | 32 | if (reflectionFound) break; 33 | 34 | if (x == 0) maxIter++; 35 | 36 | let rFound = true; 37 | for (let i = 0; i < maxIter; i++) { 38 | let c1 = x - i; 39 | let c2 = x + 1 + i; 40 | 41 | // console.log("Checking column", c1, c2); 42 | 43 | if (c1 < 0 || c2 >= grid[0].length) { 44 | // console.log("- out of bounds, continue"); 45 | continue; 46 | } 47 | 48 | if (!rFound) break; 49 | // check if two adjecent columns compare 50 | 51 | for (let y = 0; y < grid.length; y++) { 52 | if (grid[y][c1] !== grid[y][c2]) { 53 | rFound = false; 54 | break; 55 | } 56 | } 57 | } 58 | 59 | if (rFound) { 60 | // console.log("Found reflection at", x); 61 | reflectionFound = true; 62 | sum += x + 1; 63 | } 64 | } 65 | 66 | if (reflectionFound) continue; 67 | 68 | // go iteratively htrough every option 69 | for (let y = 0; y < grid.length - 1; y++) { 70 | let maxIter = Math.min(y, grid.length - y) + 1; 71 | 72 | if (y == 0) maxIter++; 73 | 74 | let rFound = true; 75 | for (let i = 0; i < maxIter; i++) { 76 | let r1 = y - i; 77 | let r2 = y + 1 + i; 78 | 79 | if (r1 < 0 || r2 >= grid.length) continue; 80 | 81 | if (!rFound) break; 82 | // check if two adjecent columns compare 83 | 84 | for (let x = 0; x < grid[0].length; x++) { 85 | if (grid[r1][x] !== grid[r2][x]) { 86 | rFound = false; 87 | break; 88 | } 89 | } 90 | } 91 | 92 | if (rFound) { 93 | reflectionFound = true; 94 | sum += (y + 1) * 100; 95 | } 96 | } 97 | } 98 | 99 | console.log(sum); 100 | --------------------------------------------------------------------------------