.gitignore ๐
@@ -0,0 +1,4 @@
+*.beam
+*.ez
+/build
+erl_crash.dump
Amolith created
.gitignore | 4
AGENTS.md | 64
README.md | 40
crush.json | 19
gleam.toml | 22
input/day01.txt | 4147 +++++++++++++++++++++++++++++++++++++
input/day01_example.txt | 10
manifest.toml | 21
mix.exs | 15
src/aoc.gleam | 84
src/compare.gleam | 96
src/internal/llm/day01.gleam | 83
src/internal/mine/day01.gleam | 90
src/utils.gleam | 23
test/aoc_test.gleam | 39
15 files changed, 4,757 insertions(+)
@@ -0,0 +1,4 @@
+*.beam
+*.ez
+/build
+erl_crash.dump
@@ -0,0 +1,64 @@
+# AGENTS.md
+
+Guidelines for AI agents working in this Advent of Code repository.
+
+## Project Overview
+
+Gleam-based Advent of Code solutions with two parallel implementation tracks (`mine/` and `llm/`) for comparing human vs LLM-generated solutions side-by-side with benchmarking.
+
+## Commands
+
+```console
+$ gleam build # Compile the project
+$ gleam test # Run all tests
+$ gleam run # Run all available days with comparison (default)
+$ gleam run -- <day> # Run specific day with comparison
+$ gleam run -- -e # Run with example input (--example)
+$ gleam run -- <day> -n # Run without comparison, mine/ only (--no-compare)
+$ gleam run -- 1 -en # Flags can be combined
+```
+
+## Code Organization
+
+```
+src/
+โโโ aoc.gleam # CLI entry point, argument parsing, day dispatch
+โโโ compare.gleam # Benchmarking harness for mine/ vs llm/ comparison
+โโโ utils.gleam # Input file reading utilities
+โโโ internal/
+ โโโ mine/ # Human-written solutions
+ โโโ llm/ # LLM-generated solutions
+
+input/
+โโโ dayXX.txt # Real puzzle input
+โโโ dayXX_example.txt # Example input from problem description
+
+test/
+โโโ aoc_test.gleam # Tests for both implementations
+```
+
+## Documentation
+
+When making changes that affect CLI usage, project structure, or workflows, update the relevant documentation (this file and README.md) to reflect those changes.
+
+## Adding a New Day
+
+1. Create `src/internal/mine/dayXX.gleam` with `pub fn part1(input: List(String)) -> Int` and `pub fn part2(input: List(String)) -> Int` and bodies of just `todo`.
+2. Create `src/internal/llm/dayXX.gleam` with the same interface. Make sure to include the `//// Authored-by: [Model] via Crush` header that you're told to use for commits.
+3. Ask the user to paste the input for `input/dayXX_example.txt`, then download the contents of `https://adventofcode.com/2025/day/XX/input` to `input/dayXX.txt`.
+4. Wire up dispatch in `src/aoc.gleam`:
+ - Add import: `import internal/mine/dayXX as mine_dayXX`
+ - Add case to `run_parts`
+5. Wire up comparison in `src/compare.gleam`:
+ - Add imports for both implementations
+ - Add `pub fn dayXX(input: List(String)) -> Nil` function
+ - Add case to `run_comparison` in aoc.gleam
+6. Add the day number to `available_days` in `src/aoc.gleam`
+7. Add tests in `test/aoc_test.gleam`
+
+## Conventions
+
+- Naming: `mine_dayXX` and `llm_dayXX` for imports to distinguish implementations
+- Types: Define custom types for domain concepts (Movement, Rotation, etc.)
+- Constants: Use module-level `const` for magic numbers (e.g., `const starting_position = 50`)
+- Pipeline style: Heavy use of `|>` operator for data transformation
@@ -0,0 +1,40 @@
+# Advent of Code 2025 (Gleam)
+
+Includes parallel me- (`mine/`) and LLM- (`llm/`) generated implementations for
+side-by-side comparison. I'm using [Crush] and whatever models interest me. Each
+LLM-authored file includes a header indicating with model was the primary
+author.
+
+[Crush]: https://git.secluded.site/crush
+
+## Usage
+
+```console
+$ gleam run # Run all days with comparison (default)
+$ gleam run -- <day> # Run specific day with comparison
+$ gleam run -- -e # Run all days with example input
+$ gleam run -- <day> -n # Run specific day without comparison (mine/ only)
+$ gleam run -- <day> -en # Combine flags
+```
+
+## Results
+
+```console
+โฏ gleam run
+ Compiled in 0.04s
+ Running aoc.main
+=== Day 1 ===
+Comparing implementations...
+
+--- Part 1 ---
+Mine: XXXX (5.3ms)
+LLM: XXXX (18.4ms)
+โ Results match
+Mine 3.46x faster
+
+--- Part 2 ---
+Mine: XXXX (2.3ms)
+LLM: XXXX (17.3ms)
+โ Results match
+Mine 7.50x faster
+```
@@ -0,0 +1,19 @@
+{
+ "$schema": "https://charm.land/crush.json",
+ "lsp": {
+ "gleam": {
+ "command": "gleam",
+ "args": ["lsp"]
+ }
+ },
+ "mcp": {
+ "hexdocs": {
+ "type": "stdio",
+ "command": "hexdocs-mcp",
+ "env": {
+ "HEXDOCS_MCP_DEFAULT_EMBEDDING_MODEL": "manutic/nomic-embed-code",
+ "HEXDOCS_MCP_PATH": "$HOME/.config/hexdocs-mcp"
+ }
+ }
+ }
+}
@@ -0,0 +1,22 @@
+name = "aoc"
+version = "1.0.0"
+
+# Fill out these fields if you intend to generate HTML documentation or publish
+# your project to the Hex package manager.
+#
+# description = ""
+# licences = ["Apache-2.0"]
+# repository = { type = "github", user = "", repo = "" }
+# links = [{ title = "Website", href = "" }]
+#
+# For a full reference of all the available options, you can have a look at
+# https://gleam.run/writing-gleam/gleam-toml/.
+
+[dependencies]
+gleam_stdlib = ">= 0.44.0 and < 2.0.0"
+argv = ">= 1.0.2 and < 2.0.0"
+simplifile = ">= 2.3.1 and < 3.0.0"
+birl = ">= 1.8.0 and < 2.0.0"
+
+[dev-dependencies]
+gleeunit = ">= 1.0.0 and < 2.0.0"
@@ -0,0 +1,4147 @@
+R41
+L10
+L18
+R22
+R17
+L29
+R4
+R32
+L32
+R19
+L29
+L13
+R25
+L11
+R47
+L10
+L12
+L29
+R8
+L32
+L38
+L27
+L4
+L34
+R19
+R23
+L49
+R25
+R49
+R13
+L7
+R17
+R23
+R10
+L43
+R45
+L16
+R49
+R7
+R17
+L7
+L44
+R35
+L27
+R16
+L26
+L48
+R4
+R27
+L49
+R95
+R18
+L13
+L97
+R64
+R33
+L68
+L86
+R95
+L41
+L12
+L96
+R10
+R30
+L59
+L1
+L62
+R76
+R33
+R81
+L16
+R67
+L51
+L89
+R86
+R52
+R84
+R64
+L97
+L57
+R65
+R55
+R94
+R32
+L89
+L63
+L89
+L48
+L74
+R74
+R65
+L62
+R97
+L94
+L3
+R24
+L36
+R76
+R33
+L66
+R66
+R65
+R85
+L50
+L11
+L40
+R51
+R49
+R772
+L95
+R674
+L350
+R525
+R25
+L997
+L303
+L75
+R75
+R278
+L12
+R25
+L91
+R391
+L91
+R28
+R72
+R644
+R56
+R37
+L316
+L23
+L98
+L54
+L25
+L92
+R71
+L52
+L24
+L62
+L63
+L99
+R75
+L53
+L822
+R21
+L21
+R72
+L72
+R26
+L26
+R27
+L527
+L60
+R22
+R71
+L33
+L19
+L898
+L50
+L604
+L6
+L766
+R3
+L160
+R673
+R5
+R22
+L195
+L586
+R81
+R83
+R98
+R864
+L45
+L321
+R21
+L13
+L87
+R83
+R331
+L35
+L73
+L77
+R71
+L15
+L53
+R386
+R82
+L452
+R52
+R6
+L663
+L742
+R70
+R50
+L117
+R18
+R27
+L29
+R80
+L798
+R22
+L24
+L75
+L25
+R78
+L27
+R49
+R797
+R37
+R66
+R1
+L95
+L68
+L38
+R763
+L93
+L61
+R19
+R94
+R69
+R709
+L78
+R5
+R23
+R18
+R57
+L364
+L58
+L993
+R90
+L45
+L55
+L79
+R83
+L211
+R222
+L538
+R21
+R68
+R6
+R77
+R799
+R8
+L56
+R72
+L91
+L84
+R7
+L4
+R632
+R6
+L250
+L697
+L14
+R43
+R80
+R243
+R98
+L43
+R36
+R4
+R62
+R66
+R771
+L39
+L55
+L85
+L65
+L8
+L91
+R51
+L51
+R69
+L7
+R331
+L69
+L95
+L64
+R441
+L739
+R39
+L8
+L18
+L40
+L29
+L3
+L71
+L20
+R289
+L45
+R365
+R54
+L74
+L349
+R34
+L96
+R11
+R50
+R50
+R33
+L533
+L4
+R4
+R14
+L96
+R44
+R31
+R707
+L9
+L91
+R44
+L93
+R82
+L733
+L75
+R19
+R24
+L68
+L481
+R87
+R80
+R663
+L19
+L705
+L59
+R60
+R86
+R64
+R40
+L63
+R67
+R19
+R43
+R18
+L7
+R207
+L68
+R7
+L82
+L54
+L6
+L97
+L672
+L28
+L90
+R90
+L807
+R7
+L15
+R176
+L66
+L26
+L47
+L245
+R123
+R4
+L4
+R14
+R30
+R42
+R88
+L74
+R26
+R9
+R98
+R58
+R9
+L775
+L60
+R17
+L82
+R9
+L9
+L2
+L19
+L866
+R87
+L37
+R137
+R51
+R68
+L19
+L39
+L1
+R12
+L72
+L44
+L56
+L77
+R77
+R87
+R57
+R56
+R16
+R962
+R812
+R75
+R79
+R56
+R67
+L26
+L53
+R7
+R63
+R843
+L1
+R441
+L512
+R74
+R97
+R867
+R75
+L11
+L86
+L78
+R538
+R43
+L20
+L9
+R81
+L191
+R21
+R72
+R98
+R37
+L47
+L65
+R89
+R86
+R56
+R44
+L970
+R39
+L97
+R28
+L80
+R22
+L570
+L99
+L76
+R3
+R1
+R799
+L22
+R71
+L71
+R49
+L27
+R23
+R40
+R40
+L14
+L89
+L30
+L86
+L33
+L24
+R73
+L86
+L97
+R92
+R991
+L91
+L30
+L52
+L27
+R21
+L25
+L696
+L14
+R74
+R62
+L458
+R293
+L771
+R614
+L58
+L742
+R574
+R31
+R95
+R61
+L43
+L84
+R424
+L727
+R56
+L87
+R569
+R66
+L844
+L67
+R32
+R59
+R85
+R281
+R47
+L432
+L796
+L63
+R75
+R626
+L6
+L4
+L36
+R81
+R61
+R11
+L45
+R58
+L21
+R95
+L50
+L14
+L315
+R47
+L729
+R529
+L49
+R340
+L191
+R12
+L12
+R8
+L21
+R26
+R10
+R8
+R39
+R30
+L3
+R20
+L17
+L89
+R18
+R171
+R238
+L137
+L95
+L6
+L98
+R94
+L12
+R911
+L65
+L30
+R69
+R31
+R57
+R14
+L75
+L99
+R52
+L756
+L93
+R52
+R82
+L99
+L77
+R11
+L569
+R13
+R89
+L89
+R814
+R73
+L31
+R31
+L14
+L602
+L284
+L61
+L866
+R23
+L13
+L284
+L25
+R66
+R60
+L54
+L46
+R73
+L38
+R54
+R11
+R34
+L868
+L32
+L25
+L9
+L75
+R75
+L443
+R826
+L22
+L61
+L96
+R3
+R4
+L899
+R388
+L44
+R644
+L26
+L874
+L466
+L34
+R91
+L41
+L69
+L87
+R22
+R2
+R185
+L703
+L28
+R227
+L24
+L75
+L7
+R7
+L90
+L10
+R16
+R15
+L22
+R97
+L6
+R762
+L62
+R447
+R98
+L1
+L70
+L10
+R7
+R86
+R66
+R77
+R95
+R74
+L43
+R68
+L56
+L70
+L99
+L4
+L32
+R69
+L83
+R727
+L46
+R102
+L2
+L66
+L34
+L484
+L28
+R76
+L96
+L21
+L87
+R96
+L836
+R73
+L93
+R90
+R33
+R177
+L45
+R545
+R15
+L2
+L13
+R774
+L867
+R93
+L24
+R24
+L79
+R49
+L51
+L19
+R49
+R98
+R53
+R52
+R48
+R46
+R1
+R57
+L73
+L9
+L29
+L821
+R9
+L481
+R7
+R493
+R39
+R61
+L80
+L20
+L79
+L32
+R20
+L79
+R70
+L83
+L17
+L59
+L2
+R61
+L57
+L67
+L46
+R46
+R11
+R97
+L420
+R30
+L484
+R8
+R482
+L571
+L29
+R30
+R415
+R55
+R169
+L5
+R87
+L89
+R652
+L66
+L48
+R11
+R120
+L16
+L115
+L4
+L24
+R454
+R74
+L139
+R89
+L20
+L82
+L48
+L964
+R251
+R24
+L11
+R65
+R92
+L5
+R156
+R95
+L15
+R31
+L112
+R93
+L93
+R93
+L66
+L98
+R57
+L81
+L385
+L87
+R515
+L10
+R55
+L642
+R442
+R69
+L28
+L83
+L458
+R20
+R80
+R77
+R23
+L45
+R619
+R26
+L21
+R81
+R2
+R738
+R66
+R57
+L82
+L73
+R14
+L82
+L40
+R289
+L84
+R35
+L73
+R443
+R30
+R266
+R84
+R16
+R142
+R42
+R250
+R9
+L43
+R34
+L42
+R42
+L28
+R775
+R84
+L430
+L11
+L19
+L44
+R73
+R84
+R31
+R69
+L58
+L66
+R40
+L17
+L95
+R12
+R98
+L32
+R176
+R1
+R23
+R4
+L495
+R15
+L118
+L72
+L58
+R72
+L85
+L363
+L654
+L26
+R14
+L34
+R49
+R41
+R98
+R23
+R23
+L24
+R873
+L49
+L15
+R20
+R95
+R24
+L27
+L422
+L73
+R14
+L16
+L24
+L83
+R581
+L27
+L37
+L46
+R80
+R73
+R83
+L733
+L26
+L184
+L94
+R8
+L71
+R25
+L925
+L56
+R31
+R46
+R56
+L477
+L58
+L626
+R984
+R28
+L28
+L220
+L5
+L75
+R61
+L61
+R8
+R92
+L63
+R63
+R90
+L927
+R37
+R1
+R499
+L88
+R83
+L95
+R209
+R88
+L97
+R52
+L82
+R2
+R99
+L44
+R84
+R289
+R48
+R68
+R60
+R9
+R36
+L21
+L657
+R47
+L90
+R35
+L655
+L80
+R515
+L41
+L74
+R260
+L4
+R844
+R61
+L609
+L45
+R49
+R9
+L54
+L43
+L68
+R75
+R45
+R80
+R61
+R39
+R87
+L53
+L87
+L729
+R60
+L78
+R99
+R34
+L73
+R40
+L62
+R83
+L21
+L893
+L38
+R31
+L869
+R69
+L278
+R40
+L62
+R24
+R476
+R27
+L46
+R511
+L70
+L33
+L2
+R732
+L62
+R43
+R70
+L91
+R21
+R1
+R99
+R702
+R98
+L22
+L56
+R38
+L33
+L327
+L949
+R57
+R61
+R31
+L832
+L61
+R904
+R3
+L3
+L11
+L737
+R705
+L68
+R1
+L1
+R16
+L12
+R49
+R747
+L46
+L254
+R991
+L38
+L45
+L82
+R80
+L38
+L68
+R254
+L36
+L75
+R57
+L23
+L77
+R80
+R25
+R95
+L609
+R9
+L379
+L57
+L56
+L97
+R64
+L625
+R23
+R25
+R36
+L81
+L753
+R27
+L275
+L640
+L180
+R868
+R697
+L26
+L48
+L93
+R10
+L946
+R37
+L31
+L3
+L97
+L19
+L603
+L445
+R71
+R194
+L77
+L21
+L33
+L576
+L963
+R72
+R56
+R211
+R33
+R45
+L45
+R13
+R29
+R80
+R62
+R16
+L886
+L940
+L4
+R18
+L40
+R52
+R12
+L12
+R921
+R77
+R79
+R62
+R259
+L31
+L84
+L983
+R10
+R19
+R18
+L75
+L99
+L13
+R696
+R44
+R464
+L674
+R10
+R475
+L30
+R20
+L65
+L74
+R774
+L53
+L62
+L85
+L92
+L81
+L27
+L95
+R846
+R64
+R85
+L359
+R59
+L5
+L23
+R878
+L54
+R88
+R416
+R42
+R758
+L3
+L30
+L6
+R42
+R6
+L57
+L59
+L36
+R47
+R5
+L9
+L15
+R15
+L730
+R30
+R37
+R86
+R93
+L77
+R69
+L7
+L217
+L92
+R8
+R11
+R89
+L982
+L18
+L3
+L680
+L17
+R52
+L52
+L6
+R6
+L52
+R67
+R683
+L198
+R59
+R2
+R39
+L35
+R35
+R8
+R22
+R82
+R54
+R34
+L51
+L59
+R3
+L84
+L175
+R89
+R65
+R6
+L61
+L33
+R84
+R757
+L41
+R28
+L28
+R20
+L467
+R47
+L42
+L11
+R53
+L76
+R25
+L70
+R552
+L31
+R24
+R76
+L953
+R496
+L88
+R33
+R64
+R48
+L44
+R37
+R7
+L262
+R74
+R55
+R84
+R49
+R52
+R73
+R65
+L290
+R36
+L24
+R88
+R7
+L55
+R68
+L23
+R929
+R71
+L968
+R71
+R97
+R73
+R48
+R16
+R21
+L55
+R71
+L549
+L6
+R84
+L21
+R929
+L8
+L96
+L87
+L517
+R335
+R60
+L72
+L23
+R26
+R20
+R54
+R94
+L2
+R8
+L19
+L99
+L14
+L286
+R18
+L10
+R610
+L34
+L37
+L99
+L130
+R86
+L63
+R77
+L574
+L26
+R66
+R46
+L58
+L54
+R84
+R16
+L76
+R376
+R84
+L71
+L87
+L26
+R31
+R31
+L77
+L74
+L19
+L13
+R22
+L23
+L49
+R37
+L97
+R584
+R47
+R50
+R50
+L98
+L4
+L98
+L24
+L21
+L55
+L89
+R55
+L49
+R30
+R16
+R88
+L797
+R346
+L89
+R89
+R97
+L97
+R997
+R36
+L33
+L70
+R19
+R48
+L97
+L74
+L86
+L53
+L87
+R76
+R66
+L49
+R4
+L4
+L69
+L24
+L53
+R16
+R5
+R42
+L10
+R56
+L56
+R624
+L5
+R81
+L26
+L93
+R71
+L59
+R7
+R762
+L49
+L244
+L61
+L62
+R69
+L15
+R17
+R83
+L41
+L48
+L235
+L61
+L15
+L81
+R87
+R34
+L40
+L61
+R61
+L1
+R18
+R97
+R42
+L84
+L50
+R515
+R98
+R65
+R56
+R94
+L50
+R49
+L47
+L542
+L5
+R45
+L71
+R83
+R88
+R601
+R44
+L60
+L7
+R57
+R65
+L56
+R923
+R35
+L23
+R421
+R27
+L65
+R9
+R48
+L19
+R518
+R80
+R31
+R479
+R8
+R63
+R21
+R93
+R40
+R167
+L91
+R98
+R25
+L55
+L77
+L51
+L62
+R13
+R61
+L25
+L83
+L53
+L73
+L27
+R47
+L38
+R76
+L85
+R705
+L79
+R5
+L66
+L6
+L48
+R63
+R14
+L420
+R41
+L9
+R66
+R84
+R39
+L51
+R198
+L931
+R95
+L63
+R18
+R26
+L35
+L262
+R216
+R82
+R18
+L901
+R930
+R71
+L34
+R34
+R7
+L34
+R687
+L74
+R141
+L66
+L61
+L22
+L85
+L93
+L8
+L492
+L42
+L56
+L424
+L94
+R67
+L76
+L98
+R35
+R68
+R80
+R20
+R20
+R36
+R42
+L60
+R531
+L49
+L18
+L50
+R991
+R86
+L309
+R90
+L90
+L601
+R61
+R40
+L50
+L60
+L98
+R78
+R9
+R49
+L28
+L55
+R55
+R24
+L24
+R422
+L331
+R9
+R42
+R58
+L76
+L79
+L745
+L86
+R86
+L85
+L47
+L81
+L55
+L32
+L80
+L20
+L30
+R54
+L796
+L5
+R77
+R57
+R901
+R23
+R703
+R58
+L436
+L67
+L79
+R195
+L155
+L87
+R33
+R54
+R77
+L92
+L3
+L21
+R53
+L84
+R45
+L358
+R383
+L220
+L80
+L18
+L64
+L18
+R192
+R45
+L54
+L56
+L27
+R46
+R71
+R30
+R51
+L11
+L87
+R69
+L98
+R29
+L2
+L98
+L79
+L94
+L729
+L98
+L51
+R51
+R69
+R10
+L986
+R399
+L19
+L322
+L10
+R90
+L42
+L66
+R92
+R91
+L6
+R342
+R30
+L43
+R51
+R59
+R61
+L79
+L45
+R90
+L66
+R25
+L51
+L74
+R54
+R72
+R774
+R28
+R72
+L126
+R32
+L6
+R50
+R440
+L7
+L83
+L47
+L53
+R44
+R41
+R75
+R40
+L5
+L95
+L26
+L94
+L394
+R99
+L85
+L43
+R743
+R647
+R98
+L29
+L16
+L53
+L585
+L62
+L688
+R56
+L46
+L673
+R51
+L342
+L258
+L39
+L28
+L33
+L865
+L73
+R32
+R6
+R92
+L15
+R35
+R29
+L41
+L88
+R88
+L80
+L491
+R87
+L72
+L44
+R31
+R69
+R270
+R30
+R10
+L278
+R74
+R73
+L22
+R693
+L15
+L106
+L29
+R65
+R35
+L99
+L30
+R97
+L68
+L8
+R68
+L67
+R86
+R95
+R19
+R7
+R6
+L6
+R45
+R66
+R89
+L38
+R474
+R55
+R71
+R38
+L45
+L55
+R91
+L91
+R41
+L62
+R21
+R80
+R20
+L244
+L6
+R57
+L7
+L27
+R42
+L130
+L17
+L97
+L71
+R40
+L58
+R24
+R94
+L792
+L6
+R952
+L54
+L6
+L694
+R2
+R498
+L98
+R76
+R16
+R35
+R382
+L20
+L775
+L18
+R2
+R87
+L13
+R665
+L69
+L356
+R190
+L3
+R70
+R20
+L91
+R589
+L15
+L16
+R42
+R998
+L383
+L96
+R81
+R195
+L91
+L983
+R79
+L94
+L441
+R35
+R25
+L7
+R36
+L21
+R821
+R92
+R54
+R83
+L83
+R89
+L89
+R848
+L85
+R86
+L49
+L89
+L6
+L456
+R68
+L117
+R48
+L48
+R20
+R80
+R17
+R83
+R773
+R27
+R76
+R24
+L109
+L91
+L55
+R555
+L85
+L30
+R33
+L380
+R6
+L60
+L31
+L35
+R82
+L38
+L17
+R58
+R97
+R53
+L14
+L62
+L984
+R7
+L43
+R55
+R961
+L239
+R66
+L45
+L455
+L40
+L461
+L9
+L17
+L73
+R81
+L21
+L14
+R54
+L24
+R24
+L78
+R778
+R49
+L749
+L88
+L50
+L88
+R47
+R79
+L584
+L16
+R641
+R64
+R577
+R682
+L11
+L29
+L20
+R77
+L981
+R42
+L112
+R70
+R83
+R17
+L40
+R56
+R90
+R94
+R91
+R48
+R2
+L41
+L85
+L76
+R61
+R189
+L89
+R426
+R19
+L845
+L35
+L32
+L33
+R97
+L761
+L32
+R52
+R520
+R22
+L404
+R92
+R14
+L34
+R34
+L65
+L235
+L893
+R55
+L669
+R7
+L91
+R46
+L90
+R55
+L128
+R84
+L47
+L29
+R41
+R70
+R89
+L401
+R1
+L937
+R54
+L37
+L84
+R45
+R5
+L946
+R30
+R80
+R35
+R55
+R713
+R26
+L833
+L91
+R65
+L180
+R95
+L795
+L21
+L79
+R693
+L927
+R6
+R528
+L372
+L59
+R325
+L63
+L31
+R89
+L75
+L414
+R79
+L134
+L839
+L67
+L93
+R145
+L76
+R85
+L55
+L69
+L28
+L10
+R62
+L17
+L83
+L91
+R91
+R63
+L63
+R768
+L68
+L45
+L330
+R896
+R30
+L83
+R132
+R2
+L77
+R50
+R825
+L5
+R5
+L20
+R88
+L68
+R68
+L68
+R13
+R85
+L79
+R22
+R46
+L87
+R76
+L84
+L14
+L15
+L57
+R94
+L38
+L478
+L790
+L94
+R89
+R211
+R769
+L78
+R709
+R89
+R46
+R781
+R44
+L70
+L54
+L36
+R6
+R94
+R32
+L886
+L51
+L95
+L50
+R32
+R85
+R222
+L53
+R504
+L40
+L89
+R59
+L70
+R34
+L39
+R99
+R29
+R81
+L43
+R72
+L14
+R30
+L676
+L58
+R85
+R27
+L527
+L25
+L375
+L13
+R904
+L68
+L123
+L57
+L49
+R6
+L91
+R35
+L66
+L63
+R58
+L243
+R81
+L11
+L578
+R2
+R22
+L7
+L39
+R48
+L148
+L946
+L3
+L84
+R433
+L15
+R915
+L76
+L14
+R290
+L85
+R85
+L34
+L66
+R56
+R544
+R85
+R33
+R436
+L21
+R245
+R22
+R826
+L14
+L112
+R19
+R12
+L18
+R12
+L20
+R6
+L876
+L35
+L62
+L38
+R27
+L27
+R93
+L93
+L94
+R660
+L6
+R766
+R425
+R38
+R35
+R78
+L88
+R78
+L58
+R22
+L56
+L5
+L15
+R15
+L95
+R96
+R4
+L2
+R373
+L20
+L85
+R66
+R68
+R34
+L3
+L289
+L70
+L72
+R28
+L29
+L12
+R25
+R771
+L83
+L46
+R46
+R23
+R58
+R19
+R73
+L56
+R667
+R87
+L74
+L44
+L35
+R66
+L125
+L93
+R734
+L492
+R327
+L89
+L995
+R54
+L905
+L267
+R667
+L95
+L43
+R4
+R5
+L62
+L309
+R80
+L80
+L91
+R860
+R31
+R50
+L41
+L64
+L942
+R4
+L204
+L11
+R8
+R518
+R82
+R3
+R38
+R33
+R26
+R32
+R68
+R1
+L47
+L54
+L64
+R45
+L81
+L99
+L955
+R88
+L53
+L81
+R234
+R266
+L280
+R87
+R71
+L68
+L22
+R91
+R29
+R992
+L25
+R5
+R12
+R8
+L250
+L50
+L2
+R2
+R15
+R903
+R782
+R66
+R46
+L64
+L7
+L7
+L34
+L51
+R35
+L35
+L410
+R61
+L50
+L50
+R67
+L367
+R13
+R39
+L52
+L52
+L28
+R48
+R32
+L92
+R92
+R12
+L83
+R71
+R67
+R33
+L55
+R2
+R53
+L70
+R95
+L98
+L94
+R567
+L21
+R25
+L245
+L78
+L81
+L56
+L88
+R681
+R994
+R712
+R457
+L73
+R156
+L968
+R8
+R78
+R6
+L74
+L33
+R185
+R15
+L668
+R2
+L86
+L758
+L89
+L1
+R675
+L730
+L11
+L77
+L28
+L29
+L42
+L61
+R29
+L26
+R90
+R10
+L96
+L69
+L721
+L81
+L81
+L61
+R409
+L79
+R379
+L31
+R31
+R5
+R33
+L83
+R96
+L33
+R82
+L9
+L756
+L182
+L53
+L92
+L37
+R29
+L16
+R416
+R64
+L64
+L10
+R22
+R268
+L21
+R71
+L75
+R833
+L29
+R77
+R55
+L11
+L82
+R14
+L43
+L53
+L16
+R6
+R94
+L51
+R31
+R20
+L95
+R295
+R34
+L570
+L102
+R85
+R564
+L711
+R688
+L88
+R95
+L95
+R62
+R34
+R8
+R31
+R659
+L49
+L88
+R2
+R98
+L79
+R5
+L62
+R379
+R355
+L57
+L38
+R815
+L20
+L831
+R76
+L47
+R677
+R70
+R740
+R39
+R8
+L87
+R7
+R32
+R86
+R97
+R78
+R38
+R428
+R98
+L64
+L28
+R928
+L65
+L635
+R20
+L20
+L53
+R53
+R278
+R624
+R52
+L51
+R86
+L10
+L16
+L63
+L69
+R69
+L35
+L92
+L73
+R92
+L92
+L95
+R95
+R86
+R28
+L14
+R29
+L29
+L49
+L51
+R68
+R76
+L644
+R63
+R137
+R56
+L56
+R99
+R858
+R20
+L77
+R982
+L68
+R73
+R13
+R227
+R68
+R405
+L24
+R59
+L71
+L638
+R74
+L31
+L81
+R85
+L73
+R41
+R59
+L40
+L60
+R17
+L17
+L87
+L13
+R14
+R391
+L5
+L821
+R21
+L73
+R73
+R7
+R17
+R52
+L8
+R169
+R63
+L709
+R9
+R62
+R15
+L63
+R67
+L81
+R35
+R65
+R24
+L83
+L704
+R363
+L5
+L44
+R49
+L47
+L53
+L77
+L23
+R31
+L31
+R48
+L48
+L2
+R272
+L23
+L6
+L841
+L5
+L52
+R57
+L948
+L29
+L19
+R30
+L78
+L10
+L41
+L88
+L76
+L91
+R50
+L305
+L95
+L66
+R366
+R71
+L71
+R452
+R5
+L57
+R882
+L82
+R96
+R37
+L75
+R42
+L56
+L144
+L73
+R73
+R625
+L9
+L216
+R28
+L912
+R84
+L897
+R497
+R85
+L22
+L46
+L38
+R121
+R99
+L18
+R19
+L163
+L237
+L23
+R623
+L20
+R87
+L67
+L396
+L102
+R98
+R24
+R76
+R62
+R36
+L98
+R16
+R4
+L20
+L222
+L678
+R98
+L1
+R262
+L459
+L54
+L16
+R283
+L27
+R114
+L78
+R64
+R45
+R69
+L6
+R5
+L28
+R76
+L76
+R29
+R83
+L83
+R119
+R95
+L98
+R84
+R28
+R72
+L99
+R89
+L90
+R111
+L66
+R55
+R50
+R28
+R78
+R559
+R85
+L36
+R36
+R67
+R33
+R846
+L46
+R999
+L80
+L19
+L55
+L63
+R69
+L68
+L33
+R50
+L264
+R534
+L43
+R173
+L30
+L70
+L60
+R99
+L86
+R59
+L19
+L93
+R272
+R58
+L30
+L23
+R77
+L80
+L41
+R97
+L52
+L25
+L88
+R35
+R10
+R10
+L46
+L40
+L72
+L5
+L613
+R76
+R80
+L33
+L67
+L19
+R16
+L10
+R4
+L60
+R69
+R319
+L185
+L85
+L49
+L20
+L80
+R61
+L66
+L247
+L17
+R69
+L65
+R65
+R25
+L12
+L21
+L92
+L66
+L83
+R49
+L51
+L30
+L81
+L87
+L53
+R80
+L392
+L32
+L95
+R22
+L481
+L84
+L16
+L75
+R75
+L11
+R11
+R962
+L62
+R740
+L40
+R7
+L22
+L85
+R6
+L42
+R390
+R37
+R34
+R60
+R723
+L308
+L76
+L46
+L78
+R41
+L68
+L95
+R7
+R15
+L94
+R76
+L39
+R18
+L49
+R31
+R57
+L131
+R60
+R96
+R19
+L44
+R19
+R40
+R41
+R942
+L39
+R63
+L66
+R650
+R77
+L48
+R54
+L412
+R879
+R724
+L424
+R1
+L4
+R703
+L92
+L1
+R59
+R134
+R97
+R88
+L52
+R30
+L63
+R30
+L618
+R88
+R38
+R44
+R18
+R55
+R45
+R86
+R18
+L639
+R5
+L70
+R65
+R48
+L13
+L84
+R41
+L57
+R85
+L85
+L65
+L10
+R35
+R76
+L840
+R44
+L40
+R23
+R65
+L488
+R26
+R70
+L13
+R606
+R11
+R96
+R604
+R426
+R74
+L50
+R33
+R40
+R58
+L715
+R534
+R55
+R29
+L41
+R60
+R18
+R279
+R15
+L75
+L61
+L33
+L62
+R84
+L48
+R864
+R94
+R78
+R51
+R93
+L81
+L90
+L70
+L29
+L45
+L685
+R408
+R52
+L94
+L62
+L28
+R6
+R18
+R205
+L90
+R75
+R84
+L74
+R40
+L640
+L53
+R436
+R604
+R99
+L46
+R550
+L141
+R14
+L67
+L74
+L34
+R12
+L78
+R78
+L83
+L505
+R388
+L36
+L159
+L5
+R598
+L933
+L47
+R96
+R76
+L8
+L318
+R6
+L970
+L951
+R51
+L35
+L186
+R146
+L25
+R97
+R3
+L527
+R35
+L24
+L384
+R66
+L28
+L62
+L28
+R19
+R33
+L30
+R78
+L248
+R57
+R92
+R51
+R75
+R25
+L78
+R78
+L74
+R15
+L744
+L97
+L36
+L76
+R12
+L95
+R62
+L855
+L12
+R61
+L892
+R3
+R328
+L72
+L30
+L96
+L5
+R150
+L447
+L520
+R80
+R40
+R43
+R52
+L92
+R56
+R677
+L36
+R594
+R6
+L86
+L19
+L34
+R410
+L71
+R3
+R97
+R82
+R94
+L176
+R63
+R26
+R11
+R55
+R45
+R17
+R709
+L972
+L76
+R68
+L74
+L72
+L70
+R57
+L60
+L27
+L17
+L83
+R49
+L17
+R84
+L33
+R405
+R13
+R99
+L41
+L19
+L77
+L804
+L10
+L30
+L28
+L705
+R214
+R63
+R56
+R81
+R99
+R88
+R13
+L74
+L42
+R56
+R58
+L36
+L62
+L95
+L5
+R86
+R255
+R28
+R82
+L15
+L72
+L42
+L89
+L33
+L165
+R65
+L49
+L29
+L22
+R96
+R31
+L27
+R18
+R2
+L21
+L84
+L15
+L88
+L110
+R6
+R81
+R39
+L28
+R80
+L56
+L24
+L43
+R43
+R20
+R25
+R36
+R27
+L7
+R99
+L19
+L45
+R92
+L78
+R39
+L87
+R98
+R85
+R15
+R59
+L4
+R65
+R680
+R61
+R39
+R76
+R24
+R96
+L26
+L70
+R79
+R521
+L83
+L22
+L528
+L62
+L505
+L5
+R5
+R77
+R23
+L18
+R18
+R2
+L63
+L739
+L522
+R22
+L11
+L140
+R36
+L85
+L392
+L97
+L36
+R25
+R56
+L56
+R545
+R39
+L34
+L692
+L82
+R89
+R2
+R33
+L56
+R20
+L677
+L44
+R57
+R6
+R22
+L228
+L70
+R48
+R48
+L383
+R257
+L43
+L51
+R66
+L87
+R715
+L80
+L1
+L14
+R45
+R50
+R45
+L320
+R75
+L64
+L24
+R71
+L486
+L28
+L7
+L53
+L9
+L75
+R96
+R38
+L82
+R95
+R28
+L16
+R16
+R658
+R42
+L67
+L91
+L42
+R93
+R40
+L93
+L802
+L26
+R88
+R99
+R1
+L64
+R79
+L764
+R81
+R81
+L95
+R22
+R93
+R67
+L24
+L76
+R60
+R806
+L29
+L39
+L8
+L68
+R72
+R6
+L86
+R452
+L966
+R86
+R596
+R71
+L86
+R43
+L97
+L22
+R9
+R67
+L30
+R80
+R76
+R30
+R361
+R16
+R32
+R331
+L39
+R760
+R69
+R47
+L20
+R20
+L69
+L31
+L12
+R95
+L9
+L57
+R83
+L112
+L51
+L62
+L75
+R49
+R32
+L81
+L36
+R36
+L80
+L20
+L15
+R60
+R37
+R66
+R76
+R12
+R1
+R63
+R38
+L38
+R24
+L24
+R121
+L21
+R645
+L5
+L263
+R23
+R21
+L621
+R815
+L79
+L47
+R11
+R52
+R48
+R12
+L72
+L849
+R26
+R706
+R77
+R848
+L81
+R646
+R16
+R71
+L87
+L60
+R18
+L71
+L20
+R20
+R96
+L42
+L47
+L452
+R77
+R22
+L149
+R95
+R5
+R478
+L83
+R54
+R46
+L497
+R517
+R80
+R353
+L82
+R29
+L40
+R40
+R516
+L16
+R922
+L22
+L32
+R89
+R74
+L55
+L76
+R78
+R78
+L70
+R14
+L88
+L912
+R369
+R9
+R29
+L74
+L833
+L37
+R737
+R87
+L787
+R95
+R38
+L61
+L67
+R295
+R3
+R97
+R27
+L82
+R64
+R691
+L56
+R136
+L72
+R49
+L77
+R61
+R59
+R29
+L932
+L44
+R42
+R299
+R709
+L471
+R88
+R80
+R63
+R39
+R998
+R66
+L730
+L83
+L53
+R88
+R10
+R2
+R31
+L57
+R86
+R725
+R879
+L13
+R70
+L21
+R20
+L20
+R61
+R739
+R10
+L10
+R221
+L23
+R734
+R10
+L42
+R458
+R842
+R2
+R24
+R452
+R291
+L32
+L37
+L98
+L2
+L48
+R15
+R51
+L20
+R2
+L169
+R169
+L42
+L58
+L9
+L19
+R28
+R804
+R96
+R74
+R26
+L61
+R61
+L41
+L53
+R94
+L15
+L85
+L19
+L81
+L68
+R84
+R84
+L12
+L88
+L12
+L52
+L30
+R94
+L60
+R10
+L50
+R457
+R72
+R71
+R16
+L43
+R66
+R4
+L35
+R73
+L88
+R507
+R54
+R37
+R4
+L19
+L14
+L14
+R52
+R36
+R51
+L87
+L876
+R62
+R14
+R45
+L30
+R84
+R1
+R86
+R71
+R43
+R39
+L39
+L65
+R65
+R387
+L389
+L8
+R91
+R55
+R3
+L39
+L10
+L70
+R52
+L8
+R36
+R65
+L99
+L5
+R64
+R117
+R38
+R63
+L43
+L66
+R66
+L76
+L24
+L7
+L32
+R1
+R31
+R3
+L359
+L37
+R90
+L190
+R196
+R4
+L71
+R99
+R72
+R91
+R9
+R10
+L44
+L57
+L69
+R60
+L36
+R77
+L21
+L85
+R65
+R77
+R68
+L71
+R43
+R34
+R249
+L58
+R307
+R51
+R72
+L384
+R12
+L33
+R5
+L37
+R65
+L808
+R508
+L870
+R70
+R95
+L95
+R16
+R84
+R39
+R16
+L73
+R18
+R60
+R76
+L89
+R53
+L96
+L85
+R44
+R519
+R98
+L383
+R3
+R12
+L12
+R84
+L108
+L76
+L10
+R710
+R44
+L44
+R97
+R3
+L54
+R25
+L43
+L528
+L47
+L53
+R78
+L954
+L24
+L16
+R16
+R66
+L66
+L526
+R832
+R194
+L634
+L9
+R71
+R7
+R31
+L67
+L16
+R17
+L27
+R27
+L95
+L5
+L70
+R70
+R93
+L418
+R36
+L51
+R13
+R29
+R98
+L77
+L37
+L153
+R67
+R74
+R90
+R25
+R711
+R5
+L252
+R1
+R17
+R80
+L29
+R73
+L8
+R613
+R92
+R15
+R93
+R504
+R6
+R34
+L70
+R42
+R384
+L21
+L902
+L64
+L64
+L49
+R3
+R97
+L9
+L885
+R11
+L64
+L52
+R7
+L50
+L80
+R8
+R58
+R25
+L16
+L253
+R16
+R78
+R32
+R174
+L84
+R56
+L10
+L16
+L528
+R778
+R36
+L48
+L36
+R52
+R74
+L47
+L58
+L69
+L95
+L105
+L828
+R415
+L28
+L87
+L2
+R30
+L471
+R78
+R71
+R88
+R34
+R12
+R88
+R52
+R48
+R519
+R81
+R44
+R56
+R77
+R56
+R71
+R90
+L94
+L673
+L65
+R38
+L212
+L38
+L50
+L641
+L59
+L394
+R28
+R65
+L708
+L20
+L4
+R473
+R30
+R731
+R99
+L82
+R89
+L35
+R10
+L82
+L99
+L1
+R98
+L19
+L79
+L52
+L48
+L471
+L29
+L4
+L96
+L41
+L23
+L36
+L35
+R35
+R27
+R73
+R64
+R33
+R32
+L29
+R46
+L66
+R211
+R868
+L59
+R17
+R21
+R27
+R521
+R91
+R23
+R1
+L79
+R23
+L45
+R85
+R15
+R41
+R559
+L17
+L40
+R86
+L45
+L39
+R56
+L30
+R81
+L33
+R82
+L1
+L631
+R531
+R56
+R92
+L90
+R42
+L94
+L28
+L40
+R662
+L232
+L68
+L65
+R37
+R28
+L48
+L99
+R83
+L76
+L95
+L424
+L572
+R99
+R68
+L20
+R84
+L911
+R3
+L91
+R99
+R47
+L147
+R312
+L61
+R949
+R74
+L88
+L307
+R53
+R4
+R64
+L3
+R99
+L31
+L28
+R63
+L70
+R6
+L77
+R22
+L212
+L69
+L86
+R86
+L27
+R56
+L29
+L999
+R99
+R83
+L15
+R99
+R67
+R19
+R42
+R7
+R62
+L831
+R1
+L51
+R955
+L13
+R92
+R4
+R720
+R26
+L71
+R4
+R37
+R520
+R43
+L90
+L20
+R98
+R376
+L3
+R39
+L37
+L32
+R9
+R33
+L32
+R465
+R794
+R19
+R81
+R80
+R20
+R7
+R593
+R29
+L29
+L21
+L79
+R27
+R673
+R63
+L79
+L84
+R62
+L62
+L52
+R52
+R57
+L12
+R55
+R69
+R8
+R52
+L71
+R23
+R50
+R73
+R959
+L91
+R7
+L715
+R93
+R92
+R951
+R42
+L42
+L69
+L31
+R14
+L814
+L903
+R67
+R68
+R77
+R1
+L66
+L44
+L63
+L37
+R19
+L40
+R34
+L43
+L14
+R16
+R62
+L83
+R49
+R12
+L12
+R73
+R27
+L60
+L65
+R14
+R567
+L56
+L8
+L171
+L14
+L785
+L41
+R99
+L19
+L61
+L54
+L43
+R96
+L321
+R79
+R73
+R22
+L54
+L98
+R22
+R78
+L72
+R67
+L95
+R96
+L97
+R75
+R43
+R183
+L31
+R198
+L467
+R426
+R98
+R89
+L13
+R531
+L13
+L19
+R15
+R886
+R49
+L95
+L98
+R34
+L90
+L99
+L1
+L876
+R76
+L910
+R65
+R45
+R53
+R784
+R91
+R78
+R9
+L642
+L71
+L1
+R10
+L11
+R79
+L93
+R69
+L55
+R878
+R55
+L97
+R59
+R805
+L21
+L25
+L27
+R73
+R91
+L447
+L550
+R35
+R6
+R44
+R55
+L834
+R77
+L73
+L4
+R75
+L10
+L883
+L60
+L95
+R73
+L25
+R48
+R877
+R67
+L67
+R98
+R302
+R93
+R29
+R78
+L17
+L69
+R86
+R19
+R51
+R853
+L37
+R14
+L921
+L61
+R63
+L681
+R54
+L62
+L92
+L40
+L79
+L81
+L81
+R54
+R790
+L4
+L75
+R560
+L44
+R33
+R64
+L80
+L98
+R45
+R4
+L68
+L63
+R69
+R25
+L66
+R36
+R55
+L56
+L97
+R97
+L42
+R42
+L58
+L42
+R19
+R4
+L12
+L32
+R78
+L57
+R74
+R24
+L8
+L90
+L61
+R61
+L39
+L36
+L25
+R79
+L18
+L86
+R30
+L62
+L19
+L24
+L88
+R99
+R53
+R75
+R44
+L14
+L45
+R29
+L46
+R95
+R66
+L70
+L44
+L46
+L17
+L45
+R22
+R29
+L27
+R40
+R32
+R18
+L11
+L24
+R36
+R5
+R42
+L27
+L35
+L29
+L42
+R38
+R10
+L20
+L24
+R20
+R38
+L29
+L28
+L23
+R28
+R9
+L48
+L9
+R23
+L50
+L5
+R22
+R46
+R12
+R23
+L32
+R26
+L3
+L47
+R7
+L4
+R21
+L47
+R3
+L14
+R24
@@ -0,0 +1,10 @@
+L68
+L30
+R48
+L5
+R60
+L55
+L1
+L99
+R14
+L82
@@ -0,0 +1,21 @@
+# This file was generated by Gleam
+# You typically do not need to edit this file
+
+packages = [
+ { name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" },
+ { name = "birl", version = "1.8.0", build_tools = ["gleam"], requirements = ["gleam_regexp", "gleam_stdlib", "ranger"], otp_app = "birl", source = "hex", outer_checksum = "2AC7BA26F998E3DFADDB657148BD5DDFE966958AD4D6D6957DD0D22E5B56C400" },
+ { name = "filepath", version = "1.1.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "B06A9AF0BF10E51401D64B98E4B627F1D2E48C154967DA7AF4D0914780A6D40A" },
+ { name = "gleam_regexp", version = "1.1.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "9C215C6CA84A5B35BB934A9B61A9A306EC743153BE2B0425A0D032E477B062A9" },
+ { name = "gleam_stdlib", version = "0.67.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "6368313DB35963DC02F677A513BB0D95D58A34ED0A9436C8116820BF94BE3511" },
+ { name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" },
+ { name = "gleeunit", version = "1.9.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "DA9553CE58B67924B3C631F96FE3370C49EB6D6DC6B384EC4862CC4AAA718F3C" },
+ { name = "ranger", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_yielder"], otp_app = "ranger", source = "hex", outer_checksum = "C8988E8F8CDBD3E7F4D8F2E663EF76490390899C2B2885A6432E942495B3E854" },
+ { name = "simplifile", version = "2.3.1", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "957E0E5B75927659F1D2A1B7B75D7B9BA96FAA8D0C53EA71C4AD9CD0C6B848F6" },
+]
+
+[requirements]
+argv = { version = ">= 1.0.2 and < 2.0.0" }
+birl = { version = ">= 1.8.0 and < 2.0.0" }
+gleam_stdlib = { version = ">= 0.44.0 and < 2.0.0" }
+gleeunit = { version = ">= 1.0.0 and < 2.0.0" }
+simplifile = { version = ">= 2.3.1 and < 3.0.0" }
@@ -0,0 +1,15 @@
+defmodule Aoc.MixProject do
+ use Mix.Project
+
+ def project do
+ [
+ app: :aoc,
+ version: "1.0.0",
+ deps: deps()
+ ]
+ end
+
+ defp deps do
+ []
+ end
+end
@@ -0,0 +1,84 @@
+import argv
+import compare
+import gleam/int
+import gleam/io
+import gleam/list
+import gleam/option.{type Option, None, Some}
+import gleam/result
+import gleam/string
+import internal/mine/day01 as mine_day01
+import utils
+
+const available_days = [1]
+
+pub fn main() -> Nil {
+ let args = argv.load().arguments
+
+ case parse_args(args) {
+ Error(msg) -> io.println("Error: " <> msg)
+ Ok(#(day, example, cmp)) ->
+ case day {
+ Some(d) -> run_day(d, example, cmp)
+ None -> list.each(available_days, fn(d) { run_day(d, example, cmp) })
+ }
+ }
+}
+
+pub type Args {
+ Args(day: Option(Int), example: Bool, compare: Bool)
+}
+
+fn parse_args(
+ args: List(String),
+) -> Result(#(Option(Int), Bool, Bool), String) {
+ let example = list.contains(args, "--example") || list.contains(args, "-e")
+ let no_cmp =
+ list.contains(args, "--no-compare") || list.contains(args, "-n")
+ let day_args = list.filter(args, fn(a) { !string.starts_with(a, "-") })
+
+ use day <- result.try(case day_args {
+ [day_str, ..] ->
+ case int.parse(day_str) {
+ Ok(d) if d >= 1 && d <= 25 -> Ok(Some(d))
+ Ok(_) -> Error("day must be between 1 and 25")
+ Error(_) -> Error("invalid day number: " <> day_str)
+ }
+ [] -> Ok(None)
+ })
+
+ Ok(#(day, example, !no_cmp))
+}
+
+fn run_day(day: Int, example: Bool, cmp: Bool) -> Nil {
+ case utils.read_input(day, example) {
+ Error(e) -> io.println(e)
+ Ok(input) -> {
+ let mode = case example {
+ True -> " (example)"
+ False -> ""
+ }
+ io.println("=== Day " <> int.to_string(day) <> mode <> " ===")
+ case cmp {
+ True -> run_comparison(day, input)
+ False -> run_parts(day, input)
+ }
+ }
+ }
+}
+
+fn run_parts(day: Int, input: List(String)) -> Nil {
+ case day {
+ 1 -> {
+ io.println("Part 1: " <> int.to_string(mine_day01.part1(input)))
+ io.println("Part 2: " <> int.to_string(mine_day01.part2(input)))
+ }
+ _ -> io.println("Day " <> int.to_string(day) <> " not implemented yet")
+ }
+}
+
+fn run_comparison(day: Int, input: List(String)) -> Nil {
+ case day {
+ 1 -> compare.day01(input)
+ _ -> io.println("Day " <> int.to_string(day) <> " comparison not available")
+ }
+}
@@ -0,0 +1,96 @@
+import birl
+import gleam/int
+import gleam/io
+import gleam/string
+import internal/llm/day01 as llm_day01
+import internal/mine/day01 as mine_day01
+
+pub type TimedResult {
+ TimedResult(result: Int, microseconds: Int)
+}
+
+fn time_fn(f: fn() -> Int) -> TimedResult {
+ let start = birl.now() |> birl.to_unix_micro
+ let result = f()
+ let end = birl.now() |> birl.to_unix_micro
+ TimedResult(result: result, microseconds: end - start)
+}
+
+fn format_time(microseconds: Int) -> String {
+ case microseconds {
+ us if us < 1000 -> int.to_string(us) <> "ยตs"
+ us if us < 1_000_000 -> {
+ let ms = us / 1000
+ let remainder = us % 1000
+ int.to_string(ms)
+ <> "."
+ <> string.pad_start(int.to_string(remainder / 100), 1, "0")
+ <> "ms"
+ }
+ us -> {
+ let s = us / 1_000_000
+ let ms = { us % 1_000_000 } / 1000
+ int.to_string(s)
+ <> "."
+ <> string.pad_start(int.to_string(ms), 3, "0")
+ <> "s"
+ }
+ }
+}
+
+fn print_comparison(part: String, mine: TimedResult, llm: TimedResult) -> Nil {
+ io.println("")
+ io.println("--- " <> part <> " ---")
+ io.println(
+ "Mine: "
+ <> int.to_string(mine.result)
+ <> " ("
+ <> format_time(mine.microseconds)
+ <> ")",
+ )
+ io.println(
+ "LLM: "
+ <> int.to_string(llm.result)
+ <> " ("
+ <> format_time(llm.microseconds)
+ <> ")",
+ )
+
+ let match = case mine.result == llm.result {
+ True -> "โ Results match"
+ False -> "โ Results differ!"
+ }
+ io.println(match)
+
+ let speedup = case mine.microseconds, llm.microseconds {
+ 0, 0 -> "Both too fast to measure"
+ m, _l if m == 0 -> "Mine too fast to measure"
+ _m, l if l == 0 -> "LLM too fast to measure"
+ m, l if m < l -> "Mine " <> format_speedup(l, m) <> " faster"
+ m, l if l < m -> "LLM " <> format_speedup(m, l) <> " faster"
+ _, _ -> "Same speed"
+ }
+ io.println(speedup)
+}
+
+fn format_speedup(slower: Int, faster: Int) -> String {
+ let ratio = { slower * 100 } / faster
+ let whole = ratio / 100
+ let frac = ratio % 100
+ int.to_string(whole)
+ <> "."
+ <> string.pad_start(int.to_string(frac), 2, "0")
+ <> "x"
+}
+
+pub fn day01(input: List(String)) -> Nil {
+ io.println("Comparing implementations...")
+
+ let mine_p1 = time_fn(fn() { mine_day01.part1(input) })
+ let llm_p1 = time_fn(fn() { llm_day01.part1(input) })
+ print_comparison("Part 1", mine_p1, llm_p1)
+
+ let mine_p2 = time_fn(fn() { mine_day01.part2(input) })
+ let llm_p2 = time_fn(fn() { llm_day01.part2(input) })
+ print_comparison("Part 2", mine_p2, llm_p2)
+}
@@ -0,0 +1,83 @@
+//// Authored-by: Claude Opus 4.5 via Crush
+
+import gleam/int
+import gleam/list
+import gleam/result
+import gleam/string
+
+pub type Rotation {
+ Left(Int)
+ Right(Int)
+}
+
+fn parse_rotation(s: String) -> Result(Rotation, Nil) {
+ let s = string.trim(s)
+ case string.first(s) {
+ Ok("L") -> s |> string.drop_start(1) |> int.parse |> result.map(Left)
+ Ok("R") -> s |> string.drop_start(1) |> int.parse |> result.map(Right)
+ _ -> Error(Nil)
+ }
+}
+
+fn apply_rotation(position: Int, rotation: Rotation) -> Int {
+ let new_pos = case rotation {
+ Left(n) -> position - n
+ Right(n) -> position + n
+ }
+ // Wrap around 0-99 (100 positions)
+ { { new_pos % 100 } + 100 } % 100
+}
+
+pub fn part1(input: List(String)) -> Int {
+ let rotations = list.filter_map(input, parse_rotation)
+ let #(zero_count, _final_pos) =
+ list.fold(rotations, #(0, 50), fn(acc, rotation) {
+ let #(count, pos) = acc
+ let new_pos = apply_rotation(pos, rotation)
+ let new_count = case new_pos {
+ 0 -> count + 1
+ _ -> count
+ }
+ #(new_count, new_pos)
+ })
+ zero_count
+}
+
+fn count_zeros_crossed(position: Int, rotation: Rotation) -> Int {
+ let #(steps, going_right) = case rotation {
+ Left(n) -> #(n, False)
+ Right(n) -> #(n, True)
+ }
+
+ case going_right {
+ True -> {
+ // Right: hit 0 when (position + k) % 100 == 0
+ let first_hit = { 100 - position } % 100
+ case first_hit {
+ 0 -> steps / 100
+ f if f <= steps -> { steps - f } / 100 + 1
+ _ -> 0
+ }
+ }
+ False -> {
+ // Left: hit 0 when (position - k) % 100 == 0, i.e., k == position
+ case position {
+ 0 -> steps / 100
+ p if p <= steps -> { steps - p } / 100 + 1
+ _ -> 0
+ }
+ }
+ }
+}
+
+pub fn part2(input: List(String)) -> Int {
+ let rotations = list.filter_map(input, parse_rotation)
+ let #(zero_count, _final_pos) =
+ list.fold(rotations, #(0, 50), fn(acc, rotation) {
+ let #(count, pos) = acc
+ let zeros = count_zeros_crossed(pos, rotation)
+ let new_pos = apply_rotation(pos, rotation)
+ #(count + zeros, new_pos)
+ })
+ zero_count
+}
@@ -0,0 +1,90 @@
+import gleam/int
+import gleam/list
+import gleam/result
+import gleam/string
+
+const starting_position = 50
+
+pub type Movement {
+ Left(Int)
+ Right(Int)
+}
+
+pub fn part1(input: List(String)) -> Int {
+ let movements = input |> list.filter_map(parse_movement)
+ let #(zero_count, _final_pos) =
+ list.fold(movements, #(0, starting_position), fn(acc, movement) {
+ let #(count, pos) = acc
+ let new_pos = apply_movement(pos, movement)
+ let new_count = case new_pos {
+ 0 -> count + 1
+ _ -> count
+ }
+ #(new_count, new_pos)
+ })
+ zero_count
+}
+
+pub fn part2(input: List(String)) -> Int {
+ let movements = input |> list.filter_map(parse_movement)
+ let #(zero_count, _final_pos) =
+ list.fold(movements, #(0, starting_position), fn(acc, movement) {
+ let #(count, pos) = acc
+ let new_pos = apply_movement(pos, movement)
+ let zeroes = zeroes_hit(pos, movement)
+ #(count + zeroes, new_pos)
+ })
+ zero_count
+}
+
+pub fn parse_movement(input: String) -> Result(Movement, Nil) {
+ case string.first(input) {
+ Ok("L") ->
+ input
+ |> string.drop_start(1)
+ |> int.parse
+ |> result.map(Left)
+ Ok("R") ->
+ input
+ |> string.drop_start(1)
+ |> int.parse
+ |> result.map(Right)
+ _ -> Error(Nil)
+ }
+}
+
+fn apply_movement(position: Int, movement: Movement) -> Int {
+ let new_pos = case movement {
+ Left(n) -> position - n
+ Right(n) -> position + n
+ }
+ // Wrap around 0-99 (100 positions)
+ { { new_pos % 100 } + 100 } % 100
+}
+
+fn zeroes_hit(position: Int, movement: Movement) -> Int {
+ let #(steps, going_right) = case movement {
+ Left(n) -> #(n, False)
+ Right(n) -> #(n, True)
+ }
+
+ case going_right {
+ True -> {
+ // Right: hit 0 when (position + k) % 100 == 0
+ let first_hit = { 100 - position } % 100
+ case first_hit {
+ 0 -> steps / 100
+ f if f <= steps -> { steps - f } / 100 + 1
+ _ -> 0
+ }
+ }
+ False -> {
+ // Left: hit 0 when (position - k) % 100 == 0, i.e., k == position
+ case position {
+ 0 -> steps / 100
+ p if p <= steps -> { steps - p } / 100 + 1
+ _ -> 0
+ }
+ }
+ }
+}
@@ -0,0 +1,23 @@
+import gleam/int
+import gleam/string
+import simplifile
+
+/// Read input for a given day. If example is True, reads from dayXX_example.txt
+pub fn read_input(day: Int, example: Bool) -> Result(List(String), String) {
+ let day_str = int.to_string(day) |> string.pad_start(2, "0")
+ let suffix = case example {
+ True -> "_example"
+ False -> ""
+ }
+ let path = "input/day" <> day_str <> suffix <> ".txt"
+
+ case simplifile.read(path) {
+ Ok(content) ->
+ Ok(
+ content
+ |> string.trim
+ |> string.split("\n"),
+ )
+ Error(e) -> Error("failed to read " <> path <> ": " <> string.inspect(e))
+ }
+}
@@ -0,0 +1,39 @@
+import gleeunit
+import gleeunit/should
+import internal/llm/day01 as llm_day01
+import internal/mine/day01 as mine_day01
+import utils
+
+pub fn main() -> Nil {
+ gleeunit.main()
+}
+
+pub fn mine_day01_part1_example_test() {
+ let assert Ok(input) = utils.read_input(1, True)
+ mine_day01.part1(input)
+ |> should.equal(3)
+}
+
+pub fn mine_day01_part1_test() {
+ let assert Ok(input) = utils.read_input(1, False)
+ mine_day01.part1(input)
+ |> should.equal(1011)
+}
+
+pub fn llm_day01_part1_example_test() {
+ let assert Ok(input) = utils.read_input(1, True)
+ llm_day01.part1(input)
+ |> should.equal(3)
+}
+
+pub fn llm_day01_part1_test() {
+ let assert Ok(input) = utils.read_input(1, False)
+ llm_day01.part1(input)
+ |> should.equal(1011)
+}
+
+pub fn llm_day01_part2_example_test() {
+ let assert Ok(input) = utils.read_input(1, True)
+ llm_day01.part2(input)
+ |> should.equal(6)
+}