├── day16 ├── test1.txt ├── output.txt ├── test2.txt ├── test3.txt ├── test4.txt ├── test5.txt ├── test6.txt ├── test7.txt ├── input.txt └── day16.go ├── rs ├── .gitignore ├── day2 │ ├── foo.txt │ ├── test1.txt │ ├── test2.txt │ ├── Cargo.lock │ ├── Cargo.toml │ ├── input.txt │ └── src │ │ └── main.rs ├── day20 │ ├── output.txt │ ├── rustfmt.toml │ ├── Cargo.lock │ ├── Cargo.toml │ ├── test1.txt │ └── test2.txt ├── day3 │ ├── output.txt │ ├── Cargo.lock │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── input.txt ├── day4 │ ├── input.txt │ ├── output.txt │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── day6 │ ├── output.txt │ ├── test.txt │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── day1 │ ├── output.txt │ ├── Cargo.lock │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── input.txt ├── day18 │ ├── test2.txt │ ├── test3.txt │ ├── test4.txt │ ├── test1.txt │ ├── Cargo.lock │ └── Cargo.toml ├── day10 │ ├── test1.txt │ ├── test6.txt │ ├── Cargo.lock │ ├── test2.txt │ ├── test3.txt │ ├── test4.txt │ ├── Cargo.toml │ ├── test5.txt │ └── input.txt ├── day24 │ ├── input.txt │ ├── test.txt │ ├── test2.txt │ ├── Cargo.lock │ └── Cargo.toml ├── day8 │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── geom │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── intcode │ └── Cargo.toml ├── day5 │ ├── Cargo.lock │ ├── Cargo.toml │ ├── src │ │ └── main.rs │ └── input.txt └── day9 │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ └── main.rs ├── day10 ├── output.txt ├── test1.txt ├── test6.txt ├── test2.txt ├── test3.txt ├── test4.txt ├── test5.txt ├── input.txt └── day10_rf.go ├── day15 ├── output.txt └── input.txt ├── day2 ├── test1.txt ├── output.txt ├── test2.txt ├── input.txt └── day2.go ├── day20 ├── output.txt ├── test1.txt └── test2.txt ├── day3 ├── output.txt ├── test3.txt ├── test1.txt ├── test2.txt ├── input.txt └── day3.go ├── day4 ├── output.txt ├── README └── day4.go ├── day5 ├── test.txt ├── output.txt ├── README └── input.txt ├── day13 ├── output.txt ├── README ├── day13.patch ├── play.go └── day13.go ├── day17 └── output.txt ├── day18 ├── output.txt ├── test4.txt ├── test1.txt ├── test5.txt ├── test3.txt └── test2.txt ├── day19 ├── output.txt ├── input.txt └── day19.go ├── day21 ├── test.txt ├── output.txt ├── part1.txt ├── part2.txt ├── README └── day21.go ├── day23 ├── output.txt └── day23.go ├── day6 ├── output.txt ├── test.txt └── day6.go ├── day7 ├── output.txt ├── test1.txt ├── test2.txt ├── test1_part2.txt ├── test3.txt └── input.txt ├── py ├── day20 │ ├── output.txt │ ├── .gitignore │ ├── README │ ├── test1.txt │ └── test2.txt ├── day18 │ ├── test1.txt │ ├── test3.txt │ └── test2.txt └── day1 │ ├── main.py │ └── input.txt ├── day1 ├── output.txt ├── day1_short.go ├── input.txt └── day1.go ├── day14 ├── output.txt ├── test1.txt ├── test2.txt ├── test3.txt ├── test4.txt ├── test5.txt ├── input.txt └── day14.go ├── day9 ├── output.txt ├── test3.txt ├── test2.txt ├── test1.txt ├── README ├── day9.go └── input.txt ├── c ├── .gitignore ├── .clang-format ├── test.sh ├── comb.h ├── parse.c ├── parse.h ├── queue.h ├── test.c ├── snapshot.txt ├── amp.h ├── pt2.h ├── README ├── comb.c ├── hash.h ├── hash_test.c ├── run_remote.sh ├── queue.c ├── day5.c ├── vm.h ├── day9.c ├── day2.c ├── pt2.c ├── day2_test.c ├── day7.c ├── amp.c ├── day25.c ├── day9_test.c ├── hash.c └── day13.c ├── day12 ├── output.txt ├── test1.txt ├── test2.txt ├── input.txt ├── day12_part1.go └── day12_both.go ├── day22 ├── output.txt └── input.txt ├── ocaml ├── day14 │ ├── output.txt │ ├── test1.txt │ ├── test2.txt │ ├── test3.txt │ ├── test4.txt │ ├── test5.txt │ ├── main.ml │ └── input.txt ├── .gitignore ├── day12 │ ├── output.txt │ ├── test1.txt │ ├── test2.txt │ ├── input.txt │ └── main.ml ├── day18 │ ├── test2.txt │ ├── pt2.mli │ ├── test3.txt │ ├── test4.txt │ ├── test1.txt │ └── pt2.ml ├── day24 │ ├── input.txt │ ├── pt2.mli │ └── pt2.ml ├── README ├── day9 │ ├── vm.mli │ ├── day9.ml │ ├── vm.ml │ └── input.txt ├── day2 │ ├── input.txt │ └── day2.ml ├── day5 │ ├── vm.mli │ ├── day5.ml │ ├── input.txt │ └── vm.ml └── day1 │ ├── day1.ml │ └── input.txt ├── day24 ├── input.txt ├── test.txt └── test2.txt ├── day11 ├── output.gif ├── output.txt ├── input.txt ├── day11.go └── day11_gif.go ├── day8 ├── output.gif ├── output.txt ├── day8.go └── day8_gif.go ├── go.mod ├── geom ├── rect.go ├── point3.go ├── point_test.go └── point.go ├── ints ├── ints_test.go └── ints.go ├── intcode ├── cmd │ └── intdisasm │ │ └── main.go ├── instruct.go ├── intcode.go └── disasm.go ├── README.md ├── LICENSE ├── go.sum ├── day25 └── day25.go └── breakout └── breakout.go /day16/test1.txt: -------------------------------------------------------------------------------- 1 | 12345678 2 | -------------------------------------------------------------------------------- /rs/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | -------------------------------------------------------------------------------- /rs/day2/foo.txt: -------------------------------------------------------------------------------- 1 | foo,bar 2 | -------------------------------------------------------------------------------- /day10/output.txt: -------------------------------------------------------------------------------- 1 | 288 2 | 616 3 | -------------------------------------------------------------------------------- /day15/output.txt: -------------------------------------------------------------------------------- 1 | 282 2 | 286 3 | -------------------------------------------------------------------------------- /day2/test1.txt: -------------------------------------------------------------------------------- 1 | 1,0,0,0,99 2 | -------------------------------------------------------------------------------- /day20/output.txt: -------------------------------------------------------------------------------- 1 | 578 2 | 6592 3 | -------------------------------------------------------------------------------- /day3/output.txt: -------------------------------------------------------------------------------- 1 | 557 2 | 56410 3 | -------------------------------------------------------------------------------- /day4/output.txt: -------------------------------------------------------------------------------- 1 | 1660 1135 2 | -------------------------------------------------------------------------------- /day5/test.txt: -------------------------------------------------------------------------------- 1 | 1002,4,3,4,33 2 | -------------------------------------------------------------------------------- /day13/output.txt: -------------------------------------------------------------------------------- 1 | 277 2 | 12856 3 | -------------------------------------------------------------------------------- /day17/output.txt: -------------------------------------------------------------------------------- 1 | 4800 2 | 982279 3 | -------------------------------------------------------------------------------- /day18/output.txt: -------------------------------------------------------------------------------- 1 | 5450 2 | 2020 3 | -------------------------------------------------------------------------------- /day19/output.txt: -------------------------------------------------------------------------------- 1 | 112 2 | 18261982 3 | -------------------------------------------------------------------------------- /day2/output.txt: -------------------------------------------------------------------------------- 1 | 4930687 2 | 5335 3 | -------------------------------------------------------------------------------- /day2/test2.txt: -------------------------------------------------------------------------------- 1 | 1,1,1,4,99,5,6,0,99 2 | -------------------------------------------------------------------------------- /day21/test.txt: -------------------------------------------------------------------------------- 1 | NOT D J 2 | WALK 3 | -------------------------------------------------------------------------------- /day23/output.txt: -------------------------------------------------------------------------------- 1 | 22877 2 | 15210 3 | -------------------------------------------------------------------------------- /day6/output.txt: -------------------------------------------------------------------------------- 1 | 453028 2 | 562 3 | -------------------------------------------------------------------------------- /day7/output.txt: -------------------------------------------------------------------------------- 1 | 65464 2 | 1518124 3 | -------------------------------------------------------------------------------- /py/day20/output.txt: -------------------------------------------------------------------------------- 1 | 578 2 | 6592 3 | -------------------------------------------------------------------------------- /rs/day20/output.txt: -------------------------------------------------------------------------------- 1 | 578 2 | 6592 3 | -------------------------------------------------------------------------------- /rs/day3/output.txt: -------------------------------------------------------------------------------- 1 | 557 2 | 56410 3 | -------------------------------------------------------------------------------- /rs/day4/input.txt: -------------------------------------------------------------------------------- 1 | 172851-675869 2 | -------------------------------------------------------------------------------- /rs/day4/output.txt: -------------------------------------------------------------------------------- 1 | 1660 2 | 1135 3 | -------------------------------------------------------------------------------- /rs/day6/output.txt: -------------------------------------------------------------------------------- 1 | 453028 2 | 562 3 | -------------------------------------------------------------------------------- /day1/output.txt: -------------------------------------------------------------------------------- 1 | 3402609 2 | 5101025 3 | -------------------------------------------------------------------------------- /day14/output.txt: -------------------------------------------------------------------------------- 1 | 158482 2 | 7993831 3 | -------------------------------------------------------------------------------- /day16/output.txt: -------------------------------------------------------------------------------- 1 | 68317988 2 | 53850800 3 | -------------------------------------------------------------------------------- /day5/output.txt: -------------------------------------------------------------------------------- 1 | 9025675 2 | 11981754 3 | -------------------------------------------------------------------------------- /day9/output.txt: -------------------------------------------------------------------------------- 1 | 2494485073 2 | 44997 3 | -------------------------------------------------------------------------------- /day9/test3.txt: -------------------------------------------------------------------------------- 1 | 104,1125899906842624,99 2 | -------------------------------------------------------------------------------- /rs/day1/output.txt: -------------------------------------------------------------------------------- 1 | 3402609 2 | 5101025 3 | -------------------------------------------------------------------------------- /rs/day2/test1.txt: -------------------------------------------------------------------------------- 1 | 1,1,1,4,99,5,6,0,99 2 | -------------------------------------------------------------------------------- /rs/day20/rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 80 2 | -------------------------------------------------------------------------------- /c/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | inputs 3 | gmon.out 4 | -------------------------------------------------------------------------------- /day12/output.txt: -------------------------------------------------------------------------------- 1 | 8960 2 | 314917503970904 3 | -------------------------------------------------------------------------------- /day21/output.txt: -------------------------------------------------------------------------------- 1 | 19348404 2 | 1139206699 3 | -------------------------------------------------------------------------------- /day22/output.txt: -------------------------------------------------------------------------------- 1 | 2519 2 | 58966729050483 3 | -------------------------------------------------------------------------------- /day3/test3.txt: -------------------------------------------------------------------------------- 1 | R8,U5,L5,D3 2 | U7,R6,D4,L4 3 | -------------------------------------------------------------------------------- /ocaml/day14/output.txt: -------------------------------------------------------------------------------- 1 | 158482 2 | 7993831 3 | -------------------------------------------------------------------------------- /day16/test2.txt: -------------------------------------------------------------------------------- 1 | 80871224585914546619083218645595 2 | -------------------------------------------------------------------------------- /day16/test3.txt: -------------------------------------------------------------------------------- 1 | 19617804207202209144916044189917 2 | -------------------------------------------------------------------------------- /day16/test4.txt: -------------------------------------------------------------------------------- 1 | 69317163492948606335995924319873 2 | -------------------------------------------------------------------------------- /day16/test5.txt: -------------------------------------------------------------------------------- 1 | 03036732577212944063491565474664 2 | -------------------------------------------------------------------------------- /day16/test6.txt: -------------------------------------------------------------------------------- 1 | 02935109699940807407585447034323 2 | -------------------------------------------------------------------------------- /day16/test7.txt: -------------------------------------------------------------------------------- 1 | 03081770884921959731165446850517 2 | -------------------------------------------------------------------------------- /day9/test2.txt: -------------------------------------------------------------------------------- 1 | 1102,34915192,34915192,7,4,7,99,0 2 | -------------------------------------------------------------------------------- /ocaml/.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | *.byte 3 | *.native 4 | -------------------------------------------------------------------------------- /ocaml/day12/output.txt: -------------------------------------------------------------------------------- 1 | 8960 2 | 314917503970904 3 | -------------------------------------------------------------------------------- /rs/day2/test2.txt: -------------------------------------------------------------------------------- 1 | 1,9,10,3,2,3,11,0,99,30,40,50 2 | -------------------------------------------------------------------------------- /c/.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | IndentWidth: 4 3 | -------------------------------------------------------------------------------- /ocaml/day18/test2.txt: -------------------------------------------------------------------------------- 1 | ######### 2 | #b.A.@.a# 3 | ######### 4 | -------------------------------------------------------------------------------- /rs/day18/test2.txt: -------------------------------------------------------------------------------- 1 | ######### 2 | #b.A.@.a# 3 | ######### 4 | -------------------------------------------------------------------------------- /day10/test1.txt: -------------------------------------------------------------------------------- 1 | .#..# 2 | ..... 3 | ##### 4 | ....# 5 | ...## 6 | -------------------------------------------------------------------------------- /day24/input.txt: -------------------------------------------------------------------------------- 1 | ###.. 2 | #...# 3 | .#.## 4 | ##.#. 5 | #.### 6 | -------------------------------------------------------------------------------- /day24/test.txt: -------------------------------------------------------------------------------- 1 | ....# 2 | #..#. 3 | #..## 4 | ..#.. 5 | #.... 6 | -------------------------------------------------------------------------------- /day24/test2.txt: -------------------------------------------------------------------------------- 1 | ..... 2 | ..... 3 | ..... 4 | #.... 5 | .#... 6 | -------------------------------------------------------------------------------- /day7/test1.txt: -------------------------------------------------------------------------------- 1 | 3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0 2 | -------------------------------------------------------------------------------- /rs/day10/test1.txt: -------------------------------------------------------------------------------- 1 | .#..# 2 | ..... 3 | ##### 4 | ....# 5 | ...## 6 | -------------------------------------------------------------------------------- /rs/day24/input.txt: -------------------------------------------------------------------------------- 1 | ###.. 2 | #...# 3 | .#.## 4 | ##.#. 5 | #.### 6 | -------------------------------------------------------------------------------- /rs/day24/test.txt: -------------------------------------------------------------------------------- 1 | ....# 2 | #..#. 3 | #..## 4 | ..#.. 5 | #.... 6 | -------------------------------------------------------------------------------- /rs/day24/test2.txt: -------------------------------------------------------------------------------- 1 | ..... 2 | ..... 3 | ..... 4 | #.... 5 | .#... 6 | -------------------------------------------------------------------------------- /day21/part1.txt: -------------------------------------------------------------------------------- 1 | NOT A J 2 | NOT C T 3 | AND D T 4 | OR T J 5 | WALK 6 | -------------------------------------------------------------------------------- /ocaml/day24/input.txt: -------------------------------------------------------------------------------- 1 | ###.. 2 | #...# 3 | .#.## 4 | ##.#. 5 | #.### 6 | -------------------------------------------------------------------------------- /py/day20/.gitignore: -------------------------------------------------------------------------------- 1 | .venv 2 | .pytest* 3 | .mypy* 4 | __pycache__ 5 | -------------------------------------------------------------------------------- /day9/test1.txt: -------------------------------------------------------------------------------- 1 | 109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99 2 | -------------------------------------------------------------------------------- /day4/README: -------------------------------------------------------------------------------- 1 | to run this day's solution: 2 | 3 | go run day4.go 172851 675869 4 | -------------------------------------------------------------------------------- /day3/test1.txt: -------------------------------------------------------------------------------- 1 | R75,D30,R83,U83,L12,D49,R71,U7,L72 2 | U62,R66,U55,R34,D71,R55,D58,R83 3 | -------------------------------------------------------------------------------- /day5/README: -------------------------------------------------------------------------------- 1 | To run today's program: 2 | 3 | go build 4 | ./day5 input.txt 1 5 5 | -------------------------------------------------------------------------------- /day7/test2.txt: -------------------------------------------------------------------------------- 1 | 3,23,3,24,1002,24,10,24,1002,23,-1,23,101,5,23,23,1,24,23,23,4,23,99,0,0 2 | -------------------------------------------------------------------------------- /py/day20/README: -------------------------------------------------------------------------------- 1 | # aoc19day20 2 | 3 | ## usage 4 | 5 | python day20.py input.txt 6 | -------------------------------------------------------------------------------- /day11/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhconnelly/advent-of-code-2019/HEAD/day11/output.gif -------------------------------------------------------------------------------- /day8/output.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dhconnelly/advent-of-code-2019/HEAD/day8/output.gif -------------------------------------------------------------------------------- /day12/test1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /day12/test2.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /day3/test2.txt: -------------------------------------------------------------------------------- 1 | R98,U47,R26,D63,R33,U87,L62,D20,R33,U53,R51 2 | U98,R91,D20,R16,D67,R40,U7,R15,U6,R7 3 | -------------------------------------------------------------------------------- /day12/input.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ocaml/day12/test1.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ocaml/day12/test2.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /day7/test1_part2.txt: -------------------------------------------------------------------------------- 1 | 3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5 2 | -------------------------------------------------------------------------------- /ocaml/day12/input.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /day13/README: -------------------------------------------------------------------------------- 1 | To run today's solution: 2 | 3 | patch -p1 -d .. < day13.patch 4 | go run day13.go input.txt 5 | -------------------------------------------------------------------------------- /day6/test.txt: -------------------------------------------------------------------------------- 1 | COM)B 2 | B)C 3 | C)D 4 | D)E 5 | E)F 6 | B)G 7 | G)H 8 | D)I 9 | E)J 10 | J)K 11 | K)L 12 | -------------------------------------------------------------------------------- /day7/test3.txt: -------------------------------------------------------------------------------- 1 | 3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0 2 | -------------------------------------------------------------------------------- /ocaml/README: -------------------------------------------------------------------------------- 1 | to run the ocaml solutions: 2 | 3 | ocaml dayN.ml 4 | 5 | unless specified otherwise 6 | -------------------------------------------------------------------------------- /rs/day6/test.txt: -------------------------------------------------------------------------------- 1 | COM)B 2 | B)C 3 | C)D 4 | D)E 5 | E)F 6 | B)G 7 | G)H 8 | D)I 9 | E)J 10 | J)K 11 | K)L 12 | -------------------------------------------------------------------------------- /day10/test6.txt: -------------------------------------------------------------------------------- 1 | .#....#####...#.. 2 | ##...##.#####..## 3 | ##...#...#.#####. 4 | ..#.....X...###.. 5 | ..#.#.....#....## 6 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/dhconnelly/advent-of-code-2019 2 | 3 | go 1.13 4 | 5 | require github.com/gdamore/tcell v1.3.0 6 | -------------------------------------------------------------------------------- /rs/day10/test6.txt: -------------------------------------------------------------------------------- 1 | .#....#####...#.. 2 | ##...##.#####..## 3 | ##...#...#.#####. 4 | ..#.....X...###.. 5 | ..#.#.....#....## 6 | -------------------------------------------------------------------------------- /ocaml/day18/pt2.mli: -------------------------------------------------------------------------------- 1 | type t = int * int 2 | val compare : t -> t -> int 3 | val nbrs : t -> (t list) 4 | val fmt : t -> string 5 | -------------------------------------------------------------------------------- /ocaml/day24/pt2.mli: -------------------------------------------------------------------------------- 1 | type t = int * int 2 | val compare : t -> t -> int 3 | val nbrs : t -> (t list) 4 | val fmt : t -> string 5 | -------------------------------------------------------------------------------- /day14/test1.txt: -------------------------------------------------------------------------------- 1 | 10 ORE => 10 A 2 | 1 ORE => 1 B 3 | 7 A, 1 B => 1 C 4 | 7 A, 1 C => 1 D 5 | 7 A, 1 D => 1 E 6 | 7 A, 1 E => 1 FUEL 7 | -------------------------------------------------------------------------------- /day21/part2.txt: -------------------------------------------------------------------------------- 1 | NOT C T 2 | NOT B J 3 | OR T J 4 | NOT A T 5 | OR T J 6 | OR E T 7 | OR H T 8 | AND D T 9 | AND T J 10 | RUN 11 | -------------------------------------------------------------------------------- /day18/test4.txt: -------------------------------------------------------------------------------- 1 | ############# 2 | #DcBa.#.GhKl# 3 | #.###4#3#I### 4 | #e#d#####j#k# 5 | ###C#2#1###J# 6 | #fEbA.#.FgHi# 7 | ############# 8 | -------------------------------------------------------------------------------- /ocaml/day14/test1.txt: -------------------------------------------------------------------------------- 1 | 10 ORE => 10 A 2 | 1 ORE => 1 B 3 | 7 A, 1 B => 1 C 4 | 7 A, 1 C => 1 D 5 | 7 A, 1 D => 1 E 6 | 7 A, 1 E => 1 FUEL 7 | -------------------------------------------------------------------------------- /day14/test2.txt: -------------------------------------------------------------------------------- 1 | 9 ORE => 2 A 2 | 8 ORE => 3 B 3 | 7 ORE => 5 C 4 | 3 A, 4 B => 1 AB 5 | 5 B, 7 C => 1 BC 6 | 4 C, 1 A => 1 CA 7 | 2 AB, 3 BC, 4 CA => 1 FUEL 8 | -------------------------------------------------------------------------------- /day18/test1.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #...............b.C.D.f# 3 | #.###################### 4 | #.....@.a.B.c.d.A.e.F.g# 5 | ######################## 6 | -------------------------------------------------------------------------------- /py/day18/test1.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #...............b.C.D.f# 3 | #.###################### 4 | #.....@.a.B.c.d.A.e.F.g# 5 | ######################## 6 | -------------------------------------------------------------------------------- /rs/day18/test3.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #...............b.C.D.f# 3 | #.###################### 4 | #.....@.a.B.c.d.A.e.F.g# 5 | ######################## 6 | -------------------------------------------------------------------------------- /ocaml/day14/test2.txt: -------------------------------------------------------------------------------- 1 | 9 ORE => 2 A 2 | 8 ORE => 3 B 3 | 7 ORE => 5 C 4 | 3 A, 4 B => 1 AB 5 | 5 B, 7 C => 1 BC 6 | 4 C, 1 A => 1 CA 7 | 2 AB, 3 BC, 4 CA => 1 FUEL 8 | -------------------------------------------------------------------------------- /ocaml/day18/test3.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #...............b.C.D.f# 3 | #.###################### 4 | #.....@.a.B.c.d.A.e.F.g# 5 | ######################## 6 | -------------------------------------------------------------------------------- /rs/day8/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day8" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /day10/test2.txt: -------------------------------------------------------------------------------- 1 | ......#.#. 2 | #..#.#.... 3 | ..#######. 4 | .#.#.###.. 5 | .#..#..... 6 | ..#....#.# 7 | #..#....#. 8 | .##.#..### 9 | ##...#..#. 10 | .#....#### 11 | -------------------------------------------------------------------------------- /day10/test3.txt: -------------------------------------------------------------------------------- 1 | #.#...#.#. 2 | .###....#. 3 | .#....#... 4 | ##.#.#.#.# 5 | ....#.#.#. 6 | .##..###.# 7 | ..#...##.. 8 | ..##....## 9 | ......#... 10 | .####.###. 11 | -------------------------------------------------------------------------------- /day10/test4.txt: -------------------------------------------------------------------------------- 1 | .#..#..### 2 | ####.###.# 3 | ....###.#. 4 | ..###.##.# 5 | ##.##.#.#. 6 | ....###..# 7 | ..#.#..#.# 8 | #..#.#.### 9 | .##...##.# 10 | .....#.#.. 11 | -------------------------------------------------------------------------------- /rs/day1/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day1" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rs/day10/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day10" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /rs/day24/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day24" 5 | version = "0.1.0" 6 | -------------------------------------------------------------------------------- /rs/day4/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day4" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rs/day6/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day6" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rs/geom/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "geom" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rs/day10/test2.txt: -------------------------------------------------------------------------------- 1 | ......#.#. 2 | #..#.#.... 3 | ..#######. 4 | .#.#.###.. 5 | .#..#..... 6 | ..#....#.# 7 | #..#....#. 8 | .##.#..### 9 | ##...#..#. 10 | .#....#### 11 | -------------------------------------------------------------------------------- /rs/day10/test3.txt: -------------------------------------------------------------------------------- 1 | #.#...#.#. 2 | .###....#. 3 | .#....#... 4 | ##.#.#.#.# 5 | ....#.#.#. 6 | .##..###.# 7 | ..#...##.. 8 | ..##....## 9 | ......#... 10 | .####.###. 11 | -------------------------------------------------------------------------------- /rs/day10/test4.txt: -------------------------------------------------------------------------------- 1 | .#..#..### 2 | ####.###.# 3 | ....###.#. 4 | ..###.##.# 5 | ##.##.#.#. 6 | ....###..# 7 | ..#.#..#.# 8 | #..#.#.### 9 | .##...##.# 10 | .....#.#.. 11 | -------------------------------------------------------------------------------- /day18/test5.txt: -------------------------------------------------------------------------------- 1 | ############# 2 | #g#f.D#..h#l# 3 | #F###e#E###.# 4 | #dCba1#2BcIJ# 5 | ############# 6 | #nK.L4#3G...# 7 | #M###N#H###.# 8 | #o#m..#i#jk.# 9 | ############# 10 | -------------------------------------------------------------------------------- /day18/test3.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #@..............ac.GI.b# 3 | ###d#e#f################ 4 | ###A#B#C################ 5 | ###g#h#i################ 6 | ######################## 7 | -------------------------------------------------------------------------------- /day9/README: -------------------------------------------------------------------------------- 1 | To run this solution: 2 | 3 | go run day9.go [input_file] [input_values] 4 | 5 | For example, to solve both parts with my input: 6 | 7 | go run day9.go input.txt 1 2 8 | -------------------------------------------------------------------------------- /py/day18/test3.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #@..............ac.GI.b# 3 | ###d#e#f################ 4 | ###A#B#C################ 5 | ###g#h#i################ 6 | ######################## 7 | -------------------------------------------------------------------------------- /rs/day18/test4.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #@..............ac.GI.b# 3 | ###d#e#f################ 4 | ###A#B#C################ 5 | ###g#h#i################ 6 | ######################## 7 | -------------------------------------------------------------------------------- /ocaml/day18/test4.txt: -------------------------------------------------------------------------------- 1 | ######################## 2 | #@..............ac.GI.b# 3 | ###d#e#f################ 4 | ###A#B#C################ 5 | ###g#h#i################ 6 | ######################## 7 | -------------------------------------------------------------------------------- /day8/output.txt: -------------------------------------------------------------------------------- 1 | 2159 2 | 11 11 1111 1 1 111 3 | 1 1 1 1 1 1 1 1 4 | 1 1 1 1111 1 1 5 | 1 1 1 1 1 111 6 | 1 1 1 1 1 1 1 1 1 7 | 11 11 1111 1 1 1 1 8 | -------------------------------------------------------------------------------- /c/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if make -s test && make -s runall && diff snapshot.txt <(make -s runall); then 4 | echo "SUCCESS" 5 | exit 0 6 | else 7 | echo "FAILURE" 8 | exit 1 9 | fi 10 | -------------------------------------------------------------------------------- /day18/test2.txt: -------------------------------------------------------------------------------- 1 | ################# 2 | #i.G..c...e..H.p# 3 | ########.######## 4 | #j.A..b...f..D.o# 5 | ########@######## 6 | #k.E..a...g..B.n# 7 | ########.######## 8 | #l.F..d...h..C.m# 9 | ################# 10 | -------------------------------------------------------------------------------- /py/day18/test2.txt: -------------------------------------------------------------------------------- 1 | ################# 2 | #i.G..c...e..H.p# 3 | ########.######## 4 | #j.A..b...f..D.o# 5 | ########@######## 6 | #k.E..a...g..B.n# 7 | ########.######## 8 | #l.F..d...h..C.m# 9 | ################# 10 | -------------------------------------------------------------------------------- /rs/day18/test1.txt: -------------------------------------------------------------------------------- 1 | ################# 2 | #i.G..c...e..H.p# 3 | ########.######## 4 | #j.A..b...f..D.o# 5 | ########@######## 6 | #k.E..a...g..B.n# 7 | ########.######## 8 | #l.F..d...h..C.m# 9 | ################# 10 | -------------------------------------------------------------------------------- /geom/rect.go: -------------------------------------------------------------------------------- 1 | package geom 2 | 3 | type Rect struct { 4 | Lo, Hi Pt2 // inclusive 5 | } 6 | 7 | func (r Rect) Contains(p Pt2) bool { 8 | return p.X >= r.Lo.X && p.Y >= r.Lo.Y && p.X <= r.Hi.X && p.Y <= r.Hi.Y 9 | } 10 | -------------------------------------------------------------------------------- /ocaml/day18/test1.txt: -------------------------------------------------------------------------------- 1 | ################# 2 | #i.G..c...e..H.p# 3 | ########.######## 4 | #j.A..b...f..D.o# 5 | ########@######## 6 | #k.E..a...g..B.n# 7 | ########.######## 8 | #l.F..d...h..C.m# 9 | ################# 10 | -------------------------------------------------------------------------------- /c/comb.h: -------------------------------------------------------------------------------- 1 | #ifndef COMB_H_ 2 | #define COMB_H_ 3 | 4 | #include 5 | 6 | typedef void* visitor(int64_t xs[], void* data); 7 | void* visit_permutations(int64_t xs[], int len, visitor f, void* init); 8 | 9 | #endif // COMB_H_ 10 | -------------------------------------------------------------------------------- /rs/day10/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day10" 3 | version = "0.1.0" 4 | authors = ["dhc"] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /day21/README: -------------------------------------------------------------------------------- 1 | To run in interactive mode: 2 | 3 | go run day21.go input.txt 4 | 5 | To run a script: 6 | 7 | go run day21.go input.txt SCRIPT_FILE+ 8 | 9 | To run today's solutions: 10 | 11 | go run day21.go input.txt part1.txt part2.txt 12 | -------------------------------------------------------------------------------- /rs/day6/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day6" 3 | version = "0.1.0" 4 | authors = ["dconnelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /rs/day1/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day1" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /rs/day24/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day24" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /rs/day4/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day4" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /rs/day8/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day8" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /rs/geom/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "geom" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /c/parse.c: -------------------------------------------------------------------------------- 1 | #include "parse.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | int parse_intcode(FILE *f, int64_t result[], int max) { 8 | int n = 0; 9 | while (n < max && fscanf(f, "%lld,", &result[n]) != EOF) n++; 10 | return n; 11 | } 12 | -------------------------------------------------------------------------------- /rs/intcode/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "intcode" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | -------------------------------------------------------------------------------- /ocaml/day18/pt2.ml: -------------------------------------------------------------------------------- 1 | type t = int * int 2 | 3 | let compare (x1,y1) (x2,y2) = 4 | match Stdlib.compare x1 x2 with 5 | | 0 -> Stdlib.compare y1 y2 6 | | c -> c 7 | 8 | let nbrs (x,y) = [(x+1, y); (x-1, y); (x, y+1); (x, y-1)] 9 | 10 | let fmt (x,y) = Printf.sprintf "(%d, %d)" x y 11 | -------------------------------------------------------------------------------- /ocaml/day24/pt2.ml: -------------------------------------------------------------------------------- 1 | type t = int * int 2 | 3 | let compare (x1,y1) (x2,y2) = 4 | match Stdlib.compare x1 x2 with 5 | | 0 -> Stdlib.compare y1 y2 6 | | c -> c 7 | 8 | let nbrs (x,y) = [(x+1, y); (x-1, y); (x, y+1); (x, y-1)] 9 | 10 | let fmt (x,y) = Printf.sprintf "(%d, %d)" x y 11 | -------------------------------------------------------------------------------- /rs/day18/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day18" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "geom 0.1.0", 8 | ] 9 | 10 | [[package]] 11 | name = "geom" 12 | version = "0.1.0" 13 | 14 | -------------------------------------------------------------------------------- /rs/day20/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day20" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "geom 0.1.0", 8 | ] 9 | 10 | [[package]] 11 | name = "geom" 12 | version = "0.1.0" 13 | 14 | -------------------------------------------------------------------------------- /rs/day3/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day3" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "geom 0.1.0", 8 | ] 9 | 10 | [[package]] 11 | name = "geom" 12 | version = "0.1.0" 13 | 14 | -------------------------------------------------------------------------------- /rs/day2/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day2" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "intcode 0.1.0", 8 | ] 9 | 10 | [[package]] 11 | name = "intcode" 12 | version = "0.1.0" 13 | 14 | -------------------------------------------------------------------------------- /rs/day5/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day5" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "intcode 0.1.0", 8 | ] 9 | 10 | [[package]] 11 | name = "intcode" 12 | version = "0.1.0" 13 | 14 | -------------------------------------------------------------------------------- /rs/day9/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "day9" 5 | version = "0.1.0" 6 | dependencies = [ 7 | "intcode 0.1.0", 8 | ] 9 | 10 | [[package]] 11 | name = "intcode" 12 | version = "0.1.0" 13 | 14 | -------------------------------------------------------------------------------- /day11/output.txt: -------------------------------------------------------------------------------- 1 | 2252 2 | XX XX XX X XXX XX XX XXXX 3 | X X X X X X X X X X X X X 4 | X X X X X X X X X X XXX 5 | XXXX X XX XXXX X XXX X XX X X 6 | X X X X X X X X X X X X X X 7 | X X XXX X X XXXX X X XXX XX XXXX 8 | -------------------------------------------------------------------------------- /day14/test3.txt: -------------------------------------------------------------------------------- 1 | 157 ORE => 5 NZVS 2 | 165 ORE => 6 DCFZ 3 | 44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL 4 | 12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ 5 | 179 ORE => 7 PSHF 6 | 177 ORE => 5 HKGWZ 7 | 7 DCFZ, 7 PSHF => 2 XJWVT 8 | 165 ORE => 2 GPVTF 9 | 3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT 10 | -------------------------------------------------------------------------------- /rs/day3/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day3" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | geom = { path = "../geom" } 11 | -------------------------------------------------------------------------------- /rs/day18/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day18" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | geom = { path = "../geom" } 11 | -------------------------------------------------------------------------------- /rs/day20/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day20" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | geom = { path = "../geom" } 11 | -------------------------------------------------------------------------------- /ocaml/day14/test3.txt: -------------------------------------------------------------------------------- 1 | 157 ORE => 5 NZVS 2 | 165 ORE => 6 DCFZ 3 | 44 XJWVT, 5 KHKGT, 1 QDVJ, 29 NZVS, 9 GPVTF, 48 HKGWZ => 1 FUEL 4 | 12 HKGWZ, 1 GPVTF, 8 PSHF => 9 QDVJ 5 | 179 ORE => 7 PSHF 6 | 177 ORE => 5 HKGWZ 7 | 7 DCFZ, 7 PSHF => 2 XJWVT 8 | 165 ORE => 2 GPVTF 9 | 3 DCFZ, 7 NZVS, 5 HKGWZ, 10 PSHF => 8 KHKGT 10 | -------------------------------------------------------------------------------- /rs/day2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day2" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | intcode = { path = "../intcode" } 11 | -------------------------------------------------------------------------------- /rs/day5/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day5" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | intcode = { path = "../intcode" } 11 | -------------------------------------------------------------------------------- /rs/day9/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day9" 3 | version = "0.1.0" 4 | authors = ["Daniel Connelly "] 5 | edition = "2018" 6 | 7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 8 | 9 | [dependencies] 10 | intcode = { path = "../intcode" } 11 | -------------------------------------------------------------------------------- /ints/ints_test.go: -------------------------------------------------------------------------------- 1 | package ints 2 | 3 | import "testing" 4 | 5 | func TestAbs(t *testing.T) { 6 | for _, tc := range []struct { 7 | x, abs int 8 | }{ 9 | {0, 0}, 10 | {-7, 7}, 11 | {19, 19}, 12 | } { 13 | if abs := Abs(tc.x); abs != tc.abs { 14 | t.Errorf("Abs(%d) = %d, want %d", tc.x, abs, tc.abs) 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /c/parse.h: -------------------------------------------------------------------------------- 1 | #ifndef PARSE_H_ 2 | #define PARSE_H_ 3 | 4 | #include 5 | #include 6 | 7 | // reads a comma-separated list of at most |max| integers from |f| into the 8 | // array |result|. returns the number of integers read if successful, or -1 9 | // and sets |errno| otherwise. 10 | int parse_intcode(FILE* f, int64_t result[], int max); 11 | 12 | #endif // PARSE_H_ 13 | -------------------------------------------------------------------------------- /c/queue.h: -------------------------------------------------------------------------------- 1 | #ifndef QUEUE_H_ 2 | #define QUEUE_H_ 3 | 4 | typedef struct node { 5 | void* data; 6 | struct node* next; 7 | } node; 8 | 9 | typedef struct { 10 | node *head, *tail; 11 | } queue; 12 | 13 | queue make_q(void); 14 | void init_q(queue* q); 15 | int empty_q(queue* q); 16 | void append_q(queue* q, void* data); 17 | void* pop_q(queue* q); 18 | 19 | #endif // QUEUE_H_ 20 | -------------------------------------------------------------------------------- /day13/day13.patch: -------------------------------------------------------------------------------- 1 | diff --git a/intcode/machine.go b/intcode/machine.go 2 | index 2292ac9..693b1c6 100644 3 | --- a/intcode/machine.go 4 | +++ b/intcode/machine.go 5 | @@ -46,6 +46,9 @@ func (m *machine) get(addr int64, md Mode) int64 { 6 | var val int64 7 | switch md { 8 | case pos: 9 | + if v == 392 { 10 | + v = 388 11 | + } 12 | val = m.data[v] 13 | case imm: 14 | val = v 15 | -------------------------------------------------------------------------------- /c/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern void day2_test(void); 4 | extern void day5_test(void); 5 | extern void day7_test(void); 6 | extern void hash_test(void); 7 | extern void day9_test(void); 8 | 9 | int main() { 10 | printf("running all tests...\n"); 11 | day2_test(); 12 | day5_test(); 13 | day7_test(); 14 | hash_test(); 15 | day9_test(); 16 | printf("done.\n"); 17 | } 18 | -------------------------------------------------------------------------------- /ocaml/day9/vm.mli: -------------------------------------------------------------------------------- 1 | type data 2 | val read : Scanf.Scanning.in_channel -> data 3 | val set : int -> int -> data -> data 4 | val get : int -> data -> int 5 | 6 | type state = Running | Halted | Input | Output 7 | 8 | type vm 9 | val vm_new : data -> vm 10 | val vm_data : vm -> data 11 | val vm_state : vm -> state 12 | val vm_write : int -> vm -> vm 13 | val vm_read : vm -> int 14 | val run : vm -> vm 15 | -------------------------------------------------------------------------------- /day2/input.txt: -------------------------------------------------------------------------------- 1 | 1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,13,1,19,1,10,19,23,1,23,9,27,1,5,27,31,2,31,13,35,1,35,5,39,1,39,5,43,2,13,43,47,2,47,10,51,1,51,6,55,2,55,9,59,1,59,5,63,1,63,13,67,2,67,6,71,1,71,5,75,1,75,5,79,1,79,9,83,1,10,83,87,1,87,10,91,1,91,9,95,1,10,95,99,1,10,99,103,2,103,10,107,1,107,9,111,2,6,111,115,1,5,115,119,2,119,13,123,1,6,123,127,2,9,127,131,1,131,5,135,1,135,13,139,1,139,10,143,1,2,143,147,1,147,10,0,99,2,0,14,0 2 | -------------------------------------------------------------------------------- /rs/day2/input.txt: -------------------------------------------------------------------------------- 1 | 1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,13,1,19,1,10,19,23,1,23,9,27,1,5,27,31,2,31,13,35,1,35,5,39,1,39,5,43,2,13,43,47,2,47,10,51,1,51,6,55,2,55,9,59,1,59,5,63,1,63,13,67,2,67,6,71,1,71,5,75,1,75,5,79,1,79,9,83,1,10,83,87,1,87,10,91,1,91,9,95,1,10,95,99,1,10,99,103,2,103,10,107,1,107,9,111,2,6,111,115,1,5,115,119,2,119,13,123,1,6,123,127,2,9,127,131,1,131,5,135,1,135,13,139,1,139,10,143,1,2,143,147,1,147,10,0,99,2,0,14,0 2 | -------------------------------------------------------------------------------- /ocaml/day2/input.txt: -------------------------------------------------------------------------------- 1 | 1,0,0,3,1,1,2,3,1,3,4,3,1,5,0,3,2,13,1,19,1,10,19,23,1,23,9,27,1,5,27,31,2,31,13,35,1,35,5,39,1,39,5,43,2,13,43,47,2,47,10,51,1,51,6,55,2,55,9,59,1,59,5,63,1,63,13,67,2,67,6,71,1,71,5,75,1,75,5,79,1,79,9,83,1,10,83,87,1,87,10,91,1,91,9,95,1,10,95,99,1,10,99,103,2,103,10,107,1,107,9,111,2,6,111,115,1,5,115,119,2,119,13,123,1,6,123,127,2,9,127,131,1,131,5,135,1,135,13,139,1,139,10,143,1,2,143,147,1,147,10,0,99,2,0,14,0 2 | -------------------------------------------------------------------------------- /ocaml/day5/vm.mli: -------------------------------------------------------------------------------- 1 | type data 2 | val read : Scanf.Scanning.in_channel -> data 3 | val copy : data -> data 4 | val set : int -> int -> data -> unit 5 | val get : int -> data -> int 6 | 7 | type state = Running | Halted | Input | Output 8 | 9 | type vm 10 | val vm_new : data -> vm 11 | val vm_data : vm -> data 12 | val vm_state : vm -> state 13 | val vm_write : int -> vm -> vm 14 | val vm_read : vm -> int 15 | val run : vm -> vm 16 | -------------------------------------------------------------------------------- /day14/test4.txt: -------------------------------------------------------------------------------- 1 | 2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG 2 | 17 NVRVD, 3 JNWZP => 8 VPVL 3 | 53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL 4 | 22 VJHF, 37 MNCFX => 5 FWMGM 5 | 139 ORE => 4 NVRVD 6 | 144 ORE => 7 JNWZP 7 | 5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC 8 | 5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV 9 | 145 ORE => 6 MNCFX 10 | 1 NVRVD => 8 CXFTF 11 | 1 VJHF, 6 MNCFX => 4 RFSQX 12 | 176 ORE => 6 VJHF 13 | -------------------------------------------------------------------------------- /intcode/cmd/intdisasm/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/dhconnelly/advent-of-code-2019/intcode" 9 | ) 10 | 11 | func main() { 12 | for _, arg := range os.Args[1:] { 13 | fmt.Println(arg) 14 | data, err := intcode.ReadProgram(arg) 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | for _, line := range intcode.Disassemble(data) { 19 | fmt.Println(line) 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ocaml/day14/test4.txt: -------------------------------------------------------------------------------- 1 | 2 VPVL, 7 FWMGM, 2 CXFTF, 11 MNCFX => 1 STKFG 2 | 17 NVRVD, 3 JNWZP => 8 VPVL 3 | 53 STKFG, 6 MNCFX, 46 VJHF, 81 HVMC, 68 CXFTF, 25 GNMV => 1 FUEL 4 | 22 VJHF, 37 MNCFX => 5 FWMGM 5 | 139 ORE => 4 NVRVD 6 | 144 ORE => 7 JNWZP 7 | 5 MNCFX, 7 RFSQX, 2 FWMGM, 2 VPVL, 19 CXFTF => 3 HVMC 8 | 5 VJHF, 7 MNCFX, 9 VPVL, 37 CXFTF => 6 GNMV 9 | 145 ORE => 6 MNCFX 10 | 1 NVRVD => 8 CXFTF 11 | 1 VJHF, 6 MNCFX => 4 RFSQX 12 | 176 ORE => 6 VJHF 13 | -------------------------------------------------------------------------------- /c/snapshot.txt: -------------------------------------------------------------------------------- 1 | 4930687 2 | 5335 3 | 9025675 4 | 11981754 5 | 65464 6 | 1518124 7 | 2494485073 8 | 44997 9 | 2252 10 | ## ## ## # ### ## ## #### 11 | # # # # # # # # # # # # # 12 | # # # # # # # # # # ### 13 | #### # ## #### # ### # ## # # 14 | # # # # # # # # # # # # # # 15 | # # ### # # #### # # ### ## #### 16 | 277 17 | 12856 18 | 282 19 | 286 20 | 22877 21 | 15210 22 | 5450 23 | 2020 24 | -------------------------------------------------------------------------------- /ocaml/day9/day9.ml: -------------------------------------------------------------------------------- 1 | include Vm 2 | 3 | let main prog arg = 4 | let vm = vm_new prog in 5 | let rec loop vm = 6 | let vm' = run vm in match vm_state vm' with 7 | | Running -> loop vm' 8 | | Halted -> () 9 | | Input -> vm_write arg vm' |> loop 10 | | Output -> vm_read vm' |> Printf.printf "%d\n"; loop vm' 11 | in loop vm 12 | 13 | let () = 14 | let path = Sys.argv.(1) in 15 | let prog = Scanf.Scanning.open_in path |> read in 16 | main prog 1; 17 | main prog 2 18 | -------------------------------------------------------------------------------- /c/amp.h: -------------------------------------------------------------------------------- 1 | #ifndef AMP_H_ 2 | #define AMP_H_ 3 | 4 | #include "vm.h" 5 | 6 | #define CIRCUIT_SIZE 5 7 | 8 | typedef int64_t phase_sequence[CIRCUIT_SIZE]; 9 | 10 | typedef struct { 11 | vm vms[CIRCUIT_SIZE]; 12 | } circuit; 13 | 14 | void init_circuit(circuit* circuit, vm vm); 15 | circuit make_circuit(vm vm); 16 | int64_t run_series(circuit* circuit, phase_sequence setting, int64_t input); 17 | int64_t run_loop(circuit* circuit, phase_sequence setting, int64_t input); 18 | 19 | #endif // AMP_H_ 20 | -------------------------------------------------------------------------------- /day20/test1.txt: -------------------------------------------------------------------------------- 1 | A 2 | A 3 | #######.######### 4 | #######.........# 5 | #######.#######.# 6 | #######.#######.# 7 | #######.#######.# 8 | ##### B ###.# 9 | BC...## C ###.# 10 | ##.## ###.# 11 | ##...DE F ###.# 12 | ##### G ###.# 13 | #########.#####.# 14 | DE..#######...###.# 15 | #.#########.###.# 16 | FG..#########.....# 17 | ###########.##### 18 | Z 19 | Z 20 | -------------------------------------------------------------------------------- /py/day20/test1.txt: -------------------------------------------------------------------------------- 1 | A 2 | A 3 | #######.######### 4 | #######.........# 5 | #######.#######.# 6 | #######.#######.# 7 | #######.#######.# 8 | ##### B ###.# 9 | BC...## C ###.# 10 | ##.## ###.# 11 | ##...DE F ###.# 12 | ##### G ###.# 13 | #########.#####.# 14 | DE..#######...###.# 15 | #.#########.###.# 16 | FG..#########.....# 17 | ###########.##### 18 | Z 19 | Z 20 | -------------------------------------------------------------------------------- /rs/day20/test1.txt: -------------------------------------------------------------------------------- 1 | A 2 | A 3 | #######.######### 4 | #######.........# 5 | #######.#######.# 6 | #######.#######.# 7 | #######.#######.# 8 | ##### B ###.# 9 | BC...## C ###.# 10 | ##.## ###.# 11 | ##...DE F ###.# 12 | ##### G ###.# 13 | #########.#####.# 14 | DE..#######...###.# 15 | #.#########.###.# 16 | FG..#########.....# 17 | ###########.##### 18 | Z 19 | Z 20 | -------------------------------------------------------------------------------- /day10/test5.txt: -------------------------------------------------------------------------------- 1 | .#..##.###...####### 2 | ##.############..##. 3 | .#.######.########.# 4 | .###.#######.####.#. 5 | #####.##.#.##.###.## 6 | ..#####..#.######### 7 | #################### 8 | #.####....###.#.#.## 9 | ##.################# 10 | #####.##.###..####.. 11 | ..######..##.####### 12 | ####.##.####...##..# 13 | .#####..#.######.### 14 | ##...#.##########... 15 | #.##########.####### 16 | .####.#.###.###.#.## 17 | ....##.##.###..##### 18 | .#.#.###########.### 19 | #.#.#.#####.####.### 20 | ###.##.####.##.#..## 21 | -------------------------------------------------------------------------------- /c/pt2.h: -------------------------------------------------------------------------------- 1 | #ifndef PT2_H_ 2 | #define PT2_H_ 3 | 4 | #include 5 | 6 | #include "hash.h" 7 | 8 | typedef union { 9 | struct { 10 | int16_t x; 11 | int16_t y; 12 | } coords; 13 | uint32_t data; 14 | } pt2; 15 | 16 | pt2 make_pt(int16_t x, int16_t y); 17 | pt2 pt_from_data(uint32_t data); 18 | int pt_eq(pt2 a, pt2 b); 19 | void get_nbrs(pt2 pt, pt2 nbrs[4]); 20 | 21 | typedef struct { 22 | pt2 lo, hi; 23 | } rect; 24 | 25 | rect bounds(hashtable* map); 26 | 27 | #endif // PT2_H_ 28 | -------------------------------------------------------------------------------- /rs/day10/test5.txt: -------------------------------------------------------------------------------- 1 | .#..##.###...####### 2 | ##.############..##. 3 | .#.######.########.# 4 | .###.#######.####.#. 5 | #####.##.#.##.###.## 6 | ..#####..#.######### 7 | #################### 8 | #.####....###.#.#.## 9 | ##.################# 10 | #####.##.###..####.. 11 | ..######..##.####### 12 | ####.##.####...##..# 13 | .#####..#.######.### 14 | ##...#.##########... 15 | #.##########.####### 16 | .####.#.###.###.#.## 17 | ....##.##.###..##### 18 | .#.#.###########.### 19 | #.#.#.#####.####.### 20 | ###.##.####.##.#..## 21 | -------------------------------------------------------------------------------- /c/README: -------------------------------------------------------------------------------- 1 | prerequisites: 2 | 3 | - a c compiler 4 | - gnu make 5 | 6 | to run tests: 7 | 8 | make test 9 | 10 | to run a solution (make sure the input is saved as inputs/dayN.txt): 11 | 12 | make dayN && ./target/dayN inputs/dayN.txt 13 | 14 | to build and run remotely on the host $REMOTE_DEPLOY_HOST in the 15 | directory $REMOTE_DEPLOY_PATH: 16 | 17 | ./run_remote.sh dayN 18 | 19 | your local and remote ssh configs should allow login without a password 20 | with `ssh $REMOTE_DEPLOY_HOST`, i.e. using certificates 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Advent of Code 2019 2 | =================== 3 | 4 | Go solutions to [Advent of Code](https://adventofcode.com) problems for 5 | 2019. Written by [Daniel Connelly](https://dhconnelly.com). There's also a 6 | corresponding 7 | [blog post](https://dhconnelly.com/advent-of-code-2019-commentary.html). 8 | 9 | Unless specified otherwise in a per-day README, the solutions for a given 10 | day can be run by doing: 11 | 12 | cd dayN 13 | go run dayN.go input.txt 14 | 15 | Licensed under the MIT License, if for some reason that's interesting to you. 16 | -------------------------------------------------------------------------------- /day9/day9.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/dhconnelly/advent-of-code-2019/intcode" 6 | "log" 7 | "os" 8 | "strconv" 9 | ) 10 | 11 | func run(data []int64, input int64) { 12 | ch := make(chan int64, 1) 13 | ch <- input 14 | for o := range intcode.RunProgram(data, ch) { 15 | fmt.Println(o) 16 | } 17 | } 18 | 19 | func main() { 20 | data, err := intcode.ReadProgram(os.Args[1]) 21 | if err != nil { 22 | log.Fatal(err) 23 | } 24 | for _, s := range os.Args[2:] { 25 | x, err := strconv.Atoi(s) 26 | if err != nil { 27 | log.Fatal(err) 28 | } 29 | run(data, int64(x)) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /py/day1/main.py: -------------------------------------------------------------------------------- 1 | def fuel(mass): 2 | return (mass // 3) - 2 3 | 4 | 5 | def rec_fuel(mass): 6 | mass = fuel(mass) 7 | total = 0 8 | while mass > 0: 9 | total += mass 10 | mass = fuel(mass) 11 | return total 12 | 13 | 14 | def main(args): 15 | total_fuel = 0 16 | total_rec_fuel = 0 17 | with open(args[1]) as f: 18 | for line in f: 19 | total_fuel += fuel(int(line)) 20 | total_rec_fuel += rec_fuel(int(line)) 21 | print(total_fuel) 22 | print(total_rec_fuel) 23 | 24 | 25 | if __name__ == '__main__': 26 | import sys 27 | main(sys.argv) 28 | -------------------------------------------------------------------------------- /day16/input.txt: -------------------------------------------------------------------------------- 1 | 59727310424796235189476878806940387435291429226818921130171187957262146115559932358924341808253400617220924411865224341744614706346865536561788244183609411225788501102400269978290670307147139438239865673058478091682748114942700860895620690690625512670966265975462089087644554004423208369517716075591723905075838513598360188150158989179151879406086757964381549720210763972463291801513250953430219653258827586382953297392567981587028568433943223260723561880121205475323894070000380258122357270847092900809245133752093782889315244091880516672127950518799757198383131025701009960944008679555864631340867924665650332161673274408001712152664733237178121872 2 | -------------------------------------------------------------------------------- /day14/test5.txt: -------------------------------------------------------------------------------- 1 | 171 ORE => 8 CNZTR 2 | 7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL 3 | 114 ORE => 4 BHXH 4 | 14 VRPVC => 6 BMBT 5 | 6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL 6 | 6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT 7 | 15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW 8 | 13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW 9 | 5 BMBT => 4 WPTQ 10 | 189 ORE => 9 KTJDG 11 | 1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP 12 | 12 VRPVC, 27 CNZTR => 2 XDBXC 13 | 15 KTJDG, 12 BHXH => 5 XCVML 14 | 3 BHXH, 2 VRPVC => 7 MZWV 15 | 121 ORE => 7 VRPVC 16 | 7 XCVML => 6 RJRHP 17 | 5 BHXH, 4 VRPVC => 5 LTCX 18 | -------------------------------------------------------------------------------- /ocaml/day14/test5.txt: -------------------------------------------------------------------------------- 1 | 171 ORE => 8 CNZTR 2 | 7 ZLQW, 3 BMBT, 9 XCVML, 26 XMNCP, 1 WPTQ, 2 MZWV, 1 RJRHP => 4 PLWSL 3 | 114 ORE => 4 BHXH 4 | 14 VRPVC => 6 BMBT 5 | 6 BHXH, 18 KTJDG, 12 WPTQ, 7 PLWSL, 31 FHTLT, 37 ZDVW => 1 FUEL 6 | 6 WPTQ, 2 BMBT, 8 ZLQW, 18 KTJDG, 1 XMNCP, 6 MZWV, 1 RJRHP => 6 FHTLT 7 | 15 XDBXC, 2 LTCX, 1 VRPVC => 6 ZLQW 8 | 13 WPTQ, 10 LTCX, 3 RJRHP, 14 XMNCP, 2 MZWV, 1 ZLQW => 1 ZDVW 9 | 5 BMBT => 4 WPTQ 10 | 189 ORE => 9 KTJDG 11 | 1 MZWV, 17 XDBXC, 3 XCVML => 2 XMNCP 12 | 12 VRPVC, 27 CNZTR => 2 XDBXC 13 | 15 KTJDG, 12 BHXH => 5 XCVML 14 | 3 BHXH, 2 VRPVC => 7 MZWV 15 | 121 ORE => 7 VRPVC 16 | 7 XCVML => 6 RJRHP 17 | 5 BHXH, 4 VRPVC => 5 LTCX 18 | -------------------------------------------------------------------------------- /c/comb.c: -------------------------------------------------------------------------------- 1 | #include "comb.h" 2 | 3 | #include 4 | 5 | static void* permute(int64_t xs[], int from, int len, visitor f, void* init) { 6 | if (from == len - 1) return f(xs, init); 7 | int64_t tmp; 8 | void* result = init; 9 | for (int to = from; to < len; to++) { 10 | tmp = xs[from]; 11 | xs[from] = xs[to]; 12 | xs[to] = tmp; 13 | result = permute(xs, from + 1, len, f, result); 14 | xs[to] = xs[from]; 15 | xs[from] = tmp; 16 | } 17 | return result; 18 | } 19 | 20 | void* visit_permutations(int64_t xs[], int len, visitor f, void* init) { 21 | return permute(xs, 0, len, f, init); 22 | } 23 | -------------------------------------------------------------------------------- /geom/point3.go: -------------------------------------------------------------------------------- 1 | package geom 2 | 3 | import ( 4 | "github.com/dhconnelly/advent-of-code-2019/ints" 5 | ) 6 | 7 | type Pt3 struct { 8 | X, Y, Z int 9 | } 10 | 11 | var Zero3 Pt3 12 | 13 | func (p1 *Pt3) TranslateBy(p2 Pt3) { 14 | p1.X += p2.X 15 | p1.Y += p2.Y 16 | p1.Z += p2.Z 17 | } 18 | 19 | func (p1 Pt3) Add(p2 Pt3) Pt3 { 20 | p3 := p1 21 | p3.TranslateBy(p2) 22 | return p3 23 | } 24 | 25 | func (p Pt3) IsZero() bool { 26 | return p.Eq(Zero3) 27 | } 28 | 29 | func (p Pt3) ManhattanNorm() int { 30 | return ints.Abs(p.X) + ints.Abs(p.Y) + ints.Abs(p.Z) 31 | } 32 | 33 | func (p1 Pt3) Eq(p2 Pt3) bool { 34 | return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z 35 | } 36 | -------------------------------------------------------------------------------- /ocaml/day5/day5.ml: -------------------------------------------------------------------------------- 1 | open Array 2 | open Printf 3 | include Vm 4 | 5 | let getarg n = 6 | try Sys.argv.(n) with Invalid_argument _ -> failwith "Usage: day2.ml " 7 | 8 | let rec run_vm arg out vm = 9 | match vm_state vm with 10 | | Running -> run vm |> run_vm out arg 11 | | Input -> run_vm arg out (vm_write arg vm |> run) 12 | | Output -> run_vm arg (vm_read vm) (run vm) 13 | | Halted -> out 14 | 15 | let run_program program arg = 16 | vm_new program |> run_vm 0 arg 17 | 18 | let run path = 19 | let data = Scanf.Scanning.open_in path |> read in 20 | run_program data 1 |> printf "%d\n"; 21 | run_program data 5 |> printf "%d\n" 22 | 23 | let () = getarg 1 |> run |> ignore 24 | -------------------------------------------------------------------------------- /intcode/instruct.go: -------------------------------------------------------------------------------- 1 | package intcode 2 | 3 | type Mode int 4 | 5 | const ( 6 | pos Mode = iota 7 | imm 8 | rel 9 | ) 10 | 11 | func (md Mode) String() string { 12 | switch md { 13 | case pos: 14 | return "pos" 15 | case imm: 16 | return "imm" 17 | case rel: 18 | return "rel" 19 | } 20 | return "" 21 | } 22 | 23 | type Opcode int 24 | 25 | type instruction struct { 26 | op Opcode 27 | arity int64 28 | modes []Mode 29 | } 30 | 31 | func parseInstruction(i int64) instruction { 32 | var in instruction 33 | in.op = Opcode(i % 100) 34 | in.arity = opcodeToArity[in.op] 35 | for i /= 100; int64(len(in.modes)) < in.arity; i /= 10 { 36 | in.modes = append(in.modes, Mode(i%10)) 37 | } 38 | return in 39 | } 40 | -------------------------------------------------------------------------------- /day13/play.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/dhconnelly/advent-of-code-2019/breakout" 9 | "github.com/dhconnelly/advent-of-code-2019/intcode" 10 | "github.com/gdamore/tcell" 11 | ) 12 | 13 | func main() { 14 | screen, err := tcell.NewScreen() 15 | if err != nil { 16 | log.Fatal(err) 17 | } 18 | if err = screen.Init(); err != nil { 19 | log.Fatal(err) 20 | } 21 | data, err := intcode.ReadProgram(os.Args[1]) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | data[0] = 2 // play for free 26 | state, err := breakout.Play(data, screen, 330000000, breakout.NEUTRAL) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | screen.Fini() 31 | fmt.Println(state.Score) 32 | } 33 | -------------------------------------------------------------------------------- /c/hash.h: -------------------------------------------------------------------------------- 1 | #ifndef HASH_H_ 2 | #define HASH_H_ 3 | 4 | #include 5 | 6 | #define HASHSIZE 101 7 | 8 | typedef struct hashnode { 9 | uint64_t key; 10 | int64_t val; 11 | struct hashnode* next; 12 | } hashnode; 13 | 14 | typedef struct { 15 | hashnode* table[HASHSIZE]; 16 | int size; 17 | } hashtable; 18 | 19 | void init_table(hashtable* table); 20 | void fill_table(hashtable* table, int64_t arr[], int len); 21 | int64_t* table_get(const hashtable* table, uint64_t key); 22 | void table_set(hashtable* table, uint64_t key, int64_t val); 23 | void table_copy(hashtable* into, const hashtable* from); 24 | int table_size(hashtable* table); 25 | uint64_t* table_keys(hashtable* table); 26 | hashtable make_table(void); 27 | hashtable* new_table(void); 28 | 29 | #endif // HASH_H_ 30 | -------------------------------------------------------------------------------- /c/hash_test.c: -------------------------------------------------------------------------------- 1 | #include "hash.h" 2 | 3 | #include 4 | #include 5 | 6 | void hash_test(void) { 7 | printf("test_hash\n"); 8 | 9 | hashtable table; 10 | init_table(&table); 11 | 12 | assert(table_get(&table, 0) == NULL); 13 | assert(table_get(&table, -17) == NULL); 14 | assert(table_size(&table) == 0); 15 | 16 | table_set(&table, -17, 12345); 17 | table_set(&table, 0, 67890); 18 | 19 | assert(*table_get(&table, -17) == 12345); 20 | assert(*table_get(&table, 0) == 67890); 21 | assert(table_get(&table, 1) == NULL); 22 | assert(table_size(&table) == 2); 23 | 24 | table_set(&table, 0, 19); 25 | assert(table_get(&table, 17) == NULL); 26 | assert(*table_get(&table, 0) == 19); 27 | assert(table_size(&table) == 2); 28 | } 29 | -------------------------------------------------------------------------------- /rs/day1/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::error::Error; 3 | use std::fs; 4 | 5 | fn fuel(mass: i32) -> i32 { 6 | (mass / 3) - 2 7 | } 8 | 9 | fn rec_fuel(mass: i32) -> i32 { 10 | let f = fuel(mass); 11 | if f <= 0 { 12 | 0 13 | } else { 14 | f + rec_fuel(f) 15 | } 16 | } 17 | 18 | fn main() -> Result<(), Box> { 19 | let path = env::args().nth(1).ok_or("missing input path")?; 20 | let input: Vec = fs::read_to_string(path)? 21 | .lines() 22 | .map(|l| l.parse::().unwrap()) 23 | .collect(); 24 | let part1: i32 = input.iter().copied().map(fuel).sum(); 25 | println!("{}", part1); 26 | let part2: i32 = input.iter().copied().map(rec_fuel).sum(); 27 | println!("{}", part2); 28 | Ok(()) 29 | } 30 | -------------------------------------------------------------------------------- /ocaml/day1/day1.ml: -------------------------------------------------------------------------------- 1 | open List 2 | open Printf 3 | open Sys 4 | 5 | let read_line ic = 6 | try Some (input_line ic) with End_of_file -> None 7 | 8 | let rec map_lines f ic = 9 | match read_line ic with 10 | | Some line -> (f line)::(map_lines f ic) 11 | | None -> [] 12 | 13 | let getarg n = 14 | try argv.(n) with Invalid_argument _ -> failwith "Usage: day1.ml " 15 | 16 | let fuel mass = mass / 3 - 2 17 | 18 | let rec fuelrec mass = 19 | let x = (fuel mass) in 20 | if x < 0 then 0 else x + fuelrec x 21 | 22 | let process f path = 23 | let ic = open_in path in 24 | let nums = map_lines (fun line -> line |> int_of_string |> f) ic in 25 | fold_right (+) nums 0 26 | 27 | let _ = 28 | let path = getarg 1 in 29 | printf "%d\n" (process fuel path); 30 | printf "%d\n" (process fuelrec path) 31 | -------------------------------------------------------------------------------- /day1/day1_short.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "log" 7 | "os" 8 | ) 9 | 10 | func fuelForMass(mass int) int { 11 | return (mass / 3) - 2 12 | } 13 | 14 | func fuelSum(mass int) int { 15 | sum := 0 16 | for { 17 | fuel := fuelForMass(mass) 18 | if fuel < 0 { 19 | break 20 | } 21 | sum += fuel 22 | mass = fuel 23 | } 24 | return sum 25 | } 26 | 27 | func main() { 28 | f, err := os.Open(os.Args[1]) 29 | if err != nil { 30 | log.Fatal(err) 31 | } 32 | defer f.Close() 33 | sum, recSum := 0, 0 34 | var mass int 35 | for { 36 | if _, err := fmt.Fscanf(f, "%d\n", &mass); err == io.EOF { 37 | break 38 | } else if err != nil { 39 | log.Fatal(err) 40 | } 41 | sum += fuelForMass(mass) 42 | recSum += fuelSum(mass) 43 | } 44 | fmt.Println(sum) 45 | fmt.Println(recSum) 46 | } 47 | -------------------------------------------------------------------------------- /ints/ints.go: -------------------------------------------------------------------------------- 1 | package ints 2 | 3 | func Max(x, y int) int { 4 | if x >= y { 5 | return x 6 | } 7 | return y 8 | } 9 | 10 | func Max64(x, y int64) int64 { 11 | if x >= y { 12 | return x 13 | } 14 | return y 15 | } 16 | 17 | func Min(x, y int) int { 18 | if x <= y { 19 | return x 20 | } 21 | return y 22 | } 23 | 24 | func Abs(x int) int { 25 | if x < 0 { 26 | return -x 27 | } 28 | return x 29 | } 30 | 31 | func Abs64(x int64) int64 { 32 | if x < 0 { 33 | return -x 34 | } 35 | return x 36 | } 37 | 38 | func Gcd(m, n int) int { 39 | if n == 0 { 40 | return m 41 | } 42 | return Gcd(n, m%n) 43 | } 44 | 45 | func Gcd64(m, n int64) int64 { 46 | if n == 0 { 47 | return m 48 | } 49 | return Gcd64(n, m%n) 50 | } 51 | 52 | func Copied64(x []int64) []int64 { 53 | y := make([]int64, len(x)) 54 | copy(y, x) 55 | return y 56 | } 57 | -------------------------------------------------------------------------------- /c/run_remote.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | if [ -z "$REMOTE_DEPLOY_HOST" ]; then 4 | echo "missing variable: REMOTE_DEPLOY_HOST" 5 | exit 1 6 | fi 7 | 8 | if [ -z "$REMOTE_DEPLOY_PATH" ]; then 9 | echo "missing variable: REMOTE_DEPLOYPATH" 10 | exit 1 11 | fi 12 | 13 | HOST=$REMOTE_DEPLOY_HOST 14 | ROOT=deploy/advent-of-code-2019 15 | 16 | echo "deploying to $HOST:$ROOT..." && 17 | make clean && 18 | ssh $HOST "mkdir -p $ROOT" && 19 | scp -r * $HOST:$ROOT/ 20 | 21 | CMD=$1 22 | 23 | if [ -z "$CMD" ]; then 24 | echo "building on $HOST..." && 25 | ssh $HOST "cd $ROOT && make clean && make all" && 26 | echo "executing on $HOST..." && 27 | ssh $HOST "cd $ROOT && time ./test.sh" && 28 | echo "done." 29 | else 30 | echo "executing on $HOST: $CMD" && 31 | ssh $HOST "cd $ROOT && time $CMD" && 32 | echo "done." 33 | fi 34 | -------------------------------------------------------------------------------- /day13/day13.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/dhconnelly/advent-of-code-2019/breakout" 9 | "github.com/dhconnelly/advent-of-code-2019/intcode" 10 | ) 11 | 12 | func countTiles( 13 | state breakout.GameState, 14 | which breakout.TileId, 15 | ) int { 16 | n := 0 17 | for _, tile := range state.Tiles { 18 | if tile == which { 19 | n++ 20 | } 21 | } 22 | return n 23 | } 24 | 25 | func main() { 26 | data, err := intcode.ReadProgram(os.Args[1]) 27 | if err != nil { 28 | log.Fatal(err) 29 | } 30 | 31 | state, err := breakout.Play(data, nil, 1, breakout.NEUTRAL) 32 | if err != nil { 33 | log.Fatal(err) 34 | } 35 | fmt.Println(countTiles(state, breakout.BLOCK)) 36 | 37 | data[0] = 2 // play for free 38 | state, err = breakout.Play(data, nil, 1, breakout.LEFT) 39 | if err != nil { 40 | log.Fatal(err) 41 | } 42 | fmt.Println(state.Score) 43 | } 44 | -------------------------------------------------------------------------------- /c/queue.c: -------------------------------------------------------------------------------- 1 | #include "queue.h" 2 | 3 | #include 4 | #include 5 | 6 | void init_q(queue* q) { q->head = q->tail = NULL; } 7 | 8 | queue make_q(void) { 9 | queue q; 10 | init_q(&q); 11 | return q; 12 | } 13 | 14 | int empty_q(queue* q) { return q->head == NULL; } 15 | 16 | static node* new_node(void* data) { 17 | node* nd = malloc(sizeof(node)); 18 | nd->data = data; 19 | nd->next = NULL; 20 | return nd; 21 | } 22 | 23 | void append_q(queue* q, void* data) { 24 | if (empty_q(q)) { 25 | q->head = q->tail = new_node(data); 26 | } else { 27 | q->tail->next = new_node(data); 28 | q->tail = q->tail->next; 29 | } 30 | } 31 | 32 | void* pop_q(queue* q) { 33 | assert(!empty_q(q)); 34 | node* head = q->head; 35 | void* data = head->data; 36 | q->head = head->next; 37 | free(head); 38 | if (empty_q(q)) q->tail = NULL; 39 | return data; 40 | } 41 | -------------------------------------------------------------------------------- /rs/day9/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::error; 3 | use std::fs; 4 | 5 | fn run(prog: &intcode::Program, input: i64) -> Result { 6 | let mut machine = intcode::Machine::new(prog); 7 | let mut output = Vec::new(); 8 | loop { 9 | let state = machine.run()?; 10 | match state { 11 | intcode::State::Running => (), 12 | intcode::State::Reading => machine.write(input), 13 | intcode::State::Writing => output.push(machine.read()), 14 | intcode::State::Halted => break, 15 | } 16 | } 17 | if output.len() != 1 { 18 | Err(format!("bad output: {:?}", output)) 19 | } else { 20 | Ok(output[0]) 21 | } 22 | } 23 | 24 | fn main() -> Result<(), Box> { 25 | let path = env::args().nth(1).ok_or("missing input path")?; 26 | let text = fs::read_to_string(&path)?; 27 | let prog = intcode::Program::new(&text)?; 28 | println!("{}", run(&prog, 1)?); 29 | println!("{}", run(&prog, 2)?); 30 | Ok(()) 31 | } 32 | -------------------------------------------------------------------------------- /c/day5.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "parse.h" 6 | #include "vm.h" 7 | 8 | int64_t evaluate(vm vm, int64_t input) { 9 | run(&vm); 10 | assert(vm.state == VM_INPUT); 11 | vm.input = input; 12 | int64_t output; 13 | for (run(&vm); vm.state == VM_OUTPUT; run(&vm)) output = vm.output; 14 | assert(vm.state == VM_HALTED); 15 | return output; 16 | } 17 | 18 | int main(int argc, char* argv[]) { 19 | if (argc != 2) { 20 | fprintf(stderr, "usage: day5 file\n"); 21 | exit(1); 22 | } 23 | 24 | FILE* f = fopen(argv[1], "r"); 25 | if (f == NULL) { 26 | perror("day5"); 27 | exit(1); 28 | } 29 | 30 | int64_t data[1024]; 31 | int len; 32 | if ((len = parse_intcode(f, data, 1024)) < 0) { 33 | perror("day5"); 34 | exit(1); 35 | } 36 | 37 | vm base = make_vm(data, len); 38 | 39 | printf("%lld\n", evaluate(copy_vm(&base), 1)); 40 | printf("%lld\n", evaluate(copy_vm(&base), 5)); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /intcode/intcode.go: -------------------------------------------------------------------------------- 1 | package intcode 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "os" 8 | ) 9 | 10 | func RunProgram(data []int64, in <-chan int64) <-chan int64 { 11 | return Run(data, in, false) 12 | } 13 | 14 | func Run(data []int64, in <-chan int64, dbg bool) <-chan int64 { 15 | out := make(chan int64) 16 | m := newMachine(data, in, out, dbg) 17 | go m.run() 18 | return out 19 | } 20 | 21 | func ReadProgram(path string) ([]int64, error) { 22 | f, err := os.Open(path) 23 | if err != nil { 24 | return nil, err 25 | } 26 | defer f.Close() 27 | var data []int64 28 | for r := bufio.NewReader(f); ; { 29 | tok, err := r.ReadString(',') 30 | if err != nil && err != io.EOF { 31 | return nil, fmt.Errorf("bad int in %s: %w", path, err) 32 | } 33 | if len(tok) > 0 { 34 | var i int64 35 | if _, err := fmt.Sscanf(tok, "%d", &i); err != nil { 36 | return nil, fmt.Errorf("bad int in %s: %w", path, err) 37 | } 38 | data = append(data, i) 39 | } 40 | if err == io.EOF { 41 | break 42 | } 43 | } 44 | return data, nil 45 | } 46 | -------------------------------------------------------------------------------- /rs/day5/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::error; 3 | use std::fs; 4 | 5 | fn run(prog: &intcode::Program, input: i64) -> Result { 6 | let mut machine = intcode::Machine::new(&prog); 7 | let mut state = machine.run()?; 8 | let mut output = 0; 9 | loop { 10 | if state == intcode::State::Reading { 11 | machine.write(input); 12 | } else if state == intcode::State::Writing { 13 | output = machine.read(); 14 | } 15 | state = machine.run()?; 16 | if state == intcode::State::Halted { 17 | break; 18 | } 19 | if output != 0 { 20 | return Err(format!("diagnostic failed: {}", output)); 21 | } 22 | } 23 | Ok(output) 24 | } 25 | 26 | fn main() -> Result<(), Box> { 27 | let path = env::args().nth(1).ok_or("missing input path")?; 28 | let text = fs::read_to_string(&path)?; 29 | let prog = intcode::Program::new(&text)?; 30 | println!("{}", run(&prog, 1)?); 31 | println!("{}", run(&prog, 5)?); 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /c/vm.h: -------------------------------------------------------------------------------- 1 | #ifndef VM_H_ 2 | #define VM_H_ 3 | 4 | #include 5 | 6 | #include "hash.h" 7 | 8 | typedef enum { 9 | VM_HALTED, 10 | VM_RUNNING, 11 | VM_ERROR, 12 | VM_INPUT, 13 | VM_OUTPUT, 14 | } state; 15 | 16 | typedef enum { 17 | ADD = 1, 18 | MUL = 2, 19 | IN = 3, 20 | OUT = 4, 21 | JMP_IF = 5, 22 | JMP_NOT = 6, 23 | LT = 7, 24 | EQ = 8, 25 | ADJREL = 9, 26 | HALT = 99, 27 | } opcode; 28 | 29 | typedef enum { 30 | ERR_NONE, 31 | ERR_PC_OUT_OF_RANGE, 32 | ERR_INVALID_OPCODE, 33 | ERR_INVALID_MODE, 34 | } error; 35 | 36 | typedef struct { 37 | state state; 38 | error error; 39 | int pc; 40 | int relbase; 41 | hashtable mem; 42 | int64_t input; 43 | int64_t output; 44 | int trace; 45 | } vm; 46 | 47 | vm new_vm(void); 48 | vm make_vm(int64_t mem[], int mem_size); 49 | vm copy_vm(const vm* vm); 50 | void init_vm(vm* vm); 51 | void load_vm(vm* vm, int64_t mem[], int mem_size); 52 | void run(vm* vm); 53 | int64_t get_mem(vm* vm, int addr); 54 | void set_mem(vm* vm, int addr, int64_t val); 55 | 56 | #endif // VM_H_ 57 | -------------------------------------------------------------------------------- /day10/input.txt: -------------------------------------------------------------------------------- 1 | #...##.####.#.......#.##..##.#. 2 | #.##.#..#..#...##..##.##.#..... 3 | #..#####.#......#..#....#.###.# 4 | ...#.#.#...#..#.....#..#..#.#.. 5 | .#.....##..#...#..#.#...##..... 6 | ##.....#..........##..#......## 7 | .##..##.#.#....##..##.......#.. 8 | #.##.##....###..#...##...##.... 9 | ##.#.#............##..#...##..# 10 | ###..##.###.....#.##...####.... 11 | ...##..#...##...##..#.#..#...#. 12 | ..#.#.##.#.#.#####.#....####.#. 13 | #......###.##....#...#...#...## 14 | .....#...#.#.#.#....#...#...... 15 | #..#.#.#..#....#..#...#..#..##. 16 | #.....#..##.....#...###..#..#.# 17 | .....####.#..#...##..#..#..#..# 18 | ..#.....#.#........#.#.##..#### 19 | .#.....##..#.##.....#...###.... 20 | ###.###....#..#..#.....#####... 21 | #..##.##..##.#.#....#.#......#. 22 | .#....#.##..#.#.#.......##..... 23 | ##.##...#...#....###.#....#.... 24 | .....#.######.#.#..#..#.#.....# 25 | .#..#.##.#....#.##..#.#...##..# 26 | .##.###..#..#..#.###...#####.#. 27 | #...#...........#.....#.......# 28 | #....##.#.#..##...#..####...#.. 29 | #.####......#####.....#.##..#.. 30 | .#...#....#...##..##.#.#......# 31 | #..###.....##.#.......#.##...## 32 | -------------------------------------------------------------------------------- /rs/day10/input.txt: -------------------------------------------------------------------------------- 1 | #...##.####.#.......#.##..##.#. 2 | #.##.#..#..#...##..##.##.#..... 3 | #..#####.#......#..#....#.###.# 4 | ...#.#.#...#..#.....#..#..#.#.. 5 | .#.....##..#...#..#.#...##..... 6 | ##.....#..........##..#......## 7 | .##..##.#.#....##..##.......#.. 8 | #.##.##....###..#...##...##.... 9 | ##.#.#............##..#...##..# 10 | ###..##.###.....#.##...####.... 11 | ...##..#...##...##..#.#..#...#. 12 | ..#.#.##.#.#.#####.#....####.#. 13 | #......###.##....#...#...#...## 14 | .....#...#.#.#.#....#...#...... 15 | #..#.#.#..#....#..#...#..#..##. 16 | #.....#..##.....#...###..#..#.# 17 | .....####.#..#...##..#..#..#..# 18 | ..#.....#.#........#.#.##..#### 19 | .#.....##..#.##.....#...###.... 20 | ###.###....#..#..#.....#####... 21 | #..##.##..##.#.#....#.#......#. 22 | .#....#.##..#.#.#.......##..... 23 | ##.##...#...#....###.#....#.... 24 | .....#.######.#.#..#..#.#.....# 25 | .#..#.##.#....#.##..#.#...##..# 26 | .##.###..#..#..#.###...#####.#. 27 | #...#...........#.....#.......# 28 | #....##.#.#..##...#..####...#.. 29 | #.####......#####.....#.##..#.. 30 | .#...#....#...##..##.#.#......# 31 | #..###.....##.#.......#.##...## 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Daniel Connelly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /rs/day2/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::error; 3 | use std::fs; 4 | 5 | fn run(program: &intcode::Program, noun: i64, verb: i64) -> Result { 6 | let mut machine = intcode::Machine::new(program); 7 | machine.set(1, noun); 8 | machine.set(2, verb); 9 | assert_eq!(machine.run()?, intcode::State::Halted); 10 | Ok(machine.get(0)) 11 | } 12 | 13 | fn find_noun_verb(program: &intcode::Program, target: i64) -> Result<(i64, i64), String> { 14 | for noun in 0..100 { 15 | for verb in 0..100 { 16 | if run(&program, noun, verb)? == target { 17 | return Ok((noun, verb)); 18 | } 19 | } 20 | } 21 | Err(format!("no noun and verb matching {}", target)) 22 | } 23 | 24 | fn main() -> Result<(), Box> { 25 | let path = env::args().nth(1).ok_or("missing input path")?; 26 | let text = fs::read_to_string(&path)?; 27 | let program = intcode::Program::new(&text)?; 28 | println!("{}", run(&program, 12, 2)?); 29 | let (noun, verb) = find_noun_verb(&program, 19690720)?; 30 | println!("{}", 100 * noun + verb); 31 | Ok(()) 32 | } 33 | -------------------------------------------------------------------------------- /day7/input.txt: -------------------------------------------------------------------------------- 1 | 3,8,1001,8,10,8,105,1,0,0,21,30,39,64,81,102,183,264,345,426,99999,3,9,1001,9,2,9,4,9,99,3,9,1002,9,4,9,4,9,99,3,9,1002,9,5,9,101,2,9,9,102,3,9,9,1001,9,2,9,1002,9,2,9,4,9,99,3,9,1002,9,3,9,1001,9,5,9,1002,9,3,9,4,9,99,3,9,102,4,9,9,1001,9,3,9,102,4,9,9,1001,9,5,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,99,3,9,1002,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,1,9,4,9,3,9,102,2,9,9,4,9,99,3,9,101,1,9,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,99,3,9,102,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,102,2,9,9,4,9,3,9,101,2,9,9,4,9,3,9,1001,9,2,9,4,9,3,9,1001,9,1,9,4,9,3,9,101,2,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,2,9,4,9,99,3,9,101,2,9,9,4,9,3,9,1002,9,2,9,4,9,3,9,1001,9,2,9,4,9,3,9,1002,9,2,9,4,9,3,9,101,1,9,9,4,9,3,9,102,2,9,9,4,9,3,9,1001,9,1,9,4,9,3,9,1001,9,2,9,4,9,3,9,101,2,9,9,4,9,3,9,101,1,9,9,4,9,99 2 | -------------------------------------------------------------------------------- /day1/input.txt: -------------------------------------------------------------------------------- 1 | 109364 2 | 144584 3 | 87498 4 | 130293 5 | 91960 6 | 117563 7 | 91730 8 | 138879 9 | 144269 10 | 89058 11 | 89982 12 | 115609 13 | 114728 14 | 85422 15 | 111803 16 | 148524 17 | 130035 18 | 107558 19 | 138936 20 | 95622 21 | 58042 22 | 50697 23 | 86848 24 | 123301 25 | 123631 26 | 143125 27 | 76434 28 | 78004 29 | 91115 30 | 89062 31 | 58465 32 | 141127 33 | 139993 34 | 80958 35 | 104184 36 | 145131 37 | 87438 38 | 74385 39 | 102113 40 | 97392 41 | 105986 42 | 58600 43 | 147156 44 | 54377 45 | 61409 46 | 73552 47 | 87138 48 | 63168 49 | 149602 50 | 111776 51 | 113191 52 | 80137 53 | 145985 54 | 145177 55 | 73192 56 | 141631 57 | 132979 58 | 52565 59 | 126574 60 | 92005 61 | 134655 62 | 115894 63 | 89175 64 | 127328 65 | 139873 66 | 50072 67 | 78814 68 | 134750 69 | 120848 70 | 132950 71 | 126523 72 | 58206 73 | 70885 74 | 85482 75 | 70889 76 | 100029 77 | 68447 78 | 95111 79 | 79896 80 | 138650 81 | 83079 82 | 83112 83 | 117762 84 | 57223 85 | 138122 86 | 145193 87 | 85251 88 | 103331 89 | 134501 90 | 77023 91 | 148189 92 | 141341 93 | 75994 94 | 67024 95 | 137767 96 | 86260 97 | 58705 98 | 58771 99 | 60684 100 | 79655 101 | -------------------------------------------------------------------------------- /py/day1/input.txt: -------------------------------------------------------------------------------- 1 | 109364 2 | 144584 3 | 87498 4 | 130293 5 | 91960 6 | 117563 7 | 91730 8 | 138879 9 | 144269 10 | 89058 11 | 89982 12 | 115609 13 | 114728 14 | 85422 15 | 111803 16 | 148524 17 | 130035 18 | 107558 19 | 138936 20 | 95622 21 | 58042 22 | 50697 23 | 86848 24 | 123301 25 | 123631 26 | 143125 27 | 76434 28 | 78004 29 | 91115 30 | 89062 31 | 58465 32 | 141127 33 | 139993 34 | 80958 35 | 104184 36 | 145131 37 | 87438 38 | 74385 39 | 102113 40 | 97392 41 | 105986 42 | 58600 43 | 147156 44 | 54377 45 | 61409 46 | 73552 47 | 87138 48 | 63168 49 | 149602 50 | 111776 51 | 113191 52 | 80137 53 | 145985 54 | 145177 55 | 73192 56 | 141631 57 | 132979 58 | 52565 59 | 126574 60 | 92005 61 | 134655 62 | 115894 63 | 89175 64 | 127328 65 | 139873 66 | 50072 67 | 78814 68 | 134750 69 | 120848 70 | 132950 71 | 126523 72 | 58206 73 | 70885 74 | 85482 75 | 70889 76 | 100029 77 | 68447 78 | 95111 79 | 79896 80 | 138650 81 | 83079 82 | 83112 83 | 117762 84 | 57223 85 | 138122 86 | 145193 87 | 85251 88 | 103331 89 | 134501 90 | 77023 91 | 148189 92 | 141341 93 | 75994 94 | 67024 95 | 137767 96 | 86260 97 | 58705 98 | 58771 99 | 60684 100 | 79655 101 | -------------------------------------------------------------------------------- /rs/day1/input.txt: -------------------------------------------------------------------------------- 1 | 109364 2 | 144584 3 | 87498 4 | 130293 5 | 91960 6 | 117563 7 | 91730 8 | 138879 9 | 144269 10 | 89058 11 | 89982 12 | 115609 13 | 114728 14 | 85422 15 | 111803 16 | 148524 17 | 130035 18 | 107558 19 | 138936 20 | 95622 21 | 58042 22 | 50697 23 | 86848 24 | 123301 25 | 123631 26 | 143125 27 | 76434 28 | 78004 29 | 91115 30 | 89062 31 | 58465 32 | 141127 33 | 139993 34 | 80958 35 | 104184 36 | 145131 37 | 87438 38 | 74385 39 | 102113 40 | 97392 41 | 105986 42 | 58600 43 | 147156 44 | 54377 45 | 61409 46 | 73552 47 | 87138 48 | 63168 49 | 149602 50 | 111776 51 | 113191 52 | 80137 53 | 145985 54 | 145177 55 | 73192 56 | 141631 57 | 132979 58 | 52565 59 | 126574 60 | 92005 61 | 134655 62 | 115894 63 | 89175 64 | 127328 65 | 139873 66 | 50072 67 | 78814 68 | 134750 69 | 120848 70 | 132950 71 | 126523 72 | 58206 73 | 70885 74 | 85482 75 | 70889 76 | 100029 77 | 68447 78 | 95111 79 | 79896 80 | 138650 81 | 83079 82 | 83112 83 | 117762 84 | 57223 85 | 138122 86 | 145193 87 | 85251 88 | 103331 89 | 134501 90 | 77023 91 | 148189 92 | 141341 93 | 75994 94 | 67024 95 | 137767 96 | 86260 97 | 58705 98 | 58771 99 | 60684 100 | 79655 101 | -------------------------------------------------------------------------------- /ocaml/day1/input.txt: -------------------------------------------------------------------------------- 1 | 109364 2 | 144584 3 | 87498 4 | 130293 5 | 91960 6 | 117563 7 | 91730 8 | 138879 9 | 144269 10 | 89058 11 | 89982 12 | 115609 13 | 114728 14 | 85422 15 | 111803 16 | 148524 17 | 130035 18 | 107558 19 | 138936 20 | 95622 21 | 58042 22 | 50697 23 | 86848 24 | 123301 25 | 123631 26 | 143125 27 | 76434 28 | 78004 29 | 91115 30 | 89062 31 | 58465 32 | 141127 33 | 139993 34 | 80958 35 | 104184 36 | 145131 37 | 87438 38 | 74385 39 | 102113 40 | 97392 41 | 105986 42 | 58600 43 | 147156 44 | 54377 45 | 61409 46 | 73552 47 | 87138 48 | 63168 49 | 149602 50 | 111776 51 | 113191 52 | 80137 53 | 145985 54 | 145177 55 | 73192 56 | 141631 57 | 132979 58 | 52565 59 | 126574 60 | 92005 61 | 134655 62 | 115894 63 | 89175 64 | 127328 65 | 139873 66 | 50072 67 | 78814 68 | 134750 69 | 120848 70 | 132950 71 | 126523 72 | 58206 73 | 70885 74 | 85482 75 | 70889 76 | 100029 77 | 68447 78 | 95111 79 | 79896 80 | 138650 81 | 83079 82 | 83112 83 | 117762 84 | 57223 85 | 138122 86 | 145193 87 | 85251 88 | 103331 89 | 134501 90 | 77023 91 | 148189 92 | 141341 93 | 75994 94 | 67024 95 | 137767 96 | 86260 97 | 58705 98 | 58771 99 | 60684 100 | 79655 101 | -------------------------------------------------------------------------------- /geom/point_test.go: -------------------------------------------------------------------------------- 1 | package geom 2 | 3 | import "testing" 4 | 5 | func TestAdd(t *testing.T) { 6 | for _, tc := range []struct { 7 | pt1, pt2, want Pt2 8 | }{ 9 | {Zero2, Zero2, Zero2}, 10 | {Pt2{1, 2}, Pt2{-2, -1}, Pt2{-1, 1}}, 11 | {Pt2{1, 2}, Pt2{2, 1}, Pt2{3, 3}}, 12 | } { 13 | got := tc.pt1.Add(tc.pt2) 14 | if got != tc.want { 15 | t.Errorf("Add(%d, %d) = %d, want %d", tc.pt1, tc.pt2, got, tc.want) 16 | } 17 | } 18 | } 19 | 20 | func TestManhattanDist(t *testing.T) { 21 | for _, tc := range []struct { 22 | pt1, pt2 Pt2 23 | dist int 24 | }{ 25 | {Zero2, Zero2, 0}, 26 | {Zero2, Pt2{1, 1}, 2}, 27 | {Pt2{-2, -3}, Zero2, 5}, 28 | {Pt2{-3, 5}, Pt2{4, -7}, 19}, 29 | } { 30 | dist := tc.pt1.ManhattanDist(tc.pt2) 31 | if dist != tc.dist { 32 | t.Errorf("ManhattanDist(%v, %v) = %d, want %d", tc.pt1, tc.pt2, dist, tc.dist) 33 | } 34 | } 35 | } 36 | 37 | func TestManhattanNorm(t *testing.T) { 38 | for _, tc := range []struct { 39 | pt Pt2 40 | dist int 41 | }{ 42 | {Zero2, 0}, 43 | {Pt2{1, 1}, 2}, 44 | {Pt2{-2, -3}, 5}, 45 | {Pt2{4, -7}, 11}, 46 | } { 47 | dist := tc.pt.ManhattanNorm() 48 | if dist != tc.dist { 49 | t.Errorf("ManhattanNorm(%v) = %d, want %d", tc.pt, dist, tc.dist) 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/DATA-DOG/go-sqlmock v1.3.3 h1:CWUqKXe0s8A2z6qCgkP4Kru7wC11YoAnoupUKFDnH08= 2 | github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= 3 | github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko= 4 | github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg= 5 | github.com/gdamore/tcell v1.3.0 h1:r35w0JBADPZCVQijYebl6YMWWtHRqVEGt7kL2eBADRM= 6 | github.com/gdamore/tcell v1.3.0/go.mod h1:Hjvr+Ofd+gLglo7RYKxxnzCBmev3BzsS67MebKS4zMM= 7 | github.com/lucasb-eyer/go-colorful v1.0.2 h1:mCMFu6PgSozg9tDNMMK3g18oJBX7oYGrC09mS6CXfO4= 8 | github.com/lucasb-eyer/go-colorful v1.0.2/go.mod h1:0MS4r+7BZKSJ5mw4/S5MPN+qHFF1fYclkSPilDOKW0s= 9 | github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= 10 | github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= 11 | golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756 h1:9nuHUbU8dRnRRfj9KjWUVrJeoexdbeMjttk6Oh1rD10= 12 | golang.org/x/sys v0.0.0-20190626150813-e07cf5db2756/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 13 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 14 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 15 | -------------------------------------------------------------------------------- /c/day9.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "parse.h" 6 | #include "vm.h" 7 | 8 | void execute(vm vm, int64_t input) { 9 | do { 10 | run(&vm); 11 | switch (vm.state) { 12 | case VM_ERROR: 13 | fprintf(stderr, "vm error: %d\n", vm.error); 14 | return; 15 | case VM_OUTPUT: 16 | printf("%lld\n", vm.output); 17 | break; 18 | case VM_INPUT: 19 | vm.input = input; 20 | break; 21 | case VM_RUNNING: 22 | break; 23 | case VM_HALTED: 24 | break; 25 | } 26 | } while (vm.state != VM_HALTED); 27 | } 28 | 29 | int main(int argc, char* argv[]) { 30 | if (argc != 2) { 31 | fprintf(stderr, "usage: day9 file\n"); 32 | exit(1); 33 | } 34 | FILE* f = fopen(argv[1], "r"); 35 | if (f == NULL) { 36 | perror("day9"); 37 | exit(1); 38 | } 39 | int64_t data[1024]; 40 | int len; 41 | if ((len = parse_intcode(f, data, 1024)) < 0) { 42 | perror("day9"); 43 | exit(1); 44 | } 45 | vm vm = make_vm(data, len); 46 | execute(copy_vm(&vm), 1); 47 | execute(copy_vm(&vm), 2); 48 | } 49 | -------------------------------------------------------------------------------- /c/day2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "hash.h" 6 | #include "parse.h" 7 | #include "vm.h" 8 | 9 | int64_t execute(vm* vm, int64_t noun, int64_t verb) { 10 | set_mem(vm, 1, noun); 11 | set_mem(vm, 2, verb); 12 | run(vm); 13 | return get_mem(vm, 0); 14 | } 15 | 16 | int64_t part1(vm vm) { return execute(&vm, 12, 2); } 17 | 18 | int64_t part2(vm base) { 19 | vm local; 20 | for (int noun = 0; noun <= 99; noun++) { 21 | for (int verb = 0; verb <= 99; verb++) { 22 | local = copy_vm(&base); 23 | if (execute(&local, noun, verb) == 19690720) { 24 | return 100 * noun + verb; 25 | } 26 | } 27 | } 28 | assert(0); 29 | } 30 | 31 | int main(int argc, char* argv[]) { 32 | if (argc != 2) { 33 | printf("usage: day2 file\n"); 34 | exit(1); 35 | } 36 | 37 | FILE* f = fopen(argv[1], "r"); 38 | if (f == NULL) { 39 | perror("day2"); 40 | exit(1); 41 | } 42 | 43 | int64_t data[1024]; 44 | int len; 45 | if ((len = parse_intcode(f, data, 1024)) < 0) { 46 | perror("day2"); 47 | exit(1); 48 | } 49 | 50 | printf("%lld\n", part1(make_vm(data, len))); 51 | printf("%lld\n", part2(make_vm(data, len))); 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /day4/day4.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | "strconv" 8 | ) 9 | 10 | func toPassword(x int) [6]byte { 11 | var p [6]byte 12 | for i := 5; i >= 0; i-- { 13 | p[i] = byte(x % 10) 14 | x /= 10 15 | } 16 | return p 17 | } 18 | 19 | func valid(p [6]byte) (bool, bool) { 20 | twoAdjacentSame, onlyTwoAdjacentSame := false, false 21 | matchLen := 1 22 | for i := 0; i < len(p)-1; i++ { 23 | if p[i] > p[i+1] { 24 | return false, false 25 | } 26 | if p[i] == p[i+1] { 27 | twoAdjacentSame = true 28 | matchLen++ 29 | } else if matchLen == 2 { 30 | onlyTwoAdjacentSame = true 31 | } else { 32 | matchLen = 1 33 | } 34 | } 35 | return twoAdjacentSame, onlyTwoAdjacentSame || matchLen == 2 36 | } 37 | 38 | func countValidPasswords(from, to int) (int, int) { 39 | numValid1, numValid2 := 0, 0 40 | for i := from; i < to; i++ { 41 | p := toPassword(i) 42 | valid1, valid2 := valid(p) 43 | if valid1 { 44 | numValid1++ 45 | } 46 | if valid2 { 47 | numValid2++ 48 | } 49 | } 50 | return numValid1, numValid2 51 | } 52 | 53 | func main() { 54 | from, err := strconv.Atoi(os.Args[1]) 55 | if err != nil { 56 | log.Fatal(err) 57 | } 58 | to, err := strconv.Atoi(os.Args[2]) 59 | if err != nil { 60 | log.Fatal(err) 61 | } 62 | fmt.Println(countValidPasswords(from, to)) 63 | } 64 | -------------------------------------------------------------------------------- /day1/day1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "log" 8 | "os" 9 | "strconv" 10 | ) 11 | 12 | func fuelForMass(mass int) int { 13 | return (mass / 3) - 2 14 | } 15 | 16 | func fuelSum(mass int) int { 17 | sum := 0 18 | for { 19 | fuel := fuelForMass(mass) 20 | if fuel < 0 { 21 | break 22 | } 23 | sum += fuel 24 | mass = fuel 25 | } 26 | return sum 27 | } 28 | 29 | func solvePart1(masses <-chan int) int { 30 | sum := 0 31 | for mass := range masses { 32 | sum += fuelForMass(mass) 33 | } 34 | return sum 35 | } 36 | 37 | func solvePart2(masses <-chan int) int { 38 | sum := 0 39 | for mass := range masses { 40 | sum += fuelSum(mass) 41 | } 42 | return sum 43 | } 44 | 45 | func scanLines(r io.Reader) <-chan int { 46 | ch := make(chan int) 47 | go func() { 48 | scan := bufio.NewScanner(r) 49 | for scan.Scan() { 50 | i, err := strconv.Atoi(scan.Text()) 51 | if err != nil { 52 | log.Fatal(err) 53 | } 54 | ch <- i 55 | } 56 | if err := scan.Err(); err != nil { 57 | log.Fatal(err) 58 | } 59 | close(ch) 60 | }() 61 | return ch 62 | } 63 | 64 | func main() { 65 | f, err := os.Open(os.Args[1]) 66 | if err != nil { 67 | log.Fatal(err) 68 | } 69 | defer f.Close() 70 | 71 | fmt.Println(solvePart1(scanLines(f))) 72 | f.Seek(0, 0) 73 | fmt.Println(solvePart2(scanLines(f))) 74 | } 75 | -------------------------------------------------------------------------------- /c/pt2.c: -------------------------------------------------------------------------------- 1 | #include "pt2.h" 2 | 3 | #include 4 | #include 5 | 6 | pt2 make_pt(int16_t x, int16_t y) { 7 | pt2 pt; 8 | pt.coords.x = x; 9 | pt.coords.y = y; 10 | return pt; 11 | } 12 | 13 | pt2 pt_from_data(uint32_t data) { 14 | pt2 pt; 15 | pt.data = data; 16 | return pt; 17 | } 18 | 19 | int pt_eq(pt2 a, pt2 b) { return a.data == b.data; } 20 | 21 | void get_nbrs(pt2 pt, pt2 nbrs[4]) { 22 | nbrs[0] = make_pt(pt.coords.x, pt.coords.y - 1); 23 | nbrs[1] = make_pt(pt.coords.x, pt.coords.y + 1); 24 | nbrs[2] = make_pt(pt.coords.x - 1, pt.coords.y); 25 | nbrs[3] = make_pt(pt.coords.x + 1, pt.coords.y); 26 | } 27 | 28 | rect bounds(hashtable* map) { 29 | uint64_t* keys = table_keys(map); 30 | rect lohi; 31 | lohi.lo.coords.y = INT16_MAX, lohi.hi.coords.y = INT16_MIN, 32 | lohi.lo.coords.x = INT16_MAX, lohi.hi.coords.x = INT16_MIN; 33 | for (int i = 0; i < table_size(map); i++) { 34 | pt2 pt = pt_from_data(keys[i]); 35 | if (pt.coords.y < lohi.lo.coords.y) lohi.lo.coords.y = pt.coords.y; 36 | if (pt.coords.y > lohi.hi.coords.y) lohi.hi.coords.y = pt.coords.y; 37 | if (pt.coords.x < lohi.lo.coords.x) lohi.lo.coords.x = pt.coords.x; 38 | if (pt.coords.x > lohi.hi.coords.x) lohi.hi.coords.x = pt.coords.x; 39 | } 40 | free(keys); 41 | return lohi; 42 | } 43 | -------------------------------------------------------------------------------- /day19/input.txt: -------------------------------------------------------------------------------- 1 | 109,424,203,1,21102,11,1,0,1106,0,282,21101,18,0,0,1106,0,259,2101,0,1,221,203,1,21102,31,1,0,1106,0,282,21102,1,38,0,1105,1,259,20102,1,23,2,22101,0,1,3,21101,0,1,1,21101,0,57,0,1106,0,303,1202,1,1,222,21001,221,0,3,20102,1,221,2,21102,259,1,1,21101,80,0,0,1105,1,225,21102,1,149,2,21101,0,91,0,1105,1,303,1202,1,1,223,21002,222,1,4,21102,259,1,3,21102,225,1,2,21102,225,1,1,21101,118,0,0,1105,1,225,20102,1,222,3,21101,0,127,2,21102,133,1,0,1105,1,303,21202,1,-1,1,22001,223,1,1,21102,1,148,0,1106,0,259,1201,1,0,223,21001,221,0,4,21002,222,1,3,21102,14,1,2,1001,132,-2,224,1002,224,2,224,1001,224,3,224,1002,132,-1,132,1,224,132,224,21001,224,1,1,21101,195,0,0,106,0,108,20207,1,223,2,20102,1,23,1,21101,0,-1,3,21102,214,1,0,1106,0,303,22101,1,1,1,204,1,99,0,0,0,0,109,5,1202,-4,1,249,22102,1,-3,1,21201,-2,0,2,21201,-1,0,3,21102,1,250,0,1105,1,225,22102,1,1,-4,109,-5,2106,0,0,109,3,22107,0,-2,-1,21202,-1,2,-1,21201,-1,-1,-1,22202,-1,-2,-2,109,-3,2105,1,0,109,3,21207,-2,0,-1,1206,-1,294,104,0,99,21202,-2,1,-2,109,-3,2106,0,0,109,5,22207,-3,-4,-1,1206,-1,346,22201,-4,-3,-4,21202,-3,-1,-1,22201,-4,-1,2,21202,2,-1,-1,22201,-4,-1,1,22101,0,-2,3,21101,343,0,0,1106,0,303,1106,0,415,22207,-2,-3,-1,1206,-1,387,22201,-3,-2,-3,21202,-2,-1,-1,22201,-3,-1,3,21202,3,-1,-1,22201,-3,-1,2,22101,0,-4,1,21102,1,384,0,1106,0,303,1105,1,415,21202,-4,-1,-4,22201,-4,-3,-4,22202,-3,-2,-2,22202,-2,-4,-4,22202,-3,-2,-3,21202,-4,-1,-2,22201,-3,-2,1,22102,1,1,-4,109,-5,2106,0,0 2 | -------------------------------------------------------------------------------- /c/day2_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "vm.h" 6 | 7 | static void test1() { 8 | printf("day5_test1\n"); 9 | int64_t data[] = {1, 9, 10, 3, 2, 3, 11, 0, 99, 30, 40, 50}; 10 | vm vm = make_vm(data, sizeof(data) / sizeof(data[0])); 11 | run(&vm); 12 | assert(get_mem(&vm, 0) == 3500); 13 | } 14 | 15 | static void test2() { 16 | printf("day5_test2\n"); 17 | int64_t data[] = {1, 0, 0, 0, 99}; 18 | vm vm = make_vm(data, sizeof(data) / sizeof(data[0])); 19 | run(&vm); 20 | assert(get_mem(&vm, 0) == 2); 21 | } 22 | 23 | static void test3() { 24 | printf("day5_test3\n"); 25 | int64_t data[] = {2, 3, 0, 3, 99}; 26 | vm vm = make_vm(data, sizeof(data) / sizeof(data[0])); 27 | run(&vm); 28 | assert(get_mem(&vm, 3) == 6); 29 | } 30 | 31 | static void test4() { 32 | printf("day5_test4\n"); 33 | int64_t data[] = {2, 4, 4, 5, 99, 0}; 34 | vm vm = make_vm(data, sizeof(data) / sizeof(data[0])); 35 | run(&vm); 36 | assert(get_mem(&vm, 5) == 9801); 37 | } 38 | 39 | static void test5() { 40 | printf("day5_test5\n"); 41 | int64_t data[] = {1, 1, 1, 4, 99, 5, 6, 0, 99}; 42 | vm vm = make_vm(data, sizeof(data) / sizeof(data[0])); 43 | run(&vm); 44 | assert(get_mem(&vm, 0) == 30); 45 | } 46 | 47 | void day2_test() { 48 | printf("day2_test\n"); 49 | test1(); 50 | test2(); 51 | test3(); 52 | test4(); 53 | test5(); 54 | } 55 | -------------------------------------------------------------------------------- /day20/test2.txt: -------------------------------------------------------------------------------- 1 | A 2 | A 3 | #################.############# 4 | #.#...#...................#.#.# 5 | #.#.#.###.###.###.#########.#.# 6 | #.#.#.......#...#.....#.#.#...# 7 | #.#########.###.#####.#.#.###.# 8 | #.............#.#.....#.......# 9 | ###.###########.###.#####.#.#.# 10 | #.....# A C #.#.#.# 11 | ####### S P #####.# 12 | #.#...# #......VT 13 | #.#.#.# #.##### 14 | #...#.# YN....#.# 15 | #.###.# #####.# 16 | DI....#.# #.....# 17 | #####.# #.###.# 18 | ZZ......# QG....#..AS 19 | ###.### ####### 20 | JO..#.#.# #.....# 21 | #.#.#.# ###.#.# 22 | #...#..DI BU....#..LF 23 | #####.# #.##### 24 | YN......# VT..#....QG 25 | #.###.# #.###.# 26 | #.#...# #.....# 27 | ###.### J L J #.#.### 28 | #.....# O F P #.#...# 29 | #.###.#####.#.#####.#####.###.# 30 | #...#.#.#...#.....#.....#.#...# 31 | #.#####.###.###.#.#.#########.# 32 | #...#.#.....#...#.#.#.#.....#.# 33 | #.###.#####.###.###.#.#.####### 34 | #.#.........#...#.............# 35 | #########.###.###.############# 36 | B J C 37 | U P P 38 | -------------------------------------------------------------------------------- /py/day20/test2.txt: -------------------------------------------------------------------------------- 1 | A 2 | A 3 | #################.############# 4 | #.#...#...................#.#.# 5 | #.#.#.###.###.###.#########.#.# 6 | #.#.#.......#...#.....#.#.#...# 7 | #.#########.###.#####.#.#.###.# 8 | #.............#.#.....#.......# 9 | ###.###########.###.#####.#.#.# 10 | #.....# A C #.#.#.# 11 | ####### S P #####.# 12 | #.#...# #......VT 13 | #.#.#.# #.##### 14 | #...#.# YN....#.# 15 | #.###.# #####.# 16 | DI....#.# #.....# 17 | #####.# #.###.# 18 | ZZ......# QG....#..AS 19 | ###.### ####### 20 | JO..#.#.# #.....# 21 | #.#.#.# ###.#.# 22 | #...#..DI BU....#..LF 23 | #####.# #.##### 24 | YN......# VT..#....QG 25 | #.###.# #.###.# 26 | #.#...# #.....# 27 | ###.### J L J #.#.### 28 | #.....# O F P #.#...# 29 | #.###.#####.#.#####.#####.###.# 30 | #...#.#.#...#.....#.....#.#...# 31 | #.#####.###.###.#.#.#########.# 32 | #...#.#.....#...#.#.#.#.....#.# 33 | #.###.#####.###.###.#.#.####### 34 | #.#.........#...#.............# 35 | #########.###.###.############# 36 | B J C 37 | U P P 38 | -------------------------------------------------------------------------------- /rs/day20/test2.txt: -------------------------------------------------------------------------------- 1 | A 2 | A 3 | #################.############# 4 | #.#...#...................#.#.# 5 | #.#.#.###.###.###.#########.#.# 6 | #.#.#.......#...#.....#.#.#...# 7 | #.#########.###.#####.#.#.###.# 8 | #.............#.#.....#.......# 9 | ###.###########.###.#####.#.#.# 10 | #.....# A C #.#.#.# 11 | ####### S P #####.# 12 | #.#...# #......VT 13 | #.#.#.# #.##### 14 | #...#.# YN....#.# 15 | #.###.# #####.# 16 | DI....#.# #.....# 17 | #####.# #.###.# 18 | ZZ......# QG....#..AS 19 | ###.### ####### 20 | JO..#.#.# #.....# 21 | #.#.#.# ###.#.# 22 | #...#..DI BU....#..LF 23 | #####.# #.##### 24 | YN......# VT..#....QG 25 | #.###.# #.###.# 26 | #.#...# #.....# 27 | ###.### J L J #.#.### 28 | #.....# O F P #.#...# 29 | #.###.#####.#.#####.#####.###.# 30 | #...#.#.#...#.....#.....#.#...# 31 | #.#####.###.###.#.#.#########.# 32 | #...#.#.....#...#.#.#.#.....#.# 33 | #.###.#####.###.###.#.#.####### 34 | #.#.........#...#.............# 35 | #########.###.###.############# 36 | B J C 37 | U P P 38 | -------------------------------------------------------------------------------- /day2/day2.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | "strconv" 9 | "strings" 10 | ) 11 | 12 | func readData(path string) []int { 13 | txt, err := ioutil.ReadFile(path) 14 | if err != nil { 15 | log.Fatal(err) 16 | } 17 | // drop the comma 18 | toks := strings.Split(string(txt[:len(txt)-1]), ",") 19 | data := make([]int, len(toks)) 20 | for i, tok := range toks { 21 | val, err := strconv.Atoi(tok) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | data[i] = val 26 | } 27 | return data 28 | } 29 | 30 | func execute(data []int) { 31 | for i := 0; i < len(data); i += 4 { 32 | switch data[i] { 33 | case 1: 34 | data[data[i+3]] = data[data[i+1]] + data[data[i+2]] 35 | case 2: 36 | data[data[i+3]] = data[data[i+1]] * data[data[i+2]] 37 | case 99: 38 | return 39 | default: 40 | log.Fatalf("undefined opcode at position %d: %d", i, data[i]) 41 | } 42 | } 43 | } 44 | 45 | func executeWith(data []int, noun, verb int) int { 46 | local := make([]int, len(data)) 47 | copy(local, data) 48 | local[1], local[2] = noun, verb 49 | execute(local) 50 | return local[0] 51 | } 52 | 53 | func main() { 54 | data := readData(os.Args[1]) 55 | 56 | // part 1 57 | fmt.Println(executeWith(data, 12, 2)) 58 | 59 | // part 2 60 | for noun := 0; noun <= 99; noun++ { 61 | for verb := 0; verb <= 99; verb++ { 62 | result := executeWith(data, noun, verb) 63 | if result == 19690720 { 64 | fmt.Println(100*noun + verb) 65 | return 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /c/day7.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "amp.h" 7 | #include "comb.h" 8 | #include "parse.h" 9 | #include "vm.h" 10 | 11 | typedef int64_t (*execute)(circuit*, phase_sequence, int64_t); 12 | 13 | typedef struct { 14 | execute f; 15 | vm vm; 16 | int64_t max; 17 | int64_t input; 18 | } acc; 19 | 20 | void* find_max(int64_t seq[], void* data) { 21 | acc* acc = data; 22 | circuit circuit = make_circuit(acc->vm); 23 | int64_t output = acc->f(&circuit, seq, acc->input); 24 | if (output > acc->max) acc->max = output; 25 | return acc; 26 | } 27 | 28 | int main(int argc, char* argv[]) { 29 | if (argc != 2) { 30 | fprintf(stderr, "usage: day7 file\n"); 31 | exit(1); 32 | } 33 | FILE* f = fopen(argv[1], "r"); 34 | if (f == NULL) { 35 | perror("day7"); 36 | exit(1); 37 | } 38 | 39 | int64_t data[1024]; 40 | int len; 41 | if ((len = parse_intcode(f, data, 1024)) < 0) { 42 | perror("day7"); 43 | exit(1); 44 | } 45 | 46 | vm base = make_vm(data, len); 47 | 48 | acc acc1 = {.f = &run_series, .vm = copy_vm(&base), .input = 0, .max = ~0}; 49 | phase_sequence seq1 = {0, 1, 2, 3, 4}; 50 | visit_permutations(seq1, 5, find_max, &acc1); 51 | printf("%lld\n", acc1.max); 52 | 53 | acc acc2 = {.f = &run_loop, .vm = copy_vm(&base), .input = 0, .max = ~0}; 54 | phase_sequence seq2 = {5, 6, 7, 8, 9}; 55 | visit_permutations(seq2, 5, find_max, &acc2); 56 | printf("%lld\n", acc2.max); 57 | } 58 | -------------------------------------------------------------------------------- /intcode/disasm.go: -------------------------------------------------------------------------------- 1 | package intcode 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | type Kind int 9 | 10 | const ( 11 | RawData Kind = iota + 1 12 | Instr 13 | ) 14 | 15 | type Instruction struct { 16 | Opcode Opcode 17 | Modes []Mode 18 | } 19 | 20 | type Line struct { 21 | Offset int 22 | Width int 23 | 24 | Which Kind 25 | Data []int64 26 | Instr Instruction 27 | } 28 | 29 | func joinInts(ints []int64) string { 30 | strs := make([]string, len(ints)) 31 | for i, v := range ints { 32 | strs[i] = fmt.Sprintf("%d", v) 33 | } 34 | return strings.Join(strs, ", ") 35 | } 36 | 37 | func (l Line) String() string { 38 | switch l.Which { 39 | case Instr: 40 | s := fmt.Sprintf("[%4d] %8s ", l.Offset, l.Instr.Opcode) 41 | args := make([]string, len(l.Instr.Modes)) 42 | for i, md := range l.Instr.Modes { 43 | args[i] = fmt.Sprintf("%8s", fmt.Sprintf("%s(%d)", md, l.Data[i+1])) 44 | } 45 | return s + strings.Join(args, " ") 46 | default: 47 | return fmt.Sprintf("[%4d] %v", l.Offset, l.Data) 48 | } 49 | } 50 | 51 | func Disassemble(data []int64) []Line { 52 | var lines []Line 53 | var line Line 54 | for i := 0; i < len(data); { 55 | line.Offset = i 56 | instr := parseInstruction(data[i]) 57 | if !instr.op.isValid() { 58 | line.Which = RawData 59 | line.Width = 1 60 | } else { 61 | line.Which = Instr 62 | line.Instr.Opcode = instr.op 63 | line.Instr.Modes = instr.modes 64 | line.Width = int(instr.arity) + 1 65 | } 66 | line.Data = data[i : i+line.Width] 67 | lines = append(lines, line) 68 | i += line.Width 69 | } 70 | return lines 71 | } 72 | -------------------------------------------------------------------------------- /day21/day21.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "log" 8 | "math" 9 | "os" 10 | 11 | "github.com/dhconnelly/advent-of-code-2019/intcode" 12 | ) 13 | 14 | func readLine(ch <-chan int64) string { 15 | var data []byte 16 | for c := byte(<-ch); c != '\n'; c = byte(<-ch) { 17 | data = append(data, c) 18 | } 19 | return string(data) 20 | } 21 | 22 | func writeLine(ch chan<- int64, s string) { 23 | for _, c := range s { 24 | ch <- int64(c) 25 | } 26 | ch <- int64('\n') 27 | } 28 | 29 | type springdroid struct { 30 | prog []int64 31 | } 32 | 33 | func (d springdroid) execute(r io.Reader, prompt bool) error { 34 | in := make(chan int64) 35 | out := intcode.RunProgram(d.prog, in) 36 | line := readLine(out) 37 | if prompt { 38 | fmt.Println(line) 39 | } 40 | scan := bufio.NewScanner(r) 41 | for scan.Scan() { 42 | line := scan.Text() 43 | writeLine(in, line) 44 | if line == "WALK" || line == "RUN" { 45 | break 46 | } 47 | } 48 | for c, ok := <-out; ok; c, ok = <-out { 49 | if c > math.MaxInt8 { 50 | fmt.Printf("%d\n", c) 51 | } else if prompt { 52 | fmt.Printf("%c", c) 53 | } 54 | } 55 | return scan.Err() 56 | } 57 | 58 | func openOrDie(path string) *os.File { 59 | f, err := os.Open(path) 60 | if err != nil { 61 | log.Fatal(err) 62 | } 63 | return f 64 | } 65 | 66 | func main() { 67 | data, err := intcode.ReadProgram(os.Args[1]) 68 | if err != nil { 69 | log.Fatal(err) 70 | } 71 | d := springdroid{data} 72 | 73 | if len(os.Args) > 2 { 74 | for _, path := range os.Args[2:] { 75 | f := openOrDie(path) 76 | defer f.Close() 77 | d.execute(f, false) 78 | } 79 | } else { 80 | d.execute(os.Stdin, true) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /geom/point.go: -------------------------------------------------------------------------------- 1 | package geom 2 | 3 | import ( 4 | "github.com/dhconnelly/advent-of-code-2019/ints" 5 | "math" 6 | ) 7 | 8 | type Pt2 struct { 9 | X, Y int 10 | } 11 | 12 | var Zero2 Pt2 13 | 14 | func (pt1 Pt2) Add(pt2 Pt2) Pt2 { 15 | pt := pt1 16 | pt.TranslateBy(pt2) 17 | return pt 18 | } 19 | 20 | func (pt1 *Pt2) TranslateBy(pt2 Pt2) { 21 | pt1.X += pt2.X 22 | pt1.Y += pt2.Y 23 | } 24 | 25 | func (pt1 Pt2) ManhattanDist(pt2 Pt2) int { 26 | return ints.Abs(pt1.X-pt2.X) + ints.Abs(pt1.Y-pt2.Y) 27 | } 28 | 29 | func (pt Pt2) ManhattanNorm() int { 30 | return pt.ManhattanDist(Zero2) 31 | } 32 | 33 | func (pt1 Pt2) Dist(pt2 Pt2) float64 { 34 | pt := pt1 35 | pt.TranslateBy(Pt2{-pt2.X, -pt2.Y}) 36 | return pt.Norm() 37 | } 38 | 39 | func (pt Pt2) Norm() float64 { 40 | return math.Sqrt(math.Pow(float64(pt.X), 2.0) + math.Pow(float64(pt.Y), 2.0)) 41 | } 42 | 43 | type Direction rune 44 | 45 | const ( 46 | None Direction = 0 47 | Up Direction = '^' 48 | Down Direction = 'v' 49 | Right Direction = '>' 50 | Left Direction = '<' 51 | ) 52 | 53 | var Directions = map[Direction]Pt2{ 54 | Up: Pt2{0, 1}, 55 | Down: Pt2{0, -1}, 56 | Left: Pt2{-1, 0}, 57 | Right: Pt2{1, 0}, 58 | } 59 | 60 | func (from Pt2) DirectionTo(to Pt2) Direction { 61 | switch { 62 | case from.X < to.X: 63 | return Right 64 | case to.X < from.X: 65 | return Left 66 | case from.Y < to.Y: 67 | return Down 68 | case to.Y < from.Y: 69 | return Up 70 | } 71 | return 0 72 | } 73 | 74 | func (p Pt2) Go(dir Direction) Pt2 { 75 | return p.Add(Directions[dir]) 76 | } 77 | 78 | func (p Pt2) ManhattanNeighbors() []Pt2 { 79 | return []Pt2{ 80 | p.Add(Directions[Up]), 81 | p.Add(Directions[Down]), 82 | p.Add(Directions[Left]), 83 | p.Add(Directions[Right]), 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /c/amp.c: -------------------------------------------------------------------------------- 1 | #include "amp.h" 2 | 3 | #include 4 | #include 5 | 6 | void init_circuit(circuit* circuit, vm vm) { 7 | for (int i = 0; i < CIRCUIT_SIZE; i++) circuit->vms[i] = vm; 8 | } 9 | 10 | circuit make_circuit(vm vm) { 11 | circuit circuit; 12 | init_circuit(&circuit, vm); 13 | return circuit; 14 | } 15 | 16 | typedef int64_t phase_sequence[CIRCUIT_SIZE]; 17 | 18 | int64_t run_series(circuit* circuit, phase_sequence setting, int64_t input) { 19 | int64_t prev_output = input; 20 | for (int i = 0; i < CIRCUIT_SIZE; i++) { 21 | vm* vm = &circuit->vms[i]; 22 | run(vm); 23 | assert(vm->state == VM_INPUT); 24 | vm->input = setting[i]; 25 | run(vm); 26 | assert(vm->state == VM_INPUT); 27 | vm->input = prev_output; 28 | run(vm); 29 | assert(vm->state == VM_OUTPUT); 30 | prev_output = vm->output; 31 | } 32 | return prev_output; 33 | } 34 | 35 | int64_t run_loop(circuit* circuit, phase_sequence setting, int64_t input) { 36 | int64_t prev_output = input; 37 | for (int iter = 0, done = 0; !done; iter++) { 38 | for (int i = 0; i < CIRCUIT_SIZE; i++) { 39 | vm* vm = &circuit->vms[i]; 40 | if (iter == 0) { 41 | run(vm); 42 | assert(vm->state == VM_INPUT); 43 | vm->input = setting[i]; 44 | } 45 | run(vm); 46 | if (vm->state == VM_HALTED) { 47 | done = 1; 48 | break; 49 | } 50 | assert(vm->state == VM_INPUT); 51 | vm->input = prev_output; 52 | run(vm); 53 | assert(vm->state == VM_OUTPUT); 54 | prev_output = vm->output; 55 | } 56 | } 57 | return prev_output; 58 | } 59 | -------------------------------------------------------------------------------- /rs/day4/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::error::Error; 3 | use std::fs; 4 | 5 | fn valid1(mut x: i32) -> bool { 6 | let mut prev = x % 10; 7 | let mut chain = 1; 8 | let mut two_chain = false; 9 | x /= 10; 10 | while x > 0 { 11 | let y = x % 10; 12 | if y > prev { 13 | return false; 14 | } 15 | if y == prev { 16 | chain += 1; 17 | } else { 18 | chain = 1; 19 | } 20 | if chain == 2 { 21 | two_chain = true; 22 | } 23 | prev = y; 24 | x /= 10; 25 | } 26 | two_chain 27 | } 28 | 29 | fn valid2(mut x: i32) -> bool { 30 | let mut prev = x % 10; 31 | let mut chain = 1; 32 | let mut two_chain = false; 33 | x /= 10; 34 | while x > 0 { 35 | let y = x % 10; 36 | if y > prev { 37 | return false; 38 | } 39 | if y == prev { 40 | chain += 1; 41 | } else { 42 | if chain == 2 { 43 | two_chain = true; 44 | } 45 | chain = 1; 46 | } 47 | prev = y; 48 | x /= 10; 49 | } 50 | two_chain || chain == 2 51 | } 52 | 53 | fn count_valid bool>(from: i32, to: i32, valid: T) -> usize { 54 | (from..to + 1).filter(|x| valid(*x)).count() 55 | } 56 | 57 | fn main() -> Result<(), Box> { 58 | let path = env::args().nth(1).ok_or("missing input path")?; 59 | let toks = fs::read_to_string(path)? 60 | .trim() 61 | .split('-') 62 | .map(|x| x.parse::()) 63 | .collect::, _>>()?; 64 | let (from, to) = (toks[0], toks[1]); 65 | println!("{}", count_valid(from, to, valid1)); 66 | println!("{}", count_valid(from, to, valid2)); 67 | Ok(()) 68 | } 69 | -------------------------------------------------------------------------------- /day6/day6.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "os" 8 | "strings" 9 | ) 10 | 11 | type orbit struct { 12 | orbiter, orbited string 13 | } 14 | 15 | func read(path string) []orbit { 16 | f, err := os.Open(path) 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | defer f.Close() 21 | scan := bufio.NewScanner(f) 22 | var orbits []orbit 23 | for scan.Scan() { 24 | line := scan.Text() 25 | objs := strings.Split(line, ")") 26 | orbits = append(orbits, orbit{objs[1], objs[0]}) 27 | } 28 | if err = scan.Err(); err != nil { 29 | log.Fatal(err) 30 | } 31 | return orbits 32 | } 33 | 34 | func orbitMap(orbits []orbit) map[string]string { 35 | m := make(map[string]string) 36 | for _, o := range orbits { 37 | m[o.orbiter] = o.orbited 38 | } 39 | return m 40 | } 41 | 42 | func chain(k string, m map[string]string) []string { 43 | var chain []string 44 | for v, ok := m[k]; ok; v, ok = m[v] { 45 | chain = append(chain, v) 46 | } 47 | return chain 48 | } 49 | 50 | func countOrbits(orbits map[string]string) int { 51 | n := 0 52 | for k, _ := range orbits { 53 | n += len(chain(k, orbits)) 54 | } 55 | return n 56 | } 57 | 58 | func closestAncestor(chain1, chain2 []string) (string, int, int) { 59 | m := make(map[string]int) 60 | for i, k := range chain1 { 61 | m[k] = i 62 | } 63 | for i, o := range chain2 { 64 | if j, ok := m[o]; ok { 65 | return o, i, j 66 | } 67 | } 68 | return "", 0, 0 69 | } 70 | 71 | func transfers(orbits map[string]string, from, to string) int { 72 | fromChain, toChain := chain(from, orbits), chain(to, orbits) 73 | _, dist1, dist2 := closestAncestor(fromChain, toChain) 74 | return dist1 + dist2 75 | } 76 | 77 | func main() { 78 | m := orbitMap(read(os.Args[1])) 79 | fmt.Println(countOrbits(m)) 80 | fmt.Println(transfers(m, "YOU", "SAN")) 81 | } 82 | -------------------------------------------------------------------------------- /ocaml/day2/day2.ml: -------------------------------------------------------------------------------- 1 | open Array 2 | open Printf 3 | 4 | let getarg n = 5 | try Sys.argv.(n) with Invalid_argument _ -> failwith "Usage: day2.ml " 6 | 7 | let next_instr ic = 8 | try Some (Scanf.bscanf ic "%d%c" (fun i _ -> i)) with End_of_file -> None 9 | 10 | let rec read_program ic = 11 | match next_instr ic with 12 | | None -> [] 13 | | Some instr -> instr::(read_program ic) 14 | 15 | type opcode = Add | Mul | Halt 16 | type state = Running | Halted 17 | 18 | type vm = { 19 | pc: int; 20 | data: int array; 21 | state: state; 22 | } 23 | 24 | let get vm pos = 25 | vm.data.(vm.data.(vm.pc + pos)) 26 | 27 | let set vm pos x = 28 | vm.data.(vm.data.(vm.pc + pos)) <- x 29 | 30 | let new_vm program = {pc=0; data=of_list program; state=Running} 31 | 32 | let decode = function 33 | | 1 -> Add 34 | | 2 -> Mul 35 | | 99 -> Halt 36 | | o -> failwith (sprintf "invalid opcode: %d" o) 37 | 38 | let step vm = 39 | let {pc; data} = vm in 40 | if pc > length data then failwith "program terminated without halting" 41 | else match decode data.(pc) with 42 | | Add -> set vm 3 ((get vm 1) + (get vm 2)); {vm with pc=pc+4} 43 | | Mul -> set vm 3 ((get vm 1) * (get vm 2)); {vm with pc=pc+4} 44 | | Halt -> {vm with state=Halted} 45 | 46 | let rec run = function 47 | | {state=Halted} -> () 48 | | vm -> run (step vm) 49 | 50 | let run_program program noun verb = 51 | let vm = new_vm program in 52 | vm.data.(1) <- noun; 53 | vm.data.(2) <- verb; 54 | run vm; 55 | vm.data.(0) 56 | 57 | let () = 58 | let program = getarg 1 |> Scanf.Scanning.open_in |> read_program in 59 | run_program program 12 2 |> printf "%d\n"; 60 | for noun=0 to 99 do 61 | for verb=0 to 99 do 62 | if run_program program noun verb = 19690720 then 63 | printf "%d\n" (100 * noun + verb) 64 | done 65 | done 66 | 67 | -------------------------------------------------------------------------------- /c/day25.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "parse.h" 7 | #include "vm.h" 8 | 9 | void play(vm* vm) { 10 | while (vm->state != VM_HALTED) { 11 | switch (vm->state) { 12 | case VM_INPUT: { 13 | char* line = NULL; 14 | size_t len; 15 | int result = getline(&line, &len, stdin); 16 | if (feof(stdin)) { 17 | free(line); 18 | printf("Goodbye\n"); 19 | return; 20 | } else if (result < 0) { 21 | free(line); 22 | perror("day25: failed to read input"); 23 | exit(1); 24 | } 25 | for (int i = 0; i < len && vm->state == VM_INPUT; i++) { 26 | vm->input = line[i]; 27 | run(vm); 28 | } 29 | free(line); 30 | break; 31 | } 32 | case VM_OUTPUT: 33 | while (vm->state == VM_OUTPUT) { 34 | putchar(vm->output); 35 | run(vm); 36 | } 37 | break; 38 | default: 39 | assert(0); 40 | } 41 | } 42 | } 43 | 44 | int main(int argc, char* argv[]) { 45 | if (argc != 2) { 46 | fprintf(stderr, "usage: day25 file\n"); 47 | exit(1); 48 | } 49 | 50 | FILE* f = fopen(argv[1], "r"); 51 | if (f == NULL) { 52 | perror("day25"); 53 | exit(1); 54 | } 55 | 56 | int64_t data[8192]; 57 | int len; 58 | if ((len = parse_intcode(f, data, 8192)) < 0) { 59 | perror("day25: failed to parse intcode"); 60 | exit(1); 61 | } 62 | 63 | vm vm = make_vm(data, len); 64 | run(&vm); 65 | play(&vm); 66 | } 67 | -------------------------------------------------------------------------------- /ocaml/day12/main.ml: -------------------------------------------------------------------------------- 1 | type vec3 = int * int * int 2 | let zero3 = (0, 0, 0) 3 | 4 | let scan_vec (line: string): vec3 = 5 | let to_vec x y z = x, y, z in 6 | Scanf.sscanf line "" to_vec 7 | 8 | type planet = {pos: vec3; vel: vec3} 9 | 10 | let scan_planets (ic: in_channel): planet list = 11 | let add vs v = {pos=v; vel=zero3}::vs in 12 | let rec loop vs = 13 | try input_line ic |> scan_vec |> add vs |> loop 14 | with End_of_file -> vs in 15 | loop [] |> List.rev 16 | 17 | let pairs (ps: planet list): (planet * planet) list = 18 | List.combine ps ps |> List.filter (fun (p, q) -> p != q) 19 | 20 | let apply_gravity (ps: planet list): planet list = 21 | let update_vel (gx, gy, gz) (x, y, z) (dx, dy, dz) = 22 | (if gx < x then dx-1 else if gx > x then dx+1 else dx), 23 | (if gy < y then dy-1 else if gy > y then dy+1 else dy), 24 | (if gz < z then dz-1 else if gz > z then dz+1 else dz) in 25 | let apply {pos=pos1} {pos=pos2; vel} = 26 | {pos=pos2; vel=update_vel pos1 pos2 vel} in 27 | let apply1 ps p = 28 | List.fold_left (fun acc q -> apply p q::acc) [] ps in 29 | List.fold_left apply1 ps ps 30 | 31 | let apply_velocity (ps: planet list): planet list = 32 | let apply1 ({pos=(x, y, z); vel=(dx, dy, dz)} as p) = 33 | {p with pos=(x+dx, y+dy, z+dz)} in 34 | List.map apply1 ps 35 | 36 | let step (ps: planet list): planet list = 37 | apply_gravity ps |> apply_velocity 38 | 39 | let rec steps (n: int) (ps: planet list): planet list = 40 | if n = 0 then ps else step ps |> steps (n-1) 41 | 42 | let energy (ps: planet list): int = 43 | let energy1 {pos=(x, y, z); vel=(dx, dy, dz)} = 44 | Int.((abs x + abs y + abs z) * (abs dx + abs dy + abs dz)) in 45 | List.map energy1 ps |> List.fold_left (+) 0 46 | 47 | let () = 48 | let ps = open_in Sys.argv.(1) |> scan_planets in 49 | steps 1000 ps |> energy |> Printf.printf "%d\n" 50 | -------------------------------------------------------------------------------- /ocaml/day14/main.ml: -------------------------------------------------------------------------------- 1 | module StrMap = Map.Make(String) 2 | type quant = {chem: string; amt: int} 3 | type reaction = {out: quant; ins: quant list} 4 | type reaction_map = reaction StrMap.t 5 | type chem_map = int StrMap.t 6 | 7 | let reaction_delim = Str.regexp_string " => " 8 | let quants_delim = Str.regexp_string ", " 9 | 10 | let read_reactions (ic: in_channel): reaction_map = 11 | let parse_quant s = Scanf.sscanf s "%d %s" (fun amt chem -> {amt; chem}) in 12 | let parse_quants qs = Str.split quants_delim qs |> List.map parse_quant in 13 | let parse_reaction line = match Str.split reaction_delim line with 14 | | ins::out::[] -> {ins=parse_quants ins; out=parse_quant out} 15 | | _ -> failwith ("bad reaction: " ^ line) in 16 | let add_reaction m r = StrMap.add r.out.chem r m in 17 | let rec loop acc = 18 | try input_line ic |> parse_reaction |> add_reaction acc |> loop 19 | with End_of_file -> acc in 20 | loop StrMap.empty 21 | 22 | let print_reactions (rs: reaction_map) = 23 | StrMap.iter (fun _ {out; ins} -> 24 | Printf.printf "%d %s: " out.amt out.chem; 25 | List.iter (fun {amt; chem} -> Printf.printf "%d %s, " amt chem) ins; 26 | print_newline ()) rs 27 | 28 | type react_state = {need: chem_map; have: chem_map} 29 | 30 | let initial_state (rs: reaction_map): react_state = 31 | {need=StrMap.empty |> StrMap.add "FUEL" 1; have=StrMap.empty} 32 | 33 | let print_state ({need; have}: react_state) = 34 | let print_chems chem amt = Printf.printf "%s: %d\n" chem amt in 35 | Printf.printf "Need:\n"; 36 | StrMap.iter print_chems need; 37 | Printf.printf "Have:\n"; 38 | StrMap.iter print_chems have 39 | 40 | let rec reduce (rs: reaction_map) (state: react_state): react_state = 41 | state 42 | 43 | let cost (rs: reaction_map): int = 44 | 0 45 | 46 | let () = 47 | let reactions = Sys.argv.(1) |> open_in |> read_reactions in 48 | let state = initial_state reactions in 49 | print_state state 50 | -------------------------------------------------------------------------------- /day11/input.txt: -------------------------------------------------------------------------------- 1 | 3,8,1005,8,299,1106,0,11,0,0,0,104,1,104,0,3,8,102,-1,8,10,101,1,10,10,4,10,108,1,8,10,4,10,102,1,8,28,1006,0,85,1,106,14,10,3,8,102,-1,8,10,1001,10,1,10,4,10,1008,8,0,10,4,10,101,0,8,58,1,1109,15,10,3,8,1002,8,-1,10,1001,10,1,10,4,10,1008,8,0,10,4,10,1002,8,1,84,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1002,8,1,105,1006,0,48,3,8,1002,8,-1,10,1001,10,1,10,4,10,108,0,8,10,4,10,102,1,8,130,1006,0,46,1,1001,17,10,3,8,1002,8,-1,10,101,1,10,10,4,10,1008,8,0,10,4,10,1002,8,1,160,2,109,20,10,3,8,102,-1,8,10,1001,10,1,10,4,10,108,0,8,10,4,10,1002,8,1,185,3,8,102,-1,8,10,1001,10,1,10,4,10,108,1,8,10,4,10,1001,8,0,207,1006,0,89,2,1002,6,10,1,1007,0,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,101,0,8,241,2,4,14,10,3,8,102,-1,8,10,101,1,10,10,4,10,1008,8,1,10,4,10,101,0,8,267,1,1107,8,10,1,109,16,10,2,1107,4,10,101,1,9,9,1007,9,1003,10,1005,10,15,99,109,621,104,0,104,1,21101,0,387239486208,1,21102,316,1,0,1106,0,420,21101,0,936994976664,1,21102,327,1,0,1105,1,420,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,3,10,104,0,104,1,3,10,104,0,104,0,3,10,104,0,104,1,21102,1,29192457307,1,21102,1,374,0,1106,0,420,21101,0,3450965211,1,21101,0,385,0,1106,0,420,3,10,104,0,104,0,3,10,104,0,104,0,21102,1,837901103972,1,21101,408,0,0,1106,0,420,21102,867965752164,1,1,21101,0,419,0,1105,1,420,99,109,2,22102,1,-1,1,21102,40,1,2,21102,451,1,3,21102,1,441,0,1106,0,484,109,-2,2106,0,0,0,1,0,0,1,109,2,3,10,204,-1,1001,446,447,462,4,0,1001,446,1,446,108,4,446,10,1006,10,478,1102,0,1,446,109,-2,2105,1,0,0,109,4,1201,-1,0,483,1207,-3,0,10,1006,10,501,21101,0,0,-3,22101,0,-3,1,22102,1,-2,2,21101,1,0,3,21101,520,0,0,1106,0,525,109,-4,2106,0,0,109,5,1207,-3,1,10,1006,10,548,2207,-4,-2,10,1006,10,548,21201,-4,0,-4,1105,1,616,22101,0,-4,1,21201,-3,-1,2,21202,-2,2,3,21101,0,567,0,1106,0,525,22101,0,1,-4,21101,1,0,-1,2207,-4,-2,10,1006,10,586,21102,1,0,-1,22202,-2,-1,-2,2107,0,-3,10,1006,10,608,21202,-1,1,1,21102,608,1,0,106,0,483,21202,-2,-1,-2,22201,-4,-2,-4,109,-5,2105,1,0 2 | -------------------------------------------------------------------------------- /c/day9_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "vm.h" 6 | 7 | static int execute(vm* vm, int64_t outputs[], int max_outputs) { 8 | int i = 0; 9 | do { 10 | run(vm); 11 | switch (vm->state) { 12 | case VM_INPUT: 13 | printf("unexpected INPUT\n"); 14 | exit(1); 15 | case VM_OUTPUT: 16 | assert(i < max_outputs); 17 | outputs[i++] = vm->output; 18 | break; 19 | case VM_RUNNING: 20 | case VM_HALTED: 21 | break; 22 | case VM_ERROR: 23 | fprintf(stderr, "error: %d\n", vm->error); 24 | assert(0); 25 | } 26 | } while (vm->state != VM_HALTED); 27 | return i; 28 | } 29 | 30 | static void day9_test1(void) { 31 | printf("day9_test1\n"); 32 | int64_t prog[] = {109, 1, 204, -1, 1001, 100, 1, 100, 33 | 1008, 100, 16, 101, 1006, 101, 0, 99}; 34 | vm vm = make_vm(prog, sizeof(prog) / sizeof(int64_t)); 35 | int64_t outputs[100]; 36 | int n = execute(&vm, outputs, 100); 37 | for (int i = 0; i < n; i++) { 38 | assert(outputs[i] == prog[i]); 39 | } 40 | } 41 | 42 | static void day9_test2(void) { 43 | printf("day9_test2\n"); 44 | int64_t prog[] = {1102, 34915192, 34915192, 7, 4, 7, 99, 0}; 45 | vm vm = make_vm(prog, sizeof(prog) / sizeof(int64_t)); 46 | int64_t outputs[1]; 47 | int n = execute(&vm, outputs, 1); 48 | assert(outputs[0] == 1219070632396864); 49 | } 50 | 51 | static void day9_test3(void) { 52 | printf("day9_test3\n"); 53 | int64_t prog[] = {104, 1125899906842624, 99}; 54 | vm vm = make_vm(prog, sizeof(prog) / sizeof(int64_t)); 55 | int64_t outputs[100]; 56 | int n = execute(&vm, outputs, 100); 57 | assert(outputs[0] == prog[1]); 58 | } 59 | 60 | void day9_test(void) { 61 | printf("day9_test\n"); 62 | day9_test1(); 63 | day9_test2(); 64 | day9_test3(); 65 | } 66 | -------------------------------------------------------------------------------- /day14/input.txt: -------------------------------------------------------------------------------- 1 | 1 FJFL, 1 BPVQN => 7 CMNH 2 | 6 FJFL, 2 KZJLT, 3 DZQJ => 2 NSPZ 3 | 11 TPZDN => 2 TNMC 4 | 1 NSPZ, 2 KQVL => 2 HPNWP 5 | 3 XHDVT => 9 LRBN 6 | 3 LRBN => 6 TPZDN 7 | 1 KPFLZ, 1 XVXCZ => 6 WHMLV 8 | 1 BDWQP, 1 JPGK, 1 MTWG => 5 GLHWQ 9 | 2 BGLTP, 1 HPNWP, 2 GLHWQ, 9 CRJZ, 22 QVQJ, 3 PHGWC, 1 BDWQP => 3 LKPNB 10 | 4 BDSB => 2 PNSD 11 | 2 BRJDJ, 13 THQR => 2 BGLTP 12 | 1 WHJKH, 2 JBTJ => 6 THQR 13 | 1 JBTJ => 9 WGVP 14 | 10 CTXHZ, 2 DGMN => 5 TNVC 15 | 7 LCSV, 1 LKPNB, 36 CMNH, 1 JZXPH, 20 DGJPN, 3 WDWB, 69 DXJKC, 3 WHJKH, 18 XSGP, 22 CGZL, 2 BNVB, 57 PNSD => 1 FUEL 16 | 13 CRCG, 8 NMQN => 1 JZXPH 17 | 2 FZVS, 2 ZPFBH => 9 SRPD 18 | 1 QPNTQ, 4 QVQJ, 1 XZKTG => 9 WDWB 19 | 6 SXZW => 5 FJFL 20 | 6 GVGZ => 6 ZPFBH 21 | 1 JPGK, 3 WDFXH, 22 FJFL => 7 BDSB 22 | 3 WHMLV => 4 JPGK 23 | 7 CGZL, 4 LRBN => 8 MTWG 24 | 11 SXZW, 33 ZTBFN => 4 XVXCZ 25 | 1 FZVS, 1 TNMC, 7 JPGK => 9 FLHW 26 | 2 XKFZ => 8 CGZL 27 | 5 WHMLV => 8 MQRS 28 | 1 QVSH, 6 TPZDN, 9 JQHCH => 2 BMNJ 29 | 3 CMNH, 10 XKFZ => 2 KQVL 30 | 119 ORE => 9 PSPQ 31 | 1 WGVP, 18 BRJDJ => 9 PHGWC 32 | 110 ORE => 6 NMQN 33 | 13 NMQN, 24 XVXCZ, 9 XHDVT => 6 KQVS 34 | 6 TNMC => 4 DXJKC 35 | 1 XZKTG => 8 WHJKH 36 | 1 KPFLZ, 1 LRBN, 7 KQVS => 9 JBTJ 37 | 1 XKFZ => 8 JVGD 38 | 152 ORE => 7 SXZW 39 | 1 BDWQP => 5 CTXHZ 40 | 2 JVGD, 8 DGMN, 2 MTWG => 6 QVQJ 41 | 1 KQVL => 2 BNVB 42 | 3 DZQJ, 37 MQRS => 4 CRJZ 43 | 1 KQVL, 5 WDFXH => 7 BDWQP 44 | 3 GVGZ => 3 BPVQN 45 | 4 PSPQ, 6 ZTBFN => 1 KPFLZ 46 | 34 FBTG => 9 XZKTG 47 | 14 TNMC, 4 FZVS, 3 MTWG => 9 KZJLT 48 | 157 ORE => 6 GVGZ 49 | 5 JVGD, 11 JPGK => 5 CRCG 50 | 1 SXZW, 1 NMQN => 3 XHDVT 51 | 1 FBTG => 5 JQHCH 52 | 3 WDFXH, 4 FZVS, 9 CGFML => 6 DZQJ 53 | 5 BDWQP, 3 TNVC, 7 SRPD, 1 WDFXH, 3 JQHCH, 4 QVQJ, 5 CRCG, 4 DGMN => 7 XSGP 54 | 1 KPFLZ, 3 TPZDN, 1 SRPD => 6 FBTG 55 | 1 WHMLV, 3 BDSB, 2 JVGD => 9 LCSV 56 | 13 XZKTG => 4 QVSH 57 | 1 XHDVT => 7 XKFZ 58 | 1 CMNH, 1 KQVS, 2 XVXCZ => 6 CGFML 59 | 6 FLHW => 4 BRJDJ 60 | 2 KQVL, 2 WGVP, 7 BMNJ, 11 KQVS, 1 HPNWP, 6 CRJZ => 4 DGJPN 61 | 2 DZQJ, 1 BDSB => 2 DGMN 62 | 1 XVXCZ, 4 MQRS => 3 WDFXH 63 | 5 FLHW, 10 JPGK, 1 XZKTG => 4 QPNTQ 64 | 2 LRBN => 9 FZVS 65 | 149 ORE => 8 ZTBFN 66 | -------------------------------------------------------------------------------- /ocaml/day14/input.txt: -------------------------------------------------------------------------------- 1 | 1 FJFL, 1 BPVQN => 7 CMNH 2 | 6 FJFL, 2 KZJLT, 3 DZQJ => 2 NSPZ 3 | 11 TPZDN => 2 TNMC 4 | 1 NSPZ, 2 KQVL => 2 HPNWP 5 | 3 XHDVT => 9 LRBN 6 | 3 LRBN => 6 TPZDN 7 | 1 KPFLZ, 1 XVXCZ => 6 WHMLV 8 | 1 BDWQP, 1 JPGK, 1 MTWG => 5 GLHWQ 9 | 2 BGLTP, 1 HPNWP, 2 GLHWQ, 9 CRJZ, 22 QVQJ, 3 PHGWC, 1 BDWQP => 3 LKPNB 10 | 4 BDSB => 2 PNSD 11 | 2 BRJDJ, 13 THQR => 2 BGLTP 12 | 1 WHJKH, 2 JBTJ => 6 THQR 13 | 1 JBTJ => 9 WGVP 14 | 10 CTXHZ, 2 DGMN => 5 TNVC 15 | 7 LCSV, 1 LKPNB, 36 CMNH, 1 JZXPH, 20 DGJPN, 3 WDWB, 69 DXJKC, 3 WHJKH, 18 XSGP, 22 CGZL, 2 BNVB, 57 PNSD => 1 FUEL 16 | 13 CRCG, 8 NMQN => 1 JZXPH 17 | 2 FZVS, 2 ZPFBH => 9 SRPD 18 | 1 QPNTQ, 4 QVQJ, 1 XZKTG => 9 WDWB 19 | 6 SXZW => 5 FJFL 20 | 6 GVGZ => 6 ZPFBH 21 | 1 JPGK, 3 WDFXH, 22 FJFL => 7 BDSB 22 | 3 WHMLV => 4 JPGK 23 | 7 CGZL, 4 LRBN => 8 MTWG 24 | 11 SXZW, 33 ZTBFN => 4 XVXCZ 25 | 1 FZVS, 1 TNMC, 7 JPGK => 9 FLHW 26 | 2 XKFZ => 8 CGZL 27 | 5 WHMLV => 8 MQRS 28 | 1 QVSH, 6 TPZDN, 9 JQHCH => 2 BMNJ 29 | 3 CMNH, 10 XKFZ => 2 KQVL 30 | 119 ORE => 9 PSPQ 31 | 1 WGVP, 18 BRJDJ => 9 PHGWC 32 | 110 ORE => 6 NMQN 33 | 13 NMQN, 24 XVXCZ, 9 XHDVT => 6 KQVS 34 | 6 TNMC => 4 DXJKC 35 | 1 XZKTG => 8 WHJKH 36 | 1 KPFLZ, 1 LRBN, 7 KQVS => 9 JBTJ 37 | 1 XKFZ => 8 JVGD 38 | 152 ORE => 7 SXZW 39 | 1 BDWQP => 5 CTXHZ 40 | 2 JVGD, 8 DGMN, 2 MTWG => 6 QVQJ 41 | 1 KQVL => 2 BNVB 42 | 3 DZQJ, 37 MQRS => 4 CRJZ 43 | 1 KQVL, 5 WDFXH => 7 BDWQP 44 | 3 GVGZ => 3 BPVQN 45 | 4 PSPQ, 6 ZTBFN => 1 KPFLZ 46 | 34 FBTG => 9 XZKTG 47 | 14 TNMC, 4 FZVS, 3 MTWG => 9 KZJLT 48 | 157 ORE => 6 GVGZ 49 | 5 JVGD, 11 JPGK => 5 CRCG 50 | 1 SXZW, 1 NMQN => 3 XHDVT 51 | 1 FBTG => 5 JQHCH 52 | 3 WDFXH, 4 FZVS, 9 CGFML => 6 DZQJ 53 | 5 BDWQP, 3 TNVC, 7 SRPD, 1 WDFXH, 3 JQHCH, 4 QVQJ, 5 CRCG, 4 DGMN => 7 XSGP 54 | 1 KPFLZ, 3 TPZDN, 1 SRPD => 6 FBTG 55 | 1 WHMLV, 3 BDSB, 2 JVGD => 9 LCSV 56 | 13 XZKTG => 4 QVSH 57 | 1 XHDVT => 7 XKFZ 58 | 1 CMNH, 1 KQVS, 2 XVXCZ => 6 CGFML 59 | 6 FLHW => 4 BRJDJ 60 | 2 KQVL, 2 WGVP, 7 BMNJ, 11 KQVS, 1 HPNWP, 6 CRJZ => 4 DGJPN 61 | 2 DZQJ, 1 BDSB => 2 DGMN 62 | 1 XVXCZ, 4 MQRS => 3 WDFXH 63 | 5 FLHW, 10 JPGK, 1 XZKTG => 4 QPNTQ 64 | 2 LRBN => 9 FZVS 65 | 149 ORE => 8 ZTBFN 66 | -------------------------------------------------------------------------------- /day22/input.txt: -------------------------------------------------------------------------------- 1 | deal with increment 66 2 | cut -2068 3 | deal with increment 8 4 | cut -6565 5 | deal with increment 22 6 | cut -8629 7 | deal with increment 56 8 | cut -697 9 | deal with increment 58 10 | cut 4957 11 | deal with increment 71 12 | cut -4506 13 | deal with increment 39 14 | cut 6144 15 | deal with increment 48 16 | cut 1392 17 | deal with increment 51 18 | cut -8043 19 | deal with increment 30 20 | cut 7798 21 | deal with increment 25 22 | deal into new stack 23 | deal with increment 43 24 | cut 1048 25 | deal with increment 63 26 | cut 257 27 | deal into new stack 28 | deal with increment 15 29 | deal into new stack 30 | deal with increment 12 31 | deal into new stack 32 | cut 3316 33 | deal with increment 68 34 | cut -4495 35 | deal with increment 4 36 | cut -421 37 | deal with increment 11 38 | cut 7629 39 | deal with increment 32 40 | cut -3956 41 | deal with increment 33 42 | cut -596 43 | deal with increment 42 44 | cut 8505 45 | deal into new stack 46 | cut 4215 47 | deal with increment 74 48 | cut 9999 49 | deal with increment 7 50 | deal into new stack 51 | deal with increment 71 52 | cut 6836 53 | deal with increment 27 54 | cut 188 55 | deal with increment 45 56 | deal into new stack 57 | deal with increment 17 58 | cut -6659 59 | deal into new stack 60 | cut -8919 61 | deal with increment 23 62 | cut 7758 63 | deal with increment 58 64 | cut -9377 65 | deal with increment 51 66 | cut -8010 67 | deal into new stack 68 | cut -8058 69 | deal with increment 57 70 | deal into new stack 71 | deal with increment 7 72 | cut -1977 73 | deal into new stack 74 | cut -4748 75 | deal with increment 55 76 | cut -2901 77 | deal into new stack 78 | cut 4362 79 | deal with increment 65 80 | cut -4367 81 | deal with increment 51 82 | cut 2133 83 | deal into new stack 84 | deal with increment 15 85 | deal into new stack 86 | deal with increment 28 87 | cut -5331 88 | deal with increment 41 89 | cut -5157 90 | deal with increment 68 91 | cut 4776 92 | deal into new stack 93 | deal with increment 28 94 | cut 2005 95 | deal with increment 14 96 | deal into new stack 97 | cut 1341 98 | deal into new stack 99 | cut 7623 100 | deal with increment 36 101 | -------------------------------------------------------------------------------- /rs/day6/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | use std::collections::HashSet; 3 | use std::error::Error; 4 | use std::iter; 5 | 6 | fn read_orbits(input: &str) -> HashMap<&str, &str> { 7 | let mut orbits = HashMap::new(); 8 | for line in input.trim().lines() { 9 | let mut toks = line.splitn(2, ')'); 10 | let (left, right) = (toks.next().unwrap(), toks.next().unwrap()); 11 | orbits.insert(right, left); 12 | } 13 | orbits 14 | } 15 | 16 | fn count_orbits<'a>( 17 | from: &'a str, 18 | orbits: &HashMap<&'a str, &'a str>, 19 | counts: &mut HashMap<&'a str, i32>, 20 | ) -> i32 { 21 | if let Some(count) = counts.get(from) { 22 | return *count; 23 | } 24 | let count = match orbits.get(from) { 25 | None => 0, 26 | Some(to) => count_orbits(to, orbits, counts) + 1, 27 | }; 28 | counts.insert(from, count); 29 | count 30 | } 31 | 32 | fn count_all_orbits(orbits: &HashMap<&str, &str>) -> i32 { 33 | let mut counts = HashMap::new(); 34 | orbits 35 | .keys() 36 | .map(|from| count_orbits(from, orbits, &mut counts)) 37 | .sum() 38 | } 39 | 40 | fn orbit_path<'a>(from: &'a str, orbits: &HashMap<&str, &'a str>) -> Vec<&'a str> { 41 | match orbits.get(from) { 42 | Some(to) => iter::once(from).chain(orbit_path(to, orbits)).collect(), 43 | None => vec![from], 44 | } 45 | } 46 | 47 | fn dist(from: &str, to: &str, orbits: &HashMap<&str, &str>) -> usize { 48 | let orbit = orbit_path(from, orbits); 49 | let set: HashSet<&str> = orbit_path(from, orbits).iter().copied().collect(); 50 | let (i, parent) = orbit_path(to, orbits) 51 | .iter() 52 | .copied() 53 | .enumerate() 54 | .find(|(_, node)| set.contains(node)) 55 | .unwrap(); 56 | let j = orbit.iter().position(|node| *node == parent).unwrap(); 57 | i + j - 2 58 | } 59 | 60 | fn main() -> Result<(), Box> { 61 | let path = std::env::args().nth(1).ok_or("missing path")?; 62 | let input = std::fs::read_to_string(path)?; 63 | let orbits = read_orbits(&input); 64 | println!("{}", count_all_orbits(&orbits)); 65 | println!("{}", dist("YOU", "SAN", &orbits)); 66 | Ok(()) 67 | } 68 | -------------------------------------------------------------------------------- /day25/day25.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "log" 8 | "os" 9 | 10 | "github.com/dhconnelly/advent-of-code-2019/geom" 11 | "github.com/dhconnelly/advent-of-code-2019/intcode" 12 | ) 13 | 14 | type game struct { 15 | in chan<- int64 16 | out <-chan int64 17 | r *bufio.Scanner 18 | } 19 | 20 | func NewGame(data []int64, r io.Reader) game { 21 | in := make(chan int64) 22 | out := intcode.RunProgram(data, in) 23 | return game{in, out, bufio.NewScanner(r)} 24 | } 25 | 26 | func (g game) readLine() (string, bool) { 27 | var b []byte 28 | var ok bool 29 | var c int64 30 | for c, ok = <-g.out; ok && c != '\n'; c = <-g.out { 31 | b = append(b, byte(c)) 32 | } 33 | if len(b) > 0 { 34 | return string(b), true 35 | } 36 | return "", ok 37 | } 38 | 39 | func (g game) getCommand() (string, bool) { 40 | if g.r.Scan() { 41 | return g.r.Text(), true 42 | } 43 | if err := g.r.Err(); err != nil { 44 | log.Fatalf("failed to read command: %s", err) 45 | } 46 | return "", false 47 | } 48 | 49 | func (g game) writeLine(line string) { 50 | for _, c := range line { 51 | g.in <- int64(c) 52 | } 53 | g.in <- '\n' 54 | } 55 | 56 | var commandToDir = map[string]geom.Direction{ 57 | "north": geom.Up, 58 | "south": geom.Down, 59 | "west": geom.Left, 60 | "east": geom.Right, 61 | } 62 | 63 | func isDir(line string) bool { 64 | for cmd := range commandToDir { 65 | if cmd == line { 66 | return true 67 | } 68 | } 69 | return false 70 | } 71 | 72 | func (g game) loop() { 73 | for { 74 | line, ok := g.readLine() 75 | if !ok { 76 | fmt.Println("machine halted; exiting") 77 | return 78 | } 79 | if line != prompt { 80 | fmt.Println(line) 81 | continue 82 | } 83 | fmt.Println(prompt) 84 | cmd, ok := g.getCommand() 85 | if !ok { 86 | fmt.Println("no more commands; exiting") 87 | return 88 | } 89 | g.writeLine(cmd) 90 | } 91 | } 92 | 93 | const ( 94 | prompt = "Command?" 95 | ) 96 | 97 | func main() { 98 | data, err := intcode.ReadProgram(os.Args[1]) 99 | if err != nil { 100 | log.Fatal(err) 101 | } 102 | g := NewGame(data, os.Stdin) 103 | g.loop() 104 | } 105 | -------------------------------------------------------------------------------- /day12/day12_part1.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "log" 7 | "os" 8 | 9 | "github.com/dhconnelly/advent-of-code-2019/geom" 10 | ) 11 | 12 | type moon struct { 13 | p, v geom.Pt3 14 | } 15 | 16 | func readPoints(path string) []moon { 17 | f, err := os.Open(path) 18 | if err != nil { 19 | log.Fatal(err) 20 | } 21 | defer f.Close() 22 | scan := bufio.NewScanner(f) 23 | var ms []moon 24 | var m moon 25 | for scan.Scan() { 26 | line := scan.Text() 27 | _, err = fmt.Sscanf( 28 | line, "", 29 | &m.p.X, &m.p.Y, &m.p.Z, 30 | ) 31 | if err != nil { 32 | log.Fatalf("bad point: %s", err) 33 | } 34 | ms = append(ms, m) 35 | } 36 | if err = scan.Err(); err != nil { 37 | log.Fatal(err) 38 | } 39 | return ms 40 | } 41 | 42 | func applyGravityPair(m1, m2 *moon) { 43 | if m1.p.X < m2.p.X { 44 | m1.v.X, m2.v.X = m1.v.X+1, m2.v.X-1 45 | } else if m1.p.X > m2.p.X { 46 | m1.v.X, m2.v.X = m1.v.X-1, m2.v.X+1 47 | } 48 | 49 | if m1.p.Y < m2.p.Y { 50 | m1.v.Y, m2.v.Y = m1.v.Y+1, m2.v.Y-1 51 | } else if m1.p.Y > m2.p.Y { 52 | m1.v.Y, m2.v.Y = m1.v.Y-1, m2.v.Y+1 53 | } 54 | 55 | if m1.p.Z < m2.p.Z { 56 | m1.v.Z, m2.v.Z = m1.v.Z+1, m2.v.Z-1 57 | } else if m1.p.Z > m2.p.Z { 58 | m1.v.Z, m2.v.Z = m1.v.Z-1, m2.v.Z+1 59 | } 60 | } 61 | 62 | func applyGravity(ms []moon) { 63 | for i := 0; i < len(ms)-1; i++ { 64 | for j := i + 1; j < len(ms); j++ { 65 | applyGravityPair(&ms[i], &ms[j]) 66 | } 67 | } 68 | } 69 | 70 | func applyVelocity(ms []moon) { 71 | for i := range ms { 72 | ms[i].p.TranslateBy(ms[i].v) 73 | } 74 | } 75 | 76 | func step(ms []moon) { 77 | applyGravity(ms) 78 | applyVelocity(ms) 79 | } 80 | 81 | func simulate(ms []moon, n int) []moon { 82 | ms2 := make([]moon, len(ms)) 83 | copy(ms2, ms) 84 | for i := 0; i < n; i++ { 85 | step(ms2) 86 | } 87 | return ms2 88 | } 89 | 90 | func moonEnergy(m moon) int { 91 | return m.p.ManhattanNorm() * m.v.ManhattanNorm() 92 | } 93 | 94 | func energy(ms []moon) int { 95 | total := 0 96 | for _, m := range ms { 97 | total += moonEnergy(m) 98 | } 99 | return total 100 | } 101 | 102 | func main() { 103 | ms := readPoints(os.Args[1]) 104 | fmt.Println(energy(simulate(ms, 1000))) 105 | } 106 | -------------------------------------------------------------------------------- /day23/day23.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/dhconnelly/advent-of-code-2019/intcode" 9 | ) 10 | 11 | type packet struct { 12 | dest int64 13 | x, y int64 14 | } 15 | 16 | type machine struct { 17 | addr int64 18 | q []packet 19 | in chan<- int64 20 | out <-chan int64 21 | snd chan<- packet 22 | rcv chan packet 23 | last int64 24 | } 25 | 26 | func (m *machine) run() { 27 | for { 28 | if len(m.q) > 0 { 29 | first := m.q[0] 30 | select { 31 | case p := <-m.rcv: 32 | if first.x == -1 { 33 | m.q = m.q[1:] 34 | } 35 | m.q = append(m.q, p) 36 | case dest := <-m.out: 37 | x := <-m.out 38 | y := <-m.out 39 | m.snd <- packet{dest, x, y} 40 | case m.in <- first.x: 41 | m.q = m.q[1:] 42 | if first.x != -1 { 43 | m.in <- first.y 44 | if len(m.q) == 0 { 45 | m.q = append(m.q, packet{x: -1}) 46 | } 47 | } 48 | } 49 | } else { 50 | select { 51 | case p := <-m.rcv: 52 | m.q = append(m.q, p) 53 | case dest := <-m.out: 54 | x := <-m.out 55 | y := <-m.out 56 | m.snd <- packet{dest, x, y} 57 | } 58 | } 59 | } 60 | } 61 | 62 | func newMachine( 63 | addr int64, 64 | prog []int64, 65 | snd chan<- packet, 66 | ) *machine { 67 | in := make(chan int64, 1) 68 | in <- addr 69 | rcv := make(chan packet) 70 | out := intcode.RunProgram(prog, in) 71 | m := &machine{ 72 | addr: addr, 73 | q: []packet{{x: -1}}, 74 | rcv: rcv, 75 | snd: snd, 76 | in: in, 77 | out: out, 78 | } 79 | go m.run() 80 | return m 81 | } 82 | 83 | func machines( 84 | n int, 85 | prog []int64, 86 | out chan<- packet, 87 | ) map[int64]*machine { 88 | ms := make(map[int64]*machine) 89 | for i := int64(0); i < int64(n); i++ { 90 | ms[i] = newMachine(i, prog, out) 91 | } 92 | return ms 93 | } 94 | 95 | func network(n int, prog []int64) int64 { 96 | out := make(chan packet) 97 | ms := machines(n, prog, out) 98 | for p := range out { 99 | fmt.Println(p) 100 | if p.dest == 255 { 101 | return p.y 102 | } 103 | ms[p.dest].rcv <- p 104 | } 105 | log.Fatal("network failed") 106 | return 0 107 | } 108 | 109 | func main() { 110 | prog, err := intcode.ReadProgram(os.Args[1]) 111 | if err != nil { 112 | log.Fatal(err) 113 | } 114 | fmt.Println(network(50, prog)) 115 | } 116 | -------------------------------------------------------------------------------- /day5/input.txt: -------------------------------------------------------------------------------- 1 | 3,225,1,225,6,6,1100,1,238,225,104,0,1102,79,14,225,1101,17,42,225,2,74,69,224,1001,224,-5733,224,4,224,1002,223,8,223,101,4,224,224,1,223,224,223,1002,191,83,224,1001,224,-2407,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1101,18,64,225,1102,63,22,225,1101,31,91,225,1001,65,26,224,101,-44,224,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,101,78,13,224,101,-157,224,224,4,224,1002,223,8,223,1001,224,3,224,1,224,223,223,102,87,187,224,101,-4698,224,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,1102,79,85,224,101,-6715,224,224,4,224,1002,223,8,223,1001,224,2,224,1,224,223,223,1101,43,46,224,101,-89,224,224,4,224,1002,223,8,223,101,1,224,224,1,223,224,223,1101,54,12,225,1102,29,54,225,1,17,217,224,101,-37,224,224,4,224,102,8,223,223,1001,224,3,224,1,223,224,223,1102,20,53,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,107,226,226,224,1002,223,2,223,1006,224,329,101,1,223,223,1108,677,226,224,1002,223,2,223,1006,224,344,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,359,101,1,223,223,108,226,226,224,1002,223,2,223,1005,224,374,101,1,223,223,8,226,677,224,1002,223,2,223,1006,224,389,101,1,223,223,1108,226,226,224,102,2,223,223,1006,224,404,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,419,101,1,223,223,8,677,677,224,1002,223,2,223,1005,224,434,1001,223,1,223,1008,226,226,224,102,2,223,223,1005,224,449,1001,223,1,223,1008,226,677,224,102,2,223,223,1006,224,464,101,1,223,223,1107,677,677,224,102,2,223,223,1006,224,479,101,1,223,223,107,677,677,224,1002,223,2,223,1005,224,494,1001,223,1,223,1107,226,677,224,1002,223,2,223,1005,224,509,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,524,101,1,223,223,7,226,226,224,1002,223,2,223,1005,224,539,101,1,223,223,108,677,677,224,1002,223,2,223,1005,224,554,101,1,223,223,8,677,226,224,1002,223,2,223,1005,224,569,1001,223,1,223,1008,677,677,224,102,2,223,223,1006,224,584,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,599,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,614,101,1,223,223,1007,226,226,224,1002,223,2,223,1005,224,629,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,644,101,1,223,223,108,226,677,224,102,2,223,223,1006,224,659,101,1,223,223,1007,677,226,224,102,2,223,223,1006,224,674,101,1,223,223,4,223,99,226 2 | -------------------------------------------------------------------------------- /ocaml/day5/input.txt: -------------------------------------------------------------------------------- 1 | 3,225,1,225,6,6,1100,1,238,225,104,0,1102,79,14,225,1101,17,42,225,2,74,69,224,1001,224,-5733,224,4,224,1002,223,8,223,101,4,224,224,1,223,224,223,1002,191,83,224,1001,224,-2407,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1101,18,64,225,1102,63,22,225,1101,31,91,225,1001,65,26,224,101,-44,224,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,101,78,13,224,101,-157,224,224,4,224,1002,223,8,223,1001,224,3,224,1,224,223,223,102,87,187,224,101,-4698,224,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,1102,79,85,224,101,-6715,224,224,4,224,1002,223,8,223,1001,224,2,224,1,224,223,223,1101,43,46,224,101,-89,224,224,4,224,1002,223,8,223,101,1,224,224,1,223,224,223,1101,54,12,225,1102,29,54,225,1,17,217,224,101,-37,224,224,4,224,102,8,223,223,1001,224,3,224,1,223,224,223,1102,20,53,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,107,226,226,224,1002,223,2,223,1006,224,329,101,1,223,223,1108,677,226,224,1002,223,2,223,1006,224,344,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,359,101,1,223,223,108,226,226,224,1002,223,2,223,1005,224,374,101,1,223,223,8,226,677,224,1002,223,2,223,1006,224,389,101,1,223,223,1108,226,226,224,102,2,223,223,1006,224,404,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,419,101,1,223,223,8,677,677,224,1002,223,2,223,1005,224,434,1001,223,1,223,1008,226,226,224,102,2,223,223,1005,224,449,1001,223,1,223,1008,226,677,224,102,2,223,223,1006,224,464,101,1,223,223,1107,677,677,224,102,2,223,223,1006,224,479,101,1,223,223,107,677,677,224,1002,223,2,223,1005,224,494,1001,223,1,223,1107,226,677,224,1002,223,2,223,1005,224,509,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,524,101,1,223,223,7,226,226,224,1002,223,2,223,1005,224,539,101,1,223,223,108,677,677,224,1002,223,2,223,1005,224,554,101,1,223,223,8,677,226,224,1002,223,2,223,1005,224,569,1001,223,1,223,1008,677,677,224,102,2,223,223,1006,224,584,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,599,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,614,101,1,223,223,1007,226,226,224,1002,223,2,223,1005,224,629,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,644,101,1,223,223,108,226,677,224,102,2,223,223,1006,224,659,101,1,223,223,1007,677,226,224,102,2,223,223,1006,224,674,101,1,223,223,4,223,99,226 2 | -------------------------------------------------------------------------------- /rs/day5/input.txt: -------------------------------------------------------------------------------- 1 | 3,225,1,225,6,6,1100,1,238,225,104,0,1102,79,14,225,1101,17,42,225,2,74,69,224,1001,224,-5733,224,4,224,1002,223,8,223,101,4,224,224,1,223,224,223,1002,191,83,224,1001,224,-2407,224,4,224,102,8,223,223,101,2,224,224,1,223,224,223,1101,18,64,225,1102,63,22,225,1101,31,91,225,1001,65,26,224,101,-44,224,224,4,224,102,8,223,223,101,3,224,224,1,224,223,223,101,78,13,224,101,-157,224,224,4,224,1002,223,8,223,1001,224,3,224,1,224,223,223,102,87,187,224,101,-4698,224,224,4,224,102,8,223,223,1001,224,4,224,1,223,224,223,1102,79,85,224,101,-6715,224,224,4,224,1002,223,8,223,1001,224,2,224,1,224,223,223,1101,43,46,224,101,-89,224,224,4,224,1002,223,8,223,101,1,224,224,1,223,224,223,1101,54,12,225,1102,29,54,225,1,17,217,224,101,-37,224,224,4,224,102,8,223,223,1001,224,3,224,1,223,224,223,1102,20,53,225,4,223,99,0,0,0,677,0,0,0,0,0,0,0,0,0,0,0,1105,0,99999,1105,227,247,1105,1,99999,1005,227,99999,1005,0,256,1105,1,99999,1106,227,99999,1106,0,265,1105,1,99999,1006,0,99999,1006,227,274,1105,1,99999,1105,1,280,1105,1,99999,1,225,225,225,1101,294,0,0,105,1,0,1105,1,99999,1106,0,300,1105,1,99999,1,225,225,225,1101,314,0,0,106,0,0,1105,1,99999,107,226,226,224,1002,223,2,223,1006,224,329,101,1,223,223,1108,677,226,224,1002,223,2,223,1006,224,344,101,1,223,223,7,677,226,224,102,2,223,223,1006,224,359,101,1,223,223,108,226,226,224,1002,223,2,223,1005,224,374,101,1,223,223,8,226,677,224,1002,223,2,223,1006,224,389,101,1,223,223,1108,226,226,224,102,2,223,223,1006,224,404,101,1,223,223,1007,677,677,224,1002,223,2,223,1006,224,419,101,1,223,223,8,677,677,224,1002,223,2,223,1005,224,434,1001,223,1,223,1008,226,226,224,102,2,223,223,1005,224,449,1001,223,1,223,1008,226,677,224,102,2,223,223,1006,224,464,101,1,223,223,1107,677,677,224,102,2,223,223,1006,224,479,101,1,223,223,107,677,677,224,1002,223,2,223,1005,224,494,1001,223,1,223,1107,226,677,224,1002,223,2,223,1005,224,509,101,1,223,223,1108,226,677,224,102,2,223,223,1006,224,524,101,1,223,223,7,226,226,224,1002,223,2,223,1005,224,539,101,1,223,223,108,677,677,224,1002,223,2,223,1005,224,554,101,1,223,223,8,677,226,224,1002,223,2,223,1005,224,569,1001,223,1,223,1008,677,677,224,102,2,223,223,1006,224,584,101,1,223,223,107,226,677,224,102,2,223,223,1005,224,599,1001,223,1,223,7,226,677,224,102,2,223,223,1005,224,614,101,1,223,223,1007,226,226,224,1002,223,2,223,1005,224,629,101,1,223,223,1107,677,226,224,1002,223,2,223,1006,224,644,101,1,223,223,108,226,677,224,102,2,223,223,1006,224,659,101,1,223,223,1007,677,226,224,102,2,223,223,1006,224,674,101,1,223,223,4,223,99,226 2 | -------------------------------------------------------------------------------- /day8/day8.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "log" 7 | "os" 8 | ) 9 | 10 | type image struct { 11 | width, height int 12 | layers [][]byte 13 | } 14 | 15 | func readImage(path string, width, height int) image { 16 | f, err := os.Open(path) 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | defer f.Close() 21 | img := image{width, height, [][]byte{{}}} 22 | b := make([]byte, 1) 23 | for { 24 | n, err := f.Read(b) 25 | if n == 1 && b[0] != '\n' { 26 | if len(img.layers[len(img.layers)-1]) == width*height { 27 | img.layers = append(img.layers, []byte{}) 28 | } 29 | i := len(img.layers) - 1 30 | img.layers[i] = append(img.layers[i], b[0]-'0') 31 | } else if err == io.EOF { 32 | break 33 | } else if err != nil { 34 | log.Fatal(err) 35 | } 36 | } 37 | return img 38 | } 39 | 40 | func zeroes(pixels []byte) int { 41 | n := 0 42 | for _, p := range pixels { 43 | if p == 0 { 44 | n++ 45 | } 46 | } 47 | return n 48 | } 49 | 50 | func layerChecksum(pixels []byte) int { 51 | ones, twos := 0, 0 52 | for _, p := range pixels { 53 | switch p { 54 | case 1: 55 | ones++ 56 | case 2: 57 | twos++ 58 | } 59 | } 60 | return ones * twos 61 | } 62 | 63 | func checksum(img image) int { 64 | fewestLayer := img.layers[0] 65 | fewestZeroes := zeroes(fewestLayer) 66 | x := layerChecksum(fewestLayer) 67 | for _, layer := range img.layers[1:] { 68 | if z := zeroes(layer); z < fewestZeroes { 69 | fewestZeroes = z 70 | fewestLayer = layer 71 | x = layerChecksum(layer) 72 | } 73 | } 74 | return x 75 | } 76 | 77 | func apply(base, layer []byte) { 78 | for i := 0; i < len(base); i++ { 79 | if layerPix := layer[i]; layerPix != 2 { 80 | base[i] = layerPix 81 | } 82 | } 83 | } 84 | 85 | func decode(img image) []byte { 86 | b := make([]byte, img.width*img.height) 87 | for i := len(img.layers) - 1; i >= 0; i-- { 88 | apply(b, img.layers[i]) 89 | } 90 | return b 91 | } 92 | 93 | func printImage(b []byte, width, height int) { 94 | for i := 0; i < height; i++ { 95 | for j := 0; j < width; j++ { 96 | pix := b[i*width+j] 97 | if pix == 0 { 98 | fmt.Printf(" ") 99 | } else { 100 | fmt.Printf("%d", b[i*width+j]) 101 | } 102 | } 103 | fmt.Println() 104 | } 105 | } 106 | 107 | func main() { 108 | img := readImage(os.Args[1], 25, 6) 109 | fmt.Println(checksum(img)) 110 | printImage(decode(img), 25, 6) 111 | } 112 | -------------------------------------------------------------------------------- /c/hash.c: -------------------------------------------------------------------------------- 1 | #include "hash.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void init_table(hashtable* table) { 8 | table->size = 0; 9 | for (int i = 0; i < HASHSIZE; i++) table->table[i] = NULL; 10 | } 11 | 12 | hashtable make_table(void) { 13 | hashtable table; 14 | init_table(&table); 15 | return table; 16 | } 17 | 18 | hashtable* new_table(void) { 19 | hashtable* table = malloc(sizeof(hashtable)); 20 | init_table(table); 21 | return table; 22 | } 23 | 24 | void fill_table(hashtable* table, int64_t arr[], int len) { 25 | init_table(table); 26 | for (int i = 0; i < len; i++) table_set(table, i, arr[i]); 27 | } 28 | 29 | void table_copy(hashtable* into, const hashtable* from) { 30 | init_table(into); 31 | // TODO: optimize if needed by just cloning the lists instead of instering 32 | for (int i = 0; i < HASHSIZE; i++) { 33 | for (const hashnode* node = from->table[i]; node != NULL; 34 | node = node->next) { 35 | table_set(into, node->key, node->val); 36 | } 37 | } 38 | } 39 | 40 | static uint16_t hash(uint64_t key) { 41 | uint16_t idx; 42 | for (idx = 0; key != 0; key /= 10) idx = (key % 10) + 31 * idx; 43 | return idx % HASHSIZE; 44 | } 45 | 46 | int64_t* table_get(const hashtable* table, uint64_t key) { 47 | for (hashnode* node = table->table[hash(key)]; node != NULL; 48 | node = node->next) { 49 | if (node->key == key) { 50 | return &node->val; 51 | } 52 | } 53 | return NULL; 54 | } 55 | 56 | void table_set(hashtable* table, uint64_t key, int64_t val) { 57 | hashnode** node; 58 | for (node = &table->table[hash(key)]; *node != NULL && (*node)->key != key; 59 | node = &(*node)->next) 60 | ; 61 | if (*node == NULL) { 62 | *node = malloc(sizeof(hashnode)); 63 | (*node)->key = key; 64 | (*node)->val = val; 65 | (*node)->next = NULL; 66 | table->size++; 67 | } else { 68 | assert((*node)->key == key); 69 | (*node)->val = val; 70 | } 71 | } 72 | 73 | int table_size(hashtable* table) { return table->size; } 74 | 75 | uint64_t* table_keys(hashtable* table) { 76 | uint64_t* keys = malloc(table->size * sizeof(uint64_t)); 77 | int i = 0; 78 | for (int bucket = 0; bucket < HASHSIZE; bucket++) { 79 | for (hashnode* node = table->table[bucket]; node != NULL; 80 | node = node->next) { 81 | keys[i++] = node->key; 82 | } 83 | } 84 | return keys; 85 | } 86 | -------------------------------------------------------------------------------- /day11/day11.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/dhconnelly/advent-of-code-2019/geom" 6 | "github.com/dhconnelly/advent-of-code-2019/intcode" 7 | "github.com/dhconnelly/advent-of-code-2019/ints" 8 | "log" 9 | "math" 10 | "os" 11 | ) 12 | 13 | type color int64 14 | 15 | const ( 16 | BLACK color = iota 17 | WHITE 18 | ) 19 | 20 | type direction int64 21 | 22 | const ( 23 | TURN_LEFT direction = iota 24 | TURN_RIGHT 25 | ) 26 | 27 | type orientation rune 28 | 29 | const ( 30 | LEFT orientation = iota 31 | UP 32 | RIGHT 33 | DOWN 34 | ) 35 | 36 | func turn(cur orientation, dir direction) orientation { 37 | switch dir { 38 | case TURN_LEFT: 39 | if cur == LEFT { 40 | return DOWN 41 | } 42 | return cur - 1 43 | case TURN_RIGHT: 44 | return (cur + 1) % 4 45 | } 46 | log.Fatalf("bad dir: %d", dir) 47 | return -1 48 | } 49 | 50 | var diffs = map[orientation]geom.Pt2{ 51 | LEFT: geom.Pt2{-1, 0}, 52 | UP: geom.Pt2{0, 1}, 53 | RIGHT: geom.Pt2{1, 0}, 54 | DOWN: geom.Pt2{0, -1}, 55 | } 56 | 57 | func move(cur geom.Pt2, o orientation) geom.Pt2 { 58 | return cur.Add(diffs[o]) 59 | } 60 | 61 | type grid map[geom.Pt2]color 62 | 63 | func run(data []int64, initial color) grid { 64 | in := make(chan int64) 65 | out := intcode.RunProgram(data, in) 66 | g := grid(make(map[geom.Pt2]color)) 67 | p := geom.Zero2 68 | g[p] = initial 69 | o := UP 70 | loop: 71 | for { 72 | select { 73 | case c, ok := <-out: 74 | if !ok { 75 | break loop 76 | } 77 | g[p] = color(c) 78 | dir := direction(<-out) 79 | o = turn(o, dir) 80 | p = move(p, o) 81 | case in <- int64(g[p]): 82 | } 83 | } 84 | return g 85 | } 86 | 87 | func printGrid(g grid) { 88 | minX, minY := math.MaxInt64, math.MaxInt64 89 | maxX, maxY := math.MinInt64, math.MinInt64 90 | for p, _ := range g { 91 | minX, maxX = ints.Min(minX, p.X), ints.Max(maxX, p.X) 92 | minY, maxY = ints.Min(minY, p.Y), ints.Max(maxY, p.Y) 93 | } 94 | for row := maxY; row >= minY; row-- { 95 | for col := minX; col <= maxX; col++ { 96 | p := geom.Pt2{col, row} 97 | switch g[p] { 98 | case BLACK: 99 | fmt.Print(" ") 100 | case WHITE: 101 | fmt.Print("X") 102 | } 103 | } 104 | fmt.Println() 105 | } 106 | } 107 | 108 | func main() { 109 | data, err := intcode.ReadProgram(os.Args[1]) 110 | if err != nil { 111 | log.Fatal(err) 112 | } 113 | g := run(data, BLACK) 114 | fmt.Println(len(g)) 115 | g = run(data, WHITE) 116 | printGrid(g) 117 | } 118 | -------------------------------------------------------------------------------- /day16/day16.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "os" 9 | "strconv" 10 | 11 | "github.com/dhconnelly/advent-of-code-2019/ints" 12 | ) 13 | 14 | func parseVec(b []byte) []int { 15 | v := make([]int, len(b)) 16 | for i, a := range b { 17 | v[i] = int(a - '0') 18 | } 19 | return v 20 | } 21 | 22 | func coef(row, col int) int { 23 | switch (col / row) % 4 { 24 | case 0: 25 | return 0 26 | case 1: 27 | return 1 28 | case 2: 29 | return 0 30 | default: 31 | return -1 32 | } 33 | } 34 | 35 | func copied(data []int) []int { 36 | data2 := make([]int, len(data)) 37 | copy(data2, data) 38 | return data2 39 | } 40 | 41 | func fft(signal []int, phases int) []int { 42 | signal = copied(signal) 43 | scratch := make([]int, len(signal)) 44 | for ; phases > 0; phases-- { 45 | for i := 0; i < len(signal); i++ { 46 | sum := 0 47 | for j := 0; j < len(signal); j++ { 48 | sum += coef(i+1, j+1) * signal[j] 49 | } 50 | scratch[i] = ints.Abs(sum) % 10 51 | } 52 | signal, scratch = scratch, signal 53 | } 54 | return signal 55 | } 56 | 57 | func toSignal(signal []int) string { 58 | b := make([]byte, len(signal)) 59 | for i, v := range signal { 60 | b[i] = byte(v + '0') 61 | } 62 | return string(b) 63 | } 64 | 65 | func offset(b []byte) int { 66 | i, err := strconv.Atoi(string(b[:7])) 67 | if err != nil { 68 | log.Fatal(err) 69 | } 70 | return i 71 | } 72 | 73 | func sliceSignal(signal []int, from, to int) []int { 74 | sliced := make([]int, to-from) 75 | for i := range sliced { 76 | sliced[i] = signal[(from+i)%len(signal)] 77 | } 78 | return sliced 79 | } 80 | 81 | func extractMessage(signal []int, reps, phases, offset, digits int) []int { 82 | msg := sliceSignal(signal, offset, len(signal)*reps) 83 | n := len(msg) 84 | 85 | // for offset >= len(signal)/2, coef(i) = 0 for i < offset/2 and 1 for 86 | // i >= offset/2 87 | if offset < len(signal)*reps/2 { 88 | log.Fatal("offset too great:", offset) 89 | } 90 | 91 | for ; phases > 0; phases-- { 92 | sum := 0 93 | for i := n - 1; i >= 0; i-- { 94 | sum += msg[i] 95 | msg[i] = ints.Abs(sum) % 10 96 | } 97 | } 98 | 99 | return msg[:digits] 100 | } 101 | 102 | func main() { 103 | txt, err := ioutil.ReadFile(os.Args[1]) 104 | if err != nil { 105 | log.Fatal(err) 106 | } 107 | v := parseVec(bytes.TrimSpace(txt)) 108 | i := offset(txt) 109 | 110 | const digits = 8 111 | const phases = 100 112 | const reps = 10000 113 | 114 | fmt.Println(toSignal(fft(v, phases)[:digits])) 115 | fmt.Println(toSignal(extractMessage(v, reps, phases, i, digits))) 116 | } 117 | -------------------------------------------------------------------------------- /day12/day12_both.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "github.com/dhconnelly/advent-of-code-2019/ints" 7 | "log" 8 | "os" 9 | ) 10 | 11 | type state struct { 12 | px, py, pz, vx, vy, vz [4]int64 13 | } 14 | 15 | func readState(path string) state { 16 | f, err := os.Open(path) 17 | if err != nil { 18 | log.Fatal(err) 19 | } 20 | defer f.Close() 21 | scan := bufio.NewScanner(f) 22 | var s state 23 | i := 0 24 | for scan.Scan() { 25 | line := scan.Text() 26 | _, err = fmt.Sscanf( 27 | line, "", 28 | &s.px[i], &s.py[i], &s.pz[i], 29 | ) 30 | if err != nil { 31 | log.Fatalf("bad point: %s", err) 32 | } 33 | i++ 34 | } 35 | if i > 4 { 36 | log.Fatalf("bad number of moons: %d", i) 37 | } 38 | if err = scan.Err(); err != nil { 39 | log.Fatal(err) 40 | } 41 | return s 42 | } 43 | 44 | func applyGravity(px, vx *[4]int64) { 45 | for i := 0; i < len(px)-1; i++ { 46 | for j := i + 1; j < len(px); j++ { 47 | if px[i] < px[j] { 48 | vx[i] += 1 49 | vx[j] -= 1 50 | } else if px[i] > px[j] { 51 | vx[i] -= 1 52 | vx[j] += 1 53 | } 54 | } 55 | } 56 | } 57 | 58 | func applyVelocity(px, vx *[4]int64) { 59 | for i := range px { 60 | px[i] += vx[i] 61 | } 62 | } 63 | 64 | func step(px, vx *[4]int64) { 65 | applyGravity(px, vx) 66 | applyVelocity(px, vx) 67 | } 68 | 69 | func simulate(s state, n int) state { 70 | for i := 0; i < n; i++ { 71 | step(&s.px, &s.vx) 72 | step(&s.py, &s.vy) 73 | step(&s.pz, &s.vz) 74 | } 75 | return s 76 | } 77 | 78 | func energy(s state) int64 { 79 | e := int64(0) 80 | for i := 0; i < len(s.px); i++ { 81 | pe := ints.Abs64(s.px[i]) 82 | pe += ints.Abs64(s.py[i]) 83 | pe += ints.Abs64(s.pz[i]) 84 | ke := ints.Abs64(s.vx[i]) 85 | ke += ints.Abs64(s.vy[i]) 86 | ke += ints.Abs64(s.vz[i]) 87 | e += pe * ke 88 | } 89 | return e 90 | } 91 | 92 | func lcm(a, b, c int64) int64 { 93 | lcm := a * (b / ints.Gcd64(a, b)) 94 | return c * (lcm / ints.Gcd64(lcm, c)) 95 | } 96 | 97 | func findLoopCoord(px, vx [4]int64, ch chan<- int64) { 98 | pi, vi := px, vx 99 | for i := int64(1); ; i++ { 100 | step(&px, &vx) 101 | if px == pi && vx == vi { 102 | ch <- i 103 | return 104 | } 105 | } 106 | } 107 | 108 | func findLoop(s state) int64 { 109 | ch := make(chan int64) 110 | defer close(ch) 111 | go findLoopCoord(s.px, s.vx, ch) 112 | go findLoopCoord(s.py, s.vy, ch) 113 | go findLoopCoord(s.pz, s.vz, ch) 114 | return lcm(<-ch, <-ch, <-ch) 115 | } 116 | 117 | func main() { 118 | s := readState(os.Args[1]) 119 | fmt.Println(energy(simulate(s, 1000))) 120 | fmt.Println(findLoop(s)) 121 | } 122 | -------------------------------------------------------------------------------- /day19/day19.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "os" 7 | 8 | "github.com/dhconnelly/advent-of-code-2019/geom" 9 | "github.com/dhconnelly/advent-of-code-2019/intcode" 10 | "github.com/dhconnelly/advent-of-code-2019/ints" 11 | ) 12 | 13 | type state int64 14 | 15 | const ( 16 | stationary = 0 17 | pulled = 1 18 | ) 19 | 20 | type drone struct { 21 | prog []int64 22 | } 23 | 24 | func (d drone) test(x, y int, debug bool) state { 25 | prog := ints.Copied64(d.prog) 26 | in := make(chan int64) 27 | defer close(in) 28 | out := intcode.Run(prog, in, debug) 29 | in <- int64(x) 30 | in <- int64(y) 31 | return state(<-out) 32 | } 33 | 34 | type beamReadings struct { 35 | x, y, width, height int 36 | m map[geom.Pt2]state 37 | } 38 | 39 | func mapBeamReadings(prog []int64, x, y, width, height int) beamReadings { 40 | d := drone{prog} 41 | m := beamReadings{x, y, width, height, make(map[geom.Pt2]state)} 42 | for j := x; j < x+width; j++ { 43 | for i := y; i < y+height; i++ { 44 | m.m[geom.Pt2{j, i}] = d.test(j, i, false) 45 | } 46 | } 47 | return m 48 | } 49 | 50 | func printBeamReadings(m beamReadings) { 51 | for x := m.x; x < m.x+m.width; x++ { 52 | for y := m.y; y < m.y+m.height; y++ { 53 | switch m.m[geom.Pt2{x, y}] { 54 | case pulled: 55 | fmt.Print("#") 56 | case stationary: 57 | fmt.Print(".") 58 | } 59 | } 60 | fmt.Println() 61 | } 62 | } 63 | 64 | func countBeamReadings(m beamReadings) int { 65 | affected := 0 66 | for _, v := range m.m { 67 | if v == pulled { 68 | affected++ 69 | } 70 | } 71 | return affected 72 | } 73 | 74 | func fastTest(x, y int) bool { 75 | // see asm.txt for how this was determined 76 | return 14*x*y >= ints.Abs(149*x*x-127*y*y) 77 | } 78 | 79 | func testRange(x, y, width, height int) bool { 80 | return (fastTest(x, y) && 81 | fastTest(x+width-1, y) && 82 | fastTest(x, y+height-1) && 83 | fastTest(x+width-1, y+height-1)) 84 | } 85 | 86 | func findRange(fromX, fromY, toX, toY, width, height int) (int, int) { 87 | for x := fromX; x <= toX; x++ { 88 | for y := fromY; y <= toY; y++ { 89 | if testRange(x, y, width, height) { 90 | return x, y 91 | } 92 | } 93 | } 94 | return 0, 0 95 | } 96 | 97 | func main() { 98 | data, err := intcode.ReadProgram(os.Args[1]) 99 | if err != nil { 100 | log.Fatal(err) 101 | } 102 | m := mapBeamReadings(data, 0, 0, 50, 50) 103 | fmt.Println(countBeamReadings(m)) 104 | 105 | // range chosen by dumping the formula in fastTest 106 | // into desmos.com/calculator 107 | x, y := findRange(1500, 1600, 2000, 2200, 100, 100) 108 | fmt.Println(x*10000 + y) 109 | } 110 | -------------------------------------------------------------------------------- /rs/geom/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[derive(Copy, Clone, Debug)] 2 | pub enum Direction { 3 | Up, 4 | Down, 5 | Left, 6 | Right, 7 | } 8 | 9 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] 10 | pub struct Point2 { 11 | pub x: i32, 12 | pub y: i32, 13 | } 14 | 15 | pub const ZERO2: Point2 = Point2 { x: 0, y: 0 }; 16 | 17 | impl Point2 { 18 | pub fn new(x: i32, y: i32) -> Point2 { 19 | Point2 { x, y } 20 | } 21 | 22 | pub fn manhattan_dist(&self, q: &Point2) -> i32 { 23 | (self.x - q.x).abs() + (self.y - q.y).abs() 24 | } 25 | 26 | pub fn manhattan_norm(&self) -> i32 { 27 | self.manhattan_dist(&Point2 { x: 0, y: 0 }) 28 | } 29 | 30 | pub fn go(&self, dir: Direction) -> Point2 { 31 | let mut q = *self; 32 | match dir { 33 | Direction::Up => q.y += 1, 34 | Direction::Down => q.y -= 1, 35 | Direction::Left => q.x -= 1, 36 | Direction::Right => q.x += 1, 37 | } 38 | q 39 | } 40 | 41 | pub fn manhattan_neighbors(&self) -> [Point2; 4] { 42 | [ 43 | self.go(Direction::Up), 44 | self.go(Direction::Down), 45 | self.go(Direction::Left), 46 | self.go(Direction::Right), 47 | ] 48 | } 49 | 50 | pub fn angle_from(&self, q: &Point2) -> f64 { 51 | let x = (self.x - q.x) as f64; 52 | let y = (self.y - q.y) as f64; 53 | y.atan2(x) 54 | } 55 | 56 | pub fn angle_to(&self, q: &Point2) -> f64 { 57 | q.angle_from(self) 58 | } 59 | } 60 | 61 | #[test] 62 | fn manhattan_dist() { 63 | let p = Point2 { x: 4, y: -5 }; 64 | let q = Point2 { x: -10, y: 7 }; 65 | assert_eq!(p.manhattan_dist(&q), 26); 66 | } 67 | 68 | #[test] 69 | fn manhattan_norm() { 70 | let p = Point2 { x: 4, y: -5 }; 71 | assert_eq!(p.manhattan_norm(), 9); 72 | } 73 | 74 | #[test] 75 | fn go() { 76 | let p = Point2 { x: 4, y: -5 }; 77 | assert_eq!(p.go(Direction::Up), Point2 { x: 4, y: -4 }); 78 | assert_eq!(p.go(Direction::Down), Point2 { x: 4, y: -6 }); 79 | assert_eq!(p.go(Direction::Left), Point2 { x: 3, y: -5 }); 80 | assert_eq!(p.go(Direction::Right), Point2 { x: 5, y: -5 }); 81 | } 82 | 83 | #[test] 84 | fn manhattan_neighbors() { 85 | let p = Point2 { x: 4, y: -5 }; 86 | let nbrs = p.manhattan_neighbors(); 87 | for q in nbrs.iter() { 88 | assert_eq!(p.manhattan_dist(q), 1); 89 | } 90 | } 91 | 92 | #[cfg(test)] 93 | use std::f64::consts::PI; 94 | 95 | #[test] 96 | fn angle_from() { 97 | let p = Point2 { x: 1, y: 1 }; 98 | assert_eq!(p.angle_from(&ZERO2), PI / 4.0); 99 | assert_eq!(ZERO2.angle_from(&p), -3.0 * PI / 4.0); 100 | } 101 | -------------------------------------------------------------------------------- /day10/day10_rf.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "log" 8 | "math" 9 | "os" 10 | "sort" 11 | 12 | "github.com/dhconnelly/advent-of-code-2019/geom" 13 | "github.com/dhconnelly/advent-of-code-2019/ints" 14 | ) 15 | 16 | type grid struct { 17 | width, height int 18 | points map[geom.Pt2]bool 19 | } 20 | 21 | func readGrid(path string) grid { 22 | txt, err := ioutil.ReadFile(path) 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | txt = bytes.TrimSpace(txt) 27 | lines := bytes.Split(txt, []byte("\n")) 28 | g := grid{len(lines[0]), len(lines), make(map[geom.Pt2]bool)} 29 | for i, line := range lines { 30 | for j, ch := range line { 31 | if ch == '#' { 32 | g.points[geom.Pt2{j, i}] = true 33 | } 34 | } 35 | } 36 | return g 37 | } 38 | 39 | func angle(dy, dx int) float64 { 40 | g := ints.Abs(ints.Gcd(dx, dy)) 41 | if g == 0 { 42 | return math.NaN() 43 | } 44 | return math.Atan2(float64(dy/g), float64(dx/g)) 45 | } 46 | 47 | func reachable(g grid, from geom.Pt2) map[float64]geom.Pt2 { 48 | ps := make(map[float64]geom.Pt2) 49 | for p1, ok1 := range g.points { 50 | if !ok1 { 51 | continue 52 | } 53 | if p1 == from { 54 | continue 55 | } 56 | s := angle(p1.Y-from.Y, p1.X-from.X) 57 | if p2, ok2 := ps[s]; !ok2 || from.Dist(p1) < from.Dist(p2) { 58 | ps[s] = p1 59 | } 60 | } 61 | return ps 62 | } 63 | 64 | func maxReachable(g grid) (geom.Pt2, int) { 65 | maxPt, max := geom.Zero2, 0 66 | for p, ok := range g.points { 67 | if !ok { 68 | continue 69 | } 70 | to := reachable(g, p) 71 | if l := len(to); l > max { 72 | max, maxPt = l, p 73 | } 74 | } 75 | return maxPt, max 76 | } 77 | 78 | func sortedByAngle(ps map[float64]geom.Pt2) []geom.Pt2 { 79 | sorted := make([]float64, 0, len(ps)) 80 | for a := range ps { 81 | sorted = append(sorted, a) 82 | } 83 | sort.Float64s(sorted) 84 | var j int 85 | for j = 0; j < len(sorted) && sorted[j] < -math.Pi/2.0; j++ { 86 | } 87 | byAngle := make([]geom.Pt2, len(ps)) 88 | for i := 0; i < len(sorted); i++ { 89 | a := sorted[(i+j)%len(sorted)] 90 | byAngle[i] = ps[a] 91 | } 92 | return byAngle 93 | } 94 | 95 | func vaporize(g grid, from geom.Pt2) []geom.Pt2 { 96 | vaporized := make([]geom.Pt2, len(g.points)-1) 97 | for i := 0; i < len(g.points)-1; { 98 | ps := reachable(g, from) 99 | sorted := sortedByAngle(ps) 100 | for _, p := range sorted { 101 | vaporized[i] = p 102 | g.points[p] = false 103 | i++ 104 | } 105 | } 106 | return vaporized 107 | } 108 | 109 | func main() { 110 | g := readGrid(os.Args[1]) 111 | pt, max := maxReachable(g) 112 | winner := vaporize(g, pt)[199] 113 | 114 | fmt.Println(max) 115 | fmt.Println(winner.X*100 + winner.Y) 116 | } 117 | -------------------------------------------------------------------------------- /rs/day3/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashSet; 2 | use std::env; 3 | use std::error::Error; 4 | use std::fs; 5 | 6 | #[derive(Copy, Clone, Debug)] 7 | struct Step { 8 | dir: geom::Direction, 9 | dist: i32, 10 | } 11 | 12 | fn read_path(line: &str) -> Result, String> { 13 | line.split(',') 14 | .map(|tok| { 15 | let dir = match &tok[..1] { 16 | "R" => Ok(geom::Direction::Right), 17 | "L" => Ok(geom::Direction::Left), 18 | "U" => Ok(geom::Direction::Up), 19 | "D" => Ok(geom::Direction::Down), 20 | _ => Err(format!("bad step {} in line {}", tok, line)), 21 | }?; 22 | let dist = tok[1..] 23 | .parse::() 24 | .map_err(|_| format!("bad step {} in line {}", tok, line))?; 25 | Ok(Step { dir, dist }) 26 | }) 27 | .collect() 28 | } 29 | 30 | fn read_paths(input: &str) -> Result>, String> { 31 | input.trim().lines().take(2).map(|l| read_path(l)).collect() 32 | } 33 | 34 | fn read_wire(path: &Vec) -> Vec { 35 | let mut p = geom::ZERO2; 36 | let mut w = Vec::new(); 37 | for step in path { 38 | for i in 0..step.dist { 39 | p = p.go(step.dir); 40 | w.push(p); 41 | } 42 | } 43 | w 44 | } 45 | 46 | fn read_wires(paths: &Vec>) -> Vec> { 47 | paths.iter().map(read_wire).collect() 48 | } 49 | 50 | fn closest_intersect(p1: &Vec, p2: &Vec) -> i32 { 51 | let set: HashSet<&geom::Point2> = p1.iter().collect(); 52 | let mut min_dist = std::i32::MAX; 53 | for p in p2 { 54 | let dist = p.manhattan_norm(); 55 | if set.contains(p) { 56 | if dist < min_dist { 57 | min_dist = dist; 58 | } 59 | } 60 | } 61 | min_dist 62 | } 63 | 64 | fn fastest_intersect(p1: &Vec, p2: &Vec) -> i32 { 65 | let set: HashSet<&geom::Point2> = p1.iter().collect(); 66 | let mut min_dist = std::i32::MAX; 67 | for (i, p) in p2.iter().enumerate() { 68 | if set.contains(p) { 69 | let j = p1.iter().position(|q| q == p).unwrap(); 70 | let dist = (i + j) as i32 + 2; 71 | if dist < min_dist { 72 | min_dist = dist; 73 | } 74 | } 75 | } 76 | min_dist 77 | } 78 | 79 | fn main() -> Result<(), Box> { 80 | let path = env::args().nth(1).ok_or("missing input path")?; 81 | let input = fs::read_to_string(path)?; 82 | let paths = read_paths(&input)?; 83 | let wires = read_wires(&paths); 84 | println!("{}", closest_intersect(&wires[0], &wires[1])); 85 | println!("{}", fastest_intersect(&wires[0], &wires[1])); 86 | Ok(()) 87 | } 88 | -------------------------------------------------------------------------------- /day3/input.txt: -------------------------------------------------------------------------------- 1 | R999,D586,L462,D725,L236,U938,R366,D306,R263,D355,R354,D332,L599,U48,R829,U210,R697,D534,L19,U991,L110,U981,L954,U323,R851,U290,R76,D513,R844,D780,L257,D24,L586,U865,L341,U572,L122,D304,R398,D641,L221,U726,R270,D321,R503,D112,L151,D179,R439,U594,R242,U1,L484,D259,L604,U760,R362,D93,R29,D647,R482,U814,L214,D510,R281,U327,L170,D993,R191,D33,L305,D657,L897,U609,R512,D866,R654,U980,L899,D602,L141,D365,L13,D584,L706,U404,L238,U720,L732,U716,R672,U979,L49,D352,R712,U396,L843,D816,L276,U906,L375,D410,R275,U664,R487,D158,L713,D451,L859,U194,L736,D51,R659,U632,R586,U342,L222,U184,R741,U989,L175,D521,R820,U183,L950,D888,R54,D149,R776,D200,R939,U529,L377,D226,R769,U395,R392,U570,L398,D358,L644,D975,R578,D687,L133,D884,R822,D226,L527,U439,R175,D388,L539,D450,L391,U392,L131,U134,R873,U741,R761,U620,R667,D31,R481,D945,L373,D463,R57,D402,R181,U340,L835,U81,R908,U257,R592,U702,R713,D352,R418,D486,L904,U866,R828,D545,R578,U469,L845,D437,R371,D246,L996,D920,L171,U83,R471,D152,R550,U344,L390,U287,L126,D883,L576,U303,L68,U854,L463,D915,R184,D282,L513,U909,R770,U638,L751,U168,R354,D480,R19,U144,R381,D554,R594,D526,L957,D464,R267,D802,L709,U306,L907,D266,L871,U286,R975,D549,L732,U721,R825,U753,R443,U465,L966,U982,L833,D62,L5,U299,R500,D168,R155,D102,R455,D855,L376,D479,L469,D6,R588,U301,R329,U19,L63,D488,L936,D238,L798,D452,L231,D652,R935,D522,L401,U234,L20,U285,L949,D88,L120,D159,R641,D960,L946,U516,L530,D447,R23,U962,R860,D352,R904,D241,R702,U108,L155,U99,L43,D401,R19 2 | L1008,U23,L793,D944,L109,U830,L103,U255,L391,D574,R433,U468,R800,D831,L39,U8,L410,D467,R655,D287,R550,U467,L627,D529,R361,D865,L755,D895,L148,U110,R593,U567,L646,D89,L133,D552,R576,U228,L119,U734,R591,U680,L163,D498,L394,U884,R217,U46,R684,D499,L522,U373,L322,U347,R48,D459,L692,U569,R267,U296,L949,U915,R599,D113,R770,U322,R304,U920,L880,D257,R915,D672,L950,U209,R601,U663,R461,D514,R415,U82,L396,U233,R606,U500,R70,D696,R945,D686,L405,U176,R728,U562,L710,D35,R707,D931,L857,U792,R337,D490,L963,U731,R909,U532,R375,D990,L154,U660,L17,U32,R593,U529,R136,U835,R717,U255,L93,D295,L473,U608,L109,D858,R719,U207,R60,D36,R790,D382,L684,D233,R988,U625,R410,U804,R552,D578,L440,D749,R653,U362,L900,U549,R790,D870,R672,U503,R343,D343,R738,D270,R494,D527,L182,U654,R933,D594,R447,U933,R4,U364,L309,U967,R648,U537,R990,U203,R584,D474,L852,U736,R305,D781,R774,D92,L398,U207,R472,D664,R369,U807,L474,U588,R339,D536,R305,D506,R516,U772,R177,U450,L211,U850,R777,U483,L595,U104,L916,U548,R256,U173,L27,D167,L574,D288,R569,U192,R771,D98,R432,U165,L651,D524,L582,D698,L393,D152,L280,U461,R573,D771,R833,D409,R991,U996,R780,U617,R63,U563,L844,D63,R15,U634,R643,D124,L147,D583,R716,D28,L799,D59,R819,D723,L43,D975,L755,D635,R118,U325,L969,D445,R374,D797,L821,U118,R962,D643,R127,U267,R768,D50,L343,U80,R281,U575,R618,D718,L74,U146,R242,D547,L492,U71,R826,D483,L402,U953,R184,U707,L973,D550,L593,U281,L652,D247,L254,D60,R908,U581,L731,D634,R286,D186,R9,D983,L181,U262,R241,D674,R463,U238,R600 3 | -------------------------------------------------------------------------------- /rs/day3/input.txt: -------------------------------------------------------------------------------- 1 | R999,D586,L462,D725,L236,U938,R366,D306,R263,D355,R354,D332,L599,U48,R829,U210,R697,D534,L19,U991,L110,U981,L954,U323,R851,U290,R76,D513,R844,D780,L257,D24,L586,U865,L341,U572,L122,D304,R398,D641,L221,U726,R270,D321,R503,D112,L151,D179,R439,U594,R242,U1,L484,D259,L604,U760,R362,D93,R29,D647,R482,U814,L214,D510,R281,U327,L170,D993,R191,D33,L305,D657,L897,U609,R512,D866,R654,U980,L899,D602,L141,D365,L13,D584,L706,U404,L238,U720,L732,U716,R672,U979,L49,D352,R712,U396,L843,D816,L276,U906,L375,D410,R275,U664,R487,D158,L713,D451,L859,U194,L736,D51,R659,U632,R586,U342,L222,U184,R741,U989,L175,D521,R820,U183,L950,D888,R54,D149,R776,D200,R939,U529,L377,D226,R769,U395,R392,U570,L398,D358,L644,D975,R578,D687,L133,D884,R822,D226,L527,U439,R175,D388,L539,D450,L391,U392,L131,U134,R873,U741,R761,U620,R667,D31,R481,D945,L373,D463,R57,D402,R181,U340,L835,U81,R908,U257,R592,U702,R713,D352,R418,D486,L904,U866,R828,D545,R578,U469,L845,D437,R371,D246,L996,D920,L171,U83,R471,D152,R550,U344,L390,U287,L126,D883,L576,U303,L68,U854,L463,D915,R184,D282,L513,U909,R770,U638,L751,U168,R354,D480,R19,U144,R381,D554,R594,D526,L957,D464,R267,D802,L709,U306,L907,D266,L871,U286,R975,D549,L732,U721,R825,U753,R443,U465,L966,U982,L833,D62,L5,U299,R500,D168,R155,D102,R455,D855,L376,D479,L469,D6,R588,U301,R329,U19,L63,D488,L936,D238,L798,D452,L231,D652,R935,D522,L401,U234,L20,U285,L949,D88,L120,D159,R641,D960,L946,U516,L530,D447,R23,U962,R860,D352,R904,D241,R702,U108,L155,U99,L43,D401,R19 2 | L1008,U23,L793,D944,L109,U830,L103,U255,L391,D574,R433,U468,R800,D831,L39,U8,L410,D467,R655,D287,R550,U467,L627,D529,R361,D865,L755,D895,L148,U110,R593,U567,L646,D89,L133,D552,R576,U228,L119,U734,R591,U680,L163,D498,L394,U884,R217,U46,R684,D499,L522,U373,L322,U347,R48,D459,L692,U569,R267,U296,L949,U915,R599,D113,R770,U322,R304,U920,L880,D257,R915,D672,L950,U209,R601,U663,R461,D514,R415,U82,L396,U233,R606,U500,R70,D696,R945,D686,L405,U176,R728,U562,L710,D35,R707,D931,L857,U792,R337,D490,L963,U731,R909,U532,R375,D990,L154,U660,L17,U32,R593,U529,R136,U835,R717,U255,L93,D295,L473,U608,L109,D858,R719,U207,R60,D36,R790,D382,L684,D233,R988,U625,R410,U804,R552,D578,L440,D749,R653,U362,L900,U549,R790,D870,R672,U503,R343,D343,R738,D270,R494,D527,L182,U654,R933,D594,R447,U933,R4,U364,L309,U967,R648,U537,R990,U203,R584,D474,L852,U736,R305,D781,R774,D92,L398,U207,R472,D664,R369,U807,L474,U588,R339,D536,R305,D506,R516,U772,R177,U450,L211,U850,R777,U483,L595,U104,L916,U548,R256,U173,L27,D167,L574,D288,R569,U192,R771,D98,R432,U165,L651,D524,L582,D698,L393,D152,L280,U461,R573,D771,R833,D409,R991,U996,R780,U617,R63,U563,L844,D63,R15,U634,R643,D124,L147,D583,R716,D28,L799,D59,R819,D723,L43,D975,L755,D635,R118,U325,L969,D445,R374,D797,L821,U118,R962,D643,R127,U267,R768,D50,L343,U80,R281,U575,R618,D718,L74,U146,R242,D547,L492,U71,R826,D483,L402,U953,R184,U707,L973,D550,L593,U281,L652,D247,L254,D60,R908,U581,L731,D634,R286,D186,R9,D983,L181,U262,R241,D674,R463,U238,R600 3 | -------------------------------------------------------------------------------- /day8/day8_gif.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "image" 7 | "image/color" 8 | "image/gif" 9 | "io" 10 | "log" 11 | "os" 12 | ) 13 | 14 | type tileColor int 15 | 16 | const ( 17 | BLACK tileColor = 0 18 | WHITE tileColor = 1 19 | TRANSPARENT tileColor = 2 20 | ) 21 | 22 | const ( 23 | HEIGHT = 6 24 | WIDTH = 25 25 | ) 26 | 27 | type layer [HEIGHT * WIDTH]tileColor 28 | 29 | func readImage(r io.Reader) []layer { 30 | br := bufio.NewReader(r) 31 | var layers []layer 32 | for { 33 | var l layer 34 | for i := 0; i < HEIGHT*WIDTH; i++ { 35 | b, err := br.ReadByte() 36 | if err == io.EOF { 37 | return layers 38 | } 39 | if err != nil { 40 | log.Fatalf("bad color at row,height = %d,%d: %s", err) 41 | } 42 | l[i] = tileColor(b - '0') 43 | } 44 | layers = append(layers, l) 45 | } 46 | return layers 47 | } 48 | 49 | const ( 50 | pixelSize = 5 51 | ) 52 | 53 | var ( 54 | layerRect = image.Rect(0, 0, WIDTH*pixelSize, HEIGHT*pixelSize) 55 | layerPalette = []color.Color{ 56 | color.Black, 57 | color.White, 58 | color.Transparent, 59 | } 60 | ) 61 | 62 | var toColor = map[tileColor]color.Color{ 63 | BLACK: color.Black, 64 | WHITE: color.White, 65 | TRANSPARENT: color.Transparent, 66 | } 67 | 68 | func toPaletted(from *layer) *image.Paletted { 69 | p := image.NewPaletted(layerRect, layerPalette) 70 | for i := 0; i < HEIGHT; i++ { 71 | for j := 0; j < WIDTH; j++ { 72 | p.Set(j, i, toColor[from[i*WIDTH+j]]) 73 | } 74 | } 75 | return p 76 | } 77 | 78 | func apply(to, from *layer) { 79 | for i := 0; i < HEIGHT*WIDTH; i++ { 80 | if c := from[i]; c != TRANSPARENT { 81 | to[i] = c 82 | } 83 | } 84 | } 85 | 86 | func flattenLayers(ls []layer) { 87 | prev := &ls[len(ls)-1] 88 | for i := len(ls) - 2; i >= 0; i-- { 89 | next := &ls[i] 90 | apply(prev, next) 91 | next = prev 92 | } 93 | } 94 | 95 | func printLayer(l *layer) { 96 | for i := 0; i < HEIGHT; i++ { 97 | for j := 0; j < WIDTH; j++ { 98 | switch c := l[i*WIDTH+j]; c { 99 | case BLACK: 100 | fmt.Print(" ") 101 | default: 102 | fmt.Printf("%d", c) 103 | } 104 | } 105 | fmt.Println() 106 | } 107 | } 108 | 109 | func main() { 110 | in, err := os.Open(os.Args[1]) 111 | if err != nil { 112 | log.Fatal(err) 113 | } 114 | defer in.Close() 115 | 116 | out, err := os.Create(os.Args[2]) 117 | if err != nil { 118 | log.Fatal(err) 119 | } 120 | defer out.Close() 121 | 122 | m := readImage(in) 123 | flattenLayers(m) 124 | final := &m[len(m)-1] 125 | if err := gif.Encode(out, toPaletted(final), nil); err != nil { 126 | log.Fatal(err) 127 | } 128 | printLayer(final) 129 | //g := toGif(img) 130 | //if err := gif.EncodeAll(out, g); err != nil { 131 | //log.Fatal(err) 132 | //} 133 | } 134 | -------------------------------------------------------------------------------- /day14/day14.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "log" 8 | "os" 9 | "strings" 10 | 11 | "github.com/dhconnelly/advent-of-code-2019/ints" 12 | ) 13 | 14 | type quant struct { 15 | amt int 16 | chem string 17 | } 18 | 19 | type reaction struct { 20 | out quant 21 | ins []quant 22 | } 23 | 24 | func readQuant(s string) quant { 25 | var q quant 26 | _, err := fmt.Sscanf(s, "%d %s", &q.amt, &q.chem) 27 | if err != nil { 28 | log.Fatalf("failed to read quant %s: %s", s, err) 29 | } 30 | return q 31 | } 32 | 33 | func readReactions(r io.Reader) map[string]reaction { 34 | scan := bufio.NewScanner(r) 35 | reacts := make(map[string]reaction) 36 | for scan.Scan() { 37 | line := scan.Text() 38 | parts := strings.Split(line, "=>") 39 | out := readQuant(parts[1]) 40 | var ins []quant 41 | for _, tok := range strings.Split(parts[0], ",") { 42 | ins = append(ins, readQuant(tok)) 43 | } 44 | reacts[out.chem] = reaction{out, ins} 45 | } 46 | if err := scan.Err(); err != nil { 47 | log.Fatal(err) 48 | } 49 | return reacts 50 | } 51 | 52 | func divceil(m, n int) int { 53 | q := m / n 54 | if m%n == 0 { 55 | return q 56 | } 57 | return q + 1 58 | } 59 | 60 | func oreNeeded( 61 | chem string, amt int, 62 | reacts map[string]reaction, 63 | waste map[string]int, 64 | ) int { 65 | if chem == "ORE" { 66 | return amt 67 | } 68 | 69 | // reuse excess production before building more 70 | if avail := waste[chem]; avail > 0 { 71 | reclaimed := ints.Min(amt, avail) 72 | waste[chem] -= reclaimed 73 | amt -= reclaimed 74 | } 75 | if amt == 0 { 76 | return 0 77 | } 78 | 79 | // build as much as necessary and store the excess 80 | react := reacts[chem] 81 | k := 1 82 | if amt > react.out.amt { 83 | k = divceil(amt, react.out.amt) 84 | } 85 | waste[chem] += k*react.out.amt - amt 86 | 87 | // recursively find the ore needed for the ingredients 88 | ore := 0 89 | for _, in := range react.ins { 90 | ore += oreNeeded(in.chem, k*in.amt, reacts, waste) 91 | } 92 | return ore 93 | } 94 | 95 | func maxFuel(ore int, reacts map[string]reaction) int { 96 | lower, upper := 0, ore 97 | for target := upper / 2; lower != target; { 98 | needed := oreNeeded("FUEL", target, reacts, map[string]int{}) 99 | if needed > ore { 100 | upper = target 101 | target = lower + (target-lower)/2 102 | } else if needed < ore { 103 | lower = target 104 | target = target + (upper-target)/2 105 | } else { 106 | return target 107 | } 108 | } 109 | return lower 110 | } 111 | 112 | func main() { 113 | f, err := os.Open(os.Args[1]) 114 | if err != nil { 115 | log.Fatal(err) 116 | } 117 | defer f.Close() 118 | reacts := readReactions(f) 119 | fmt.Println(oreNeeded("FUEL", 1, reacts, map[string]int{})) 120 | fmt.Println(maxFuel(1000000000000, reacts)) 121 | } 122 | -------------------------------------------------------------------------------- /day3/day3.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "log" 7 | "math" 8 | "os" 9 | "strings" 10 | ) 11 | 12 | type vec struct { 13 | dir rune 14 | dist int 15 | } 16 | 17 | type coord struct { 18 | x, y int 19 | } 20 | 21 | func readVecPaths(filePath string) [][]vec { 22 | txt, err := ioutil.ReadFile(filePath) 23 | if err != nil { 24 | log.Fatal(err) 25 | } 26 | lines := strings.TrimSpace(string(txt)) 27 | var vecPaths [][]vec 28 | for _, line := range strings.Split(lines, "\n") { 29 | var vecPath []vec 30 | for _, tok := range strings.Split(line, ",") { 31 | var v vec 32 | _, err := fmt.Sscanf(tok, "%c%d", &v.dir, &v.dist) 33 | if err != nil { 34 | log.Fatalf("failed to parse vec: %s", tok) 35 | } 36 | vecPath = append(vecPath, v) 37 | } 38 | vecPaths = append(vecPaths, vecPath) 39 | } 40 | return vecPaths 41 | } 42 | 43 | func toPath(vecPath []vec) []coord { 44 | var path []coord 45 | var cur coord 46 | for _, v := range vecPath { 47 | var dim *int 48 | d := 0 49 | switch v.dir { 50 | case 'U': 51 | dim = &cur.y 52 | d = +1 53 | case 'D': 54 | dim = &cur.y 55 | d = -1 56 | case 'R': 57 | dim = &cur.x 58 | d = +1 59 | case 'L': 60 | dim = &cur.x 61 | d = -1 62 | default: 63 | log.Fatalf("bad direction: %s", v.dir) 64 | } 65 | for n := v.dist; n > 0; n-- { 66 | *dim += d 67 | path = append(path, cur) 68 | } 69 | } 70 | return path 71 | } 72 | 73 | func findIntersects(coords1, coords2 []coord) []coord { 74 | coords := make(map[coord]bool) 75 | for _, c := range coords1 { 76 | coords[c] = true 77 | } 78 | var intersections []coord 79 | for _, c := range coords2 { 80 | if coords[c] { 81 | intersections = append(intersections, c) 82 | } 83 | } 84 | return intersections 85 | } 86 | 87 | func dist(c coord) int { 88 | return int(math.Abs(float64(c.x)) + math.Abs(float64(c.y))) 89 | } 90 | 91 | func closestIntersect(intersects []coord) int { 92 | var closestDist int 93 | for _, coord := range intersects { 94 | if d := dist(coord); closestDist == 0 || d < closestDist { 95 | closestDist = d 96 | } 97 | } 98 | return closestDist 99 | } 100 | 101 | func stepsTo(to coord, path []coord) int { 102 | for i, cur := range path { 103 | if cur == to { 104 | return i + 1 105 | } 106 | } 107 | return 0 108 | } 109 | 110 | func fastestIntersect(coords []coord, path1, path2 []coord) int { 111 | var speed int 112 | for _, c := range coords { 113 | sum := stepsTo(c, path1) + stepsTo(c, path2) 114 | if speed == 0 || sum < speed { 115 | speed = sum 116 | } 117 | } 118 | return speed 119 | } 120 | 121 | func main() { 122 | vecPaths := readVecPaths(os.Args[1]) 123 | path1, path2 := toPath(vecPaths[0]), toPath(vecPaths[1]) 124 | intersects := findIntersects(path1, path2) 125 | fmt.Println(closestIntersect(intersects)) 126 | fmt.Println(fastestIntersect(intersects, path1, path2)) 127 | } 128 | -------------------------------------------------------------------------------- /c/day13.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "parse.h" 7 | #include "vm.h" 8 | 9 | static int readint(vm* vm) { 10 | assert(vm->state == VM_OUTPUT); 11 | int output = vm->output; 12 | run(vm); 13 | return output; 14 | } 15 | 16 | enum { 17 | TILE_EMPTY = 0, 18 | TILE_WALL, 19 | TILE_BLOCK, 20 | TILE_PADDLE, 21 | TILE_BALL, 22 | }; 23 | 24 | char tile(int of) { 25 | static char tiles[] = { 26 | [TILE_EMPTY] = ' ', // 27 | [TILE_WALL] = '$', // 28 | [TILE_BLOCK] = '#', // 29 | [TILE_PADDLE] = '-', // 30 | [TILE_BALL] = 'o', // 31 | }; 32 | return tiles[of]; 33 | } 34 | 35 | static int part1(int64_t data[], int len) { 36 | vm vm = make_vm(data, len); 37 | run(&vm); 38 | int blocks = 0; 39 | do { 40 | int x = readint(&vm); 41 | int y = readint(&vm); 42 | int c = readint(&vm); 43 | if (c == TILE_BLOCK) blocks++; 44 | } while (vm.state != VM_HALTED); 45 | printf("%d\n", blocks); 46 | return EXIT_SUCCESS; 47 | } 48 | 49 | static void writeint(vm* vm, int val) { 50 | assert(vm->state == VM_INPUT); 51 | vm->input = val; 52 | run(vm); 53 | } 54 | 55 | static int sign(int x) { 56 | if (x < 0) return -1; 57 | if (x > 0) return 1; 58 | return 0; 59 | } 60 | 61 | static int part2(int64_t data[], int len) { 62 | vm vm = make_vm(data, len); 63 | set_mem(&vm, 0, 2); 64 | run(&vm); 65 | int ball_x = -1, paddle_x = -1; 66 | int score = 0; 67 | do { 68 | switch (vm.state) { 69 | case VM_INPUT: 70 | writeint(&vm, ball_x != -1 ? sign(ball_x - paddle_x) : 0); 71 | break; 72 | case VM_OUTPUT: { 73 | int x = readint(&vm); 74 | int y = readint(&vm); 75 | int c = readint(&vm); 76 | if (x == -1 && y == 0) 77 | score = c; 78 | else if (c == TILE_PADDLE) 79 | paddle_x = x; 80 | else if (c == TILE_BALL) 81 | ball_x = x; 82 | break; 83 | } 84 | default: 85 | assert(0); 86 | } 87 | } while (vm.state != VM_HALTED); 88 | printf("%d\n", score); 89 | return EXIT_SUCCESS; 90 | } 91 | 92 | int main(int argc, char* argv[]) { 93 | if (argc != 2) { 94 | fprintf(stderr, "usage: day13 file\n"); 95 | exit(1); 96 | } 97 | 98 | FILE* f = fopen(argv[1], "r"); 99 | if (f == NULL) { 100 | perror("day13"); 101 | exit(1); 102 | } 103 | 104 | int64_t data[4096]; 105 | int len; 106 | if ((len = parse_intcode(f, data, 4096)) < 0) { 107 | perror("day13: failed to parse intcode"); 108 | exit(1); 109 | } 110 | 111 | part1(data, len); 112 | part2(data, len); 113 | } 114 | -------------------------------------------------------------------------------- /ocaml/day5/vm.ml: -------------------------------------------------------------------------------- 1 | type data = (int, int) Hashtbl.t 2 | let copy = Hashtbl.copy 3 | let set x pos data = Hashtbl.replace data pos x 4 | let get pos data = match Hashtbl.find_opt data pos with 5 | | None -> 0 6 | | Some x -> x 7 | 8 | let read ic = 9 | let next_instr () = 10 | try Some (Scanf.bscanf ic "%d%c" (fun i _ -> i)) 11 | with End_of_file -> None 12 | in let rec read_rec () = match next_instr () with 13 | | None -> [] 14 | | Some instr -> instr::read_rec () 15 | in read_rec () |> List.mapi (fun i x -> i, x) 16 | |> List.to_seq |> Hashtbl.of_seq 17 | 18 | type opcode = Add | Mul | Read | Write | JmpIf | JmpNot | Lt | Eq | Halt 19 | type mode = Pos | Imm 20 | type instruction = { op: opcode; modes: mode*mode*mode } 21 | 22 | let parse_mode = function 23 | | 0 -> Pos 24 | | 1 -> Imm 25 | | n -> failwith (Printf.sprintf "invalid mode: %d" n) 26 | 27 | let modes_of x = 28 | let x = x / 100 in 29 | let (m1,m2,m3) = (x mod 10), (x/10 mod 10), (x/100 mod 10) in 30 | (parse_mode m1), (parse_mode m2), (parse_mode m3) 31 | 32 | let decode x = 33 | let modes = modes_of x in 34 | match x mod 100 with 35 | | 1 -> {op=Add; modes} 36 | | 2 -> {op=Mul; modes} 37 | | 3 -> {op=Read; modes} 38 | | 4 -> {op=Write; modes} 39 | | 5 -> {op=JmpIf; modes} 40 | | 6 -> {op=JmpNot; modes} 41 | | 7 -> {op=Lt; modes} 42 | | 8 -> {op=Eq; modes} 43 | | 99 -> {op=Halt; modes} 44 | | o -> failwith (Printf.sprintf "invalid opcode: %d" o) 45 | 46 | type state = Running | Halted | Input | Output 47 | 48 | type vm = { 49 | pc: int; 50 | data: data; 51 | state: state; 52 | input: int; 53 | output: int; 54 | } 55 | 56 | let vm_new data = {pc=0; data=copy data; input=0; output=0; state=Running} 57 | let vm_data vm = vm.data 58 | let vm_state vm = vm.state 59 | let vm_read vm = vm.output 60 | let vm_write x vm = {vm with input=x} 61 | 62 | let ld x md data = match md with 63 | | Pos -> get x data 64 | | Imm -> x 65 | 66 | let store y x md vm = match md with 67 | | Pos -> set y x vm.data 68 | | Imm -> failwith "invalid store in immediate mode" 69 | 70 | let rec step ({pc; data; state} as vm) = 71 | let {op; modes=m1,m2,m3} = get pc data |> decode in 72 | let (a,b,c) = (get (pc+1) data), (get (pc+2) data), (get (pc+3) data) in 73 | let (x,y) = (ld a m1 data), (ld b m2 data) in 74 | if state = Input then ( 75 | store vm.input a m1 vm; 76 | step {vm with pc=pc+2; state=Running} 77 | ) else match op with 78 | | Add -> store (x+y) c m3 vm; {vm with pc=pc+4} 79 | | Mul -> store (x*y) c m3 vm; {vm with pc=pc+4} 80 | | Read -> {vm with state=Input} 81 | | Write -> {vm with pc=pc+2; output=x; state=Output} 82 | | JmpIf -> {vm with pc=if x<>0 then y else pc+3} 83 | | JmpNot -> {vm with pc=if x=0 then y else pc+3} 84 | | Lt -> store (if x store (if x=y then 1 else 0) c m3 vm; {vm with pc=pc+4} 86 | | Halt -> {vm with pc=pc+1; state=Halted} 87 | 88 | let rec run vm = match step vm with 89 | | {state=Running} as vm' -> run vm' 90 | | vm' -> vm' 91 | -------------------------------------------------------------------------------- /day11/day11_gif.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/dhconnelly/advent-of-code-2019/geom" 6 | "github.com/dhconnelly/advent-of-code-2019/intcode" 7 | "github.com/dhconnelly/advent-of-code-2019/ints" 8 | "image" 9 | "image/color" 10 | "image/gif" 11 | "log" 12 | "math" 13 | "os" 14 | ) 15 | 16 | type tileColor int64 17 | 18 | const ( 19 | BLACK tileColor = iota 20 | WHITE 21 | ) 22 | 23 | type direction int64 24 | 25 | const ( 26 | TURN_LEFT direction = iota 27 | TURN_RIGHT 28 | ) 29 | 30 | type orientation rune 31 | 32 | const ( 33 | LEFT orientation = iota 34 | UP 35 | RIGHT 36 | DOWN 37 | ) 38 | 39 | func turn(cur orientation, dir direction) orientation { 40 | switch dir { 41 | case TURN_LEFT: 42 | if cur == LEFT { 43 | return DOWN 44 | } 45 | return cur - 1 46 | case TURN_RIGHT: 47 | return (cur + 1) % 4 48 | } 49 | log.Fatalf("bad dir: %d", dir) 50 | return -1 51 | } 52 | 53 | var diffs = map[orientation]geom.Pt2{ 54 | LEFT: geom.Pt2{-1, 0}, 55 | UP: geom.Pt2{0, 1}, 56 | RIGHT: geom.Pt2{1, 0}, 57 | DOWN: geom.Pt2{0, -1}, 58 | } 59 | 60 | func move(cur geom.Pt2, o orientation) geom.Pt2 { 61 | return cur.Add(diffs[o]) 62 | } 63 | 64 | const ( 65 | tileHeight = 10 66 | tileWidth = 10 67 | ) 68 | 69 | type grid map[geom.Pt2]tileColor 70 | 71 | func (g grid) ColorModel() color.Model { 72 | return color.RGBAModel 73 | } 74 | 75 | func (g grid) Bounds() image.Rectangle { 76 | minX, minY := math.MaxInt64, math.MaxInt64 77 | maxX, maxY := math.MinInt64, math.MinInt64 78 | for p, _ := range g { 79 | minX, minY = ints.Min(minX, p.X), ints.Min(minY, p.Y) 80 | maxX, maxY = ints.Max(maxX, p.X), ints.Max(maxY, p.Y) 81 | } 82 | return image.Rect( 83 | 0, 0, 84 | int((maxX-minX+1)*tileWidth), 85 | int((maxY-minY+1)*tileHeight), 86 | ) 87 | } 88 | 89 | var toColor = map[tileColor]color.Color{ 90 | BLACK: color.Black, 91 | WHITE: color.White, 92 | } 93 | 94 | func (g grid) At(x, y int) color.Color { 95 | p := geom.Pt2{(x / tileWidth), -(y / tileHeight)} 96 | return toColor[g[p]] 97 | } 98 | 99 | func run(data []int64, initial tileColor) grid { 100 | in := make(chan int64) 101 | out := intcode.RunProgram(data, in) 102 | g := grid(make(map[geom.Pt2]tileColor)) 103 | p := geom.Zero2 104 | g[p] = initial 105 | o := UP 106 | loop: 107 | for { 108 | select { 109 | case c, ok := <-out: 110 | if !ok { 111 | break loop 112 | } 113 | g[p] = tileColor(c) 114 | dir := direction(<-out) 115 | o = turn(o, dir) 116 | p = move(p, o) 117 | case in <- int64(g[p]): 118 | } 119 | } 120 | return g 121 | } 122 | 123 | func main() { 124 | data, err := intcode.ReadProgram(os.Args[1]) 125 | if err != nil { 126 | log.Fatal(err) 127 | } 128 | out, err := os.Create(os.Args[2]) 129 | if err != nil { 130 | log.Fatal(err) 131 | } 132 | defer out.Close() 133 | g := run(data, BLACK) 134 | fmt.Println(len(g)) 135 | g = run(data, WHITE) 136 | if err = gif.Encode(out, g, nil); err != nil { 137 | log.Fatal(err) 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /rs/day8/src/main.rs: -------------------------------------------------------------------------------- 1 | const WIDTH: usize = 25; 2 | const HEIGHT: usize = 6; 3 | const LAYER_SIZE: usize = WIDTH * HEIGHT; 4 | 5 | #[derive(Debug)] 6 | struct Layer(Vec); 7 | 8 | #[derive(Debug)] 9 | struct Image(Vec); 10 | 11 | fn read_layer(text: &str) -> Layer { 12 | Layer(text.chars().collect()) 13 | } 14 | 15 | fn read_image(text: &str) -> Image { 16 | let n = text.len() / LAYER_SIZE; 17 | let mut layers = Vec::new(); 18 | for i in 0..n { 19 | let from = i * LAYER_SIZE; 20 | let to = from + LAYER_SIZE; 21 | let layer = read_layer(&text[from..to]); 22 | layers.push(layer); 23 | } 24 | Image(layers) 25 | } 26 | 27 | fn count_elem(chs: &[char], elem: char) -> usize { 28 | chs.iter().filter(|ch| **ch == elem).count() 29 | } 30 | 31 | fn find_layer_fewest_zeroes(img: &Image) -> &Layer { 32 | let zeroes = |chs| count_elem(chs, '0'); 33 | img.0 34 | .iter() 35 | .min_by(|Layer(l1), Layer(l2)| zeroes(&l1).cmp(&zeroes(&l2))) 36 | .unwrap() 37 | } 38 | 39 | fn num1s_times_num2s(layer: &Layer) -> usize { 40 | let ones = |chs| count_elem(chs, '1'); 41 | let twos = |chs| count_elem(chs, '2'); 42 | ones(&layer.0) * twos(&layer.0) 43 | } 44 | 45 | #[derive(Debug, Clone, Copy, PartialEq)] 46 | enum Color { 47 | Black, 48 | White, 49 | Transparent, 50 | } 51 | 52 | impl Color { 53 | fn of(ch: char) -> Color { 54 | match ch { 55 | '0' => Color::Black, 56 | '1' => Color::White, 57 | '2' => Color::Transparent, 58 | ch => panic!("bad color: {}", ch), 59 | } 60 | } 61 | } 62 | 63 | #[derive(Debug)] 64 | struct RenderedImage(Vec); 65 | 66 | impl std::fmt::Display for RenderedImage { 67 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { 68 | for i in 0..HEIGHT { 69 | for j in 0..WIDTH { 70 | let idx = i * WIDTH + j; 71 | match self.0[idx] { 72 | Color::Black => write!(f, "⬛")?, 73 | Color::White => write!(f, "⬜")?, 74 | Color::Transparent => write!(f, " ")?, 75 | } 76 | } 77 | println!(); 78 | } 79 | Ok(()) 80 | } 81 | } 82 | 83 | fn apply_layer(ri: &mut RenderedImage, layer: &Layer) { 84 | assert!(ri.0.len() == layer.0.len()); 85 | for i in 0..ri.0.len() { 86 | let layer_color = Color::of(layer.0[i]); 87 | if layer_color != Color::Transparent { 88 | ri.0[i] = layer_color; 89 | } 90 | } 91 | } 92 | 93 | fn render(img: &Image) -> RenderedImage { 94 | let mut ri = RenderedImage(vec![Color::Transparent; LAYER_SIZE]); 95 | for layer in img.0.iter().rev() { 96 | apply_layer(&mut ri, layer); 97 | } 98 | ri 99 | } 100 | 101 | fn main() { 102 | let path: String = std::env::args().nth(1).unwrap(); 103 | let text: String = std::fs::read_to_string(&path).unwrap(); 104 | let img = read_image(&text); 105 | 106 | println!("{}", num1s_times_num2s(find_layer_fewest_zeroes(&img))); 107 | println!("{}", render(&img)); 108 | } 109 | -------------------------------------------------------------------------------- /breakout/breakout.go: -------------------------------------------------------------------------------- 1 | package breakout 2 | 3 | import ( 4 | "time" 5 | 6 | "github.com/dhconnelly/advent-of-code-2019/geom" 7 | "github.com/dhconnelly/advent-of-code-2019/intcode" 8 | "github.com/gdamore/tcell" 9 | ) 10 | 11 | type TileId int 12 | 13 | const ( 14 | EMPTY TileId = 0 15 | WALL TileId = 1 16 | BLOCK TileId = 2 17 | PADDLE TileId = 3 18 | BALL TileId = 4 19 | ) 20 | 21 | var tileToRune = map[TileId]rune{ 22 | EMPTY: ' ', 23 | WALL: '@', 24 | BLOCK: 'X', 25 | PADDLE: '-', 26 | BALL: 'o', 27 | } 28 | 29 | var backgroundStyle = tcell.StyleDefault.Background(tcell.ColorLightSlateGrey) 30 | 31 | var tileToStyle = map[TileId]tcell.Style{ 32 | EMPTY: backgroundStyle, 33 | WALL: backgroundStyle.Foreground(tcell.ColorNames["black"]), 34 | BLOCK: backgroundStyle.Foreground(tcell.ColorNames["blue"]), 35 | PADDLE: backgroundStyle.Foreground(tcell.ColorNames["red"]), 36 | BALL: backgroundStyle.Foreground(tcell.ColorNames["yellow"]), 37 | } 38 | 39 | type JoystickPos int 40 | 41 | const ( 42 | NEUTRAL JoystickPos = 0 43 | LEFT JoystickPos = -1 44 | RIGHT JoystickPos = 1 45 | ) 46 | 47 | type ScreenTiles map[geom.Pt2]TileId 48 | 49 | type GameState struct { 50 | Joystick JoystickPos 51 | Score int 52 | Tiles ScreenTiles 53 | } 54 | 55 | func draw(screen tcell.Screen, x, y int, tile TileId) { 56 | screen.SetContent(x, y, tileToRune[tile], nil, tileToStyle[tile]) 57 | screen.Show() 58 | } 59 | 60 | func readEvents(screen tcell.Screen) chan *tcell.EventKey { 61 | ch := make(chan *tcell.EventKey) 62 | go func() { 63 | for { 64 | event := screen.PollEvent() 65 | switch e := event.(type) { 66 | case *tcell.EventKey: 67 | ch <- e 68 | } 69 | } 70 | }() 71 | return ch 72 | } 73 | 74 | func Play( 75 | data []int64, 76 | screen tcell.Screen, 77 | frameDelay time.Duration, 78 | joystickInit JoystickPos, 79 | ) (GameState, error) { 80 | in := make(chan int64) 81 | defer close(in) 82 | out := intcode.RunProgram(data, in) 83 | var events chan *tcell.EventKey 84 | if screen != nil { 85 | screen.Clear() 86 | events = readEvents(screen) 87 | } 88 | state := GameState{ 89 | Tiles: ScreenTiles(make(map[geom.Pt2]TileId)), 90 | Joystick: joystickInit, 91 | } 92 | tick := time.Tick(frameDelay) 93 | 94 | loop: 95 | for { 96 | select { 97 | case e := <-events: 98 | switch e.Key() { 99 | case tcell.KeyCtrlC: 100 | break loop 101 | case tcell.KeyLeft: 102 | state.Joystick = LEFT 103 | case tcell.KeyRight: 104 | state.Joystick = RIGHT 105 | } 106 | 107 | case <-tick: 108 | select { 109 | case in <- int64(state.Joystick): 110 | state.Joystick = joystickInit 111 | default: 112 | continue 113 | } 114 | 115 | case x, ok := <-out: 116 | if !ok { 117 | break loop 118 | } 119 | 120 | y, z := <-out, <-out 121 | if x == -1 && y == 0 { 122 | if z > 0 { 123 | state.Score = int(z) 124 | } 125 | } else { 126 | tile := TileId(z) 127 | state.Tiles[geom.Pt2{int(x), int(y)}] = tile 128 | if screen != nil { 129 | draw(screen, int(x), int(y), tile) 130 | } 131 | } 132 | } 133 | } 134 | 135 | return state, nil 136 | } 137 | -------------------------------------------------------------------------------- /ocaml/day9/vm.ml: -------------------------------------------------------------------------------- 1 | module IntMap = Map.Make(Int) 2 | type data = int IntMap.t 3 | let empty = IntMap.empty 4 | let set x pos data = IntMap.add pos x data 5 | let get pos data = match IntMap.find_opt pos data with 6 | | None -> 0 7 | | Some x -> x 8 | 9 | let read ic = 10 | let next_instr () = 11 | try Some (Scanf.bscanf ic "%d%c" (fun i _ -> i)) with End_of_file -> None 12 | in let rec read_rec () = match next_instr () with 13 | | None -> [] 14 | | Some instr -> instr::read_rec () 15 | in read_rec () |> List.mapi (fun i x -> i,x) |> List.to_seq |> IntMap.of_seq 16 | 17 | type opcode = 18 | Add | Mul | Read | Write | JmpIf | JmpNot | Lt | Eq | Halt | AdjRel 19 | type mode = Pos | Imm | Rel 20 | type instruction = { op: opcode; modes: mode*mode*mode } 21 | 22 | let mode_of = function 23 | | 0 -> Pos 24 | | 1 -> Imm 25 | | 2 -> Rel 26 | | n -> failwith (Printf.sprintf "invalid mode: %d" n) 27 | 28 | let modes_of x = 29 | let x = x/100 in 30 | let (a,b,c) = (x mod 10), (x/10 mod 10), (x/100 mod 10) in 31 | (mode_of a), (mode_of b), (mode_of c) 32 | 33 | let decode x = 34 | let op = match x mod 100 with 35 | | 1 -> Add 36 | | 2 -> Mul 37 | | 3 -> Read 38 | | 4 -> Write 39 | | 5 -> JmpIf 40 | | 6 -> JmpNot 41 | | 7 -> Lt 42 | | 8 -> Eq 43 | | 9 -> AdjRel 44 | | 99 -> Halt 45 | | o -> failwith (Printf.sprintf "invalid opcode: %d" o) 46 | in {op; modes=modes_of x} 47 | 48 | type state = Running | Halted | Input | Output 49 | 50 | type vm = { 51 | pc: int; 52 | data: data; 53 | state: state; 54 | input: int; 55 | output: int; 56 | rel: int; 57 | } 58 | 59 | let vm_empty = {pc=0; data=empty; input=0; output=0; state=Halted; rel=0} 60 | let vm_new data = {vm_empty with data=data; state=Running} 61 | let vm_data vm = vm.data 62 | let vm_state vm = vm.state 63 | let vm_read vm = vm.output 64 | let vm_write x vm = {vm with input=x} 65 | let vm_incr n vm = {vm with pc=vm.pc+n} 66 | 67 | let ld x md vm = match md with 68 | | Pos -> get x vm.data 69 | | Imm -> x 70 | | Rel -> get (vm.rel+x) vm.data 71 | 72 | let store a pos md vm = match md with 73 | | Pos -> {vm with data=set a pos vm.data} 74 | | Imm -> failwith "invalid store in immediate mode" 75 | | Rel -> {vm with data=set a (vm.rel+pos) vm.data} 76 | 77 | let rec step ({pc; data; state} as vm) = 78 | let {op; modes=m1,m2,m3} = get pc data |> decode in 79 | let (a,b,c) = (get (pc+1) data), (get (pc+2) data), (get (pc+3) data) in 80 | let (x,y) = (ld a m1 vm), (ld b m2 vm) in 81 | if state = Input then 82 | let vm = store vm.input a m1 vm in 83 | step {vm with pc=pc+2; state=Running} 84 | else match op with 85 | | Add -> store (x+y) c m3 vm |> vm_incr 4 86 | | Mul -> store (x*y) c m3 vm |> vm_incr 4 87 | | Read -> {vm with state=Input} 88 | | Write -> {vm with pc=pc+2; output=x; state=Output} 89 | | JmpIf -> {vm with pc=if x<>0 then y else pc+3} 90 | | JmpNot -> {vm with pc=if x=0 then y else pc+3} 91 | | Lt -> store (if x vm_incr 4 92 | | Eq -> store (if x=y then 1 else 0) c m3 vm |> vm_incr 4 93 | | AdjRel -> {vm with pc=pc+2; rel=vm.rel+x} 94 | | Halt -> {vm with pc=pc+1; state=Halted} 95 | 96 | let rec run vm = match step vm with 97 | | {state=Running} as vm' -> run vm' 98 | | vm' -> vm' 99 | -------------------------------------------------------------------------------- /day15/input.txt: -------------------------------------------------------------------------------- 1 | 3,1033,1008,1033,1,1032,1005,1032,31,1008,1033,2,1032,1005,1032,58,1008,1033,3,1032,1005,1032,81,1008,1033,4,1032,1005,1032,104,99,102,1,1034,1039,102,1,1036,1041,1001,1035,-1,1040,1008,1038,0,1043,102,-1,1043,1032,1,1037,1032,1042,1105,1,124,101,0,1034,1039,1001,1036,0,1041,1001,1035,1,1040,1008,1038,0,1043,1,1037,1038,1042,1105,1,124,1001,1034,-1,1039,1008,1036,0,1041,101,0,1035,1040,1002,1038,1,1043,102,1,1037,1042,1106,0,124,1001,1034,1,1039,1008,1036,0,1041,1002,1035,1,1040,101,0,1038,1043,1002,1037,1,1042,1006,1039,217,1006,1040,217,1008,1039,40,1032,1005,1032,217,1008,1040,40,1032,1005,1032,217,1008,1039,35,1032,1006,1032,165,1008,1040,1,1032,1006,1032,165,1101,0,2,1044,1105,1,224,2,1041,1043,1032,1006,1032,179,1101,1,0,1044,1106,0,224,1,1041,1043,1032,1006,1032,217,1,1042,1043,1032,1001,1032,-1,1032,1002,1032,39,1032,1,1032,1039,1032,101,-1,1032,1032,101,252,1032,211,1007,0,71,1044,1105,1,224,1102,0,1,1044,1106,0,224,1006,1044,247,101,0,1039,1034,101,0,1040,1035,101,0,1041,1036,101,0,1043,1038,1001,1042,0,1037,4,1044,1105,1,0,63,79,32,16,21,23,90,91,50,57,98,31,96,21,59,30,88,68,89,15,28,86,14,75,41,29,86,4,80,51,46,48,68,93,74,17,76,18,32,36,80,2,77,80,9,98,38,82,65,93,76,29,23,89,97,13,75,35,2,91,73,86,69,90,9,78,84,6,16,98,97,91,66,41,99,56,35,78,15,85,67,77,55,96,59,20,88,24,80,48,85,79,92,23,68,67,99,98,96,57,20,32,90,20,6,79,33,97,21,58,90,41,83,83,7,64,14,8,92,59,83,13,96,95,51,89,41,72,51,82,60,34,81,56,77,10,4,14,61,74,94,87,3,86,52,84,92,35,88,28,78,17,57,72,85,67,56,82,83,54,89,33,4,84,3,66,45,85,16,22,74,94,75,57,68,80,86,94,18,27,53,90,72,38,95,34,20,99,98,40,95,93,55,46,7,29,87,32,56,21,98,30,88,95,77,24,73,95,14,85,2,66,73,30,85,8,69,78,75,93,4,76,56,51,89,99,51,94,14,72,39,85,96,98,37,37,75,79,61,73,96,4,97,41,92,68,58,76,29,29,78,97,44,73,67,75,85,18,1,2,9,99,10,98,19,11,73,67,86,1,94,35,29,16,99,27,35,76,42,60,99,43,28,74,11,74,91,81,11,13,91,97,75,80,68,51,81,81,77,51,72,75,59,85,62,83,91,9,20,83,57,61,31,94,80,26,52,93,86,87,78,39,46,74,86,55,24,87,95,16,82,49,75,11,73,92,64,69,43,82,41,50,24,98,8,3,73,77,19,49,99,29,96,35,86,82,60,65,36,92,89,84,69,58,95,31,67,84,44,78,24,80,46,48,98,39,94,10,78,89,95,28,82,41,97,88,23,83,67,42,97,44,78,83,28,29,66,94,45,61,37,79,55,79,30,95,45,47,76,18,84,81,93,29,90,90,86,13,86,18,47,86,87,70,1,92,98,16,70,21,54,85,54,29,73,76,80,59,84,92,16,81,87,33,96,86,29,18,84,42,60,94,67,59,89,26,42,91,42,75,58,95,81,82,38,49,85,52,43,93,90,41,88,85,12,37,77,78,95,35,87,35,35,55,92,72,26,76,19,96,19,87,66,97,81,85,58,58,74,39,74,43,51,90,48,77,56,78,16,81,57,34,95,72,18,6,75,16,61,89,56,59,76,35,18,98,76,5,75,11,86,93,51,94,6,76,84,26,82,10,29,95,74,20,74,78,5,63,14,96,84,54,55,75,85,24,95,72,54,49,92,78,22,95,97,58,70,87,28,41,88,25,75,7,29,95,67,32,82,80,81,41,63,69,56,10,81,75,8,18,94,56,67,18,83,56,64,93,84,60,73,95,13,72,4,96,97,40,77,35,62,78,77,35,73,56,99,40,64,60,90,82,86,52,89,17,21,87,84,19,92,81,92,84,81,67,73,9,26,87,2,11,76,31,72,61,89,11,78,83,67,1,64,97,82,12,73,99,81,68,58,77,15,14,31,91,76,58,17,83,45,54,77,40,47,82,40,72,73,95,10,96,29,77,21,92,87,11,55,93,87,84,8,89,51,24,87,38,97,92,48,99,8,49,78,42,91,78,50,87,89,46,80,83,25,11,74,22,81,39,99,53,93,61,93,65,83,80,35,2,85,27,33,95,24,99,86,23,89,9,26,75,66,81,29,75,20,89,8,97,17,73,63,82,73,90,32,92,68,82,59,93,48,78,67,98,34,91,32,82,73,74,2,77,16,90,61,75,30,92,0,0,21,21,1,10,1,0,0,0,0,0,0 2 | -------------------------------------------------------------------------------- /day9/input.txt: -------------------------------------------------------------------------------- 1 | 1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,3,1,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,22,1012,1101,309,0,1024,1102,1,29,1015,1101,0,30,1014,1101,0,221,1028,1102,24,1,1007,1102,32,1,1006,1102,1,31,1001,1101,0,20,1010,1101,34,0,1003,1102,899,1,1026,1101,304,0,1025,1101,0,1,1021,1101,892,0,1027,1101,0,0,1020,1101,0,484,1023,1101,25,0,1018,1101,0,21,1008,1102,491,1,1022,1102,212,1,1029,1102,1,23,1000,1101,0,26,1009,1102,36,1,1005,1101,27,0,1013,1101,35,0,1019,1101,38,0,1017,1101,0,39,1004,1102,37,1,1002,1102,33,1,1011,1102,28,1,1016,109,1,1208,5,35,63,1005,63,201,1001,64,1,64,1106,0,203,4,187,1002,64,2,64,109,36,2106,0,-9,4,209,1001,64,1,64,1105,1,221,1002,64,2,64,109,-30,2101,0,-4,63,1008,63,34,63,1005,63,247,4,227,1001,64,1,64,1105,1,247,1002,64,2,64,109,1,21108,40,40,8,1005,1016,265,4,253,1106,0,269,1001,64,1,64,1002,64,2,64,109,10,21101,41,0,-7,1008,1011,41,63,1005,63,295,4,275,1001,64,1,64,1105,1,295,1002,64,2,64,109,3,2105,1,3,4,301,1106,0,313,1001,64,1,64,1002,64,2,64,109,-18,2108,38,1,63,1005,63,329,1105,1,335,4,319,1001,64,1,64,1002,64,2,64,109,-11,2108,37,10,63,1005,63,357,4,341,1001,64,1,64,1106,0,357,1002,64,2,64,109,25,21107,42,41,-6,1005,1011,377,1001,64,1,64,1106,0,379,4,363,1002,64,2,64,109,-11,1207,3,25,63,1005,63,395,1105,1,401,4,385,1001,64,1,64,1002,64,2,64,109,-4,1202,0,1,63,1008,63,37,63,1005,63,423,4,407,1105,1,427,1001,64,1,64,1002,64,2,64,109,8,21102,43,1,6,1008,1016,43,63,1005,63,453,4,433,1001,64,1,64,1106,0,453,1002,64,2,64,109,-11,1208,6,36,63,1005,63,471,4,459,1105,1,475,1001,64,1,64,1002,64,2,64,109,21,2105,1,3,1001,64,1,64,1105,1,493,4,481,1002,64,2,64,109,-15,2107,22,3,63,1005,63,513,1001,64,1,64,1106,0,515,4,499,1002,64,2,64,109,-7,2107,35,7,63,1005,63,537,4,521,1001,64,1,64,1105,1,537,1002,64,2,64,109,23,1205,0,551,4,543,1105,1,555,1001,64,1,64,1002,64,2,64,109,-4,21101,44,0,-3,1008,1014,45,63,1005,63,579,1001,64,1,64,1105,1,581,4,561,1002,64,2,64,109,-15,2102,1,3,63,1008,63,33,63,1005,63,601,1106,0,607,4,587,1001,64,1,64,1002,64,2,64,109,23,1205,-5,623,1001,64,1,64,1106,0,625,4,613,1002,64,2,64,109,-7,21102,45,1,-8,1008,1010,43,63,1005,63,645,1105,1,651,4,631,1001,64,1,64,1002,64,2,64,109,-11,2102,1,1,63,1008,63,21,63,1005,63,677,4,657,1001,64,1,64,1106,0,677,1002,64,2,64,109,3,21107,46,47,4,1005,1014,695,4,683,1106,0,699,1001,64,1,64,1002,64,2,64,109,7,21108,47,48,-4,1005,1013,715,1106,0,721,4,705,1001,64,1,64,1002,64,2,64,109,-14,1201,0,0,63,1008,63,32,63,1005,63,741,1106,0,747,4,727,1001,64,1,64,1002,64,2,64,109,4,1201,2,0,63,1008,63,26,63,1005,63,769,4,753,1105,1,773,1001,64,1,64,1002,64,2,64,109,5,1207,-4,22,63,1005,63,795,4,779,1001,64,1,64,1106,0,795,1002,64,2,64,109,2,2101,0,-9,63,1008,63,34,63,1005,63,819,1001,64,1,64,1106,0,821,4,801,1002,64,2,64,109,-11,1202,1,1,63,1008,63,38,63,1005,63,841,1105,1,847,4,827,1001,64,1,64,1002,64,2,64,109,21,1206,-4,865,4,853,1001,64,1,64,1105,1,865,1002,64,2,64,109,3,1206,-6,877,1105,1,883,4,871,1001,64,1,64,1002,64,2,64,109,6,2106,0,-6,1001,64,1,64,1105,1,901,4,889,4,64,99,21101,0,27,1,21101,915,0,0,1106,0,922,21201,1,23692,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21102,942,1,0,1106,0,922,21202,1,1,-1,21201,-2,-3,1,21101,0,957,0,1106,0,922,22201,1,-1,-2,1106,0,968,22102,1,-2,-2,109,-3,2106,0,0 2 | -------------------------------------------------------------------------------- /ocaml/day9/input.txt: -------------------------------------------------------------------------------- 1 | 1102,34463338,34463338,63,1007,63,34463338,63,1005,63,53,1102,3,1,1000,109,988,209,12,9,1000,209,6,209,3,203,0,1008,1000,1,63,1005,63,65,1008,1000,2,63,1005,63,904,1008,1000,0,63,1005,63,58,4,25,104,0,99,4,0,104,0,99,4,17,104,0,99,0,0,1102,1,22,1012,1101,309,0,1024,1102,1,29,1015,1101,0,30,1014,1101,0,221,1028,1102,24,1,1007,1102,32,1,1006,1102,1,31,1001,1101,0,20,1010,1101,34,0,1003,1102,899,1,1026,1101,304,0,1025,1101,0,1,1021,1101,892,0,1027,1101,0,0,1020,1101,0,484,1023,1101,25,0,1018,1101,0,21,1008,1102,491,1,1022,1102,212,1,1029,1102,1,23,1000,1101,0,26,1009,1102,36,1,1005,1101,27,0,1013,1101,35,0,1019,1101,38,0,1017,1101,0,39,1004,1102,37,1,1002,1102,33,1,1011,1102,28,1,1016,109,1,1208,5,35,63,1005,63,201,1001,64,1,64,1106,0,203,4,187,1002,64,2,64,109,36,2106,0,-9,4,209,1001,64,1,64,1105,1,221,1002,64,2,64,109,-30,2101,0,-4,63,1008,63,34,63,1005,63,247,4,227,1001,64,1,64,1105,1,247,1002,64,2,64,109,1,21108,40,40,8,1005,1016,265,4,253,1106,0,269,1001,64,1,64,1002,64,2,64,109,10,21101,41,0,-7,1008,1011,41,63,1005,63,295,4,275,1001,64,1,64,1105,1,295,1002,64,2,64,109,3,2105,1,3,4,301,1106,0,313,1001,64,1,64,1002,64,2,64,109,-18,2108,38,1,63,1005,63,329,1105,1,335,4,319,1001,64,1,64,1002,64,2,64,109,-11,2108,37,10,63,1005,63,357,4,341,1001,64,1,64,1106,0,357,1002,64,2,64,109,25,21107,42,41,-6,1005,1011,377,1001,64,1,64,1106,0,379,4,363,1002,64,2,64,109,-11,1207,3,25,63,1005,63,395,1105,1,401,4,385,1001,64,1,64,1002,64,2,64,109,-4,1202,0,1,63,1008,63,37,63,1005,63,423,4,407,1105,1,427,1001,64,1,64,1002,64,2,64,109,8,21102,43,1,6,1008,1016,43,63,1005,63,453,4,433,1001,64,1,64,1106,0,453,1002,64,2,64,109,-11,1208,6,36,63,1005,63,471,4,459,1105,1,475,1001,64,1,64,1002,64,2,64,109,21,2105,1,3,1001,64,1,64,1105,1,493,4,481,1002,64,2,64,109,-15,2107,22,3,63,1005,63,513,1001,64,1,64,1106,0,515,4,499,1002,64,2,64,109,-7,2107,35,7,63,1005,63,537,4,521,1001,64,1,64,1105,1,537,1002,64,2,64,109,23,1205,0,551,4,543,1105,1,555,1001,64,1,64,1002,64,2,64,109,-4,21101,44,0,-3,1008,1014,45,63,1005,63,579,1001,64,1,64,1105,1,581,4,561,1002,64,2,64,109,-15,2102,1,3,63,1008,63,33,63,1005,63,601,1106,0,607,4,587,1001,64,1,64,1002,64,2,64,109,23,1205,-5,623,1001,64,1,64,1106,0,625,4,613,1002,64,2,64,109,-7,21102,45,1,-8,1008,1010,43,63,1005,63,645,1105,1,651,4,631,1001,64,1,64,1002,64,2,64,109,-11,2102,1,1,63,1008,63,21,63,1005,63,677,4,657,1001,64,1,64,1106,0,677,1002,64,2,64,109,3,21107,46,47,4,1005,1014,695,4,683,1106,0,699,1001,64,1,64,1002,64,2,64,109,7,21108,47,48,-4,1005,1013,715,1106,0,721,4,705,1001,64,1,64,1002,64,2,64,109,-14,1201,0,0,63,1008,63,32,63,1005,63,741,1106,0,747,4,727,1001,64,1,64,1002,64,2,64,109,4,1201,2,0,63,1008,63,26,63,1005,63,769,4,753,1105,1,773,1001,64,1,64,1002,64,2,64,109,5,1207,-4,22,63,1005,63,795,4,779,1001,64,1,64,1106,0,795,1002,64,2,64,109,2,2101,0,-9,63,1008,63,34,63,1005,63,819,1001,64,1,64,1106,0,821,4,801,1002,64,2,64,109,-11,1202,1,1,63,1008,63,38,63,1005,63,841,1105,1,847,4,827,1001,64,1,64,1002,64,2,64,109,21,1206,-4,865,4,853,1001,64,1,64,1105,1,865,1002,64,2,64,109,3,1206,-6,877,1105,1,883,4,871,1001,64,1,64,1002,64,2,64,109,6,2106,0,-6,1001,64,1,64,1105,1,901,4,889,4,64,99,21101,0,27,1,21101,915,0,0,1106,0,922,21201,1,23692,1,204,1,99,109,3,1207,-2,3,63,1005,63,964,21201,-2,-1,1,21102,942,1,0,1106,0,922,21202,1,1,-1,21201,-2,-3,1,21101,0,957,0,1106,0,922,22201,1,-1,-2,1106,0,968,22102,1,-2,-2,109,-3,2106,0,0 2 | --------------------------------------------------------------------------------