├── 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 |
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 |
29 |
30 |
31 |
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 |
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 |
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 |
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 |
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 |
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 |
41 |
42 |
43 |
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 |
40 |
41 |
42 |
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 |
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 |
40 |
41 |
42 |
43 |
46 |
47 |
50 |
51 |
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 |
40 |
41 |
42 |
43 |
44 | Sprite position:
45 | Clock cycle:
46 |
47 |
48 |
52 |
53 |
54 |
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 |
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 |
--------------------------------------------------------------------------------