├── .editorconfig ├── .gitattributes ├── .github └── FUNDING.yml ├── .gitignore ├── LICENSE ├── README.md ├── day01a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day01b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day02a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day02b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day03a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day03b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day04a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day04b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day05a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day05b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day06a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day06b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day07a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day07b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day08a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day08b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day09a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day09b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day10a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day10b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day11a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day11b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day12a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day12b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day13a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day13b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day14a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day14b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day15a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day15b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day16a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ ├── bits.rs │ └── main.rs ├── day16b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ ├── bits.rs │ └── main.rs ├── day17a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day17b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day18a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day18b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day19a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day19b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day20a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day20b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day21a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day21b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day22a ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs ├── day22b ├── Cargo.lock ├── Cargo.toml ├── input.txt └── src │ └── main.rs └── runner ├── Cargo.lock ├── Cargo.toml └── src ├── bin ├── bench.rs ├── runner-par.rs └── runner.rs └── lib.rs /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [day*/input.txt] 4 | end_of_line = lf 5 | insert_final_newline = false 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Always use LF line ending on our input files 2 | *.txt text eol=lf 3 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # Funding links 2 | github: 3 | - timvisee 4 | custom: 5 | - "https://timvisee.com/donate" 6 | patreon: timvisee 7 | ko_fi: timvisee 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .*.sw[po] 2 | target/ 3 | **/*.rs.bk 4 | .idea/ 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Advent of Code 2021 in Rust 2 | 3 | My [Advent of Code 2021][aoc-2021] solutions in the Rust programming language. 4 | This repository holds a separate Rust project for each day and part. 5 | 6 | I attempt to develop a standalone, elegant, compact and fast solution for each 7 | problem (two each day). 8 | 9 | Previous year I did the same, solving everything in under a second: 10 | 11 | - https://timvisee.com/blog/solving-aoc-2020-in-under-a-second/ 12 | - https://github.com/timvisee/advent-of-code-2020 13 | 14 | ## Timings 15 | 16 | Here is how long each solution runs. All solutions are measured (non 17 | scientifically) in [`bench.rs`](./runner/src/bin/bench.rs) on an 18 | `AMD Ryzen 9 5900X (24) @ 3.7GHz` machine running Linux. 19 | 20 | | | part A | part B | 21 | |:-----------------------------------------------|:------------------------------------|:------------------------------------| 22 | | [day 1](https://adventofcode.com/2021/day/1) | [` 0.025ms`](./day01a/src/main.rs) | [` 0.024ms`](./day01b/src/main.rs) | 23 | | [day 2](https://adventofcode.com/2021/day/2) | [` 0.024ms`](./day02a/src/main.rs) | [` 0.025ms`](./day02b/src/main.rs) | 24 | | [day 3](https://adventofcode.com/2021/day/3) | [` 0.021ms`](./day03a/src/main.rs) | [` 0.023ms`](./day03b/src/main.rs) | 25 | | [day 4](https://adventofcode.com/2021/day/4) | [` 0.075ms`](./day04a/src/main.rs) | [` 0.106ms`](./day04b/src/main.rs) | 26 | | [day 5](https://adventofcode.com/2021/day/5) | [` 0.110ms`](./day05a/src/main.rs) | [` 0.220ms`](./day05b/src/main.rs) | 27 | | [day 6](https://adventofcode.com/2021/day/6) | [` 0.0027ms`](./day06a/src/main.rs) | [` 0.0028ms`](./day06b/src/main.rs) | 28 | | [day 7](https://adventofcode.com/2021/day/7) | [` 0.013ms`](./day07a/src/main.rs) | [` 0.013ms`](./day07b/src/main.rs) | 29 | | [day 8](https://adventofcode.com/2021/day/8) | [` 0.008ms`](./day08a/src/main.rs) | [` 0.026ms`](./day08b/src/main.rs) | 30 | | [day 9](https://adventofcode.com/2021/day/9) | [` 0.012ms`](./day09a/src/main.rs) | [` 0.036ms`](./day09b/src/main.rs) | 31 | | [day 10](https://adventofcode.com/2021/day/10) | [` 0.011ms`](./day10a/src/main.rs) | [` 0.015ms`](./day10b/src/main.rs) | 32 | | [day 11](https://adventofcode.com/2021/day/11) | [` 0.019ms`](./day11a/src/main.rs) | [` 0.039ms`](./day11b/src/main.rs) | 33 | | [day 12](https://adventofcode.com/2021/day/12) | [` 0.015ms`](./day12a/src/main.rs) | [` 0.272ms`](./day12b/src/main.rs) | 34 | | [day 13](https://adventofcode.com/2021/day/13) | [` 0.038ms`](./day13a/src/main.rs) | [` 0.044ms`](./day13b/src/main.rs) | 35 | | [day 14](https://adventofcode.com/2021/day/14) | [` 0.007ms`](./day14a/src/main.rs) | [` 0.008ms`](./day14b/src/main.rs) | 36 | | [day 15](https://adventofcode.com/2021/day/15) | [` 1.05 ms`](./day15a/src/main.rs) | [` 37.7 ms`](./day15b/src/main.rs) | 37 | | [day 16](https://adventofcode.com/2021/day/16) | [` 0.002ms`](./day16a/src/main.rs) | [` 0.007ms`](./day16b/src/main.rs) | 38 | | [day 17](https://adventofcode.com/2021/day/17) | [` 0.0002ms`](./day17a/src/main.rs) | [` 0.095ms`](./day17b/src/main.rs) | 39 | | [day 18](https://adventofcode.com/2021/day/18) | [` 0.141ms`](./day18a/src/main.rs) | [` 2.61 ms`](./day18b/src/main.rs) | 40 | | [day 19](https://adventofcode.com/2021/day/19) | [` 1.03 ms`](./day19a/src/main.rs) | [` 1.03 ms`](./day19b/src/main.rs) | 41 | | [day 20](https://adventofcode.com/2021/day/20) | [` 0.042ms`](./day20a/src/main.rs) | [` 3.10 ms`](./day20b/src/main.rs) | 42 | | [day 21](https://adventofcode.com/2021/day/21) | [` 0.0008ms`](./day21a/src/main.rs) | [` 0.016ms`](./day21b/src/main.rs) | 43 | | [day 22](https://adventofcode.com/2021/day/22) | [` 0.083ms`](./day22a/src/main.rs) | [` 1.74 ms`](./day22b/src/main.rs) | 44 | 45 | | | one-by-one (1 CPU core) | parallel | 46 | |:-------------|:-----------------------------------------|:---------------------------------------------| 47 | | _everything_ | [`50.36 ms`](./runner/src/bin/runner.rs) | [`39.53ms`](./runner/src/bin/runner-par.rs) | 48 | 49 | ## Run solutions 50 | 51 | Each Rust project contains a `input.txt` file, holding the puzzle input. Simply 52 | run the project to see the solution appear. 53 | 54 | ```bash 55 | # Switch to day 1a, and run it 56 | cd day01a 57 | cargo +nightly run --release 58 | 59 | # or run everything in parallel 60 | cd ../runner 61 | cargo +nightly run --release --bin runner-par 62 | 63 | # or benchmark every day 64 | cd ../runner 65 | cargo +nightly run --release --bin bench 66 | ``` 67 | 68 | Some solutions require Rust Nightly, that's why `+nightly` is included. 69 | 70 | ## Other years 71 | 72 | - [2024](https://github.com/timvisee/advent-of-code-2024) 73 | - [2023](https://github.com/timvisee/advent-of-code-2023) 74 | - [2022](https://github.com/timvisee/advent-of-code-2022) 75 | - [2021](https://github.com/timvisee/advent-of-code-2021) _(current)_ 76 | - [2020](https://github.com/timvisee/advent-of-code-2020) 77 | - [2019](https://github.com/timvisee/advent-of-code-2019) 78 | - [2018](https://github.com/timvisee/advent-of-code-2018) 79 | - [2017](https://github.com/timvisee/advent-of-code-2017) 80 | 81 | ## License 82 | 83 | This project is released under the GNU GPL-3.0 license. 84 | Check out the [LICENSE](LICENSE) file for more information. 85 | 86 | [aoc-2021]: https://adventofcode.com/2021 87 | -------------------------------------------------------------------------------- /day01a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day01a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day01a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day01a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day01a/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(array_windows)] 2 | 3 | pub fn main() { 4 | println!( 5 | "{}", 6 | include_str!("../input.txt") 7 | .lines() 8 | .map(|n| n.parse().unwrap()) 9 | .collect::>() 10 | .array_windows() 11 | .filter(|[a, b]| a < b) 12 | .count(), 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /day01b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day01b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day01b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day01b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day01b/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(array_windows)] 2 | 3 | pub fn main() { 4 | println!( 5 | "{}", 6 | include_str!("../input.txt") 7 | .lines() 8 | .map(|n| n.parse().unwrap()) 9 | .collect::>() 10 | .array_windows() 11 | .filter(|[a, _, _, d]| a < d) 12 | .count(), 13 | ); 14 | } 15 | -------------------------------------------------------------------------------- /day02a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day02a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day02a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day02a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day02a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let (f, d) = include_str!("../input.txt") 3 | .lines() 4 | .map(|l| l.split_once(" ").unwrap()) 5 | .fold((0, 0), |(f, d), (k, v)| { 6 | match (k, v.parse::().unwrap()) { 7 | ("forward", v) => (f + v, d), 8 | ("down", v) => (f, d + v), 9 | ("up", v) => (f, d - v), 10 | _ => unreachable!(), 11 | } 12 | }); 13 | 14 | println!("{}", f * d); 15 | } 16 | -------------------------------------------------------------------------------- /day02b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day02b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day02b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day02b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day02b/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let (f, d, _) = include_str!("../input.txt") 3 | .lines() 4 | .map(|l| l.split_once(" ").unwrap()) 5 | .fold((0, 0, 0), |(f, d, a), (k, v)| { 6 | match (k, v.parse::().unwrap()) { 7 | ("forward", v) => (f + v, d + a * v, a), 8 | ("down", v) => (f, d, a + v), 9 | ("up", v) => (f, d, a - v), 10 | _ => unreachable!(), 11 | } 12 | }); 13 | 14 | println!("{}", f * d); 15 | } 16 | -------------------------------------------------------------------------------- /day03a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day03a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day03a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day03a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day03a/src/main.rs: -------------------------------------------------------------------------------- 1 | const WIDTH: usize = 12; 2 | const COUNT: usize = 1000; 3 | 4 | pub fn main() { 5 | let gamma = include_str!("../input.txt") 6 | .lines() 7 | .map(|l| usize::from_str_radix(l, 2).unwrap()) 8 | .fold(vec![0; WIDTH], |count, bits| { 9 | count 10 | .into_iter() 11 | .enumerate() 12 | .map(|(i, n)| n + ((bits & 1 << i) >> i)) 13 | .collect() 14 | }) 15 | .into_iter() 16 | .enumerate() 17 | .map(|(i, b)| ((b >= COUNT / 2) as u32) << i) 18 | .sum::(); 19 | 20 | println!("{}", gamma * (!gamma & ((1 << WIDTH) - 1))); 21 | } 22 | -------------------------------------------------------------------------------- /day03b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day03b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day03b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day03b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day03b/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(drain_filter)] 2 | 3 | const WIDTH: usize = 12; 4 | 5 | pub fn main() { 6 | let nums = include_str!("../input.txt") 7 | .lines() 8 | .map(|l| u32::from_str_radix(l, 2).unwrap()) 9 | .collect::>(); 10 | 11 | let oxy = (0..WIDTH) 12 | .rev() 13 | .scan(nums.clone(), |oxy, i| { 14 | let one = oxy.iter().filter(|n| *n & 1 << i > 0).count() >= (oxy.len() + 1) / 2; 15 | oxy.drain_filter(|n| (*n & 1 << i > 0) != one); 16 | oxy.first().copied() 17 | }) 18 | .last() 19 | .unwrap(); 20 | 21 | let co2 = (0..WIDTH) 22 | .rev() 23 | .scan(nums, |co2, i| { 24 | let one = co2.iter().filter(|n| *n & 1 << i > 0).count() >= (co2.len() + 1) / 2; 25 | co2.drain_filter(|n| (*n & 1 << i > 0) == one); 26 | co2.first().copied() 27 | }) 28 | .last() 29 | .unwrap(); 30 | 31 | println!("{}", oxy * co2); 32 | } 33 | -------------------------------------------------------------------------------- /day04a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "cfg-if" 18 | version = "1.0.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 21 | 22 | [[package]] 23 | name = "day04a" 24 | version = "0.1.0" 25 | dependencies = [ 26 | "hashbrown", 27 | ] 28 | 29 | [[package]] 30 | name = "getrandom" 31 | version = "0.2.3" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" 34 | dependencies = [ 35 | "cfg-if", 36 | "libc", 37 | "wasi", 38 | ] 39 | 40 | [[package]] 41 | name = "hashbrown" 42 | version = "0.11.2" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 45 | dependencies = [ 46 | "ahash", 47 | ] 48 | 49 | [[package]] 50 | name = "libc" 51 | version = "0.2.112" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" 54 | 55 | [[package]] 56 | name = "once_cell" 57 | version = "1.9.0" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" 60 | 61 | [[package]] 62 | name = "version_check" 63 | version = "0.9.3" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 66 | 67 | [[package]] 68 | name = "wasi" 69 | version = "0.10.2+wasi-snapshot-preview1" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 72 | -------------------------------------------------------------------------------- /day04a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day04a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | hashbrown = "0.11" 12 | -------------------------------------------------------------------------------- /day04a/src/main.rs: -------------------------------------------------------------------------------- 1 | use hashbrown::HashMap; 2 | 3 | const ROW: u32 = 0b11111; 4 | const COL: u32 = 0b100001000010000100001; 5 | 6 | pub fn main() { 7 | let (nums, boards) = include_str!("../input.txt").split_once("\n\n").unwrap(); 8 | 9 | let mut boards: Vec<(HashMap, u32)> = boards 10 | .split("\n\n") 11 | .map(|b| { 12 | ( 13 | b.split_ascii_whitespace() 14 | .enumerate() 15 | .map(|(i, n)| (n.parse().unwrap(), i)) 16 | .collect(), 17 | 0, 18 | ) 19 | }) 20 | .collect(); 21 | 22 | let (board, mark, num) = nums 23 | .split(',') 24 | .map(|n| n.parse().unwrap()) 25 | .find_map(|n| { 26 | boards.iter_mut().find_map(|(b, m)| { 27 | b.get(&n) 28 | .map(|i| *m |= 1 << *i) 29 | .filter(|_| (0..5).any(|i| *m >> i & COL == COL || *m >> (i * 5) & ROW == ROW)) 30 | .map(|_| (b.clone(), *m, n)) 31 | }) 32 | }) 33 | .unwrap(); 34 | 35 | println!( 36 | "{}", 37 | board 38 | .into_iter() 39 | .map(|(n, i)| (mark >> i & 1 ^ 1) * n as u32 * num as u32) 40 | .sum::() 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /day04b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "cfg-if" 18 | version = "1.0.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 21 | 22 | [[package]] 23 | name = "day04b" 24 | version = "0.1.0" 25 | dependencies = [ 26 | "hashbrown", 27 | ] 28 | 29 | [[package]] 30 | name = "getrandom" 31 | version = "0.2.3" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" 34 | dependencies = [ 35 | "cfg-if", 36 | "libc", 37 | "wasi", 38 | ] 39 | 40 | [[package]] 41 | name = "hashbrown" 42 | version = "0.11.2" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 45 | dependencies = [ 46 | "ahash", 47 | ] 48 | 49 | [[package]] 50 | name = "libc" 51 | version = "0.2.112" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" 54 | 55 | [[package]] 56 | name = "once_cell" 57 | version = "1.9.0" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" 60 | 61 | [[package]] 62 | name = "version_check" 63 | version = "0.9.3" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 66 | 67 | [[package]] 68 | name = "wasi" 69 | version = "0.10.2+wasi-snapshot-preview1" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 72 | -------------------------------------------------------------------------------- /day04b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day04b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | hashbrown = "0.11" 12 | -------------------------------------------------------------------------------- /day04b/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(drain_filter)] 2 | 3 | use hashbrown::HashMap; 4 | 5 | const ROW: u32 = 0b11111; 6 | const COL: u32 = 0b100001000010000100001; 7 | 8 | pub fn main() { 9 | let (nums, boards) = include_str!("../input.txt").split_once("\n\n").unwrap(); 10 | 11 | let mut boards: Vec<(HashMap, u32)> = boards 12 | .split("\n\n") 13 | .map(|b| { 14 | ( 15 | b.split_ascii_whitespace() 16 | .enumerate() 17 | .map(|(i, n)| (n.parse().unwrap(), i)) 18 | .collect(), 19 | 0, 20 | ) 21 | }) 22 | .collect(); 23 | 24 | let (board, mark, num) = nums 25 | .split(',') 26 | .map(|n| n.parse().unwrap()) 27 | .filter_map(|n| { 28 | boards 29 | .drain_filter(|(b, m)| { 30 | b.get(&n) 31 | .map(|i| *m |= 1 << *i) 32 | .map(|_| (0..5).any(|i| *m >> i & COL == COL || *m >> (i * 5) & ROW == ROW)) 33 | .unwrap_or(false) 34 | }) 35 | .map(|(b, m)| (b, m, n)) 36 | .next() 37 | }) 38 | .last() 39 | .unwrap(); 40 | 41 | println!( 42 | "{}", 43 | board 44 | .into_iter() 45 | .map(|(n, i)| (mark >> i & 1 ^ 1) * n as u32 * num as u32) 46 | .sum::() 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /day05a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "arrayvec" 7 | version = "0.5.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 10 | 11 | [[package]] 12 | name = "atoi" 13 | version = "0.4.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" 16 | dependencies = [ 17 | "num-traits", 18 | ] 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.0.1" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 25 | 26 | [[package]] 27 | name = "bitflags" 28 | version = "1.3.2" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 31 | 32 | [[package]] 33 | name = "bitvec" 34 | version = "0.19.6" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" 37 | dependencies = [ 38 | "funty", 39 | "radium", 40 | "tap", 41 | "wyz", 42 | ] 43 | 44 | [[package]] 45 | name = "cfg-if" 46 | version = "1.0.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 49 | 50 | [[package]] 51 | name = "day05a" 52 | version = "0.1.0" 53 | dependencies = [ 54 | "atoi", 55 | "nom", 56 | ] 57 | 58 | [[package]] 59 | name = "funty" 60 | version = "1.1.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" 63 | 64 | [[package]] 65 | name = "lexical-core" 66 | version = "0.7.6" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" 69 | dependencies = [ 70 | "arrayvec", 71 | "bitflags", 72 | "cfg-if", 73 | "ryu", 74 | "static_assertions", 75 | ] 76 | 77 | [[package]] 78 | name = "memchr" 79 | version = "2.3.4" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" 82 | 83 | [[package]] 84 | name = "nom" 85 | version = "6.2.1" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6" 88 | dependencies = [ 89 | "bitvec", 90 | "funty", 91 | "lexical-core", 92 | "memchr", 93 | "version_check", 94 | ] 95 | 96 | [[package]] 97 | name = "num-traits" 98 | version = "0.2.14" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 101 | dependencies = [ 102 | "autocfg", 103 | ] 104 | 105 | [[package]] 106 | name = "radium" 107 | version = "0.5.3" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" 110 | 111 | [[package]] 112 | name = "ryu" 113 | version = "1.0.6" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" 116 | 117 | [[package]] 118 | name = "static_assertions" 119 | version = "1.1.0" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 122 | 123 | [[package]] 124 | name = "tap" 125 | version = "1.0.1" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 128 | 129 | [[package]] 130 | name = "version_check" 131 | version = "0.9.3" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 134 | 135 | [[package]] 136 | name = "wyz" 137 | version = "0.2.0" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" 140 | -------------------------------------------------------------------------------- /day05a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day05a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | atoi = "0.4" 12 | nom = "6" 13 | -------------------------------------------------------------------------------- /day05a/src/main.rs: -------------------------------------------------------------------------------- 1 | use atoi::atoi; 2 | use nom::*; 3 | 4 | pub fn main() { 5 | let (mut map, mut overlaps) = (vec![0u8; 1000 * 1000], 0); 6 | include_bytes!("../input.txt") 7 | .split(|b| *b == b'\n') 8 | .map(|entry| { 9 | let ((x, y), (xx, yy)) = line(entry).unwrap().1; 10 | (x.min(xx), y.min(yy), x.max(xx), y.max(yy)) 11 | }) 12 | .for_each(|(x, y, xx, yy)| { 13 | let mut mark = |x, y| { 14 | if map[(x + y * 1000) as usize] == 1 { 15 | overlaps += 1; 16 | } 17 | map[(x + y * 1000) as usize] += 1; 18 | }; 19 | if x == xx { 20 | (y..=yy).for_each(|y| mark(x, y)); 21 | } else if y == yy { 22 | (x..=xx).for_each(|x| mark(x, y)); 23 | } 24 | }); 25 | 26 | println!("{}", overlaps); 27 | } 28 | 29 | named!(usize<&[u8], usize>, map_opt!(nom::character::complete::digit1, atoi)); 30 | named!(coord<&[u8], (usize, usize)>, separated_pair!(usize, char!(','), usize)); 31 | named!(line<&[u8], ((usize, usize), (usize, usize))>, separated_pair!(coord, tag!(" -> "), coord)); 32 | -------------------------------------------------------------------------------- /day05b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "arrayvec" 7 | version = "0.5.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 10 | 11 | [[package]] 12 | name = "atoi" 13 | version = "0.4.0" 14 | source = "registry+https://github.com/rust-lang/crates.io-index" 15 | checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" 16 | dependencies = [ 17 | "num-traits", 18 | ] 19 | 20 | [[package]] 21 | name = "autocfg" 22 | version = "1.0.1" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 25 | 26 | [[package]] 27 | name = "bitflags" 28 | version = "1.3.2" 29 | source = "registry+https://github.com/rust-lang/crates.io-index" 30 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 31 | 32 | [[package]] 33 | name = "bitvec" 34 | version = "0.19.6" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | checksum = "55f93d0ef3363c364d5976646a38f04cf67cfe1d4c8d160cdea02cab2c116b33" 37 | dependencies = [ 38 | "funty", 39 | "radium", 40 | "tap", 41 | "wyz", 42 | ] 43 | 44 | [[package]] 45 | name = "cfg-if" 46 | version = "1.0.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 49 | 50 | [[package]] 51 | name = "day05b" 52 | version = "0.1.0" 53 | dependencies = [ 54 | "atoi", 55 | "nom", 56 | ] 57 | 58 | [[package]] 59 | name = "funty" 60 | version = "1.1.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" 63 | 64 | [[package]] 65 | name = "lexical-core" 66 | version = "0.7.6" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" 69 | dependencies = [ 70 | "arrayvec", 71 | "bitflags", 72 | "cfg-if", 73 | "ryu", 74 | "static_assertions", 75 | ] 76 | 77 | [[package]] 78 | name = "memchr" 79 | version = "2.3.4" 80 | source = "registry+https://github.com/rust-lang/crates.io-index" 81 | checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525" 82 | 83 | [[package]] 84 | name = "nom" 85 | version = "6.2.1" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "9c5c51b9083a3c620fa67a2a635d1ce7d95b897e957d6b28ff9a5da960a103a6" 88 | dependencies = [ 89 | "bitvec", 90 | "funty", 91 | "lexical-core", 92 | "memchr", 93 | "version_check", 94 | ] 95 | 96 | [[package]] 97 | name = "num-traits" 98 | version = "0.2.14" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 101 | dependencies = [ 102 | "autocfg", 103 | ] 104 | 105 | [[package]] 106 | name = "radium" 107 | version = "0.5.3" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" 110 | 111 | [[package]] 112 | name = "ryu" 113 | version = "1.0.6" 114 | source = "registry+https://github.com/rust-lang/crates.io-index" 115 | checksum = "3c9613b5a66ab9ba26415184cfc41156594925a9cf3a2057e57f31ff145f6568" 116 | 117 | [[package]] 118 | name = "static_assertions" 119 | version = "1.1.0" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 122 | 123 | [[package]] 124 | name = "tap" 125 | version = "1.0.1" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" 128 | 129 | [[package]] 130 | name = "version_check" 131 | version = "0.9.3" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 134 | 135 | [[package]] 136 | name = "wyz" 137 | version = "0.2.0" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" 140 | -------------------------------------------------------------------------------- /day05b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day05b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | atoi = "0.4" 12 | nom = "6" 13 | -------------------------------------------------------------------------------- /day05b/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(int_abs_diff)] 2 | 3 | use atoi::atoi; 4 | use nom::*; 5 | use std::iter; 6 | 7 | pub fn main() { 8 | let (mut map, mut overlaps) = (vec![0u8; 1000 * 1000], 0); 9 | include_bytes!("../input.txt") 10 | .split(|b| *b == b'\n') 11 | .for_each(|entry| { 12 | let ((x, y), (xx, yy)) = line(entry).unwrap().1; 13 | let range = 14 | |a: isize, b: isize| iter::successors(Some(a), move |n| Some(n + (b - a).signum())); 15 | range(x, xx) 16 | .zip(range(y, yy)) 17 | .take(x.abs_diff(xx).max(y.abs_diff(yy)) + 1) 18 | .for_each(|(x, y)| { 19 | if map[(x + y * 1000) as usize] == 1 { 20 | overlaps += 1; 21 | } 22 | map[(x + y * 1000) as usize] += 1; 23 | }); 24 | }); 25 | 26 | println!("{}", overlaps); 27 | } 28 | 29 | named!(isize<&[u8], isize>, map_opt!(nom::character::complete::digit1, atoi)); 30 | named!(coord<&[u8], (isize, isize)>, separated_pair!(isize, char!(','), isize)); 31 | named!(line<&[u8], ((isize, isize), (isize, isize))>, separated_pair!(coord, tag!(" -> "), coord)); 32 | -------------------------------------------------------------------------------- /day06a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day06a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day06a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day06a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day06a/input.txt: -------------------------------------------------------------------------------- 1 | 1,1,1,1,1,1,1,4,1,2,1,1,4,1,1,1,5,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1,1,3,1,1,2,1,2,1,3,3,4,1,4,1,1,3,1,1,5,1,1,1,1,4,1,1,5,1,1,1,4,1,5,1,1,1,3,1,1,5,3,1,1,1,1,1,4,1,1,1,1,1,2,4,1,1,1,1,4,1,2,2,1,1,1,3,1,2,5,1,4,1,1,1,3,1,1,4,1,1,1,1,1,1,1,4,1,1,4,1,1,1,1,1,1,1,2,1,1,5,1,1,1,4,1,1,5,1,1,5,3,3,5,3,1,1,1,4,1,1,1,1,1,1,5,3,1,2,1,1,1,4,1,3,1,5,1,1,2,1,1,1,1,1,5,1,1,1,1,1,2,1,1,1,1,4,3,2,1,2,4,1,3,1,5,1,2,1,4,1,1,1,1,1,3,1,4,1,1,1,1,3,1,3,3,1,4,3,4,1,1,1,1,5,1,3,3,2,5,3,1,1,3,1,3,1,1,1,1,4,1,1,1,1,3,1,5,1,1,1,4,4,1,1,5,5,2,4,5,1,1,1,1,5,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,5,1,1,1,1,1,1,3,1,1,2,1,1 -------------------------------------------------------------------------------- /day06a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let mut map = include_str!("../input.txt") 3 | .split(',') 4 | .fold([0; 9], |mut map, n| { 5 | map[n.parse::().unwrap()] += 1; 6 | map 7 | }); 8 | 9 | (1..80).for_each(|day| map[(day + 7) % 9] += map[day % 9]); 10 | 11 | println!("{}", map.iter().sum::()); 12 | } 13 | -------------------------------------------------------------------------------- /day06b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day06b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day06b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day06b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day06b/input.txt: -------------------------------------------------------------------------------- 1 | 1,1,1,1,1,1,1,4,1,2,1,1,4,1,1,1,5,1,1,1,1,1,1,1,1,1,1,1,1,5,1,1,1,1,3,1,1,2,1,2,1,3,3,4,1,4,1,1,3,1,1,5,1,1,1,1,4,1,1,5,1,1,1,4,1,5,1,1,1,3,1,1,5,3,1,1,1,1,1,4,1,1,1,1,1,2,4,1,1,1,1,4,1,2,2,1,1,1,3,1,2,5,1,4,1,1,1,3,1,1,4,1,1,1,1,1,1,1,4,1,1,4,1,1,1,1,1,1,1,2,1,1,5,1,1,1,4,1,1,5,1,1,5,3,3,5,3,1,1,1,4,1,1,1,1,1,1,5,3,1,2,1,1,1,4,1,3,1,5,1,1,2,1,1,1,1,1,5,1,1,1,1,1,2,1,1,1,1,4,3,2,1,2,4,1,3,1,5,1,2,1,4,1,1,1,1,1,3,1,4,1,1,1,1,3,1,3,3,1,4,3,4,1,1,1,1,5,1,3,3,2,5,3,1,1,3,1,3,1,1,1,1,4,1,1,1,1,3,1,5,1,1,1,4,4,1,1,5,5,2,4,5,1,1,1,1,5,1,1,2,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1,1,5,1,1,1,1,1,1,3,1,1,2,1,1 -------------------------------------------------------------------------------- /day06b/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let mut map = include_str!("../input.txt") 3 | .split(',') 4 | .fold([0; 9], |mut map, n| { 5 | map[n.parse::().unwrap()] += 1; 6 | map 7 | }); 8 | 9 | (1..256).for_each(|day| map[(day + 7) % 9] += map[day % 9]); 10 | 11 | println!("{}", map.iter().sum::()); 12 | } 13 | -------------------------------------------------------------------------------- /day07a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day07a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day07a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day07a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day07a/input.txt: -------------------------------------------------------------------------------- 1 | 1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,867,253,111,269,117,150,421,508,1073,136,247,10,1427,802,2,492,1302,228,2,48,113,0,741,34,107,559,514,283,372,78,423,405,1303,360,281,1850,367,892,1021,930,318,80,709,349,32,203,94,1359,456,783,62,34,1487,245,294,749,250,1441,8,1388,604,324,483,696,119,294,1478,529,189,454,785,703,13,1099,790,402,251,919,116,318,201,893,571,3,45,756,41,65,92,21,1903,219,32,191,1037,177,480,232,389,1342,1178,1320,955,1020,655,276,203,221,316,689,621,270,911,537,230,327,662,552,410,1608,385,7,26,227,71,1646,257,725,531,413,8,19,1029,182,1518,270,124,113,569,468,126,505,376,367,113,425,4,80,1883,433,1167,768,231,393,528,69,422,17,350,858,1028,659,972,108,542,602,1577,11,1481,127,466,415,567,1178,38,137,777,446,965,832,1347,642,716,176,264,487,32,425,354,104,230,756,310,711,228,580,520,677,781,45,926,1063,126,235,262,199,330,874,1570,221,107,803,810,1723,266,99,940,21,38,1680,44,32,17,907,403,413,628,968,138,12,24,483,114,658,206,24,61,561,882,532,1280,255,805,75,237,321,310,1022,545,1515,609,65,791,933,233,846,506,704,628,516,868,726,134,6,243,1048,227,259,1599,117,114,461,365,63,1559,62,98,884,11,426,915,192,901,4,1481,122,424,307,250,256,693,162,1217,834,516,644,898,396,1073,642,480,361,1434,607,23,818,515,6,288,443,324,4,1559,659,409,415,82,41,1233,657,93,1405,17,94,18,379,32,8,419,1511,766,234,818,916,775,4,1009,282,372,317,371,945,1314,261,485,529,1076,298,223,40,434,401,117,1030,153,2,19,27,41,544,477,1117,588,206,155,12,1197,1518,305,51,921,775,296,1187,57,517,2,36,145,92,67,68,559,771,1,69,250,612,94,1638,1327,501,434,114,6,1468,429,28,1163,207,576,50,1759,216,9,50,432,598,664,1087,409,828,1115,169,120,318,21,1245,314,338,47,469,231,236,892,671,373,991,1136,488,341,168,143,850,1135,42,449,666,814,16,232,505,122,1316,803,1093,977,79,5,936,512,217,942,1333,13,13,1861,2,267,74,1096,1058,107,461,78,418,861,547,25,1398,255,562,344,820,1171,1376,494,17,116,1333,256,20,1425,1668,79,604,1614,223,45,18,917,30,965,866,1331,91,141,1120,829,3,0,498,57,78,1579,467,185,1399,683,590,11,913,33,540,536,459,367,175,176,946,130,324,634,671,554,277,570,968,409,468,419,1249,1039,45,238,4,808,1022,10,151,1158,32,38,1054,969,90,70,1194,1582,512,876,289,1042,91,1872,305,996,349,17,517,968,1493,637,142,141,226,590,181,811,608,4,135,97,389,385,929,1143,1319,684,509,437,133,843,101,118,71,120,80,25,33,259,894,1050,1450,583,1665,372,128,586,282,1147,1160,1643,1488,339,445,268,1577,101,8,308,719,210,288,332,1034,47,1303,31,59,16,270,104,68,1107,736,420,108,367,461,791,279,863,645,2,999,453,682,21,764,244,435,1238,36,1193,37,346,35,70,114,78,67,1245,15,1002,83,450,353,50,396,1068,26,21,429,551,13,498,117,731,601,23,1218,271,26,958,852,139,331,92,560,218,1243,410,109,296,35,588,6,645,87,64,188,497,28,693,18,88,196,62,7,33,311,1102,187,829,664,630,331,304,1249,21,309,1238,64,155,38,134,291,77,90,32,765,332,87,257,755,93,181,174,118,584,98,825,292,428,187,731,813,784,1222,117,345,1380,31,1447,269,672,747,1112,147,32,690,1258,253,763,92,1427,503,4,40,289,41,733,240,884,201,136,594,560,3,1083,1282,686,918,667,1535,702,158,65,1055,100,481,457,1565,1067,641,289,18,1537,62,545,401,1238,528,713,1042,430,144,390,220,953,42,817,18,26,137,1870,999,557,234,586,1316,87,104,369,39,215,595,922,1194,187,1056,382,397,387,872,191,464,1841,883,162,119,38,916,2,676,1524,315,1217,63,382,328,591,372,138,883,733,910,635,1059,87,773,630,1179,169,947,401,20,820,119,575,1117,48,268,45,896,772,293,217,73,732,26,528,1121,382,813,419,424,221,107,145,264,526,589,482,51,1399,954,292,276,248,1276,218,1005,296,360,60,5,499,661,192,199,250,1001,496,281,361,664,248,1090,86,203,241,61,329,1551,182,790,787,408,442,603,681,522,478,1072,527,1094,104,1267,418,730,217,1198,859 -------------------------------------------------------------------------------- /day07a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let mut subs = include_str!("../input.txt") 3 | .split(',') 4 | .map(|n| n.parse().unwrap()) 5 | .collect::>(); 6 | 7 | let mid = subs.len() / 2; 8 | let med = *subs.select_nth_unstable(mid).1; 9 | 10 | println!("{}", subs.iter().map(|n| (n - med).abs()).sum::()); 11 | } 12 | -------------------------------------------------------------------------------- /day07b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day07b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day07b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day07b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day07b/input.txt: -------------------------------------------------------------------------------- 1 | 1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,867,253,111,269,117,150,421,508,1073,136,247,10,1427,802,2,492,1302,228,2,48,113,0,741,34,107,559,514,283,372,78,423,405,1303,360,281,1850,367,892,1021,930,318,80,709,349,32,203,94,1359,456,783,62,34,1487,245,294,749,250,1441,8,1388,604,324,483,696,119,294,1478,529,189,454,785,703,13,1099,790,402,251,919,116,318,201,893,571,3,45,756,41,65,92,21,1903,219,32,191,1037,177,480,232,389,1342,1178,1320,955,1020,655,276,203,221,316,689,621,270,911,537,230,327,662,552,410,1608,385,7,26,227,71,1646,257,725,531,413,8,19,1029,182,1518,270,124,113,569,468,126,505,376,367,113,425,4,80,1883,433,1167,768,231,393,528,69,422,17,350,858,1028,659,972,108,542,602,1577,11,1481,127,466,415,567,1178,38,137,777,446,965,832,1347,642,716,176,264,487,32,425,354,104,230,756,310,711,228,580,520,677,781,45,926,1063,126,235,262,199,330,874,1570,221,107,803,810,1723,266,99,940,21,38,1680,44,32,17,907,403,413,628,968,138,12,24,483,114,658,206,24,61,561,882,532,1280,255,805,75,237,321,310,1022,545,1515,609,65,791,933,233,846,506,704,628,516,868,726,134,6,243,1048,227,259,1599,117,114,461,365,63,1559,62,98,884,11,426,915,192,901,4,1481,122,424,307,250,256,693,162,1217,834,516,644,898,396,1073,642,480,361,1434,607,23,818,515,6,288,443,324,4,1559,659,409,415,82,41,1233,657,93,1405,17,94,18,379,32,8,419,1511,766,234,818,916,775,4,1009,282,372,317,371,945,1314,261,485,529,1076,298,223,40,434,401,117,1030,153,2,19,27,41,544,477,1117,588,206,155,12,1197,1518,305,51,921,775,296,1187,57,517,2,36,145,92,67,68,559,771,1,69,250,612,94,1638,1327,501,434,114,6,1468,429,28,1163,207,576,50,1759,216,9,50,432,598,664,1087,409,828,1115,169,120,318,21,1245,314,338,47,469,231,236,892,671,373,991,1136,488,341,168,143,850,1135,42,449,666,814,16,232,505,122,1316,803,1093,977,79,5,936,512,217,942,1333,13,13,1861,2,267,74,1096,1058,107,461,78,418,861,547,25,1398,255,562,344,820,1171,1376,494,17,116,1333,256,20,1425,1668,79,604,1614,223,45,18,917,30,965,866,1331,91,141,1120,829,3,0,498,57,78,1579,467,185,1399,683,590,11,913,33,540,536,459,367,175,176,946,130,324,634,671,554,277,570,968,409,468,419,1249,1039,45,238,4,808,1022,10,151,1158,32,38,1054,969,90,70,1194,1582,512,876,289,1042,91,1872,305,996,349,17,517,968,1493,637,142,141,226,590,181,811,608,4,135,97,389,385,929,1143,1319,684,509,437,133,843,101,118,71,120,80,25,33,259,894,1050,1450,583,1665,372,128,586,282,1147,1160,1643,1488,339,445,268,1577,101,8,308,719,210,288,332,1034,47,1303,31,59,16,270,104,68,1107,736,420,108,367,461,791,279,863,645,2,999,453,682,21,764,244,435,1238,36,1193,37,346,35,70,114,78,67,1245,15,1002,83,450,353,50,396,1068,26,21,429,551,13,498,117,731,601,23,1218,271,26,958,852,139,331,92,560,218,1243,410,109,296,35,588,6,645,87,64,188,497,28,693,18,88,196,62,7,33,311,1102,187,829,664,630,331,304,1249,21,309,1238,64,155,38,134,291,77,90,32,765,332,87,257,755,93,181,174,118,584,98,825,292,428,187,731,813,784,1222,117,345,1380,31,1447,269,672,747,1112,147,32,690,1258,253,763,92,1427,503,4,40,289,41,733,240,884,201,136,594,560,3,1083,1282,686,918,667,1535,702,158,65,1055,100,481,457,1565,1067,641,289,18,1537,62,545,401,1238,528,713,1042,430,144,390,220,953,42,817,18,26,137,1870,999,557,234,586,1316,87,104,369,39,215,595,922,1194,187,1056,382,397,387,872,191,464,1841,883,162,119,38,916,2,676,1524,315,1217,63,382,328,591,372,138,883,733,910,635,1059,87,773,630,1179,169,947,401,20,820,119,575,1117,48,268,45,896,772,293,217,73,732,26,528,1121,382,813,419,424,221,107,145,264,526,589,482,51,1399,954,292,276,248,1276,218,1005,296,360,60,5,499,661,192,199,250,1001,496,281,361,664,248,1090,86,203,241,61,329,1551,182,790,787,408,442,603,681,522,478,1072,527,1094,104,1267,418,730,217,1198,859 -------------------------------------------------------------------------------- /day07b/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let subs = include_str!("../input.txt") 3 | .split(',') 4 | .map(|n| n.parse().unwrap()) 5 | .collect::>(); 6 | 7 | println!( 8 | "{}", 9 | (subs.iter().sum::() / subs.len() as i32..) 10 | .take(2) 11 | .map(|t| { 12 | subs.iter() 13 | .map(|n| { 14 | let d = (n - t).abs(); 15 | d * (d + 1) / 2 16 | }) 17 | .sum::() 18 | }) 19 | .min() 20 | .unwrap() 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /day08a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day08a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day08a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day08a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day08a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | println!( 3 | "{}", 4 | include_str!("../input.txt") 5 | .lines() 6 | .flat_map(|l| l.split_once('|').unwrap().1.split_ascii_whitespace()) 7 | .filter(|d| matches!(d.len(), 2 | 3 | 4 | 7)) 8 | .count() 9 | ); 10 | } 11 | -------------------------------------------------------------------------------- /day08b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day08b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day08b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day08b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day08b/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | println!( 3 | "{}", 4 | include_bytes!("../input.txt") 5 | .split(|&b| b == b'\n') 6 | .map(|line| { 7 | let mut part = line.splitn(2, |&b| b == b'|'); 8 | let mut input = part.next().unwrap().split(|&b| b == b' '); 9 | let one = input.clone().find(|d| d.len() == 2).unwrap(); 10 | let four = input.find(|d| d.len() == 4).unwrap(); 11 | part.next() 12 | .unwrap() 13 | .split(|&b| b == b' ') 14 | .skip(1) 15 | .map(|d| match d.len() { 16 | 2 => 1, 17 | 3 => 7, 18 | 4 => 4, 19 | 7 => 8, 20 | len => match ( 21 | len, 22 | d.iter().filter(|&b| one.contains(b)).count(), 23 | d.iter().filter(|&b| four.contains(b)).count(), 24 | ) { 25 | (5, 1, 3) => 5, 26 | (5, 2, 3) => 3, 27 | (5, _, 2) => 2, 28 | (6, 1, _) => 6, 29 | (6, _, 3) => 0, 30 | (6, _, 4) => 9, 31 | _ => unreachable!(), 32 | }, 33 | }) 34 | .enumerate() 35 | .fold(0, |acc, (i, n)| acc + n * 10_u32.pow(3 - i as u32)) 36 | }) 37 | .sum::() 38 | ); 39 | } 40 | -------------------------------------------------------------------------------- /day09a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day09a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day09a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day09a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day09a/input.txt: -------------------------------------------------------------------------------- 1 | 5796798621237995498765434567987542999765679987545679109878999877899789876532123456998999876887899921 2 | 4645976434456789349654321298997679898654698987635678998767897656789698765432012347897899865676798799 3 | 3234987545978993298795410989998989789543256897646789498756789546896579877842123456976789954345985678 4 | 4356798679989999019987329878999798679765345689856991296545890134789467998956899967895698643239874579 5 | 6467999789999898934976598967987676568996457999967999987636789345691346789769987898934987651098763456 6 | 7598997999987796899989987959876543456789569898998998765125678956910298899898776799123998862987652345 7 | 8789876789865685578999876645987665567998689656789876554034899999891989998987564679099789879876543456 8 | 9898765498974324456799865534598786788998798645889985432126954987789878987654323567988698989987664678 9 | 9989997987543212367987654323459897899549895434569876556437899876599967996543212459876587898998798789 10 | 9877989997662101456798765434567998967932987624778989787548999989679459987687301349875456967899899893 11 | 8765678998983232367899896765788939346891295434999999899659879699894349899796532656954344756910923964 12 | 9874789019894343456789949878999321235799987545678945998778964578942139769898543769843212345891949765 13 | 7965678998765764567893433989876542346987898656789236799889653989943298652999678989754523456789898976 14 | 6598789109976975698921012398999763457896559867997647989998799899874569541098799798765676579896687897 15 | 5439898929989989789962123457899894568989435998998799878999989798765798432149898649987787899965456989 16 | 5212987898999999899854336568999989879979326569109989567898879689878987544234995434599898999874345679 17 | 4309875987999876998765687679989878998765412458929875467987854599989698955679989323459979899993214589 18 | 5996954676799984329877788989878969899874324567899765359876743489996549877789878912398767789984323456 19 | 9875432545789743212989899998967659789985595678998868249965312679865435998898767899598954698765467567 20 | 2994321036897654101996936987654543679999989789997854198764301569979423459999954678997643789978578978 21 | 0987432128998763219875424698763212478998978999876543298773212458998901267898767889598732345988789989 22 | 9876544346789979329876512349998401569897569234987994987654343457897892478999878993349891234899998695 23 | 9989875679899898939984701459886212398786456946799889998795464567896789989896999321234989345678987544 24 | 9997987889998797998743212598765323987654397899989778999989978679945698999765678930349878956999898433 25 | 8986798999987676789655329679876439876541289998878656899867898791239956799954345959499867897899765321 26 | 7845679219878565678976598999987556998732378997667545798656789892398745999765237898987656789998654310 27 | 6434798998765454567897987898798677899543467896553234987545878989499636878992156987975345899219964324 28 | 0123987999874343456789876799549789987654598998421056989434767879976521767989249876543234998909878434 29 | 4339876798955102367898985678939891099967899876542159875323854568965410156978956997684456797899989545 30 | 5498765986543234488987894799012999129878999987653249986210123467894321249769767898795867956789199656 31 | 6599754397654545589996789899993998949999998799767998975351237998995432398758998989986788946999098789 32 | 7988732198765657678975698999879876898946999544979877989876456789987643459647899876097899534878999899 33 | 9876546019878767889984567899968765667939896532989966592987887893298754598756789965198997323456799989 34 | 0998757898989899992099789988754543457898789540199854301298998984129866789998999954249986412345899878 35 | 1299898987699954954299999876543212348987698921598763212349999873234977995679439765356897601234988767 36 | 2989999876569999895989986987654103467896567892349854334568989964345698934678921976897996532349875756 37 | 9879899988698988789878995498976215989995456789498999965689879899456789323567890197998987656756994345 38 | 8765677899987677697667896329865423499989997995987878897798768778968895438678991298969398967899873201 39 | 8654546789766563459548994219876534578977789104986567789949654567899976657899789349543219988932965412 40 | 8643437899854312998435689101987645689665679323975345678959868778957987798934679959654301299549876723 41 | 6532126778969409876424578912498756796553568939863203456899979989646799899012567898976432358956987894 42 | 8544434567998912998535689843569867989432459949954212568999989594535798989123467987976563567969799985 43 | 9655566789897893479697897654567979879421267898767343467898795443123497679935679876899674789997659876 44 | 9776789998656799567989998765678998967992349929876556578987654321012989567896798765678985999876642989 45 | 9988899875434678979878999879889987657889458919997967689798865452199867456987987654567896798765431096 46 | 8799943989545789999868799989999876545678967898789898797659979874987654347899999753459987979876532145 47 | 7679969998656789987657678994323965432789979987679789896535989995998321234568939894567899764987687236 48 | 7567898959767893976543467995909876645678989996545678965423599989899754359679421986789968973199875345 49 | 3467987644978912987784989879899987856789999987434569653213679876789866468789439898993459792012989466 50 | 6569999533989999798896797867789898987897999876424678962102398765898977578996598769322375679933496578 51 | 8678998921296789679987896545698769399986789764312398993923499654567897689398999954201234567894987689 52 | 9799867890145679542998987896789954234995698765101256789894987543458999791249899895312347899995798789 53 | 2988656891237789869879998998996895999876789864212345996789987652377899910299756789436556799989999890 54 | 3977545789347899998767899989434999879989898987423467895678993210466789321987645679987867989767899921 55 | 9865437896556789999946799876545998767999987976534789954589997621245679459876437898798979876545978943 56 | 9976545789697899987834689989699767656899876989675678932679876432556789598943218997659989765434567894 57 | 9989867899989999986545678995987654545998965498797889321996997543457898797654323789943596986546789965 58 | 8896978999879878997668789213986543234987894349898996549875698665678909998965534567892345697656798987 59 | 7645989898765655689779898901987662129876789234989998698954539987899919879877645689931257898767967899 60 | 9869998789964334578995937892397654398945689345678979987643012398967898767998776798890234999898957898 61 | 6998789679892123457894325943498765987834568956889467898952134579656899656549887897789656799999546457 62 | 5987654597651012349975434799579989865423567897992378999763245678947999743435998996549767987989432347 63 | 4398753299843123457896545678992099654512455789209989398754356789439879842124999987638989876678954456 64 | 1239854987653238768998956999989298743101234678998994298765768899598765431029892196547898965466795567 65 | 0123995799768545678969869878979349543213455789997899109976779998789987532139789987656987654345789979 66 | 3235986999879656789756999867668956975434696899986987912987899999894697643298678999987898543234567898 67 | 9945799876998798897645987654456899876595989989765976899998999886989987659987567998998999864365788977 68 | 8799895995439899986534598732367968988989878979954695678919998785468998798766456997899898765479899766 69 | 5678923994323999876545987543478957999976556767893254589101987674378789899854349876799649876678987645 70 | 4567919876214899987689998954989546898765432356789123678919986543245679998765467965678999987789298756 71 | 3467898765436789998998999879995434999896521237895019789998997532135998899977569876789988798992109867 72 | 2369929876545699999987899999876545689943210235994298999997989949239876789989778989899976569993298989 73 | 3458910997676789899876989212987676899656432346789987889886979898949965679999899998998665478989987897 74 | 4567899998787895798765678923598789998789545497899996779765765787898764567878921987999543289567976546 75 | 6878978999898934989894569654589890249899876569999884568954654656989843458967899876998992123458997997 76 | 7989569899919129878989678979678931239964998978998763477943212349879932123458998765876789012567919989 77 | 8991356779909019767678989989899842498643239989987542356799302345965431014568919954345692139898929879 78 | 9410124567898998654567891294998753679654134699876521245678913459876432323589109765457789256799598767 79 | 4321267898987549876899910123987654598763245698776410234569865567997943434578999988767899767895349654 80 | 6532356789876434987898943235698765679854659987654321345678976778999894565689989999878949878943298765 81 | 7656467893987545998967896545699887998767998998765432456889988999998789689789878989999432989752129976 82 | 8767589954899756899459987756989998919879897899876548668994599989987678999898769878997643496543234988 83 | 9879678975798967987598999899878959102998766999988767899123678978986567894987653967898765789759449999 84 | 2989789996987898998987899954969643213459945789799878943239989865454478923986542656949896899898998931 85 | 1299899989776999129976899769878965425678996999656989965398798754342349435965421248956997899987687899 86 | 0467999876545789098865689879989876566789987898768997897987659983210456949878543367899898999876546797 87 | 2378988965434678987674778998999998987893598999879876798965434975672569898987665456789789998695435896 88 | 4499877994323569876523467897988999999912459999989965689896323497883479767999787578995679876564326345 89 | 9987656789212489986313568966767897899106598989999984878789212598965998956799898989664868975432101234 90 | 8798878994323478965423459954456986798919987678999873165678943679879876545689939996543459876875212345 91 | 9659989765434568976796567893299765987898765569898762054567894578998765434696549987654667998994323476 92 | 8934599879876899997898879954987654496987654346789943123489965679539854323589998998767898989889456567 93 | 7895678998987899998999998769876543345798765767898894344567896789329875434567897689998999878778967678 94 | 6796989987698969799998789878998632134899878998946799465679987898919987645679976578999098767669898799 95 | 5789995799549347689987678999986721023999999769434878987989998967898998767989787459989298653456789910 96 | 4567894698432134567988566789875432335698798653212967999997859456987679878998643212578987832345679891 97 | 3779992976553235679977455698998765487987689864343458999876543237897569989797652101459876543456789789 98 | 9889689987664346798765323456789887569876598765454569986987652145789698795698768892368987956567895678 99 | 4994567899865457999974313345699998798765439879875678955698767234999987654229878765456799767878934589 100 | 2123456999876567899875101256789109999984321989989899543249878945678996542101989877667899878989123699 -------------------------------------------------------------------------------- /day09a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let map = include_bytes!("../input.txt") 3 | .split(|&b| b == b'\n') 4 | .collect::>(); 5 | let neighbors = [(0, -1), (0, 1), (-1, 0), (1, 0)]; 6 | 7 | let mut sum = 0; 8 | for (y, line) in map.iter().enumerate() { 9 | for (x, cell) in line.iter().enumerate() { 10 | if neighbors.iter().all(|&(xx, yy)| { 11 | map.get((y as isize + yy) as usize) 12 | .and_then(|l| l.get((x as isize + xx) as usize)) 13 | .map(|n| cell < n) 14 | .unwrap_or(true) 15 | }) { 16 | sum += (cell - b'0') as usize + 1; 17 | } 18 | } 19 | } 20 | println!("{sum}"); 21 | } 22 | -------------------------------------------------------------------------------- /day09b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day09b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day09b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day09b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day09b/input.txt: -------------------------------------------------------------------------------- 1 | 5796798621237995498765434567987542999765679987545679109878999877899789876532123456998999876887899921 2 | 4645976434456789349654321298997679898654698987635678998767897656789698765432012347897899865676798799 3 | 3234987545978993298795410989998989789543256897646789498756789546896579877842123456976789954345985678 4 | 4356798679989999019987329878999798679765345689856991296545890134789467998956899967895698643239874579 5 | 6467999789999898934976598967987676568996457999967999987636789345691346789769987898934987651098763456 6 | 7598997999987796899989987959876543456789569898998998765125678956910298899898776799123998862987652345 7 | 8789876789865685578999876645987665567998689656789876554034899999891989998987564679099789879876543456 8 | 9898765498974324456799865534598786788998798645889985432126954987789878987654323567988698989987664678 9 | 9989997987543212367987654323459897899549895434569876556437899876599967996543212459876587898998798789 10 | 9877989997662101456798765434567998967932987624778989787548999989679459987687301349875456967899899893 11 | 8765678998983232367899896765788939346891295434999999899659879699894349899796532656954344756910923964 12 | 9874789019894343456789949878999321235799987545678945998778964578942139769898543769843212345891949765 13 | 7965678998765764567893433989876542346987898656789236799889653989943298652999678989754523456789898976 14 | 6598789109976975698921012398999763457896559867997647989998799899874569541098799798765676579896687897 15 | 5439898929989989789962123457899894568989435998998799878999989798765798432149898649987787899965456989 16 | 5212987898999999899854336568999989879979326569109989567898879689878987544234995434599898999874345679 17 | 4309875987999876998765687679989878998765412458929875467987854599989698955679989323459979899993214589 18 | 5996954676799984329877788989878969899874324567899765359876743489996549877789878912398767789984323456 19 | 9875432545789743212989899998967659789985595678998868249965312679865435998898767899598954698765467567 20 | 2994321036897654101996936987654543679999989789997854198764301569979423459999954678997643789978578978 21 | 0987432128998763219875424698763212478998978999876543298773212458998901267898767889598732345988789989 22 | 9876544346789979329876512349998401569897569234987994987654343457897892478999878993349891234899998695 23 | 9989875679899898939984701459886212398786456946799889998795464567896789989896999321234989345678987544 24 | 9997987889998797998743212598765323987654397899989778999989978679945698999765678930349878956999898433 25 | 8986798999987676789655329679876439876541289998878656899867898791239956799954345959499867897899765321 26 | 7845679219878565678976598999987556998732378997667545798656789892398745999765237898987656789998654310 27 | 6434798998765454567897987898798677899543467896553234987545878989499636878992156987975345899219964324 28 | 0123987999874343456789876799549789987654598998421056989434767879976521767989249876543234998909878434 29 | 4339876798955102367898985678939891099967899876542159875323854568965410156978956997684456797899989545 30 | 5498765986543234488987894799012999129878999987653249986210123467894321249769767898795867956789199656 31 | 6599754397654545589996789899993998949999998799767998975351237998995432398758998989986788946999098789 32 | 7988732198765657678975698999879876898946999544979877989876456789987643459647899876097899534878999899 33 | 9876546019878767889984567899968765667939896532989966592987887893298754598756789965198997323456799989 34 | 0998757898989899992099789988754543457898789540199854301298998984129866789998999954249986412345899878 35 | 1299898987699954954299999876543212348987698921598763212349999873234977995679439765356897601234988767 36 | 2989999876569999895989986987654103467896567892349854334568989964345698934678921976897996532349875756 37 | 9879899988698988789878995498976215989995456789498999965689879899456789323567890197998987656756994345 38 | 8765677899987677697667896329865423499989997995987878897798768778968895438678991298969398967899873201 39 | 8654546789766563459548994219876534578977789104986567789949654567899976657899789349543219988932965412 40 | 8643437899854312998435689101987645689665679323975345678959868778957987798934679959654301299549876723 41 | 6532126778969409876424578912498756796553568939863203456899979989646799899012567898976432358956987894 42 | 8544434567998912998535689843569867989432459949954212568999989594535798989123467987976563567969799985 43 | 9655566789897893479697897654567979879421267898767343467898795443123497679935679876899674789997659876 44 | 9776789998656799567989998765678998967992349929876556578987654321012989567896798765678985999876642989 45 | 9988899875434678979878999879889987657889458919997967689798865452199867456987987654567896798765431096 46 | 8799943989545789999868799989999876545678967898789898797659979874987654347899999753459987979876532145 47 | 7679969998656789987657678994323965432789979987679789896535989995998321234568939894567899764987687236 48 | 7567898959767893976543467995909876645678989996545678965423599989899754359679421986789968973199875345 49 | 3467987644978912987784989879899987856789999987434569653213679876789866468789439898993459792012989466 50 | 6569999533989999798896797867789898987897999876424678962102398765898977578996598769322375679933496578 51 | 8678998921296789679987896545698769399986789764312398993923499654567897689398999954201234567894987689 52 | 9799867890145679542998987896789954234995698765101256789894987543458999791249899895312347899995798789 53 | 2988656891237789869879998998996895999876789864212345996789987652377899910299756789436556799989999890 54 | 3977545789347899998767899989434999879989898987423467895678993210466789321987645679987867989767899921 55 | 9865437896556789999946799876545998767999987976534789954589997621245679459876437898798979876545978943 56 | 9976545789697899987834689989699767656899876989675678932679876432556789598943218997659989765434567894 57 | 9989867899989999986545678995987654545998965498797889321996997543457898797654323789943596986546789965 58 | 8896978999879878997668789213986543234987894349898996549875698665678909998965534567892345697656798987 59 | 7645989898765655689779898901987662129876789234989998698954539987899919879877645689931257898767967899 60 | 9869998789964334578995937892397654398945689345678979987643012398967898767998776798890234999898957898 61 | 6998789679892123457894325943498765987834568956889467898952134579656899656549887897789656799999546457 62 | 5987654597651012349975434799579989865423567897992378999763245678947999743435998996549767987989432347 63 | 4398753299843123457896545678992099654512455789209989398754356789439879842124999987638989876678954456 64 | 1239854987653238768998956999989298743101234678998994298765768899598765431029892196547898965466795567 65 | 0123995799768545678969869878979349543213455789997899109976779998789987532139789987656987654345789979 66 | 3235986999879656789756999867668956975434696899986987912987899999894697643298678999987898543234567898 67 | 9945799876998798897645987654456899876595989989765976899998999886989987659987567998998999864365788977 68 | 8799895995439899986534598732367968988989878979954695678919998785468998798766456997899898765479899766 69 | 5678923994323999876545987543478957999976556767893254589101987674378789899854349876799649876678987645 70 | 4567919876214899987689998954989546898765432356789123678919986543245679998765467965678999987789298756 71 | 3467898765436789998998999879995434999896521237895019789998997532135998899977569876789988798992109867 72 | 2369929876545699999987899999876545689943210235994298999997989949239876789989778989899976569993298989 73 | 3458910997676789899876989212987676899656432346789987889886979898949965679999899998998665478989987897 74 | 4567899998787895798765678923598789998789545497899996779765765787898764567878921987999543289567976546 75 | 6878978999898934989894569654589890249899876569999884568954654656989843458967899876998992123458997997 76 | 7989569899919129878989678979678931239964998978998763477943212349879932123458998765876789012567919989 77 | 8991356779909019767678989989899842498643239989987542356799302345965431014568919954345692139898929879 78 | 9410124567898998654567891294998753679654134699876521245678913459876432323589109765457789256799598767 79 | 4321267898987549876899910123987654598763245698776410234569865567997943434578999988767899767895349654 80 | 6532356789876434987898943235698765679854659987654321345678976778999894565689989999878949878943298765 81 | 7656467893987545998967896545699887998767998998765432456889988999998789689789878989999432989752129976 82 | 8767589954899756899459987756989998919879897899876548668994599989987678999898769878997643496543234988 83 | 9879678975798967987598999899878959102998766999988767899123678978986567894987653967898765789759449999 84 | 2989789996987898998987899954969643213459945789799878943239989865454478923986542656949896899898998931 85 | 1299899989776999129976899769878965425678996999656989965398798754342349435965421248956997899987687899 86 | 0467999876545789098865689879989876566789987898768997897987659983210456949878543367899898999876546797 87 | 2378988965434678987674778998999998987893598999879876798965434975672569898987665456789789998695435896 88 | 4499877994323569876523467897988999999912459999989965689896323497883479767999787578995679876564326345 89 | 9987656789212489986313568966767897899106598989999984878789212598965998956799898989664868975432101234 90 | 8798878994323478965423459954456986798919987678999873165678943679879876545689939996543459876875212345 91 | 9659989765434568976796567893299765987898765569898762054567894578998765434696549987654667998994323476 92 | 8934599879876899997898879954987654496987654346789943123489965679539854323589998998767898989889456567 93 | 7895678998987899998999998769876543345798765767898894344567896789329875434567897689998999878778967678 94 | 6796989987698969799998789878998632134899878998946799465679987898919987645679976578999098767669898799 95 | 5789995799549347689987678999986721023999999769434878987989998967898998767989787459989298653456789910 96 | 4567894698432134567988566789875432335698798653212967999997859456987679878998643212578987832345679891 97 | 3779992976553235679977455698998765487987689864343458999876543237897569989797652101459876543456789789 98 | 9889689987664346798765323456789887569876598765454569986987652145789698795698768892368987956567895678 99 | 4994567899865457999974313345699998798765439879875678955698767234999987654229878765456799767878934589 100 | 2123456999876567899875101256789109999984321989989899543249878945678996542101989877667899878989123699 -------------------------------------------------------------------------------- /day09b/src/main.rs: -------------------------------------------------------------------------------- 1 | const NEXT: [(isize, isize); 4] = [(0, -1), (0, 1), (-1, 0), (1, 0)]; 2 | 3 | pub fn main() { 4 | let mut map = include_bytes!("../input.txt") 5 | .split(|&b| b == b'\n') 6 | .map(|l| l.to_vec()) 7 | .collect::>(); 8 | 9 | let mut basins = vec![]; 10 | for y in 0..map.len() { 11 | for x in 0..map[0].len() { 12 | (map[y][x] < b'9').then(|| basins.push(basin(&mut map, x, y))); 13 | } 14 | } 15 | 16 | basins.sort_unstable(); 17 | println!("{}", basins.iter().rev().take(3).product::()); 18 | } 19 | 20 | fn basin(map: &mut Vec>, x: usize, y: usize) -> usize { 21 | map[y][x] = b'9'; 22 | NEXT.iter() 23 | .map(|(xx, yy)| ((x as isize + xx) as usize, (y as isize + yy) as usize)) 24 | .fold(1, |acc, (x, y)| { 25 | match map.get(y).and_then(|l| l.get(x)).map(|&n| n < b'9') { 26 | Some(true) => acc + basin(map, x, y), 27 | _ => acc, 28 | } 29 | }) 30 | } 31 | -------------------------------------------------------------------------------- /day10a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day10a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day10a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day10a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day10a/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 | {{((<({[({{{({<>{}}<[]{}>)[{{}()}{<>[]}]}<[({}[])<<>>]>}}(<<({[]<>}([][]))(<[]()><{}[]>)>{<({}[]){{}{ 33 | [<(<[{<({[(([[[]][[]<>]][[<><>]{[]()}])[{({}{}){<>{}}}<{()<>}{{}{}}>])](<[({<>{}}([]()))][[<{}<>>([]())](( 34 | <([[<(({{([{[{<>}([]())][{()()}(<>()))}[([<><>]{<>[]})(([]{}){{}()})]](<(([]<>)([]{}))[(<>())]>)) 35 | {{{[{[(<((<([{{}{}}[[][]]](([])))])){[<<[<[]()>[<><>]]>>{{<[[][]][{}<>]>[<[]<>>{[]()}]}[[([]() 36 | <<([({({{[{[<(()[])><([]<>){<>{}}>]<[(<>[])<{}()>]>}]}<<<[{([][])((){})}(<{}<>>{()[]})][({[][]}{[]{}})]><[( 37 | [[((([([[{<([(()()){{}<>}]<([]<>){[]{}}>)[(<{}{}>[{}<>])(<{}{}>[()[]])]><[({{}[]})[[<>()][{}[]]]]{<<()[] 38 | <<<{(([{[<({{({}{})(<><>)}({{}()})}{<<()><(){}>>[{<>{}][()<>]]}){(<<{}[]>[<><>]>({[]()}<{}{}>)){{{<>}{[]< 39 | ([[{{<{<{[<{([()()]<<>[]>)[[()<>](()<>)]}>[<({()<>}(()))<{[]{}}{{}{}}>>(([(){}]<()()>)<<()()>(<><>)>)]](({ 40 | ((<<[<([{<([<<()()>{[]<>}>[<{}[]>([])]][([<>()]{()[]})])><((<<<><>>{<><>}}([{}()][()<>])){[{[]}] 41 | [<{(({{[{<[[{[<>()]}[[()()]({}[])]]<[({}<>)(<>{})]<(<>{})[{}<>]>>]<<(([]())<{}()>)(<[][]>(()[]))>>>(( 42 | <[<[[([<(<({{[()]<<>>}([<>[]][{}()])}([<[]{}><{}()>][<<>{}){<>()}]))>[<[[<()[]><()[]>][[<> 43 | {[[[{<[{[{[[[(<>()){[]}]{[{}()]}]{[<()<>><<><>>]({<>()}{[]()})}]}]<[{(<<()()><[]()>>(<{}<>>{(){}}))([{{}}][[ 44 | <([([([{<[[{{<{}()>{[]()}}}<((<><>){[]()}>>]{[[[{}[]]({}<>)]<((){})>]{(<()<>>(()<>))([<>]<{}< 45 | [({<[[{[({<{((<>{})<{}[]>)[<[]()>([]<>)]}>}<{<<<[][]>[{}{}]>>([<(){}><{}[]>])}<<<<<><>>{{}<>>>{[<> 46 | {<{{<([{([{<[(<>())<{}[]>]({<>[]})>[[(()()){<>{}}]{{<><>}(()[])}]}{([(<>)(()[])])(({<>{}}<[]<>))([ 47 | [<{(<<<{{{([{[[][]]{()()}}<[[][]](()())>][(<{}[]>({}[]))]){({<(){}>(<>())}<{(){}}{[]{}}>){<(()())[(){}]>({{}( 48 | {<<[<[{([[<{<(<>){<>{}}>{({}())(<>{})}}<(([][]))>><{{[[]<>][[]()]}[<<>()><(){}>]}>]])}[{([((<((){ 49 | ([(({<[[((<([([]())[[][]]][{<>{}}<(){}>]]><<(<(){}>[[]()])([[][]][()()])><[{()()}<<>{}>]>>)){ 50 | [{(<<<{((<<({[()[]]<{}()>}{<<>{}>{<>[]}})((<{}[]>[()<>])<<<>[]>[<>[]]>)><<<[(){}]>{<()[]>{(){}}}>([<<><>>{{ 51 | {([({[[<({{([(<>{})<[]<>>])[[<{}><<>{}>]]}{([<[]()>[{}<>]]<([]{})>)})<({{[{}[]]{<><>}}{[[]{}]<<>{}>}} 52 | [[[((<[([({({<<>{}>[<><>]}){{(()<>)<[]()>}<{{}[]}({}())>}})[((({<><>})({[][]}(()())))<[{{}{}}{() 53 | <<[([(({<<[[[<[]<>>]]<((<><>)[{}[]])>][([<<>{}>{[][]}]{{()()}[[]()]>){(([]<>)([][])){(<><>)}}]>{[{ 54 | <([[(<{{{{({<{{}{}}(()())>[[[]()]{()<>}]}[[{[]()}{()()}>])}}<[<{[(()<>)(()())][(()())]}({<()<>>(<>{} 55 | [{{[<(<{(<<<({{}()}<<>()>)([[]()]{()[]})>(({{}<>}[<>{}])([(){}]{()<>}))>[[(<[]{}>(<><>))[<[] 56 | {{{[{<{[<<{{{{()<>}{(){}}}}<([{}<>][{}{}])<<{}<>>{()[]}>>}{[<<<>>[()<>]>]([[{}()](<>{})]{{[][]}{(){}}}) 57 | [[[{<({{(<([(<()()>({}()))])>)<<(<[(()())]{(<>())[<>[]]}><<{(){}}<{}<>>>[{[]()}(<>{})]>)([{([]<>)([][ 58 | (({[(({{[{({[(())<(){}>]})<{<<{}{}](()<>)>({[]{}}((){}))}({<[]()>[[]<>]}{<{}[]>[[]{}]})>}][{< 59 | [<{<[[[<(({[[(<>())]<{<>[]}(<><>)>]}[<{<()<>>}><[{()[]}(<>[])]{{<>()}[{}<>]}]])<[<({{}[]}(<>< 60 | [(<{{[{{([({{[{}()]<()()>}{[()()]{<>[]}}}(<<()>(<>{})>))]<([(<[]>[[]<>])([{}](<>()])])<{<<[]{}>(<> 61 | [[{{([<([{{([{[]{}}<()[]>]{<(){}>([][])})}<<{{<><>}[()]}{<<>{}>{<>}}>([(<>{})<<>[]>]{{<><>}{<>()}})>} 62 | <[{([<{<[<(<{{<><>}[{}<>]}<<{}[]><[][]>>>{({()()}{<>[]})<<[]{}>[{}[]]>})<<[({}<>)]>(({{}()})(((){}]))>> 63 | {[[<(([<[<<<<[[]()]{()<>>>{({}())<[]{}>}>[({<>{}}(<>[]))((()[])[()])]>>{[[[({})]{(()())[<>()]}]]{<{<()( 64 | <([({[[([[{{<[{}[]](<>)><{()()}[[]{}]>}<<({}{})({}{})><<(){}><<>[]>>>}[{{([][])(<>{})}[<<>[]><{}{}>]}[<[ 65 | ((<<<[<[(<<[[({}<>)<[]>][[(){}]<<>()>]]{<[()()]<()<>>>{{<>()}((){})}}>[({<<>[]>{()()}))(({[]()}{()[]} 66 | [(({{<[([{[[({(){}}{()[]}){([]{})([]{})}][{{<>()}<{}{}>}]]({{[<>[]]}(<{}[]><{}()>)}(({()()}(( 67 | <[<<{<({<{<<[(()())[()[]]]]<({{}{}}[[]<>])>>[([<(){}><{}<>>]<<[]()>(<><>)>)[[(()[]){{}()}]{( 68 | <{[<({(<({<[[(()[])][<()()>({}())]](<{[]()}[{}[]]>({(){}}{()[]}))>}[<{<<<><>>[(){}]>{<()<>>{<>[]}}}>[<{ 69 | {{{<({{(<({{[[<>()]<<>[]>]{<<><>>([]<>)}}}({<<<><>>{[]<>}><(<>()>([][])>}))>([<{[{{}()}[[][]]]<{<>[]}<[]<>>> 70 | {{(([{[[([([{<[]()>{[]{}}}(<()[]><[][]>>]({{(){}}[[][]]}[[<>]{<>()}]))])]]}])[[[([<[[[<[[]<>]<( 71 | [<(<{{<((([(([()[]]<{}>)<[<><>][{}()]>)<([[]()])>](<{((){})((){})}{([]<>)<<>[]>}){[([]())](({}[]){() 72 | <({[<(<(({[([<{}()><(){}>]([<>][()()]))(<[()[]]><[()[]]({}{})>)]{(<(<>{})[{}<>]><{{}{}}{[]()}>) 73 | {<<[<{[[[([<{{[][]}[[]()]}<[[][]][<>{}]>>]){{[<<()()>(()[])][[<>()]{<>()}]]((<<><>><{}()>)[{{ 74 | {{<([{[[<(<{{{{}[]}{<><>}}}((<{}>))>[(<(()[]){<>{}}>((()())[<>]))])>]]}[{[{((([<(){}>({}[])][<( 75 | <[[((([{[[<<[{<>[])[{}[]]]>>(<[{[][]}<{}<>>][[()<>][[][]]]>([([]<>)({}())](<{}()>{()<>})))]< 76 | ({<{<[{(((<(<(()[]){[][]}>[<()<>>[<>()]])(<{{}{}}(<>{})>)>[(({(){}}{()()])[{{}{}}[<>{}]])]) 77 | ({{((<([(({([[<>()][{}{}]]<(<>)(())>}}{<([<>()]{[]})([<>{}](<>[]))><({[]()}(<>[])){([][])[<>[]]}>})[{ 78 | ([{[<(({(<<<<<[]<>>{[]{}}><((){}){<>()}>>([[()[]][<>{}]]([[][]][()<>]))>><<[([()()]{<><>}){<{}<>>{<>< 79 | [{({<{<{({(({[[]()]([][])}{{{}()}([][]>}){<({}<>)[<>()]>[[()<>]<<>>]})[(<<()()>{[][]}><[<>( 80 | {[[<({<<<<<{[[{}{}](()())]<([][]){<><>}>}>{<[[<>()]<[]>][{<>{}}({}[])]>}>[{{{[()<>][<>{}]}}}[[[({ 81 | [<(<(<{<<{{{(<()[]>{{}})}}<[[{[]{}}([]{})][(<><>)[[]()]]]{<{<>[]}(<><>)>[({})(<>[])]}>}[(([[{}{}][ 82 | (([([[<<[[(<({()<>}{()<>})<([]<>)(<>[])>>[{<{}[]>{[]()}}])[<<([][])<[]()>>[{{}()>{{}{}}]>]]][[<<(([]<>) 83 | [([[{([{[{{<(<<>()>)(<[]()><<>{}>)>><<(<[]()>([][])){<<><>><{}[]>}>([[<><>]{{}()}]<{[]()}>)>}<({([() 84 | ([[([{<{([<<<(()())[{}()]>([{}<>](()[]))>({<{}[]><<>[]>}{([]<>)({}())})>[(<<{}()><<>()>>[[<><>]])({[[]()]<{} 85 | {[{{([(<<([([<[]()>])<{({}<>)({}())}<([]()){[]<>}>>]){((<{[]<>}({}{})>({{}[]}{{}<>}))[({[][ 86 | {{[(<<<({<{[[([]<>){()()}]((<><>)[{}()])]{[(()<>)[{}()]]}}([<<[][]>)[{()<>}<{}{}>]]{{{{}{}}((){})}{[<> 87 | {(<<[(<<<<{([[[]<>]{(){}}]{{[]()}}){<<()<>>>[{{}{}}<{}<>>]}}>[[{[{<>()}<{}[]>]<{{}[]}>}<(({}[])(<><>) 88 | <<[(<{[({<<<<{[]{}}<{}[]>>>({{()[]}{()()}}<<{}{}>({}{})>)>>})]{(<((<([[]()][()<>]){((){})<[] 89 | [[[[{<<[[{<(([{}{}]([]<>))({[]()})}(<{()[]}<{}<>>>{[<>{}]})>({[<{}{}>][<<>{}>(<>)]}[<{[][]}{{}{}} 90 | {<<[(<((({{{[[<>[]]{<>{}}](({}())({}{}))}<{<(){}>([]<>)}{((){})}]}}{<{{([]())[()]}{<(){}>(<><>)}}[[<<> 91 | <([[[[[[{<(<[<<><>>{[][]}]>)([([()[]][()()])]([{()[]){()[]}][{[]()}(()<>)]))>[{[({<>()}[{} 92 | [(({<<<({<{[(<{}{}>{()<>}){{()[]}{[]{}}}]}>})([<<<({<>()}[[]()])>({[{}<>]<[]<>>}(((){})))>>{[[([<><>]([]< 93 | {{[[({{[({<{[{()<>}([][])]([(){}])}>(<(([]())<()<>>){[[]()]([]())}><<<<>[]>[()<>]>[<[]{}>[<><>]] 94 | <{({((<{[{[<(<[]{}>(<>{}))>][{{<{}<>}{()<>}}<(<>())<()()>>}[[({}()){[]()}](<<>[]>{[]()})]]}<<{(({}<> 95 | (<<{{{[{[{((<{()<>}({}<>)>[(()<>)(<><>)]))[[[(<>[])<{}<>>][[[]<>]<{}()>]]<[(<>{})[<>]]>]}]}][( 96 | ((({([[<[([[[[()[]]<{}()>](({}())[()])]<[{(){}}({}())](([]()){{}()})>]<(({<>{}}[[]{}])<<()<> 97 | {{[(<<([({((([{}<>]{{}[]})([<><>](<>())))[{(()[])[()()]>[(()()){<>[]}]])}<([{[[]()][[]{}]}( 98 | [<<({{[<<[({((()<>)[<>()]){<{}>[[]<>]}}[<{[]()}(()<>)>])<([<<>{}>[<><>]]<{[]<>}[()<>]>){[{<><>}<<>[]>]{(( 99 | -------------------------------------------------------------------------------- /day10a/src/main.rs: -------------------------------------------------------------------------------- 1 | #[allow(clippy::unit_cmp)] 2 | 3 | pub fn main() { 4 | println!( 5 | "{}", 6 | include_str!("../input.txt") 7 | .lines() 8 | .filter_map(|seq| seq 9 | .bytes() 10 | .scan(Vec::with_capacity(64), |s, c| Some(match c { 11 | c if matches!(c, b'(' | b'[' | b'{' | b'<') => (s.push(c) != ()).then(|| b' '), 12 | b')' => (s.pop().unwrap() != b'(').then(|| b')'), 13 | c => (s.pop().unwrap() != c - 2).then(|| c), 14 | })) 15 | .skip_while(Option::is_none) 16 | .map(|c| [3, 25137, 57, 1197][c.unwrap() as usize / 30 - 1]) 17 | .next()) 18 | .sum::() 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /day10b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day10b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day10b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day10b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day10b/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 | {{((<({[({{{({<>{}}<[]{}>)[{{}()}{<>[]}]}<[({}[])<<>>]>}}(<<({[]<>}([][]))(<[]()><{}[]>)>{<({}[]){{}{ 33 | [<(<[{<({[(([[[]][[]<>]][[<><>]{[]()}])[{({}{}){<>{}}}<{()<>}{{}{}}>])](<[({<>{}}([]()))][[<{}<>>([]())](( 34 | <([[<(({{([{[{<>}([]())][{()()}(<>()))}[([<><>]{<>[]})(([]{}){{}()})]](<(([]<>)([]{}))[(<>())]>)) 35 | {{{[{[(<((<([{{}{}}[[][]]](([])))])){[<<[<[]()>[<><>]]>>{{<[[][]][{}<>]>[<[]<>>{[]()}]}[[([]() 36 | <<([({({{[{[<(()[])><([]<>){<>{}}>]<[(<>[])<{}()>]>}]}<<<[{([][])((){})}(<{}<>>{()[]})][({[][]}{[]{}})]><[( 37 | [[((([([[{<([(()()){{}<>}]<([]<>){[]{}}>)[(<{}{}>[{}<>])(<{}{}>[()[]])]><[({{}[]})[[<>()][{}[]]]]{<<()[] 38 | <<<{(([{[<({{({}{})(<><>)}({{}()})}{<<()><(){}>>[{<>{}][()<>]]}){(<<{}[]>[<><>]>({[]()}<{}{}>)){{{<>}{[]< 39 | ([[{{<{<{[<{([()()]<<>[]>)[[()<>](()<>)]}>[<({()<>}(()))<{[]{}}{{}{}}>>(([(){}]<()()>)<<()()>(<><>)>)]](({ 40 | ((<<[<([{<([<<()()>{[]<>}>[<{}[]>([])]][([<>()]{()[]})])><((<<<><>>{<><>}}([{}()][()<>])){[{[]}] 41 | [<{(({{[{<[[{[<>()]}[[()()]({}[])]]<[({}<>)(<>{})]<(<>{})[{}<>]>>]<<(([]())<{}()>)(<[][]>(()[]))>>>(( 42 | <[<[[([<(<({{[()]<<>>}([<>[]][{}()])}([<[]{}><{}()>][<<>{}){<>()}]))>[<[[<()[]><()[]>][[<> 43 | {[[[{<[{[{[[[(<>()){[]}]{[{}()]}]{[<()<>><<><>>]({<>()}{[]()})}]}]<[{(<<()()><[]()>>(<{}<>>{(){}}))([{{}}][[ 44 | <([([([{<[[{{<{}()>{[]()}}}<((<><>){[]()}>>]{[[[{}[]]({}<>)]<((){})>]{(<()<>>(()<>))([<>]<{}< 45 | [({<[[{[({<{((<>{})<{}[]>)[<[]()>([]<>)]}>}<{<<<[][]>[{}{}]>>([<(){}><{}[]>])}<<<<<><>>{{}<>>>{[<> 46 | {<{{<([{([{<[(<>())<{}[]>]({<>[]})>[[(()()){<>{}}]{{<><>}(()[])}]}{([(<>)(()[])])(({<>{}}<[]<>))([ 47 | [<{(<<<{{{([{[[][]]{()()}}<[[][]](()())>][(<{}[]>({}[]))]){({<(){}>(<>())}<{(){}}{[]{}}>){<(()())[(){}]>({{}( 48 | {<<[<[{([[<{<(<>){<>{}}>{({}())(<>{})}}<(([][]))>><{{[[]<>][[]()]}[<<>()><(){}>]}>]])}[{([((<((){ 49 | ([(({<[[((<([([]())[[][]]][{<>{}}<(){}>]]><<(<(){}>[[]()])([[][]][()()])><[{()()}<<>{}>]>>)){ 50 | [{(<<<{((<<({[()[]]<{}()>}{<<>{}>{<>[]}})((<{}[]>[()<>])<<<>[]>[<>[]]>)><<<[(){}]>{<()[]>{(){}}}>([<<><>>{{ 51 | {([({[[<({{([(<>{})<[]<>>])[[<{}><<>{}>]]}{([<[]()>[{}<>]]<([]{})>)})<({{[{}[]]{<><>}}{[[]{}]<<>{}>}} 52 | [[[((<[([({({<<>{}>[<><>]}){{(()<>)<[]()>}<{{}[]}({}())>}})[((({<><>})({[][]}(()())))<[{{}{}}{() 53 | <<[([(({<<[[[<[]<>>]]<((<><>)[{}[]])>][([<<>{}>{[][]}]{{()()}[[]()]>){(([]<>)([][])){(<><>)}}]>{[{ 54 | <([[(<{{{{({<{{}{}}(()())>[[[]()]{()<>}]}[[{[]()}{()()}>])}}<[<{[(()<>)(()())][(()())]}({<()<>>(<>{} 55 | [{{[<(<{(<<<({{}()}<<>()>)([[]()]{()[]})>(({{}<>}[<>{}])([(){}]{()<>}))>[[(<[]{}>(<><>))[<[] 56 | {{{[{<{[<<{{{{()<>}{(){}}}}<([{}<>][{}{}])<<{}<>>{()[]}>>}{[<<<>>[()<>]>]([[{}()](<>{})]{{[][]}{(){}}}) 57 | [[[{<({{(<([(<()()>({}()))])>)<<(<[(()())]{(<>())[<>[]]}><<{(){}}<{}<>>>[{[]()}(<>{})]>)([{([]<>)([][ 58 | (({[(({{[{({[(())<(){}>]})<{<<{}{}](()<>)>({[]{}}((){}))}({<[]()>[[]<>]}{<{}[]>[[]{}]})>}][{< 59 | [<{<[[[<(({[[(<>())]<{<>[]}(<><>)>]}[<{<()<>>}><[{()[]}(<>[])]{{<>()}[{}<>]}]])<[<({{}[]}(<>< 60 | [(<{{[{{([({{[{}()]<()()>}{[()()]{<>[]}}}(<<()>(<>{})>))]<([(<[]>[[]<>])([{}](<>()])])<{<<[]{}>(<> 61 | [[{{([<([{{([{[]{}}<()[]>]{<(){}>([][])})}<<{{<><>}[()]}{<<>{}>{<>}}>([(<>{})<<>[]>]{{<><>}{<>()}})>} 62 | <[{([<{<[<(<{{<><>}[{}<>]}<<{}[]><[][]>>>{({()()}{<>[]})<<[]{}>[{}[]]>})<<[({}<>)]>(({{}()})(((){}]))>> 63 | {[[<(([<[<<<<[[]()]{()<>>>{({}())<[]{}>}>[({<>{}}(<>[]))((()[])[()])]>>{[[[({})]{(()())[<>()]}]]{<{<()( 64 | <([({[[([[{{<[{}[]](<>)><{()()}[[]{}]>}<<({}{})({}{})><<(){}><<>[]>>>}[{{([][])(<>{})}[<<>[]><{}{}>]}[<[ 65 | ((<<<[<[(<<[[({}<>)<[]>][[(){}]<<>()>]]{<[()()]<()<>>>{{<>()}((){})}}>[({<<>[]>{()()}))(({[]()}{()[]} 66 | [(({{<[([{[[({(){}}{()[]}){([]{})([]{})}][{{<>()}<{}{}>}]]({{[<>[]]}(<{}[]><{}()>)}(({()()}(( 67 | <[<<{<({<{<<[(()())[()[]]]]<({{}{}}[[]<>])>>[([<(){}><{}<>>]<<[]()>(<><>)>)[[(()[]){{}()}]{( 68 | <{[<({(<({<[[(()[])][<()()>({}())]](<{[]()}[{}[]]>({(){}}{()[]}))>}[<{<<<><>>[(){}]>{<()<>>{<>[]}}}>[<{ 69 | {{{<({{(<({{[[<>()]<<>[]>]{<<><>>([]<>)}}}({<<<><>>{[]<>}><(<>()>([][])>}))>([<{[{{}()}[[][]]]<{<>[]}<[]<>>> 70 | {{(([{[[([([{<[]()>{[]{}}}(<()[]><[][]>>]({{(){}}[[][]]}[[<>]{<>()}]))])]]}])[[[([<[[[<[[]<>]<( 71 | [<(<{{<((([(([()[]]<{}>)<[<><>][{}()]>)<([[]()])>](<{((){})((){})}{([]<>)<<>[]>}){[([]())](({}[]){() 72 | <({[<(<(({[([<{}()><(){}>]([<>][()()]))(<[()[]]><[()[]]({}{})>)]{(<(<>{})[{}<>]><{{}{}}{[]()}>) 73 | {<<[<{[[[([<{{[][]}[[]()]}<[[][]][<>{}]>>]){{[<<()()>(()[])][[<>()]{<>()}]]((<<><>><{}()>)[{{ 74 | {{<([{[[<(<{{{{}[]}{<><>}}}((<{}>))>[(<(()[]){<>{}}>((()())[<>]))])>]]}[{[{((([<(){}>({}[])][<( 75 | <[[((([{[[<<[{<>[])[{}[]]]>>(<[{[][]}<{}<>>][[()<>][[][]]]>([([]<>)({}())](<{}()>{()<>})))]< 76 | ({<{<[{(((<(<(()[]){[][]}>[<()<>>[<>()]])(<{{}{}}(<>{})>)>[(({(){}}{()()])[{{}{}}[<>{}]])]) 77 | ({{((<([(({([[<>()][{}{}]]<(<>)(())>}}{<([<>()]{[]})([<>{}](<>[]))><({[]()}(<>[])){([][])[<>[]]}>})[{ 78 | ([{[<(({(<<<<<[]<>>{[]{}}><((){}){<>()}>>([[()[]][<>{}]]([[][]][()<>]))>><<[([()()]{<><>}){<{}<>>{<>< 79 | [{({<{<{({(({[[]()]([][])}{{{}()}([][]>}){<({}<>)[<>()]>[[()<>]<<>>]})[(<<()()>{[][]}><[<>( 80 | {[[<({<<<<<{[[{}{}](()())]<([][]){<><>}>}>{<[[<>()]<[]>][{<>{}}({}[])]>}>[{{{[()<>][<>{}]}}}[[[({ 81 | [<(<(<{<<{{{(<()[]>{{}})}}<[[{[]{}}([]{})][(<><>)[[]()]]]{<{<>[]}(<><>)>[({})(<>[])]}>}[(([[{}{}][ 82 | (([([[<<[[(<({()<>}{()<>})<([]<>)(<>[])>>[{<{}[]>{[]()}}])[<<([][])<[]()>>[{{}()>{{}{}}]>]]][[<<(([]<>) 83 | [([[{([{[{{<(<<>()>)(<[]()><<>{}>)>><<(<[]()>([][])){<<><>><{}[]>}>([[<><>]{{}()}]<{[]()}>)>}<({([() 84 | ([[([{<{([<<<(()())[{}()]>([{}<>](()[]))>({<{}[]><<>[]>}{([]<>)({}())})>[(<<{}()><<>()>>[[<><>]])({[[]()]<{} 85 | {[{{([(<<([([<[]()>])<{({}<>)({}())}<([]()){[]<>}>>]){((<{[]<>}({}{})>({{}[]}{{}<>}))[({[][ 86 | {{[(<<<({<{[[([]<>){()()}]((<><>)[{}()])]{[(()<>)[{}()]]}}([<<[][]>)[{()<>}<{}{}>]]{{{{}{}}((){})}{[<> 87 | {(<<[(<<<<{([[[]<>]{(){}}]{{[]()}}){<<()<>>>[{{}{}}<{}<>>]}}>[[{[{<>()}<{}[]>]<{{}[]}>}<(({}[])(<><>) 88 | <<[(<{[({<<<<{[]{}}<{}[]>>>({{()[]}{()()}}<<{}{}>({}{})>)>>})]{(<((<([[]()][()<>]){((){})<[] 89 | [[[[{<<[[{<(([{}{}]([]<>))({[]()})}(<{()[]}<{}<>>>{[<>{}]})>({[<{}{}>][<<>{}>(<>)]}[<{[][]}{{}{}} 90 | {<<[(<((({{{[[<>[]]{<>{}}](({}())({}{}))}<{<(){}>([]<>)}{((){})}]}}{<{{([]())[()]}{<(){}>(<><>)}}[[<<> 91 | <([[[[[[{<(<[<<><>>{[][]}]>)([([()[]][()()])]([{()[]){()[]}][{[]()}(()<>)]))>[{[({<>()}[{} 92 | [(({<<<({<{[(<{}{}>{()<>}){{()[]}{[]{}}}]}>})([<<<({<>()}[[]()])>({[{}<>]<[]<>>}(((){})))>>{[[([<><>]([]< 93 | {{[[({{[({<{[{()<>}([][])]([(){}])}>(<(([]())<()<>>){[[]()]([]())}><<<<>[]>[()<>]>[<[]{}>[<><>]] 94 | <{({((<{[{[<(<[]{}>(<>{}))>][{{<{}<>}{()<>}}<(<>())<()()>>}[[({}()){[]()}](<<>[]>{[]()})]]}<<{(({}<> 95 | (<<{{{[{[{((<{()<>}({}<>)>[(()<>)(<><>)]))[[[(<>[])<{}<>>][[[]<>]<{}()>]]<[(<>{})[<>]]>]}]}][( 96 | ((({([[<[([[[[()[]]<{}()>](({}())[()])]<[{(){}}({}())](([]()){{}()})>]<(({<>{}}[[]{}])<<()<> 97 | {{[(<<([({((([{}<>]{{}[]})([<><>](<>())))[{(()[])[()()]>[(()()){<>[]}]])}<([{[[]()][[]{}]}( 98 | [<<({{[<<[({((()<>)[<>()]){<{}>[[]<>]}}[<{[]()}(()<>)>])<([<<>{}>[<><>]]<{[]<>}[()<>]>){[{<><>}<<>[]>]{(( 99 | -------------------------------------------------------------------------------- /day10b/src/main.rs: -------------------------------------------------------------------------------- 1 | #[allow(clippy::unit_cmp)] 2 | 3 | pub fn main() { 4 | let mut scores = include_str!("../input.txt") 5 | .lines() 6 | .filter_map(|seq| { 7 | let mut s = Vec::with_capacity(64); 8 | seq.bytes() 9 | .all(|c| match c { 10 | c if matches!(c, b'(' | b'[' | b'{' | b'<') => s.push(c) == (), 11 | b')' => s.pop().unwrap() == b'(', 12 | c => s.pop().unwrap() == c - 2, 13 | }) 14 | .then(|| s) 15 | }) 16 | .map(|s| { 17 | s.iter().rev().fold(0usize, |acc, &c| { 18 | acc * 5 + [1, 4, 2, 3][c as usize / 30 - 1] 19 | }) 20 | }) 21 | .collect::>(); 22 | 23 | let mid = scores.len() / 2; 24 | println!("{}", scores.select_nth_unstable(mid).1); 25 | } 26 | -------------------------------------------------------------------------------- /day11a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day11a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day11a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day11a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day11a/input.txt: -------------------------------------------------------------------------------- 1 | 4472562264 2 | 8631517827 3 | 7232144146 4 | 2447163824 5 | 1235272671 6 | 5133527146 7 | 6511372417 8 | 3841841614 9 | 8621368782 10 | 3246336677 -------------------------------------------------------------------------------- /day11a/src/main.rs: -------------------------------------------------------------------------------- 1 | #[rustfmt::skip] 2 | const NEXT: [(isize, isize); 8] = [(0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)]; 3 | const SIZE: usize = 10; 4 | 5 | pub fn main() { 6 | let mut m = include_bytes!("../input.txt") 7 | .split(|&b| b == b'\n') 8 | .map(|l| l.to_vec()) 9 | .collect::>(); 10 | 11 | println!( 12 | "{}", 13 | (0..100).fold(0, |acc, _| { 14 | m.iter_mut() 15 | .for_each(|row| row.iter_mut().for_each(|cell| *cell += 1)); 16 | acc + (0..SIZE) 17 | .flat_map(|y| (0..SIZE).map(move |x| (x, y))) 18 | .fold(0, |acc, (x, y)| { 19 | acc + (m[y][x] > b'9').then(|| flash(&mut m, x, y)).unwrap_or(0) 20 | }) 21 | }), 22 | ); 23 | } 24 | 25 | fn flash(map: &mut Vec>, x: usize, y: usize) -> usize { 26 | map[y][x] = b'0'; 27 | NEXT.iter() 28 | .map(|(xx, yy)| ((x as isize + xx) as usize, (y as isize + yy) as usize)) 29 | .fold(1, |acc, (x, y)| { 30 | match map.get_mut(y).and_then(|l| l.get_mut(x)) { 31 | Some(cell) if *cell > b'0' => { 32 | *cell += 1; 33 | acc + (*cell > b'9').then(|| flash(map, x, y)).unwrap_or(0) 34 | } 35 | _ => acc, 36 | } 37 | }) 38 | } 39 | -------------------------------------------------------------------------------- /day11b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day11b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day11b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day11b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day11b/input.txt: -------------------------------------------------------------------------------- 1 | 4472562264 2 | 8631517827 3 | 7232144146 4 | 2447163824 5 | 1235272671 6 | 5133527146 7 | 6511372417 8 | 3841841614 9 | 8621368782 10 | 3246336677 -------------------------------------------------------------------------------- /day11b/src/main.rs: -------------------------------------------------------------------------------- 1 | #[rustfmt::skip] 2 | const NEXT: [(isize, isize); 8] = [(0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)]; 3 | const SIZE: usize = 10; 4 | 5 | pub fn main() { 6 | let mut m = include_bytes!("../input.txt") 7 | .split(|&b| b == b'\n') 8 | .map(|l| l.to_vec()) 9 | .collect::>(); 10 | 11 | println!( 12 | "{}", 13 | (1..) 14 | .find(|_| { 15 | m.iter_mut() 16 | .for_each(|row| row.iter_mut().for_each(|cell| *cell += 1)); 17 | (0..SIZE) 18 | .flat_map(|y| (0..SIZE).map(move |x| (x, y))) 19 | .fold(0, |acc, (x, y)| { 20 | acc + (m[y][x] > b'9').then(|| flash(&mut m, x, y)).unwrap_or(0) 21 | }) 22 | == SIZE * SIZE 23 | }) 24 | .unwrap(), 25 | ); 26 | } 27 | 28 | fn flash(map: &mut Vec>, x: usize, y: usize) -> usize { 29 | map[y][x] = b'0'; 30 | NEXT.iter() 31 | .map(|(xx, yy)| ((x as isize + xx) as usize, (y as isize + yy) as usize)) 32 | .fold(1, |acc, (x, y)| { 33 | match map.get_mut(y).and_then(|l| l.get_mut(x)) { 34 | Some(cell) if *cell > b'0' => { 35 | *cell += 1; 36 | acc + (*cell > b'9').then(|| flash(map, x, y)).unwrap_or(0) 37 | } 38 | _ => acc, 39 | } 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /day12a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day12a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day12a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day12a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day12a/input.txt: -------------------------------------------------------------------------------- 1 | kc-qy 2 | qy-FN 3 | kc-ZP 4 | end-FN 5 | li-ZP 6 | yc-start 7 | end-qy 8 | yc-ZP 9 | wx-ZP 10 | qy-li 11 | yc-li 12 | yc-wx 13 | kc-FN 14 | FN-li 15 | li-wx 16 | kc-wx 17 | ZP-start 18 | li-kc 19 | qy-nv 20 | ZP-qy 21 | nv-xr 22 | wx-start 23 | end-nv 24 | kc-nv 25 | nv-XQ 26 | -------------------------------------------------------------------------------- /day12a/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::collections::BTreeMap; 2 | 3 | const EDGES: usize = 12; 4 | 5 | pub fn main() { 6 | let mut uc = vec![]; 7 | let mut id: BTreeMap<&str, u8> = BTreeMap::from([("start", 1), ("end", 0)]); 8 | let mut map: BTreeMap> = BTreeMap::new(); 9 | 10 | include_str!("../input.txt").lines().for_each(|l| { 11 | let mut idx = |a| { 12 | let idx = id.len() as u8; 13 | *id.entry(a).or_insert_with(|| { 14 | (a.as_bytes()[0] <= b'Z').then(|| uc.push(idx)); 15 | idx 16 | }) 17 | }; 18 | let mut branch = |a, b| { 19 | let entry = map.entry(a).or_insert_with(|| Vec::with_capacity(6)); 20 | (b != 0).then(|| entry.push(b)); 21 | }; 22 | let (a, b) = l.split_once('-').unwrap(); 23 | let (a, b) = (idx(a), idx(b)); 24 | branch(a, b); 25 | branch(b, a); 26 | }); 27 | 28 | let map = map 29 | .keys() 30 | .filter(|b| !uc.contains(b)) 31 | .map(|&b| { 32 | ( 33 | b, 34 | map[&b].iter().fold([0; EDGES], |mut chld, b| { 35 | if uc.contains(b) { 36 | map[b].iter().for_each(|b| chld[*b as usize] += 1); 37 | } else { 38 | chld[*b as usize] += 1; 39 | } 40 | chld 41 | }), 42 | ) 43 | }) 44 | .collect::>(); 45 | 46 | let mut todo: Vec<(u8, u8, usize)> = vec![(0, 1, 1)]; 47 | let (mut to, mut count) = ([1; EDGES], 0); 48 | while let Some((a, b, s)) = todo.pop() { 49 | to[b as usize] = a; 50 | count += map[&a] 51 | .iter() 52 | .enumerate() 53 | .filter(|&(_, routes)| *routes > 0) 54 | .fold(0, |acc, (c, _)| match c { 55 | 1 => acc + s * map[&a][c], 56 | v => { 57 | let visit = v != 0 && to[2..=b as usize].contains(&(v as u8)); 58 | (!visit).then(|| todo.push((v as u8, b + 1, s * map[&a][v]))); 59 | acc 60 | } 61 | }); 62 | } 63 | 64 | println!("{}", count); 65 | } 66 | -------------------------------------------------------------------------------- /day12b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day12b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day12b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day12b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day12b/input.txt: -------------------------------------------------------------------------------- 1 | kc-qy 2 | qy-FN 3 | kc-ZP 4 | end-FN 5 | li-ZP 6 | yc-start 7 | end-qy 8 | yc-ZP 9 | wx-ZP 10 | qy-li 11 | yc-li 12 | yc-wx 13 | kc-FN 14 | FN-li 15 | li-wx 16 | kc-wx 17 | ZP-start 18 | li-kc 19 | qy-nv 20 | ZP-qy 21 | nv-xr 22 | wx-start 23 | end-nv 24 | kc-nv 25 | nv-XQ 26 | -------------------------------------------------------------------------------- /day12b/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::collections::BTreeMap; 2 | 3 | const EDGES: usize = 12; 4 | 5 | pub fn main() { 6 | let mut uc = vec![]; 7 | let mut id: BTreeMap<&str, u8> = BTreeMap::from([("start", 1), ("end", 0)]); 8 | let mut map: BTreeMap> = BTreeMap::new(); 9 | 10 | include_str!("../input.txt").lines().for_each(|l| { 11 | let mut idx = |a| { 12 | let idx = id.len() as u8; 13 | *id.entry(a).or_insert_with(|| { 14 | (a.as_bytes()[0] <= b'Z').then(|| uc.push(idx)); 15 | idx 16 | }) 17 | }; 18 | let mut branch = |a, b| { 19 | let entry = map.entry(a).or_insert_with(|| Vec::with_capacity(6)); 20 | (b != 0).then(|| entry.push(b)); 21 | }; 22 | let (a, b) = l.split_once('-').unwrap(); 23 | let (a, b) = (idx(a), idx(b)); 24 | branch(a, b); 25 | branch(b, a); 26 | }); 27 | 28 | let map = map 29 | .keys() 30 | .filter(|b| !uc.contains(b)) 31 | .map(|&b| { 32 | ( 33 | b, 34 | map[&b].iter().fold([0; EDGES], |mut chld, b| { 35 | if uc.contains(b) { 36 | map[b].iter().for_each(|b| chld[*b as usize] += 1); 37 | } else { 38 | chld[*b as usize] += 1; 39 | } 40 | chld 41 | }), 42 | ) 43 | }) 44 | .collect::>(); 45 | 46 | let mut todo: Vec<(u8, u8, bool, usize)> = vec![(0, 1, true, 1)]; 47 | let (mut to, mut count) = ([1; EDGES], 0); 48 | while let Some((a, b, t, s)) = todo.pop() { 49 | to[b as usize] = a; 50 | count += map[&a] 51 | .iter() 52 | .enumerate() 53 | .filter(|&(_, routes)| *routes > 0) 54 | .fold(0, |acc, (c, _)| match c { 55 | 1 => acc + s * map[&a][c], 56 | v => { 57 | let visit = v != 0 && to[2..=b as usize].contains(&(v as u8)); 58 | (t || !visit).then(|| todo.push((v as u8, b + 1, t && !visit, s * map[&a][v]))); 59 | acc 60 | } 61 | }); 62 | } 63 | 64 | println!("{}", count); 65 | } 66 | -------------------------------------------------------------------------------- /day13a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day13a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day13a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day13a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day13a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let (coords, folds) = include_str!("../input.txt").split_once("\n\n").unwrap(); 3 | let fold = folds.split_once('\n').unwrap().0; 4 | let (c, i) = fold[11..].split_once('=').unwrap(); 5 | let (c, i) = (c.as_bytes()[0], i.parse().unwrap()); 6 | 7 | let mut coords = coords 8 | .lines() 9 | .map(|l| l.split_once(',').unwrap()) 10 | .map(|(x, y)| (x.parse::().unwrap(), y.parse::().unwrap())) 11 | .filter_map(|(x, y)| match c { 12 | b'x' if x == i => None, 13 | b'x' if x > i => Some((i - (x - i), y)), 14 | b'y' if y == i => None, 15 | b'y' if y > i => Some((x, i - (y - i))), 16 | _ => Some((x, y)), 17 | }) 18 | .collect::>(); 19 | coords.sort_unstable(); 20 | coords.dedup(); 21 | 22 | println!("{}", coords.len()); 23 | } 24 | -------------------------------------------------------------------------------- /day13b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day13b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day13b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day13b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day13b/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(stdio_locked)] 2 | use std::{io::Write, iter::once}; 3 | 4 | const S: [usize; 2] = [40, 6]; 5 | 6 | pub fn main() { 7 | let (coords, folds) = include_str!("../input.txt").split_once("\n\n").unwrap(); 8 | let folds = folds 9 | .lines() 10 | .map(|l| l.trim_start_matches("fold along ").split_once('=').unwrap()) 11 | .map(|(c, i)| (c.as_bytes()[0], i.parse::().unwrap())) 12 | .collect::>(); 13 | 14 | std::io::stdout_locked() 15 | .write_all( 16 | &coords 17 | .lines() 18 | .map(|l| l.split_once(',').unwrap()) 19 | .map(|(x, y)| (x.parse::().unwrap(), y.parse::().unwrap())) 20 | .filter_map(|(mut x, mut y)| { 21 | for &(c, i) in &folds { 22 | match c { 23 | b'x' if x == i => return None, 24 | b'x' if x > i => x = i - (x - i), 25 | b'y' if y == i => return None, 26 | b'y' if y > i => y = i - (y - i), 27 | _ => {} 28 | } 29 | } 30 | Some((x, y)) 31 | }) 32 | .fold(vec![0u64; S[1]], |mut map, (x, y)| { 33 | map[y as usize] |= 1 << x; 34 | map 35 | }) 36 | .iter() 37 | .flat_map(|row| { 38 | (0..S[0]) 39 | .map(move |x| b' ' + ((row & 1 << x) >> x) as u8 * 3) 40 | .chain(once(b'\n')) 41 | }) 42 | .collect::>(), 43 | ) 44 | .unwrap(); 45 | } 46 | -------------------------------------------------------------------------------- /day14a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day14a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day14a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day14a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day14a/input.txt: -------------------------------------------------------------------------------- 1 | OOVSKSPKPPPNNFFBCNOV 2 | 3 | BC -> C 4 | PP -> O 5 | SK -> K 6 | KH -> N 7 | OK -> S 8 | PC -> O 9 | VP -> K 10 | CF -> K 11 | HC -> H 12 | FV -> V 13 | PB -> P 14 | NK -> H 15 | CK -> F 16 | FH -> H 17 | SV -> B 18 | NH -> C 19 | CP -> S 20 | HP -> O 21 | HS -> O 22 | BK -> B 23 | KC -> P 24 | VV -> B 25 | OF -> O 26 | KP -> V 27 | FO -> V 28 | FK -> V 29 | VH -> K 30 | KB -> P 31 | KF -> H 32 | SH -> S 33 | HF -> O 34 | BB -> F 35 | FC -> O 36 | SO -> S 37 | BS -> O 38 | HH -> C 39 | BO -> S 40 | CO -> F 41 | VC -> V 42 | KS -> N 43 | OC -> N 44 | FP -> P 45 | HN -> B 46 | HV -> V 47 | HO -> P 48 | KO -> C 49 | SF -> H 50 | NO -> N 51 | PS -> C 52 | BP -> K 53 | SC -> C 54 | NP -> C 55 | CH -> V 56 | KV -> B 57 | HK -> V 58 | OP -> V 59 | SP -> V 60 | NC -> V 61 | FF -> B 62 | CC -> V 63 | CS -> F 64 | SB -> C 65 | OS -> C 66 | FN -> O 67 | CV -> P 68 | OH -> H 69 | OO -> P 70 | PO -> F 71 | NS -> H 72 | VB -> K 73 | OV -> K 74 | PH -> H 75 | BH -> V 76 | SS -> B 77 | PK -> F 78 | VK -> O 79 | BN -> V 80 | VF -> O 81 | PF -> H 82 | VS -> K 83 | ON -> V 84 | BF -> F 85 | CN -> F 86 | VO -> B 87 | FS -> K 88 | OB -> B 89 | PN -> H 90 | NF -> O 91 | VN -> P 92 | BV -> S 93 | NV -> V 94 | FB -> V 95 | NB -> P 96 | CB -> B 97 | KK -> S 98 | NN -> F 99 | SN -> B 100 | HB -> P 101 | PV -> S 102 | KN -> S 103 | -------------------------------------------------------------------------------- /day14a/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | pub fn main() { 4 | let (base, rules) = include_str!("../input.txt").split_once("\n\n").unwrap(); 5 | 6 | let base = base.as_bytes().to_vec(); 7 | let mut rules = rules 8 | .lines() 9 | .map(|l| { 10 | let (k, t) = l.split_once(" -> ").unwrap(); 11 | let (k, t) = (k.as_bytes(), t.as_bytes()[0]); 12 | ([k[0], k[1]], [k[0], t]) 13 | }) 14 | .collect::>(); 15 | rules.sort_unstable_by_key(|r| r.0); 16 | let rule = rules 17 | .iter() 18 | .map(|r| { 19 | ( 20 | r.0, 21 | rules.binary_search_by_key(&r.1, |r| r.0).unwrap(), 22 | rules 23 | .binary_search_by_key(&[r.1[1], r.0[1]], |r| r.0) 24 | .unwrap(), 25 | ) 26 | }) 27 | .collect::>(); 28 | 29 | let (mut num, mut next) = (vec![0; rule.len()], vec![0; rule.len()]); 30 | base.windows(2) 31 | .for_each(|key| num[rule.binary_search_by_key(&key, |r| &r.0).unwrap()] += 1); 32 | 33 | (0..10).for_each(|_| { 34 | num.iter_mut().zip(&rule).for_each(|(n, r)| { 35 | next[r.1] += *n; 36 | next[r.2] += *n; 37 | *n = 0; 38 | }); 39 | mem::swap(&mut num, &mut next); 40 | }); 41 | 42 | let mut occur = [0; (b'Z' - b'A') as usize]; 43 | occur[(base.last().unwrap() - b'A') as usize] += 1; 44 | rule.iter() 45 | .zip(num) 46 | .for_each(|(r, n)| occur[(r.0[0] - b'A') as usize] += n); 47 | 48 | let (min, max) = occur 49 | .iter() 50 | .filter(|&&n| n != 0) 51 | .fold((u64::MAX, 0), |(min, max), &n| (min.min(n), max.max(n))); 52 | println!("{}", max - min); 53 | } 54 | -------------------------------------------------------------------------------- /day14b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day14b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day14b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day14b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day14b/input.txt: -------------------------------------------------------------------------------- 1 | OOVSKSPKPPPNNFFBCNOV 2 | 3 | BC -> C 4 | PP -> O 5 | SK -> K 6 | KH -> N 7 | OK -> S 8 | PC -> O 9 | VP -> K 10 | CF -> K 11 | HC -> H 12 | FV -> V 13 | PB -> P 14 | NK -> H 15 | CK -> F 16 | FH -> H 17 | SV -> B 18 | NH -> C 19 | CP -> S 20 | HP -> O 21 | HS -> O 22 | BK -> B 23 | KC -> P 24 | VV -> B 25 | OF -> O 26 | KP -> V 27 | FO -> V 28 | FK -> V 29 | VH -> K 30 | KB -> P 31 | KF -> H 32 | SH -> S 33 | HF -> O 34 | BB -> F 35 | FC -> O 36 | SO -> S 37 | BS -> O 38 | HH -> C 39 | BO -> S 40 | CO -> F 41 | VC -> V 42 | KS -> N 43 | OC -> N 44 | FP -> P 45 | HN -> B 46 | HV -> V 47 | HO -> P 48 | KO -> C 49 | SF -> H 50 | NO -> N 51 | PS -> C 52 | BP -> K 53 | SC -> C 54 | NP -> C 55 | CH -> V 56 | KV -> B 57 | HK -> V 58 | OP -> V 59 | SP -> V 60 | NC -> V 61 | FF -> B 62 | CC -> V 63 | CS -> F 64 | SB -> C 65 | OS -> C 66 | FN -> O 67 | CV -> P 68 | OH -> H 69 | OO -> P 70 | PO -> F 71 | NS -> H 72 | VB -> K 73 | OV -> K 74 | PH -> H 75 | BH -> V 76 | SS -> B 77 | PK -> F 78 | VK -> O 79 | BN -> V 80 | VF -> O 81 | PF -> H 82 | VS -> K 83 | ON -> V 84 | BF -> F 85 | CN -> F 86 | VO -> B 87 | FS -> K 88 | OB -> B 89 | PN -> H 90 | NF -> O 91 | VN -> P 92 | BV -> S 93 | NV -> V 94 | FB -> V 95 | NB -> P 96 | CB -> B 97 | KK -> S 98 | NN -> F 99 | SN -> B 100 | HB -> P 101 | PV -> S 102 | KN -> S 103 | -------------------------------------------------------------------------------- /day14b/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::mem; 2 | 3 | pub fn main() { 4 | let (base, rules) = include_str!("../input.txt").split_once("\n\n").unwrap(); 5 | 6 | let base = base.as_bytes().to_vec(); 7 | let mut rules = rules 8 | .lines() 9 | .map(|l| { 10 | let (k, t) = l.split_once(" -> ").unwrap(); 11 | let (k, t) = (k.as_bytes(), t.as_bytes()[0]); 12 | ([k[0], k[1]], [k[0], t]) 13 | }) 14 | .collect::>(); 15 | rules.sort_unstable_by_key(|r| r.0); 16 | let rule = rules 17 | .iter() 18 | .map(|r| { 19 | ( 20 | r.0, 21 | rules.binary_search_by_key(&r.1, |r| r.0).unwrap(), 22 | rules 23 | .binary_search_by_key(&[r.1[1], r.0[1]], |r| r.0) 24 | .unwrap(), 25 | ) 26 | }) 27 | .collect::>(); 28 | 29 | let (mut num, mut next) = (vec![0; rule.len()], vec![0; rule.len()]); 30 | base.windows(2) 31 | .for_each(|key| num[rule.binary_search_by_key(&key, |r| &r.0).unwrap()] += 1); 32 | 33 | (0..40).for_each(|_| { 34 | num.iter_mut().zip(&rule).for_each(|(n, r)| { 35 | next[r.1] += *n; 36 | next[r.2] += *n; 37 | *n = 0; 38 | }); 39 | mem::swap(&mut num, &mut next); 40 | }); 41 | 42 | let mut occur = [0; (b'Z' - b'A') as usize]; 43 | occur[(base.last().unwrap() - b'A') as usize] += 1; 44 | rule.iter() 45 | .zip(num) 46 | .for_each(|(r, n)| occur[(r.0[0] - b'A') as usize] += n); 47 | 48 | let (min, max) = occur 49 | .iter() 50 | .filter(|&&n| n != 0) 51 | .fold((u64::MAX, 0), |(min, max), &n| (min.min(n), max.max(n))); 52 | println!("{}", max - min); 53 | } 54 | -------------------------------------------------------------------------------- /day15a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "autocfg" 7 | version = "1.0.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 10 | 11 | [[package]] 12 | name = "day15a" 13 | version = "0.1.0" 14 | dependencies = [ 15 | "pathfinding", 16 | ] 17 | 18 | [[package]] 19 | name = "either" 20 | version = "1.6.1" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 23 | 24 | [[package]] 25 | name = "fixedbitset" 26 | version = "0.4.0" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e" 29 | 30 | [[package]] 31 | name = "hashbrown" 32 | version = "0.11.2" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 35 | 36 | [[package]] 37 | name = "indexmap" 38 | version = "1.7.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" 41 | dependencies = [ 42 | "autocfg", 43 | "hashbrown", 44 | ] 45 | 46 | [[package]] 47 | name = "integer-sqrt" 48 | version = "0.1.5" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" 51 | dependencies = [ 52 | "num-traits", 53 | ] 54 | 55 | [[package]] 56 | name = "itertools" 57 | version = "0.10.3" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 60 | dependencies = [ 61 | "either", 62 | ] 63 | 64 | [[package]] 65 | name = "num-traits" 66 | version = "0.2.14" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 69 | dependencies = [ 70 | "autocfg", 71 | ] 72 | 73 | [[package]] 74 | name = "pathfinding" 75 | version = "3.0.5" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "8a64bfa665d8821a903701c7bb440e7f72b1f05387b390cc23f498cc23148099" 78 | dependencies = [ 79 | "fixedbitset", 80 | "indexmap", 81 | "integer-sqrt", 82 | "itertools", 83 | "num-traits", 84 | "rustc-hash", 85 | ] 86 | 87 | [[package]] 88 | name = "rustc-hash" 89 | version = "1.1.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 92 | -------------------------------------------------------------------------------- /day15a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day15a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | pathfinding = "3.0" 12 | -------------------------------------------------------------------------------- /day15a/input.txt: -------------------------------------------------------------------------------- 1 | 1631196814251372911576579235812119112999813211934811373149623868144186389623722791119539949522144313 2 | 9188121321122851414231854163348238311917148974121419323871752541929227519231198852351293513134914473 3 | 4215676183741213527339331353288981132197947331219528111783619598331913296928619184942471785158367454 4 | 2251217171971152724177163921253115122983577112942474115151352465226121141697681766839691161112219324 5 | 1961611243289419266932117156684919673116135119671489326291133816113132512372721931413936141348491174 6 | 7269114374391533415635121743625566592554111117711241378517141422713695418216125897637975945511115522 7 | 1144123216126218521233215427542393912717645925127237985932114949434192124652161499471135959814578213 8 | 7796911551446529195636181229998815359954454794223223462717188113621233432281961212942721262217614613 9 | 6118139111941491415311113193921413851521589111893147725216195198122397111413115311366121921627452518 10 | 1331264861134181111918113115248139311614354942194412221294329416731932123911261981493213891761232278 11 | 2221144593111111912992873641826161238641422623111741211211518357366249184344191148548614212244354734 12 | 1211213371213148294142153457533451931866873944444194664128116531396333843195292119371231891868991141 13 | 5831917921213162781451341196354111153139261622831671142244121611561361418691252224135365111329836345 14 | 4138219222532973518122416261247534313154771248749165139128311153131378273119913353321121189987111218 15 | 7592334519894651934117182368717748728349225314316818631357329917913899122222317415829211918984472224 16 | 3529175122394833837311556412119135519619726712474999794918232711732216596127762564141171871619424237 17 | 3811393894214611963837112311561131414275467797111295142659481511391222811435211645124732872247121173 18 | 3173296527331637499232361144799131431129827112551361111233567454814221419531332911113541333811611161 19 | 4163891857422177592289991612336735419295845427316194531541411784621119116379142173129441111899274152 20 | 3517131642652188283112778215811244153141686651213636112545392472121582491151322156419586312874359791 21 | 9693566118818185918862125826722128313318227114928267863142179212514689219713693391879641397611742624 22 | 5289313922222131322321759341211211143123969192112173141216911115384347112431363387719111515937362788 23 | 4966821841158112276911292252282531318266126917161665323441152195177525617843989725926419592293915841 24 | 9427715674347511131183159319724911513177723332277514816219785137417122459113591113117371922242432141 25 | 3812391991319161863571741619317494259138312498283218186119962111111322933111156912129311211361299732 26 | 2748225685171923963542619357241266329195292813733186931124542181194142127691111743421423373615624321 27 | 9531298911291715167822699611223153831851157425916669512228121999812232324191599893781224113431448161 28 | 2891228355912333913182991329511965117911624224497739482524533516533972914514141111218425284321377721 29 | 2392681536132118225296242231917682711533193153139453227362514131852189661144942131282863945252521391 30 | 1567442934182128674727141212129359121112721119322782334881816914225919132921993219112491538371321794 31 | 1851121361571352321135771114434418715428231469375354434831131216711193961712699818226124312321791192 32 | 8568221155322245167244326491552112112164341815539523535938114762199171462119197912229874259422126928 33 | 3862153285471615891361912115213789126413194374124242361839224236133476292148411914153928149414444961 34 | 7461614147763131314729141991937121713418823199979558936646289212684938128839126168981842499124699948 35 | 8265421321298783511889124781934115116514712658827292419163265374319848122623162121741431126189413714 36 | 3615591491111213129361911857716219134853312281219569912692312373777116174347161129929917714271572417 37 | 6996142241978141451142834339345359211195945132194281949428218333124239517519991621939221729612195587 38 | 7453424594171241919916135939617918917947229726136326874465141215221112516526966767711981138874159363 39 | 8911951264661289485146575817119114851221117236412371499921316173657127246829496192218847127895111161 40 | 1123113419449955451846755127382394821613317934848159212715151895246299242523852391672211289319121519 41 | 1924196861511342262243845221421135163244657711452121724125897613437319364233319122615551448271111164 42 | 5133231123722341158315177892111565627191791992137785793928261141113113262115795828419452218914216358 43 | 6124387731112225351316112312688523814529497441968217944126564998118211519995819214119615918164534426 44 | 1752525515747712421697274222191991237551581414218172634946215191917539153568822923272748412323139411 45 | 2112812138149164595422722712157321996235689515527117418614112267271914125366621674567541835813451514 46 | 8881742352481419174936517146533211326331215444141333893455566214323112221133221661152911221612195135 47 | 1216834911351513628171992327145922222663911497229324134248271459321851128734217482592397354583193185 48 | 1291317339119291928212177981324772453591113724462116172287361912212197161657352133525999442332211435 49 | 3241429379615293177949614321731115131297249712558943263311133226641824698994911181211115187245121131 50 | 1111791929711162413141911151841443924411295154671313821798331173411268575123129423122594397973441239 51 | 1197377389494849184613145929718181471961256221988946117736829117611948593538119914121429227149218381 52 | 5919724778141943693113368181432495841334864461446156641179542144199299975134339334113161641687211229 53 | 3123532448566613219791348281111792388295617589813585624726312556993982983544216418749532871175742351 54 | 2721129162454965116371352539341912916122114721859396192192416112214431134136556386791411622568215392 55 | 3621799113274151192616819931112911147619316186119372987129612314239572118322252941181618629623232699 56 | 9813192482642252181172211559131471999285917394523134534147475497951519638431362458263239611498363158 57 | 8245535728991769628414412379188511213889882936422421248351947446189912618547748486694324323211141918 58 | 1998221314212511122326922816119413531121523933744762819792113629611871834569713577636726416223335212 59 | 2154542143191182921154392113111871292423221329599553726289311132542312952111489893241248115161567223 60 | 9138913446711888732529173545317299684127473312332811269573217313321953996892576331162211532212813221 61 | 2151168218121466631119368341318421172383118447324377166399558315399115128122789117818417261199114111 62 | 4286912117121989561772311238351374997915786221491316523117114135961662452712222135991211415912123311 63 | 6892743381397586311122737621971129191744621933753413515159315522421711221831813929121371123532474384 64 | 8251122735497191174933721352919147616119974453271591619175998133499253258915413899231185951891166151 65 | 9512331713273258623161489559275654252516919131719973713211251342434631579819179932589194739622111123 66 | 1339115831121535522715134341326763591969241321211951111419653491777532942139935416431856169184181911 67 | 8322442891391119221542435923155688223131522411294254334992646331862111958284176126126113861121286191 68 | 9177812874423371265452679291625523653984424976279214931134541123739664876887172539131641311252382191 69 | 3424121119669565423616749471611641366819942742997819411572369143113914174477341811182562133171462325 70 | 1711994313313428253367791521138393591361116122659181592329296195223531524391111563912212721711214728 71 | 1551437228341828984252161112181117116121191535261751311235151172627518271345724945232134134294212151 72 | 1122656251334226522535362472411411379179911313531197776215191314395332193417399695732937722328973111 73 | 8374378619266683323461212711912323919327471139171677141648833836911131112221236115111818114612111364 74 | 4362921324721973324932282319973622734233219221114176719141373111198221114269333313749398513849113191 75 | 1669421864982478658119633929211112129168923647927144168171145713411128916594418125154829211124963118 76 | 2949811735984154723511132731584112935392815811136711272189211318851677185871486193852872719921646713 77 | 1128752752399328511232543151549836485324972624231329896492237681265499215321411842128112371721724977 78 | 2226137319681917161531571219347264471595923321549164311417718969716955963195871224461118161394785545 79 | 4235441925421112237112832171332119221772315716945793126212523111471281229225613454946241136518328311 80 | 2936619615411418279664261341121688111121288644899384993123737471186416166457382381114393592188534153 81 | 5129929912133411894269551832522215258229221923912693112853741343169472221148214616343391822595187541 82 | 9221939111322211316111121551955416212818291329181514244391314421113241989512195432649299174611111173 83 | 1318427121511251499322211112262571511935271537519192818191218419133637821163992942716223222171936322 84 | 3351814483393439321921981116395757476153117332328984292921912163569165191285725321281423157631377119 85 | 1121714151135462121192214364317499151979417195931241591223117715112111668861911521164289191398422731 86 | 1818141213311687121119187893592411421941811359181531328135325819537132612118544245111121481811815255 87 | 4413194121141633562993511215161912854153341311278591182266346447977312132431971319162251689431471259 88 | 7811143121185311162259114151212489914141186372746512312518177425952111213141594171363416214262351514 89 | 5113517628143491126213221834835792972575931421969294189289398522929992132146178582336732941118113323 90 | 9882859948156919699392156992959495423891191358577595239228294112424199416175617341191289593564311277 91 | 5131112911239152319458266235225243429292655981113412112281443489361299162146238153227264331444211111 92 | 9128886482518115142371937326194212122198264415241946792349243111681127571967126412714925161618934571 93 | 2692917729427716331421922131398233794729447868491611691512342966151512542917291364421311219416233342 94 | 5291125973868995179656318544811113699511461511129791112281716699116231821319391859114713132397369713 95 | 1359251887142159956112811532511675311111998139353632119924367113356324976241273941662882229642431231 96 | 8194297291181931224931292129559462427245813212177618314214187642393229269815518151141722124932591124 97 | 1954581652511649212131131371211956691675612331421991137928234749695132513122331441114117129619798254 98 | 4289741424715911236217263189784412578418861111216178695219191847216835122285633211921454732479313712 99 | 9252146448218238875939619191967421281428148665211911718952111182181114219711127632131551563327591916 100 | 4519233214164141882743882142992884172832615414912312373153212281212219298923129375514264315424683991 101 | -------------------------------------------------------------------------------- /day15a/src/main.rs: -------------------------------------------------------------------------------- 1 | use pathfinding::directed::dijkstra; 2 | 3 | const NEXT: [(i32, i32); 4] = [(1, 0), (-1, 0), (0, 1), (0, -1)]; 4 | 5 | pub fn main() { 6 | let map: Vec> = include_str!("../input.txt") 7 | .lines() 8 | .map(|l| l.bytes().map(|c| c - b'0').collect()) 9 | .collect(); 10 | let goal = (map[0].len() as i32 - 1, map.len() as i32 - 1); 11 | 12 | println!( 13 | "{}", 14 | dijkstra::dijkstra( 15 | &(0, 0), 16 | |(x, y)| { 17 | NEXT.iter() 18 | .map(|(xx, yy)| { 19 | map.get((y + yy) as usize) 20 | .and_then(|r| r.get((x + xx) as usize)) 21 | .map(|c| ((x + xx, y + yy), *c as u32)) 22 | }) 23 | .flatten() 24 | .collect::>() 25 | }, 26 | |&p| p == goal, 27 | ) 28 | .unwrap() 29 | .1, 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /day15b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "autocfg" 7 | version = "1.0.1" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 10 | 11 | [[package]] 12 | name = "day15b" 13 | version = "0.1.0" 14 | dependencies = [ 15 | "pathfinding", 16 | ] 17 | 18 | [[package]] 19 | name = "either" 20 | version = "1.6.1" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 23 | 24 | [[package]] 25 | name = "fixedbitset" 26 | version = "0.4.0" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | checksum = "398ea4fabe40b9b0d885340a2a991a44c8a645624075ad966d21f88688e2b69e" 29 | 30 | [[package]] 31 | name = "hashbrown" 32 | version = "0.11.2" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 35 | 36 | [[package]] 37 | name = "indexmap" 38 | version = "1.7.0" 39 | source = "registry+https://github.com/rust-lang/crates.io-index" 40 | checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" 41 | dependencies = [ 42 | "autocfg", 43 | "hashbrown", 44 | ] 45 | 46 | [[package]] 47 | name = "integer-sqrt" 48 | version = "0.1.5" 49 | source = "registry+https://github.com/rust-lang/crates.io-index" 50 | checksum = "276ec31bcb4a9ee45f58bec6f9ec700ae4cf4f4f8f2fa7e06cb406bd5ffdd770" 51 | dependencies = [ 52 | "num-traits", 53 | ] 54 | 55 | [[package]] 56 | name = "itertools" 57 | version = "0.10.3" 58 | source = "registry+https://github.com/rust-lang/crates.io-index" 59 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 60 | dependencies = [ 61 | "either", 62 | ] 63 | 64 | [[package]] 65 | name = "num-traits" 66 | version = "0.2.14" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 69 | dependencies = [ 70 | "autocfg", 71 | ] 72 | 73 | [[package]] 74 | name = "pathfinding" 75 | version = "3.0.5" 76 | source = "registry+https://github.com/rust-lang/crates.io-index" 77 | checksum = "8a64bfa665d8821a903701c7bb440e7f72b1f05387b390cc23f498cc23148099" 78 | dependencies = [ 79 | "fixedbitset", 80 | "indexmap", 81 | "integer-sqrt", 82 | "itertools", 83 | "num-traits", 84 | "rustc-hash", 85 | ] 86 | 87 | [[package]] 88 | name = "rustc-hash" 89 | version = "1.1.0" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" 92 | -------------------------------------------------------------------------------- /day15b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day15b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | pathfinding = "3.0" 12 | -------------------------------------------------------------------------------- /day15b/input.txt: -------------------------------------------------------------------------------- 1 | 1631196814251372911576579235812119112999813211934811373149623868144186389623722791119539949522144313 2 | 9188121321122851414231854163348238311917148974121419323871752541929227519231198852351293513134914473 3 | 4215676183741213527339331353288981132197947331219528111783619598331913296928619184942471785158367454 4 | 2251217171971152724177163921253115122983577112942474115151352465226121141697681766839691161112219324 5 | 1961611243289419266932117156684919673116135119671489326291133816113132512372721931413936141348491174 6 | 7269114374391533415635121743625566592554111117711241378517141422713695418216125897637975945511115522 7 | 1144123216126218521233215427542393912717645925127237985932114949434192124652161499471135959814578213 8 | 7796911551446529195636181229998815359954454794223223462717188113621233432281961212942721262217614613 9 | 6118139111941491415311113193921413851521589111893147725216195198122397111413115311366121921627452518 10 | 1331264861134181111918113115248139311614354942194412221294329416731932123911261981493213891761232278 11 | 2221144593111111912992873641826161238641422623111741211211518357366249184344191148548614212244354734 12 | 1211213371213148294142153457533451931866873944444194664128116531396333843195292119371231891868991141 13 | 5831917921213162781451341196354111153139261622831671142244121611561361418691252224135365111329836345 14 | 4138219222532973518122416261247534313154771248749165139128311153131378273119913353321121189987111218 15 | 7592334519894651934117182368717748728349225314316818631357329917913899122222317415829211918984472224 16 | 3529175122394833837311556412119135519619726712474999794918232711732216596127762564141171871619424237 17 | 3811393894214611963837112311561131414275467797111295142659481511391222811435211645124732872247121173 18 | 3173296527331637499232361144799131431129827112551361111233567454814221419531332911113541333811611161 19 | 4163891857422177592289991612336735419295845427316194531541411784621119116379142173129441111899274152 20 | 3517131642652188283112778215811244153141686651213636112545392472121582491151322156419586312874359791 21 | 9693566118818185918862125826722128313318227114928267863142179212514689219713693391879641397611742624 22 | 5289313922222131322321759341211211143123969192112173141216911115384347112431363387719111515937362788 23 | 4966821841158112276911292252282531318266126917161665323441152195177525617843989725926419592293915841 24 | 9427715674347511131183159319724911513177723332277514816219785137417122459113591113117371922242432141 25 | 3812391991319161863571741619317494259138312498283218186119962111111322933111156912129311211361299732 26 | 2748225685171923963542619357241266329195292813733186931124542181194142127691111743421423373615624321 27 | 9531298911291715167822699611223153831851157425916669512228121999812232324191599893781224113431448161 28 | 2891228355912333913182991329511965117911624224497739482524533516533972914514141111218425284321377721 29 | 2392681536132118225296242231917682711533193153139453227362514131852189661144942131282863945252521391 30 | 1567442934182128674727141212129359121112721119322782334881816914225919132921993219112491538371321794 31 | 1851121361571352321135771114434418715428231469375354434831131216711193961712699818226124312321791192 32 | 8568221155322245167244326491552112112164341815539523535938114762199171462119197912229874259422126928 33 | 3862153285471615891361912115213789126413194374124242361839224236133476292148411914153928149414444961 34 | 7461614147763131314729141991937121713418823199979558936646289212684938128839126168981842499124699948 35 | 8265421321298783511889124781934115116514712658827292419163265374319848122623162121741431126189413714 36 | 3615591491111213129361911857716219134853312281219569912692312373777116174347161129929917714271572417 37 | 6996142241978141451142834339345359211195945132194281949428218333124239517519991621939221729612195587 38 | 7453424594171241919916135939617918917947229726136326874465141215221112516526966767711981138874159363 39 | 8911951264661289485146575817119114851221117236412371499921316173657127246829496192218847127895111161 40 | 1123113419449955451846755127382394821613317934848159212715151895246299242523852391672211289319121519 41 | 1924196861511342262243845221421135163244657711452121724125897613437319364233319122615551448271111164 42 | 5133231123722341158315177892111565627191791992137785793928261141113113262115795828419452218914216358 43 | 6124387731112225351316112312688523814529497441968217944126564998118211519995819214119615918164534426 44 | 1752525515747712421697274222191991237551581414218172634946215191917539153568822923272748412323139411 45 | 2112812138149164595422722712157321996235689515527117418614112267271914125366621674567541835813451514 46 | 8881742352481419174936517146533211326331215444141333893455566214323112221133221661152911221612195135 47 | 1216834911351513628171992327145922222663911497229324134248271459321851128734217482592397354583193185 48 | 1291317339119291928212177981324772453591113724462116172287361912212197161657352133525999442332211435 49 | 3241429379615293177949614321731115131297249712558943263311133226641824698994911181211115187245121131 50 | 1111791929711162413141911151841443924411295154671313821798331173411268575123129423122594397973441239 51 | 1197377389494849184613145929718181471961256221988946117736829117611948593538119914121429227149218381 52 | 5919724778141943693113368181432495841334864461446156641179542144199299975134339334113161641687211229 53 | 3123532448566613219791348281111792388295617589813585624726312556993982983544216418749532871175742351 54 | 2721129162454965116371352539341912916122114721859396192192416112214431134136556386791411622568215392 55 | 3621799113274151192616819931112911147619316186119372987129612314239572118322252941181618629623232699 56 | 9813192482642252181172211559131471999285917394523134534147475497951519638431362458263239611498363158 57 | 8245535728991769628414412379188511213889882936422421248351947446189912618547748486694324323211141918 58 | 1998221314212511122326922816119413531121523933744762819792113629611871834569713577636726416223335212 59 | 2154542143191182921154392113111871292423221329599553726289311132542312952111489893241248115161567223 60 | 9138913446711888732529173545317299684127473312332811269573217313321953996892576331162211532212813221 61 | 2151168218121466631119368341318421172383118447324377166399558315399115128122789117818417261199114111 62 | 4286912117121989561772311238351374997915786221491316523117114135961662452712222135991211415912123311 63 | 6892743381397586311122737621971129191744621933753413515159315522421711221831813929121371123532474384 64 | 8251122735497191174933721352919147616119974453271591619175998133499253258915413899231185951891166151 65 | 9512331713273258623161489559275654252516919131719973713211251342434631579819179932589194739622111123 66 | 1339115831121535522715134341326763591969241321211951111419653491777532942139935416431856169184181911 67 | 8322442891391119221542435923155688223131522411294254334992646331862111958284176126126113861121286191 68 | 9177812874423371265452679291625523653984424976279214931134541123739664876887172539131641311252382191 69 | 3424121119669565423616749471611641366819942742997819411572369143113914174477341811182562133171462325 70 | 1711994313313428253367791521138393591361116122659181592329296195223531524391111563912212721711214728 71 | 1551437228341828984252161112181117116121191535261751311235151172627518271345724945232134134294212151 72 | 1122656251334226522535362472411411379179911313531197776215191314395332193417399695732937722328973111 73 | 8374378619266683323461212711912323919327471139171677141648833836911131112221236115111818114612111364 74 | 4362921324721973324932282319973622734233219221114176719141373111198221114269333313749398513849113191 75 | 1669421864982478658119633929211112129168923647927144168171145713411128916594418125154829211124963118 76 | 2949811735984154723511132731584112935392815811136711272189211318851677185871486193852872719921646713 77 | 1128752752399328511232543151549836485324972624231329896492237681265499215321411842128112371721724977 78 | 2226137319681917161531571219347264471595923321549164311417718969716955963195871224461118161394785545 79 | 4235441925421112237112832171332119221772315716945793126212523111471281229225613454946241136518328311 80 | 2936619615411418279664261341121688111121288644899384993123737471186416166457382381114393592188534153 81 | 5129929912133411894269551832522215258229221923912693112853741343169472221148214616343391822595187541 82 | 9221939111322211316111121551955416212818291329181514244391314421113241989512195432649299174611111173 83 | 1318427121511251499322211112262571511935271537519192818191218419133637821163992942716223222171936322 84 | 3351814483393439321921981116395757476153117332328984292921912163569165191285725321281423157631377119 85 | 1121714151135462121192214364317499151979417195931241591223117715112111668861911521164289191398422731 86 | 1818141213311687121119187893592411421941811359181531328135325819537132612118544245111121481811815255 87 | 4413194121141633562993511215161912854153341311278591182266346447977312132431971319162251689431471259 88 | 7811143121185311162259114151212489914141186372746512312518177425952111213141594171363416214262351514 89 | 5113517628143491126213221834835792972575931421969294189289398522929992132146178582336732941118113323 90 | 9882859948156919699392156992959495423891191358577595239228294112424199416175617341191289593564311277 91 | 5131112911239152319458266235225243429292655981113412112281443489361299162146238153227264331444211111 92 | 9128886482518115142371937326194212122198264415241946792349243111681127571967126412714925161618934571 93 | 2692917729427716331421922131398233794729447868491611691512342966151512542917291364421311219416233342 94 | 5291125973868995179656318544811113699511461511129791112281716699116231821319391859114713132397369713 95 | 1359251887142159956112811532511675311111998139353632119924367113356324976241273941662882229642431231 96 | 8194297291181931224931292129559462427245813212177618314214187642393229269815518151141722124932591124 97 | 1954581652511649212131131371211956691675612331421991137928234749695132513122331441114117129619798254 98 | 4289741424715911236217263189784412578418861111216178695219191847216835122285633211921454732479313712 99 | 9252146448218238875939619191967421281428148665211911718952111182181114219711127632131551563327591916 100 | 4519233214164141882743882142992884172832615414912312373153212281212219298923129375514264315424683991 101 | -------------------------------------------------------------------------------- /day15b/src/main.rs: -------------------------------------------------------------------------------- 1 | use pathfinding::directed::dijkstra; 2 | 3 | const NEXT: [(i32, i32); 4] = [(1, 0), (-1, 0), (0, 1), (0, -1)]; 4 | 5 | pub fn main() { 6 | let map: Vec> = include_str!("../input.txt") 7 | .lines() 8 | .map(|l| l.bytes().map(|c| c - b'0').collect()) 9 | .collect(); 10 | let s = map.len(); 11 | let goal = (s as i32 * 5 - 1, s as i32 * 5 - 1); 12 | 13 | println!( 14 | "{}", 15 | dijkstra::dijkstra( 16 | &(0, 0), 17 | |&(x, y)| { 18 | NEXT.iter() 19 | .map(|&(xx, yy)| ((x + xx) as usize, (y + yy) as usize)) 20 | .filter(|(x, y)| (x / 5 < s && y / 5 < s)) 21 | .map(|(x, y)| { 22 | map.get(y % s).and_then(|r| r.get(x % s)).map(|c| { 23 | ( 24 | (x as i32, y as i32), 25 | ((*c as usize + (x / s) + (y / s) - 1) % 9 + 1) as u32, 26 | ) 27 | }) 28 | }) 29 | .flatten() 30 | .collect::>() 31 | }, 32 | |&p| p == goal, 33 | ) 34 | .unwrap() 35 | .1, 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /day16a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day16a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day16a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day16a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day16a/input.txt: -------------------------------------------------------------------------------- 1 | 4054460802532B12FEE8B180213B19FA5AA77601C010E4EC2571A9EDFE356C7008E7B141898C1F4E50DA7438C011D005E4F6E727B738FC40180CB3ED802323A8C3FED8C4E8844297D88C578C26008E004373BCA6B1C1C99945423798025800D0CFF7DC199C9094E35980253FB50A00D4C401B87104A0C8002171CE31C41201062C01393AE2F5BCF7B6E969F3C553F2F0A10091F2D719C00CD0401A8FB1C6340803308A0947B30056803361006615C468E4200E47E8411D26697FC3F91740094E164DFA0453F46899015002A6E39F3B9802B800D04A24CC763EDBB4AFF923A96ED4BDC01F87329FA491E08180253A4DE0084C5B7F5B978CC410012F9CFA84C93900A5135BD739835F00540010F8BF1D22A0803706E0A47B3009A587E7D5E4D3A59B4C00E9567300AE791E0DCA3C4A32CDBDC4830056639D57C00D4C401C8791162380021108E26C6D991D10082549218CDC671479A97233D43993D70056663FAC630CB44D2E380592FB93C4F40CA7D1A60FE64348039CE0069E5F565697D59424B92AF246AC065DB01812805AD901552004FDB801E200738016403CC000DD2E0053801E600700091A801ED20065E60071801A800AEB00151316450014388010B86105E13980350423F447200436164688A4001E0488AC90FCDF31074929452E7612B151803A200EC398670E8401B82D04E31880390463446520040A44AA71C25653B6F2FE80124C9FF18EDFCA109275A140289CDF7B3AEEB0C954F4B5FC7CD2623E859726FB6E57DA499EA77B6B68E0401D996D9C4292A881803926FB26232A133598A118023400FA4ADADD5A97CEEC0D37696FC0E6009D002A937B459BDA3CC7FFD65200F2E531581AD80230326E11F52DFAEAAA11DCC01091D8BE0039B296AB9CE5B576130053001529BE38CDF1D22C100509298B9950020B309B3098C002F419100226DC 2 | -------------------------------------------------------------------------------- /day16a/src/bits.rs: -------------------------------------------------------------------------------- 1 | pub struct Bits<'a> { 2 | b: &'a [u8], 3 | pos: usize, 4 | len: usize, 5 | } 6 | 7 | impl<'a> Bits<'a> { 8 | pub fn new(b: &'a [u8]) -> Self { 9 | Self { 10 | pos: 0, 11 | len: b.len() * 8, 12 | b, 13 | } 14 | } 15 | 16 | pub fn take(&mut self, mut count: usize) -> usize { 17 | let mut out = 0; 18 | while count > 0 { 19 | let left = 8 - (self.pos % 8); 20 | let bits = left.min(count); 21 | out = out << bits 22 | | ((self.b[self.pos / 8] & u8::MAX >> (self.pos % 8)) >> (left - bits)) as usize; 23 | count -= bits; 24 | self.skip(bits); 25 | } 26 | out 27 | } 28 | 29 | pub fn take_literal(&mut self) -> usize { 30 | let mut out = 0; 31 | loop { 32 | let num = self.take(5); 33 | out = out << 4 | num & 0b1111; 34 | if num & 0b10000 == 0 { 35 | return out; 36 | } 37 | } 38 | } 39 | 40 | pub fn split(&mut self, count: usize) -> Bits { 41 | debug_assert!(count <= self.len - self.pos); 42 | self.pos += count; 43 | Bits { 44 | b: self.b, 45 | pos: self.pos - count, 46 | len: self.pos, 47 | } 48 | } 49 | 50 | pub fn is_empty(&self) -> bool { 51 | self.pos >= self.len 52 | } 53 | 54 | pub fn skip(&mut self, count: usize) { 55 | debug_assert!(self.pos <= self.len); 56 | self.pos += count; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /day16a/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(array_chunks)] 2 | 3 | mod bits; 4 | 5 | use bits::Bits; 6 | 7 | pub fn main() { 8 | let bytes = include_str!("../input.txt") 9 | .trim() 10 | .as_bytes() 11 | .array_chunks() 12 | .map(|&[a, b]| { 13 | (((a as char).to_digit(16).unwrap() as u8) << 4) 14 | | (b as char).to_digit(16).unwrap() as u8 15 | }) 16 | .collect::>(); 17 | println!("{}", packet(&mut Bits::new(&bytes))); 18 | } 19 | 20 | fn packet(bits: &mut Bits) -> usize { 21 | let mut ver = bits.take(3); 22 | if bits.take(3) == 4 { 23 | bits.take_literal(); 24 | return ver; 25 | } 26 | 27 | if bits.take(1) == 0 { 28 | let len = bits.take(15); 29 | let mut payload = bits.split(len); 30 | while !payload.is_empty() { 31 | ver += packet(&mut payload); 32 | } 33 | } else { 34 | (0..bits.take(11)).for_each(|_| ver += packet(bits)); 35 | } 36 | ver 37 | } 38 | -------------------------------------------------------------------------------- /day16b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day16b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day16b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day16b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day16b/input.txt: -------------------------------------------------------------------------------- 1 | 4054460802532B12FEE8B180213B19FA5AA77601C010E4EC2571A9EDFE356C7008E7B141898C1F4E50DA7438C011D005E4F6E727B738FC40180CB3ED802323A8C3FED8C4E8844297D88C578C26008E004373BCA6B1C1C99945423798025800D0CFF7DC199C9094E35980253FB50A00D4C401B87104A0C8002171CE31C41201062C01393AE2F5BCF7B6E969F3C553F2F0A10091F2D719C00CD0401A8FB1C6340803308A0947B30056803361006615C468E4200E47E8411D26697FC3F91740094E164DFA0453F46899015002A6E39F3B9802B800D04A24CC763EDBB4AFF923A96ED4BDC01F87329FA491E08180253A4DE0084C5B7F5B978CC410012F9CFA84C93900A5135BD739835F00540010F8BF1D22A0803706E0A47B3009A587E7D5E4D3A59B4C00E9567300AE791E0DCA3C4A32CDBDC4830056639D57C00D4C401C8791162380021108E26C6D991D10082549218CDC671479A97233D43993D70056663FAC630CB44D2E380592FB93C4F40CA7D1A60FE64348039CE0069E5F565697D59424B92AF246AC065DB01812805AD901552004FDB801E200738016403CC000DD2E0053801E600700091A801ED20065E60071801A800AEB00151316450014388010B86105E13980350423F447200436164688A4001E0488AC90FCDF31074929452E7612B151803A200EC398670E8401B82D04E31880390463446520040A44AA71C25653B6F2FE80124C9FF18EDFCA109275A140289CDF7B3AEEB0C954F4B5FC7CD2623E859726FB6E57DA499EA77B6B68E0401D996D9C4292A881803926FB26232A133598A118023400FA4ADADD5A97CEEC0D37696FC0E6009D002A937B459BDA3CC7FFD65200F2E531581AD80230326E11F52DFAEAAA11DCC01091D8BE0039B296AB9CE5B576130053001529BE38CDF1D22C100509298B9950020B309B3098C002F419100226DC 2 | -------------------------------------------------------------------------------- /day16b/src/bits.rs: -------------------------------------------------------------------------------- 1 | pub struct Bits<'a> { 2 | b: &'a [u8], 3 | pos: usize, 4 | len: usize, 5 | } 6 | 7 | impl<'a> Bits<'a> { 8 | pub fn new(b: &'a [u8]) -> Self { 9 | Self { 10 | pos: 0, 11 | len: b.len() * 8, 12 | b, 13 | } 14 | } 15 | 16 | pub fn take(&mut self, mut count: usize) -> usize { 17 | let mut out = 0; 18 | while count > 0 { 19 | let left = 8 - (self.pos % 8); 20 | let bits = left.min(count); 21 | out = out << bits 22 | | ((self.b[self.pos / 8] & u8::MAX >> (self.pos % 8)) >> (left - bits)) as usize; 23 | count -= bits; 24 | self.skip(bits); 25 | } 26 | out 27 | } 28 | 29 | pub fn take_literal(&mut self) -> usize { 30 | let mut out = 0; 31 | loop { 32 | let num = self.take(5); 33 | out = out << 4 | num & 0b1111; 34 | if num & 0b10000 == 0 { 35 | return out; 36 | } 37 | } 38 | } 39 | 40 | pub fn split(&mut self, count: usize) -> Bits { 41 | debug_assert!(count <= self.len - self.pos); 42 | self.pos += count; 43 | Bits { 44 | b: self.b, 45 | pos: self.pos - count, 46 | len: self.pos, 47 | } 48 | } 49 | 50 | pub fn is_empty(&self) -> bool { 51 | self.pos >= self.len 52 | } 53 | 54 | pub fn skip(&mut self, count: usize) { 55 | debug_assert!(self.pos <= self.len); 56 | self.pos += count; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /day16b/src/main.rs: -------------------------------------------------------------------------------- 1 | #![feature(array_chunks)] 2 | 3 | mod bits; 4 | 5 | use bits::Bits; 6 | 7 | pub fn main() { 8 | let bytes = include_str!("../input.txt") 9 | .trim() 10 | .as_bytes() 11 | .array_chunks() 12 | .map(|&[a, b]| { 13 | (((a as char).to_digit(16).unwrap() as u8) << 4) 14 | | (b as char).to_digit(16).unwrap() as u8 15 | }) 16 | .collect::>(); 17 | println!("{}", packet(&mut Bits::new(&bytes))[0]); 18 | } 19 | 20 | fn packet(bits: &mut Bits) -> Vec { 21 | bits.skip(3); 22 | let typ = bits.take(3); 23 | if typ == 4 { 24 | return vec![bits.take_literal()]; 25 | } 26 | 27 | let mut nums = vec![]; 28 | if bits.take(1) == 0 { 29 | let len = bits.take(15); 30 | let mut payload = bits.split(len); 31 | while !payload.is_empty() { 32 | nums.extend_from_slice(&packet(&mut payload)); 33 | } 34 | } else { 35 | (0..bits.take(11)).for_each(|_| nums.extend_from_slice(&packet(bits))); 36 | } 37 | 38 | match typ { 39 | 0 => vec![nums.iter().sum()], 40 | 1 => vec![nums.iter().product()], 41 | 2 => vec![*nums.iter().min().unwrap()], 42 | 3 => vec![*nums.iter().max().unwrap()], 43 | 5 => vec![(nums[0] > nums[1]) as usize], 44 | 6 => vec![(nums[0] < nums[1]) as usize], 45 | 7 => vec![(nums[0] == nums[1]) as usize], 46 | _ => unreachable!(), 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /day17a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day17a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day17a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day17a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day17a/input.txt: -------------------------------------------------------------------------------- 1 | target area: x=29..73, y=-248..-194 2 | -------------------------------------------------------------------------------- /day17a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let n = -include_str!("../input.txt") 3 | .trim() 4 | .trim_start_matches("target area: x=") 5 | .split_once(", y=") 6 | .unwrap() 7 | .1 8 | .splitn(2, "..") 9 | .map(|n| n.parse::().unwrap()) 10 | .min() 11 | .unwrap() 12 | - 1; 13 | println!("{}", (n * (n + 1)) / 2); 14 | } 15 | -------------------------------------------------------------------------------- /day17b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day17b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day17b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day17b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day17b/input.txt: -------------------------------------------------------------------------------- 1 | target area: x=29..73, y=-248..-194 2 | -------------------------------------------------------------------------------- /day17b/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let (x, y) = include_str!("../input.txt") 3 | .trim() 4 | .trim_start_matches("target area: x=") 5 | .split_once(", y=") 6 | .unwrap(); 7 | let (x, y) = (x.split_once("..").unwrap(), y.split_once("..").unwrap()); 8 | let target: (_, i32, _, _) = ( 9 | x.0.parse().unwrap(), 10 | y.0.parse().unwrap(), 11 | x.1.parse().unwrap(), 12 | y.1.parse().unwrap(), 13 | ); 14 | 15 | println!( 16 | "{}", 17 | (1..=target.2) 18 | .flat_map(|vx| { 19 | let range = target.1.abs(); 20 | (-range..=range).filter(move |&vy| fire(target, (vx, vy))) 21 | }) 22 | .count() 23 | ); 24 | } 25 | 26 | fn fire(target: (i32, i32, i32, i32), mut v: (i32, i32)) -> bool { 27 | let mut p = (0, 0); 28 | if v.1 > 1 { 29 | for _ in 0..v.1 * 2 + 1 { 30 | p.0 += v.0; 31 | v.0 -= 1; 32 | if p.0 > target.2 { 33 | return false; 34 | } else if v.0 == 0 { 35 | break; 36 | } 37 | } 38 | v.1 = -v.1 - 1; 39 | } 40 | for (x, y, vx, _) in path(p, v) { 41 | if vx == 0 && x < target.0 || x > target.2 || y < target.1 { 42 | return false; 43 | } else if x >= target.0 && x <= target.2 && y >= target.1 && y <= target.3 { 44 | return true; 45 | } 46 | } 47 | unreachable!(); 48 | } 49 | 50 | fn path(p: (i32, i32), v: (i32, i32)) -> impl Iterator { 51 | std::iter::successors(Some((p.0, p.1, v.0, v.1)), |p| { 52 | Some((p.0 + p.2, p.1 + p.3, (p.2 - 1).max(0), p.3 - 1)) 53 | }) 54 | } 55 | -------------------------------------------------------------------------------- /day18a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day18a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day18a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day18a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day18a/input.txt: -------------------------------------------------------------------------------- 1 | [[[2,[3,5]],[8,7]],[[9,3],2]] 2 | [[3,[3,7]],[[3,6],[[1,1],7]]] 3 | [8,[[5,5],[2,9]]] 4 | [[5,[3,5]],[[2,1],[[7,1],[7,7]]]] 5 | [[[[3,3],0],[[0,3],0]],[[8,[2,2]],[[0,4],3]]] 6 | [3,6] 7 | [[5,[[4,2],1]],[[6,[0,3]],[4,[7,7]]]] 8 | [[6,5],[2,[3,6]]] 9 | [[[[0,1],0],[[7,4],5]],[[6,2],[4,[0,8]]]] 10 | [[[[4,7],3],8],[[7,[0,4]],[7,[1,4]]]] 11 | [[[0,[9,8]],[2,9]],[[[6,4],[4,0]],4]] 12 | [2,[[4,[8,5]],[6,8]]] 13 | [[[0,7],[5,[3,0]]],[[[6,4],[3,2]],[[4,7],[9,6]]]] 14 | [[[[0,6],[0,7]],[8,0]],[8,[4,8]]] 15 | [[[[9,9],2],[[6,2],[2,2]]],[[5,[8,8]],6]] 16 | [[0,[[4,6],7]],[[7,[4,8]],9]] 17 | [[0,5],[[5,3],[[3,9],4]]] 18 | [2,[[[9,4],[8,8]],1]] 19 | [5,[[[2,3],6],[2,[7,0]]]] 20 | [[7,[[8,6],3]],[2,[2,7]]] 21 | [6,[[2,4],[[9,7],[5,9]]]] 22 | [[[9,[2,1]],9],1] 23 | [[[6,9],[2,[2,5]]],[[[4,4],0],7]] 24 | [1,[[[3,9],[6,1]],[4,0]]] 25 | [[[3,8],[3,[2,7]]],[[[9,2],2],6]] 26 | [6,[[8,[3,1]],7]] 27 | [[[9,9],7],[[[3,1],[8,4]],[0,0]]] 28 | [[[1,[7,8]],[4,2]],2] 29 | [[9,7],6] 30 | [[6,[4,8]],[[[8,6],[0,1]],[[0,4],[8,4]]]] 31 | [[[[1,8],[8,6]],[9,[2,0]]],[5,[2,[7,2]]]] 32 | [1,9] 33 | [[8,[9,[9,3]]],[[[1,1],8],[[1,5],[8,6]]]] 34 | [[[3,[4,4]],3],[[7,0],[6,0]]] 35 | [[[6,[6,3]],[6,7]],[1,[8,0]]] 36 | [[[9,7],[1,7]],8] 37 | [[8,[[4,6],[4,8]]],8] 38 | [[[1,9],6],1] 39 | [[[[0,5],[0,0]],7],[4,8]] 40 | [[[[6,0],[4,2]],[8,[5,1]]],[[0,[4,8]],[[3,2],8]]] 41 | [[[[5,9],[5,8]],[9,[0,1]]],[[[8,6],[3,1]],[[9,8],0]]] 42 | [0,[[9,9],[6,2]]] 43 | [[[[7,9],[9,1]],[[1,0],[6,4]]],[4,[[2,1],2]]] 44 | [4,2] 45 | [[[6,5],[[0,6],2]],[[[1,2],0],[[8,9],8]]] 46 | [[8,[[4,1],0]],[[[1,5],[3,5]],3]] 47 | [[[8,3],[[9,1],[8,1]]],[[9,9],3]] 48 | [[2,7],[[[3,9],[2,3]],9]] 49 | [[2,[[7,3],[1,6]]],[[4,4],[2,7]]] 50 | [[[5,6],[3,[5,3]]],[[[2,8],0],[4,[8,8]]]] 51 | [[[1,2],[4,[5,8]]],[8,[8,[9,0]]]] 52 | [[[[0,5],[8,1]],0],[[[5,4],[6,9]],[[7,5],[4,9]]]] 53 | [[9,[2,1]],[[[3,8],[9,5]],[[4,4],4]]] 54 | [[[5,9],[[1,1],[8,9]]],[[1,9],8]] 55 | [[[8,8],[3,9]],[[[2,1],0],9]] 56 | [[[[7,8],2],[5,[3,9]]],[6,1]] 57 | [[[[2,4],[9,1]],[[9,8],[4,4]]],[0,1]] 58 | [[[[8,8],0],9],4] 59 | [[[8,[1,5]],0],[[[8,5],4],[[7,3],[9,5]]]] 60 | [[[5,4],[[5,1],2]],[[[6,8],6],[[3,6],[1,9]]]] 61 | [[[3,[2,5]],[6,[6,2]]],[[0,7],[3,9]]] 62 | [3,[[2,9],8]] 63 | [[[[3,7],[1,6]],[[9,9],[0,3]]],[[[7,3],8],[[3,1],6]]] 64 | [[[[7,1],4],[[4,0],[4,5]]],[8,[[5,3],[4,6]]]] 65 | [[[[0,8],1],[7,9]],[[7,5],[[1,0],[0,9]]]] 66 | [[[9,7],[0,[7,8]]],2] 67 | [[[5,2],5],[0,[[1,6],[2,0]]]] 68 | [[[[3,9],7],7],[[3,[3,4]],[0,[5,9]]]] 69 | [[[[2,5],[9,9]],[1,[6,5]]],6] 70 | [[[1,[5,9]],[[1,1],1]],[5,[[0,4],[9,0]]]] 71 | [[[5,8],[0,7]],[3,[2,[8,6]]]] 72 | [[[[0,7],[7,9]],[[8,4],[8,7]]],[0,[[3,7],9]]] 73 | [[[5,[5,5]],[[9,5],8]],[[[2,1],5],9]] 74 | [5,[4,[[3,6],[3,2]]]] 75 | [[[9,4],3],[[[8,7],[7,5]],[8,[7,7]]]] 76 | [9,[[[9,2],0],[[9,9],[4,3]]]] 77 | [[[4,[7,2]],[[7,9],[5,4]]],1] 78 | [[[[4,9],5],7],[[5,6],0]] 79 | [[[5,[3,1]],[8,1]],[8,[7,0]]] 80 | [[5,6],[6,[[0,5],0]]] 81 | [[[5,[4,5]],9],6] 82 | [[[9,[7,0]],6],[2,[1,6]]] 83 | [[[9,[8,4]],[7,[6,0]]],[[[4,6],[7,5]],[8,[0,8]]]] 84 | [0,7] 85 | [[3,[3,8]],[9,[[3,1],[4,4]]]] 86 | [[6,7],[8,9]] 87 | [[[[9,8],[0,2]],[[4,0],[7,5]]],[[[5,0],1],2]] 88 | [[[[1,2],[3,9]],1],[[5,1],[0,1]]] 89 | [[[[5,8],0],6],[7,0]] 90 | [[[8,[5,4]],[[3,0],7]],[[8,[7,5]],4]] 91 | [[[[5,8],8],8],[[[0,4],[2,5]],0]] 92 | [[[9,6],3],[[[3,3],1],[2,[9,2]]]] 93 | [[[6,3],6],[[[4,1],8],[2,3]]] 94 | [2,[[1,8],0]] 95 | [5,[[[7,6],[1,9]],[4,[8,2]]]] 96 | [[[[6,9],[0,7]],[[2,7],8]],[[6,0],[2,[1,6]]]] 97 | [[[[7,8],[5,1]],[[2,9],2]],0] 98 | [5,3] 99 | [2,[7,[7,[5,8]]]] 100 | [[3,3],[8,[2,6]]] 101 | -------------------------------------------------------------------------------- /day18a/src/main.rs: -------------------------------------------------------------------------------- 1 | /// Snailfish sequence: `[(depth, n)]` 2 | type Num = Vec<(u8, u8)>; 3 | 4 | pub fn main() { 5 | let mut nums = include_str!("../input.txt") 6 | .trim() 7 | .as_bytes() 8 | .split(|&b| b == b'\n') 9 | .map(|b| { 10 | b.iter() 11 | .fold((0, Vec::with_capacity(b.len() / 2)), |(mut d, mut n), b| { 12 | match b { 13 | b'[' => d += 1, 14 | b']' => d -= 1, 15 | b'0'..=b'9' => n.push((d, b - b'0')), 16 | _ => {} 17 | } 18 | (d, n) 19 | }) 20 | .1 21 | }) 22 | .collect::>(); 23 | 24 | while nums.len() > 1 { 25 | let mut other = nums.remove(1); 26 | let sf = &mut nums[0]; 27 | add(sf, &mut other); 28 | reduce(sf, 0); 29 | } 30 | 31 | println!("{}", mag(&mut 0, 1, &nums[0])); 32 | } 33 | 34 | fn add(nums: &mut Num, other: &mut Num) { 35 | nums.append(other); 36 | nums.iter_mut().for_each(|(d, _)| *d += 1); 37 | } 38 | 39 | fn reduce(nums: &mut Num, i: usize) { 40 | for i in i..nums.len() - 1 { 41 | if nums[i].0 == 5 { 42 | let (l, r) = (nums[i].1, nums[i + 1].1); 43 | nums[i] = (4, 0); 44 | nums.remove(i + 1); 45 | let _ = nums.get_mut(i.overflowing_sub(1).0).map(|n| n.1 += l); 46 | let _ = nums.get_mut(i + 1).map(|n| n.1 += r); 47 | return reduce(nums, i); 48 | } 49 | } 50 | for i in 0..nums.len() { 51 | let (d, n) = nums[i]; 52 | if n >= 10 { 53 | nums[i] = (d + 1, n / 2); 54 | nums.insert(i + 1, (d + 1, (n + 1) / 2)); 55 | return reduce(nums, i); 56 | } 57 | } 58 | } 59 | 60 | #[inline] 61 | fn mag(i: &mut usize, depth: u8, sf: &Num) -> u16 { 62 | 3 * if sf[*i].0 == depth { 63 | *i += 1; 64 | sf[*i - 1].1 as u16 65 | } else { 66 | mag(i, depth + 1, sf) 67 | } + 2 * if sf[*i].0 == depth { 68 | *i += 1; 69 | sf[*i - 1].1 as u16 70 | } else { 71 | mag(i, depth + 1, sf) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /day18b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day18b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day18b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day18b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day18b/input.txt: -------------------------------------------------------------------------------- 1 | [[[2,[3,5]],[8,7]],[[9,3],2]] 2 | [[3,[3,7]],[[3,6],[[1,1],7]]] 3 | [8,[[5,5],[2,9]]] 4 | [[5,[3,5]],[[2,1],[[7,1],[7,7]]]] 5 | [[[[3,3],0],[[0,3],0]],[[8,[2,2]],[[0,4],3]]] 6 | [3,6] 7 | [[5,[[4,2],1]],[[6,[0,3]],[4,[7,7]]]] 8 | [[6,5],[2,[3,6]]] 9 | [[[[0,1],0],[[7,4],5]],[[6,2],[4,[0,8]]]] 10 | [[[[4,7],3],8],[[7,[0,4]],[7,[1,4]]]] 11 | [[[0,[9,8]],[2,9]],[[[6,4],[4,0]],4]] 12 | [2,[[4,[8,5]],[6,8]]] 13 | [[[0,7],[5,[3,0]]],[[[6,4],[3,2]],[[4,7],[9,6]]]] 14 | [[[[0,6],[0,7]],[8,0]],[8,[4,8]]] 15 | [[[[9,9],2],[[6,2],[2,2]]],[[5,[8,8]],6]] 16 | [[0,[[4,6],7]],[[7,[4,8]],9]] 17 | [[0,5],[[5,3],[[3,9],4]]] 18 | [2,[[[9,4],[8,8]],1]] 19 | [5,[[[2,3],6],[2,[7,0]]]] 20 | [[7,[[8,6],3]],[2,[2,7]]] 21 | [6,[[2,4],[[9,7],[5,9]]]] 22 | [[[9,[2,1]],9],1] 23 | [[[6,9],[2,[2,5]]],[[[4,4],0],7]] 24 | [1,[[[3,9],[6,1]],[4,0]]] 25 | [[[3,8],[3,[2,7]]],[[[9,2],2],6]] 26 | [6,[[8,[3,1]],7]] 27 | [[[9,9],7],[[[3,1],[8,4]],[0,0]]] 28 | [[[1,[7,8]],[4,2]],2] 29 | [[9,7],6] 30 | [[6,[4,8]],[[[8,6],[0,1]],[[0,4],[8,4]]]] 31 | [[[[1,8],[8,6]],[9,[2,0]]],[5,[2,[7,2]]]] 32 | [1,9] 33 | [[8,[9,[9,3]]],[[[1,1],8],[[1,5],[8,6]]]] 34 | [[[3,[4,4]],3],[[7,0],[6,0]]] 35 | [[[6,[6,3]],[6,7]],[1,[8,0]]] 36 | [[[9,7],[1,7]],8] 37 | [[8,[[4,6],[4,8]]],8] 38 | [[[1,9],6],1] 39 | [[[[0,5],[0,0]],7],[4,8]] 40 | [[[[6,0],[4,2]],[8,[5,1]]],[[0,[4,8]],[[3,2],8]]] 41 | [[[[5,9],[5,8]],[9,[0,1]]],[[[8,6],[3,1]],[[9,8],0]]] 42 | [0,[[9,9],[6,2]]] 43 | [[[[7,9],[9,1]],[[1,0],[6,4]]],[4,[[2,1],2]]] 44 | [4,2] 45 | [[[6,5],[[0,6],2]],[[[1,2],0],[[8,9],8]]] 46 | [[8,[[4,1],0]],[[[1,5],[3,5]],3]] 47 | [[[8,3],[[9,1],[8,1]]],[[9,9],3]] 48 | [[2,7],[[[3,9],[2,3]],9]] 49 | [[2,[[7,3],[1,6]]],[[4,4],[2,7]]] 50 | [[[5,6],[3,[5,3]]],[[[2,8],0],[4,[8,8]]]] 51 | [[[1,2],[4,[5,8]]],[8,[8,[9,0]]]] 52 | [[[[0,5],[8,1]],0],[[[5,4],[6,9]],[[7,5],[4,9]]]] 53 | [[9,[2,1]],[[[3,8],[9,5]],[[4,4],4]]] 54 | [[[5,9],[[1,1],[8,9]]],[[1,9],8]] 55 | [[[8,8],[3,9]],[[[2,1],0],9]] 56 | [[[[7,8],2],[5,[3,9]]],[6,1]] 57 | [[[[2,4],[9,1]],[[9,8],[4,4]]],[0,1]] 58 | [[[[8,8],0],9],4] 59 | [[[8,[1,5]],0],[[[8,5],4],[[7,3],[9,5]]]] 60 | [[[5,4],[[5,1],2]],[[[6,8],6],[[3,6],[1,9]]]] 61 | [[[3,[2,5]],[6,[6,2]]],[[0,7],[3,9]]] 62 | [3,[[2,9],8]] 63 | [[[[3,7],[1,6]],[[9,9],[0,3]]],[[[7,3],8],[[3,1],6]]] 64 | [[[[7,1],4],[[4,0],[4,5]]],[8,[[5,3],[4,6]]]] 65 | [[[[0,8],1],[7,9]],[[7,5],[[1,0],[0,9]]]] 66 | [[[9,7],[0,[7,8]]],2] 67 | [[[5,2],5],[0,[[1,6],[2,0]]]] 68 | [[[[3,9],7],7],[[3,[3,4]],[0,[5,9]]]] 69 | [[[[2,5],[9,9]],[1,[6,5]]],6] 70 | [[[1,[5,9]],[[1,1],1]],[5,[[0,4],[9,0]]]] 71 | [[[5,8],[0,7]],[3,[2,[8,6]]]] 72 | [[[[0,7],[7,9]],[[8,4],[8,7]]],[0,[[3,7],9]]] 73 | [[[5,[5,5]],[[9,5],8]],[[[2,1],5],9]] 74 | [5,[4,[[3,6],[3,2]]]] 75 | [[[9,4],3],[[[8,7],[7,5]],[8,[7,7]]]] 76 | [9,[[[9,2],0],[[9,9],[4,3]]]] 77 | [[[4,[7,2]],[[7,9],[5,4]]],1] 78 | [[[[4,9],5],7],[[5,6],0]] 79 | [[[5,[3,1]],[8,1]],[8,[7,0]]] 80 | [[5,6],[6,[[0,5],0]]] 81 | [[[5,[4,5]],9],6] 82 | [[[9,[7,0]],6],[2,[1,6]]] 83 | [[[9,[8,4]],[7,[6,0]]],[[[4,6],[7,5]],[8,[0,8]]]] 84 | [0,7] 85 | [[3,[3,8]],[9,[[3,1],[4,4]]]] 86 | [[6,7],[8,9]] 87 | [[[[9,8],[0,2]],[[4,0],[7,5]]],[[[5,0],1],2]] 88 | [[[[1,2],[3,9]],1],[[5,1],[0,1]]] 89 | [[[[5,8],0],6],[7,0]] 90 | [[[8,[5,4]],[[3,0],7]],[[8,[7,5]],4]] 91 | [[[[5,8],8],8],[[[0,4],[2,5]],0]] 92 | [[[9,6],3],[[[3,3],1],[2,[9,2]]]] 93 | [[[6,3],6],[[[4,1],8],[2,3]]] 94 | [2,[[1,8],0]] 95 | [5,[[[7,6],[1,9]],[4,[8,2]]]] 96 | [[[[6,9],[0,7]],[[2,7],8]],[[6,0],[2,[1,6]]]] 97 | [[[[7,8],[5,1]],[[2,9],2]],0] 98 | [5,3] 99 | [2,[7,[7,[5,8]]]] 100 | [[3,3],[8,[2,6]]] 101 | -------------------------------------------------------------------------------- /day18b/src/main.rs: -------------------------------------------------------------------------------- 1 | /// Snailfish sequence: `[(depth, n)]` 2 | type Num = Vec<(u8, u8)>; 3 | 4 | pub fn main() { 5 | let nums = include_str!("../input.txt") 6 | .trim() 7 | .as_bytes() 8 | .split(|&b| b == b'\n') 9 | .map(|b| { 10 | b.iter() 11 | .fold((0, Vec::with_capacity(b.len() / 2)), |(mut d, mut n), b| { 12 | match b { 13 | b'[' => d += 1, 14 | b']' => d -= 1, 15 | b'0'..=b'9' => n.push((d, b - b'0')), 16 | _ => {} 17 | } 18 | (d, n) 19 | }) 20 | .1 21 | }) 22 | .collect::>(); 23 | 24 | let mut max = 0; 25 | for i in 0..nums.len() - 1 { 26 | for j in i + 1..nums.len() { 27 | let (a, b) = (&nums[i], &nums[j]); 28 | let (mut aa, mut bb) = (a.clone(), b.clone()); 29 | add(&mut aa, b); 30 | reduce(&mut aa, 0); 31 | max = mag(&mut 0, 1, &aa).max(max); 32 | add(&mut bb, a); 33 | reduce(&mut bb, 0); 34 | max = mag(&mut 0, 1, &bb).max(max); 35 | } 36 | } 37 | 38 | println!("{}", max); 39 | } 40 | 41 | fn add(nums: &mut Num, other: &Num) { 42 | nums.extend_from_slice(other); 43 | nums.iter_mut().for_each(|(d, _)| *d += 1); 44 | } 45 | 46 | fn reduce(nums: &mut Num, i: usize) { 47 | for i in i..nums.len() - 1 { 48 | if nums[i].0 == 5 { 49 | let (l, r) = (nums[i].1, nums[i + 1].1); 50 | nums[i] = (4, 0); 51 | nums.remove(i + 1); 52 | let _ = nums.get_mut(i.overflowing_sub(1).0).map(|n| n.1 += l); 53 | let _ = nums.get_mut(i + 1).map(|n| n.1 += r); 54 | return reduce(nums, i); 55 | } 56 | } 57 | for i in 0..nums.len() { 58 | let (d, n) = nums[i]; 59 | if n >= 10 { 60 | nums[i] = (d + 1, n / 2); 61 | nums.insert(i + 1, (d + 1, (n + 1) / 2)); 62 | return reduce(nums, i); 63 | } 64 | } 65 | } 66 | 67 | #[inline] 68 | fn mag(i: &mut usize, depth: u8, sf: &Num) -> u16 { 69 | 3 * if sf[*i].0 == depth { 70 | *i += 1; 71 | sf[*i - 1].1 as u16 72 | } else { 73 | mag(i, depth + 1, sf) 74 | } + 2 * if sf[*i].0 == depth { 75 | *i += 1; 76 | sf[*i - 1].1 as u16 77 | } else { 78 | mag(i, depth + 1, sf) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /day19a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "approx" 18 | version = "0.5.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" 21 | dependencies = [ 22 | "num-traits", 23 | ] 24 | 25 | [[package]] 26 | name = "autocfg" 27 | version = "1.0.1" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 30 | 31 | [[package]] 32 | name = "bytemuck" 33 | version = "1.7.3" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" 36 | 37 | [[package]] 38 | name = "cfg-if" 39 | version = "1.0.0" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 42 | 43 | [[package]] 44 | name = "day19a" 45 | version = "0.1.0" 46 | dependencies = [ 47 | "hashbrown", 48 | "itertools", 49 | "nalgebra", 50 | ] 51 | 52 | [[package]] 53 | name = "either" 54 | version = "1.6.1" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 57 | 58 | [[package]] 59 | name = "getrandom" 60 | version = "0.2.3" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" 63 | dependencies = [ 64 | "cfg-if", 65 | "libc", 66 | "wasi", 67 | ] 68 | 69 | [[package]] 70 | name = "hashbrown" 71 | version = "0.11.2" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 74 | dependencies = [ 75 | "ahash", 76 | ] 77 | 78 | [[package]] 79 | name = "itertools" 80 | version = "0.10.3" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 83 | dependencies = [ 84 | "either", 85 | ] 86 | 87 | [[package]] 88 | name = "libc" 89 | version = "0.2.112" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" 92 | 93 | [[package]] 94 | name = "matrixmultiply" 95 | version = "0.3.2" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" 98 | dependencies = [ 99 | "rawpointer", 100 | ] 101 | 102 | [[package]] 103 | name = "nalgebra" 104 | version = "0.29.0" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "d506eb7e08d6329505faa8a3a00a5dcc6de9f76e0c77e4b75763ae3c770831ff" 107 | dependencies = [ 108 | "approx", 109 | "matrixmultiply", 110 | "nalgebra-macros", 111 | "num-complex", 112 | "num-rational", 113 | "num-traits", 114 | "simba", 115 | "typenum", 116 | ] 117 | 118 | [[package]] 119 | name = "nalgebra-macros" 120 | version = "0.1.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" 123 | dependencies = [ 124 | "proc-macro2", 125 | "quote", 126 | "syn", 127 | ] 128 | 129 | [[package]] 130 | name = "num-complex" 131 | version = "0.4.0" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" 134 | dependencies = [ 135 | "num-traits", 136 | ] 137 | 138 | [[package]] 139 | name = "num-integer" 140 | version = "0.1.44" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 143 | dependencies = [ 144 | "autocfg", 145 | "num-traits", 146 | ] 147 | 148 | [[package]] 149 | name = "num-rational" 150 | version = "0.4.0" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" 153 | dependencies = [ 154 | "autocfg", 155 | "num-integer", 156 | "num-traits", 157 | ] 158 | 159 | [[package]] 160 | name = "num-traits" 161 | version = "0.2.14" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 164 | dependencies = [ 165 | "autocfg", 166 | ] 167 | 168 | [[package]] 169 | name = "once_cell" 170 | version = "1.9.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" 173 | 174 | [[package]] 175 | name = "paste" 176 | version = "1.0.6" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" 179 | 180 | [[package]] 181 | name = "proc-macro2" 182 | version = "1.0.34" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" 185 | dependencies = [ 186 | "unicode-xid", 187 | ] 188 | 189 | [[package]] 190 | name = "quote" 191 | version = "1.0.10" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" 194 | dependencies = [ 195 | "proc-macro2", 196 | ] 197 | 198 | [[package]] 199 | name = "rawpointer" 200 | version = "0.2.1" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" 203 | 204 | [[package]] 205 | name = "safe_arch" 206 | version = "0.6.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529" 209 | dependencies = [ 210 | "bytemuck", 211 | ] 212 | 213 | [[package]] 214 | name = "simba" 215 | version = "0.6.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "f0b7840f121a46d63066ee7a99fc81dcabbc6105e437cae43528cea199b5a05f" 218 | dependencies = [ 219 | "approx", 220 | "num-complex", 221 | "num-traits", 222 | "paste", 223 | "wide", 224 | ] 225 | 226 | [[package]] 227 | name = "syn" 228 | version = "1.0.82" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" 231 | dependencies = [ 232 | "proc-macro2", 233 | "quote", 234 | "unicode-xid", 235 | ] 236 | 237 | [[package]] 238 | name = "typenum" 239 | version = "1.14.0" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" 242 | 243 | [[package]] 244 | name = "unicode-xid" 245 | version = "0.2.2" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 248 | 249 | [[package]] 250 | name = "version_check" 251 | version = "0.9.3" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 254 | 255 | [[package]] 256 | name = "wasi" 257 | version = "0.10.2+wasi-snapshot-preview1" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 260 | 261 | [[package]] 262 | name = "wide" 263 | version = "0.7.3" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "476da2f1d225632b1fffe638ff979a4bc03907e29b0ab596efca7624014f8b62" 266 | dependencies = [ 267 | "bytemuck", 268 | "safe_arch", 269 | ] 270 | -------------------------------------------------------------------------------- /day19a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day19a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | hashbrown = "0.11" 12 | itertools = "0.10" 13 | nalgebra = "0.29" 14 | -------------------------------------------------------------------------------- /day19a/src/main.rs: -------------------------------------------------------------------------------- 1 | // Used strategy from: https://is.gd/j9dCKv 2 | 3 | use hashbrown::{HashMap, HashSet}; 4 | use itertools::Itertools; 5 | use nalgebra::{Matrix3, Rotation3, Vector3}; 6 | 7 | type Fp = (i32, i32); 8 | 9 | pub fn main() { 10 | let mut rots: HashSet<_> = [Matrix3::identity()].into_iter().collect(); 11 | [Vector3::x_axis(), Vector3::y_axis(), Vector3::z_axis()] 12 | .iter() 13 | .for_each(|axis| { 14 | (0..4) 15 | .map(|n| std::f32::consts::FRAC_PI_2 * n as f32) 16 | .for_each(|angle| { 17 | let r = Matrix3::from_iterator( 18 | Rotation3::from_axis_angle(axis, angle) 19 | .matrix() 20 | .iter() 21 | .map(|n| n.round() as i32), 22 | ); 23 | rots.extend(rots.clone().into_iter().map(|m| r * m)); 24 | }); 25 | }); 26 | 27 | let scans = include_str!("../input.txt") 28 | .split("\n\n") 29 | .map(|s| { 30 | s.lines() 31 | .skip(1) 32 | .map(|l| { 33 | let mut c = l.splitn(3, ',').map(|c| c.parse().unwrap()); 34 | [c.next().unwrap(), c.next().unwrap(), c.next().unwrap()].into() 35 | }) 36 | .collect() 37 | }) 38 | .collect::>>(); 39 | let mut scans = scans 40 | .iter() 41 | .map(|scan| { 42 | ( 43 | scan, 44 | scan.iter() 45 | .tuple_combinations() 46 | .map(|(a, b)| (fp(a, b), [a, b])) 47 | .collect(), 48 | ) 49 | }) 50 | .collect::)>>(); 51 | 52 | let first = scans.remove(0); 53 | let mut beacons = first.0.iter().cloned().collect(); 54 | let mut fps = HashMap::new(); 55 | add_scan_fps(&mut fps, first.0); 56 | 57 | while !scans.is_empty() { 58 | let (i, scan) = scans 59 | .iter() 60 | .enumerate() 61 | .flat_map(|(i, (s, s_fps))| matching(&beacons, &fps, &rots, s, s_fps).map(|m| (i, m))) 62 | .next() 63 | .unwrap(); 64 | scans.remove(i); 65 | add_scan_fps(&mut fps, &scan); 66 | beacons.extend(scan.into_iter()); 67 | } 68 | 69 | println!("{}", beacons.len()); 70 | } 71 | 72 | fn fp(a: &Vector3, b: &Vector3) -> Fp { 73 | ( 74 | (a - b).iter().map(|n| n.abs()).sum(), 75 | (a - b).iter().map(|n| n.abs()).max().unwrap(), 76 | ) 77 | } 78 | 79 | fn add_scan_fps(fps: &mut HashMap; 2]>>, scan: &[Vector3]) { 80 | scan.iter().tuple_combinations().for_each(|(a, b)| { 81 | fps.entry(fp(a, b)).or_default().push([*a, *b]); 82 | }) 83 | } 84 | 85 | fn matching( 86 | beacons: &HashSet>, 87 | fps: &HashMap; 2]>>, 88 | rots: &HashSet>, 89 | scan: &[Vector3], 90 | scan_fps: &[(Fp, [&Vector3; 2])], 91 | ) -> Option>> { 92 | match scan_fps 93 | .iter() 94 | .filter(|(f, _)| fps.contains_key(f)) 95 | .take(12) 96 | .collect::>() 97 | { 98 | match_fps if match_fps.len() < 12 => None, 99 | match_fps => match_fps 100 | .into_iter() 101 | .flat_map(|(fp, [ma, mb])| { 102 | fps[fp] 103 | .iter() 104 | .flat_map(|[a, b]| { 105 | rots.iter().find(|&m| a - m * *ma == b - m * *mb).map(|r| { 106 | let t = a - r * *ma; 107 | scan.iter().map(|p| r * p + t).collect::>() 108 | }) 109 | }) 110 | .filter(|s| s.iter().filter(|b| beacons.contains(b)).take(2).count() >= 2) 111 | }) 112 | .next(), 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /day19b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "approx" 18 | version = "0.5.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" 21 | dependencies = [ 22 | "num-traits", 23 | ] 24 | 25 | [[package]] 26 | name = "autocfg" 27 | version = "1.0.1" 28 | source = "registry+https://github.com/rust-lang/crates.io-index" 29 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" 30 | 31 | [[package]] 32 | name = "bytemuck" 33 | version = "1.7.3" 34 | source = "registry+https://github.com/rust-lang/crates.io-index" 35 | checksum = "439989e6b8c38d1b6570a384ef1e49c8848128f5a97f3914baef02920842712f" 36 | 37 | [[package]] 38 | name = "cfg-if" 39 | version = "1.0.0" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 42 | 43 | [[package]] 44 | name = "day19b" 45 | version = "0.1.0" 46 | dependencies = [ 47 | "hashbrown", 48 | "itertools", 49 | "nalgebra", 50 | ] 51 | 52 | [[package]] 53 | name = "either" 54 | version = "1.6.1" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 57 | 58 | [[package]] 59 | name = "getrandom" 60 | version = "0.2.3" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" 63 | dependencies = [ 64 | "cfg-if", 65 | "libc", 66 | "wasi", 67 | ] 68 | 69 | [[package]] 70 | name = "hashbrown" 71 | version = "0.11.2" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 74 | dependencies = [ 75 | "ahash", 76 | ] 77 | 78 | [[package]] 79 | name = "itertools" 80 | version = "0.10.3" 81 | source = "registry+https://github.com/rust-lang/crates.io-index" 82 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 83 | dependencies = [ 84 | "either", 85 | ] 86 | 87 | [[package]] 88 | name = "libc" 89 | version = "0.2.112" 90 | source = "registry+https://github.com/rust-lang/crates.io-index" 91 | checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" 92 | 93 | [[package]] 94 | name = "matrixmultiply" 95 | version = "0.3.2" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "add85d4dd35074e6fedc608f8c8f513a3548619a9024b751949ef0e8e45a4d84" 98 | dependencies = [ 99 | "rawpointer", 100 | ] 101 | 102 | [[package]] 103 | name = "nalgebra" 104 | version = "0.29.0" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | checksum = "d506eb7e08d6329505faa8a3a00a5dcc6de9f76e0c77e4b75763ae3c770831ff" 107 | dependencies = [ 108 | "approx", 109 | "matrixmultiply", 110 | "nalgebra-macros", 111 | "num-complex", 112 | "num-rational", 113 | "num-traits", 114 | "simba", 115 | "typenum", 116 | ] 117 | 118 | [[package]] 119 | name = "nalgebra-macros" 120 | version = "0.1.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "01fcc0b8149b4632adc89ac3b7b31a12fb6099a0317a4eb2ebff574ef7de7218" 123 | dependencies = [ 124 | "proc-macro2", 125 | "quote", 126 | "syn", 127 | ] 128 | 129 | [[package]] 130 | name = "num-complex" 131 | version = "0.4.0" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "26873667bbbb7c5182d4a37c1add32cdf09f841af72da53318fdb81543c15085" 134 | dependencies = [ 135 | "num-traits", 136 | ] 137 | 138 | [[package]] 139 | name = "num-integer" 140 | version = "0.1.44" 141 | source = "registry+https://github.com/rust-lang/crates.io-index" 142 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" 143 | dependencies = [ 144 | "autocfg", 145 | "num-traits", 146 | ] 147 | 148 | [[package]] 149 | name = "num-rational" 150 | version = "0.4.0" 151 | source = "registry+https://github.com/rust-lang/crates.io-index" 152 | checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" 153 | dependencies = [ 154 | "autocfg", 155 | "num-integer", 156 | "num-traits", 157 | ] 158 | 159 | [[package]] 160 | name = "num-traits" 161 | version = "0.2.14" 162 | source = "registry+https://github.com/rust-lang/crates.io-index" 163 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" 164 | dependencies = [ 165 | "autocfg", 166 | ] 167 | 168 | [[package]] 169 | name = "once_cell" 170 | version = "1.9.0" 171 | source = "registry+https://github.com/rust-lang/crates.io-index" 172 | checksum = "da32515d9f6e6e489d7bc9d84c71b060db7247dc035bbe44eac88cf87486d8d5" 173 | 174 | [[package]] 175 | name = "paste" 176 | version = "1.0.6" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "0744126afe1a6dd7f394cb50a716dbe086cb06e255e53d8d0185d82828358fb5" 179 | 180 | [[package]] 181 | name = "proc-macro2" 182 | version = "1.0.34" 183 | source = "registry+https://github.com/rust-lang/crates.io-index" 184 | checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" 185 | dependencies = [ 186 | "unicode-xid", 187 | ] 188 | 189 | [[package]] 190 | name = "quote" 191 | version = "1.0.10" 192 | source = "registry+https://github.com/rust-lang/crates.io-index" 193 | checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" 194 | dependencies = [ 195 | "proc-macro2", 196 | ] 197 | 198 | [[package]] 199 | name = "rawpointer" 200 | version = "0.2.1" 201 | source = "registry+https://github.com/rust-lang/crates.io-index" 202 | checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" 203 | 204 | [[package]] 205 | name = "safe_arch" 206 | version = "0.6.0" 207 | source = "registry+https://github.com/rust-lang/crates.io-index" 208 | checksum = "794821e4ccb0d9f979512f9c1973480123f9bd62a90d74ab0f9426fcf8f4a529" 209 | dependencies = [ 210 | "bytemuck", 211 | ] 212 | 213 | [[package]] 214 | name = "simba" 215 | version = "0.6.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "f0b7840f121a46d63066ee7a99fc81dcabbc6105e437cae43528cea199b5a05f" 218 | dependencies = [ 219 | "approx", 220 | "num-complex", 221 | "num-traits", 222 | "paste", 223 | "wide", 224 | ] 225 | 226 | [[package]] 227 | name = "syn" 228 | version = "1.0.82" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" 231 | dependencies = [ 232 | "proc-macro2", 233 | "quote", 234 | "unicode-xid", 235 | ] 236 | 237 | [[package]] 238 | name = "typenum" 239 | version = "1.14.0" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" 242 | 243 | [[package]] 244 | name = "unicode-xid" 245 | version = "0.2.2" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 248 | 249 | [[package]] 250 | name = "version_check" 251 | version = "0.9.3" 252 | source = "registry+https://github.com/rust-lang/crates.io-index" 253 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" 254 | 255 | [[package]] 256 | name = "wasi" 257 | version = "0.10.2+wasi-snapshot-preview1" 258 | source = "registry+https://github.com/rust-lang/crates.io-index" 259 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 260 | 261 | [[package]] 262 | name = "wide" 263 | version = "0.7.3" 264 | source = "registry+https://github.com/rust-lang/crates.io-index" 265 | checksum = "476da2f1d225632b1fffe638ff979a4bc03907e29b0ab596efca7624014f8b62" 266 | dependencies = [ 267 | "bytemuck", 268 | "safe_arch", 269 | ] 270 | -------------------------------------------------------------------------------- /day19b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day19b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | 10 | [dependencies] 11 | hashbrown = "0.11" 12 | itertools = "0.10" 13 | nalgebra = "0.29" 14 | -------------------------------------------------------------------------------- /day19b/src/main.rs: -------------------------------------------------------------------------------- 1 | // Used strategy from: https://is.gd/j9dCKv 2 | 3 | use hashbrown::{HashMap, HashSet}; 4 | use itertools::Itertools; 5 | use nalgebra::{Matrix3, Rotation3, Vector3}; 6 | 7 | type Fp = (i32, i32); 8 | 9 | pub fn main() { 10 | let mut rots: HashSet<_> = [Matrix3::identity()].into_iter().collect(); 11 | [Vector3::x_axis(), Vector3::y_axis(), Vector3::z_axis()] 12 | .iter() 13 | .for_each(|axis| { 14 | (0..4) 15 | .map(|n| std::f32::consts::FRAC_PI_2 * n as f32) 16 | .for_each(|angle| { 17 | let r = Matrix3::from_iterator( 18 | Rotation3::from_axis_angle(axis, angle) 19 | .matrix() 20 | .iter() 21 | .map(|n| n.round() as i32), 22 | ); 23 | rots.extend(rots.clone().into_iter().map(|m| r * m)); 24 | }); 25 | }); 26 | 27 | let scans = include_str!("../input.txt") 28 | .split("\n\n") 29 | .map(|s| { 30 | s.lines() 31 | .skip(1) 32 | .map(|l| { 33 | let mut c = l.splitn(3, ',').map(|c| c.parse().unwrap()); 34 | [c.next().unwrap(), c.next().unwrap(), c.next().unwrap()].into() 35 | }) 36 | .collect() 37 | }) 38 | .collect::>>(); 39 | let mut scans = scans 40 | .iter() 41 | .map(|scan| { 42 | ( 43 | scan, 44 | scan.iter() 45 | .tuple_combinations() 46 | .map(|(a, b)| (fp(a, b), [a, b])) 47 | .collect(), 48 | ) 49 | }) 50 | .collect::)>>(); 51 | 52 | let first = scans.remove(0); 53 | let mut scans_pos = vec![[0, 0, 0].into()]; 54 | let mut beacons = first.0.iter().cloned().collect(); 55 | let mut fps = HashMap::new(); 56 | add_scan_fps(&mut fps, first.0); 57 | 58 | while !scans.is_empty() { 59 | let (i, (pos, scan)) = scans 60 | .iter() 61 | .enumerate() 62 | .flat_map(|(i, (s, s_fps))| matching(&beacons, &fps, &rots, s, s_fps).map(|m| (i, m))) 63 | .next() 64 | .unwrap(); 65 | scans.remove(i); 66 | add_scan_fps(&mut fps, &scan); 67 | beacons.extend(scan.into_iter()); 68 | scans_pos.push(pos); 69 | } 70 | 71 | println!( 72 | "{}", 73 | scans_pos 74 | .into_iter() 75 | .tuple_combinations() 76 | .map(|(a, b)| (a - b).iter().map(|n| n.abs()).sum::()) 77 | .max() 78 | .unwrap() 79 | ); 80 | } 81 | 82 | fn fp(a: &Vector3, b: &Vector3) -> Fp { 83 | ( 84 | (a - b).iter().map(|n| n.abs()).sum(), 85 | (a - b).iter().map(|n| n.abs()).max().unwrap(), 86 | ) 87 | } 88 | 89 | fn add_scan_fps(fps: &mut HashMap; 2]>>, scan: &[Vector3]) { 90 | scan.iter().tuple_combinations().for_each(|(a, b)| { 91 | fps.entry(fp(a, b)).or_default().push([*a, *b]); 92 | }) 93 | } 94 | 95 | fn matching( 96 | beacons: &HashSet>, 97 | fps: &HashMap; 2]>>, 98 | rots: &HashSet>, 99 | scan: &[Vector3], 100 | scan_fps: &[(Fp, [&Vector3; 2])], 101 | ) -> Option<(Vector3, Vec>)> { 102 | match scan_fps 103 | .iter() 104 | .filter(|(f, _)| fps.contains_key(f)) 105 | .take(12) 106 | .collect::>() 107 | { 108 | match_fps if match_fps.len() < 12 => None, 109 | match_fps => match_fps 110 | .into_iter() 111 | .flat_map(|(fp, [ma, mb])| { 112 | fps[fp] 113 | .iter() 114 | .flat_map(|[a, b]| { 115 | rots.iter().find(|&m| a - m * *ma == b - m * *mb).map(|r| { 116 | let t = a - r * *ma; 117 | (t, scan.iter().map(|p| r * p + t).collect::>()) 118 | }) 119 | }) 120 | .filter(|(_, s)| s.iter().filter(|b| beacons.contains(b)).take(2).count() >= 2) 121 | }) 122 | .next(), 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /day20a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day20a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day20a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day20a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day20a/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{iter, mem}; 2 | 3 | const RUNS: usize = 2; 4 | 5 | pub fn main() { 6 | let input = include_str!("../input.txt").trim(); 7 | let (key, map) = input.split_once("\n\n").unwrap(); 8 | let size = map.bytes().position(|b| b == b'\n').unwrap(); 9 | let key = key.bytes().map(&|b| b == b'#').collect::>(); 10 | 11 | let mut map = iter::repeat(vec![false; size + RUNS * 2]) 12 | .take(RUNS) 13 | .chain(map.lines().map(|l| { 14 | iter::repeat(b'.') 15 | .take(RUNS) 16 | .chain(l.bytes()) 17 | .chain(iter::repeat(b'.').take(RUNS)) 18 | .map(&|b| b == b'#') 19 | .collect::>() 20 | })) 21 | .chain(iter::repeat(vec![false; size + RUNS * 2]).take(RUNS)) 22 | .collect::>>(); 23 | let mut other = map.clone(); 24 | 25 | for run in 0..RUNS { 26 | let out = run % 2 == 1 && key[0]; 27 | (0..map.len()).for_each(|y| { 28 | let rows = [ 29 | map.get((y as isize - 1) as usize), 30 | map.get(y), 31 | map.get(y + 1), 32 | ]; 33 | let mut i = rows.iter().fold(0, |i, row| { 34 | row.map(|row| { 35 | (-1isize..=1) 36 | .map(|x| *row.get(x as usize).unwrap_or(&out) as usize) 37 | .fold(0usize, |i, c| i << 1 | c) 38 | }) 39 | .unwrap_or(out as usize * 7) 40 | | i << 3 41 | }); 42 | 43 | (0..map[0].len()).for_each(|x| { 44 | let new = (*rows[0].and_then(|r| r.get(x + 1)).unwrap_or(&out) as usize) << 6 45 | | (*rows[1].and_then(|r| r.get(x + 1)).unwrap_or(&out) as usize) << 3 46 | | (*rows[2].and_then(|r| r.get(x + 1)).unwrap_or(&out) as usize); 47 | i = i & 0b110110110 | new; 48 | other[y][x] = key[i]; 49 | i <<= 1; 50 | }); 51 | }); 52 | mem::swap(&mut map, &mut other); 53 | } 54 | 55 | println!( 56 | "{}", 57 | map.iter() 58 | .map(|r| r.iter().filter(|b| **b).count()) 59 | .sum::() 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /day20b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day20b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day20b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day20b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day20b/src/main.rs: -------------------------------------------------------------------------------- 1 | use std::{iter, mem}; 2 | 3 | const RUNS: usize = 50; 4 | 5 | pub fn main() { 6 | let input = include_str!("../input.txt").trim(); 7 | let (key, map) = input.split_once("\n\n").unwrap(); 8 | let size = map.bytes().position(|b| b == b'\n').unwrap(); 9 | let key = key.bytes().map(&|b| b == b'#').collect::>(); 10 | 11 | let mut map = iter::repeat(vec![false; size + RUNS * 2]) 12 | .take(RUNS) 13 | .chain(map.lines().map(|l| { 14 | iter::repeat(b'.') 15 | .take(RUNS) 16 | .chain(l.bytes()) 17 | .chain(iter::repeat(b'.').take(RUNS)) 18 | .map(&|b| b == b'#') 19 | .collect::>() 20 | })) 21 | .chain(iter::repeat(vec![false; size + RUNS * 2]).take(RUNS)) 22 | .collect::>>(); 23 | let mut other = map.clone(); 24 | 25 | for run in 0..RUNS { 26 | let out = run % 2 == 1 && key[0]; 27 | (0..map.len()).for_each(|y| { 28 | let rows = [ 29 | map.get((y as isize - 1) as usize), 30 | map.get(y), 31 | map.get(y + 1), 32 | ]; 33 | let mut i = rows.iter().fold(0, |i, row| { 34 | row.map(|row| { 35 | (-1isize..=1) 36 | .map(|x| *row.get(x as usize).unwrap_or(&out) as usize) 37 | .fold(0usize, |i, c| i << 1 | c) 38 | }) 39 | .unwrap_or(out as usize * 7) 40 | | i << 3 41 | }); 42 | 43 | (0..map[0].len()).for_each(|x| { 44 | let new = (*rows[0].and_then(|r| r.get(x + 1)).unwrap_or(&out) as usize) << 6 45 | | (*rows[1].and_then(|r| r.get(x + 1)).unwrap_or(&out) as usize) << 3 46 | | (*rows[2].and_then(|r| r.get(x + 1)).unwrap_or(&out) as usize); 47 | i = i & 0b110110110 | new; 48 | other[y][x] = key[i]; 49 | i <<= 1; 50 | }); 51 | }); 52 | mem::swap(&mut map, &mut other); 53 | } 54 | 55 | println!( 56 | "{}", 57 | map.iter() 58 | .map(|r| r.iter().filter(|b| **b).count()) 59 | .sum::() 60 | ); 61 | } 62 | -------------------------------------------------------------------------------- /day21a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day21a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day21a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day21a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day21a/input.txt: -------------------------------------------------------------------------------- 1 | Player 1 starting position: 6 2 | Player 2 starting position: 7 3 | -------------------------------------------------------------------------------- /day21a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let (mut pos, mut score): ([_; 2], _) = ( 3 | include_str!("../input.txt") 4 | .lines() 5 | .map(|l| l[l.len() - 2..l.len()].trim().parse::().unwrap() - 1) 6 | .collect::>() 7 | .try_into() 8 | .unwrap(), 9 | [0; 2], 10 | ); 11 | 12 | let mut die = 0..; 13 | let mut throw = || (die.by_ref().next().unwrap() * 3 + 2) * 3; 14 | 15 | for turn in 0.. { 16 | for p in 0..2 { 17 | pos[p] = (pos[p] + throw()) % 10; 18 | score[p] += pos[p] + 1; 19 | if score[p] >= 1000 { 20 | println!( 21 | "{}", 22 | score[(p + 1) % 2] as usize * (turn * 6 + ((p + 1) * 3)) 23 | ); 24 | return; 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /day21b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day21b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day21b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day21b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day21b/input.txt: -------------------------------------------------------------------------------- 1 | Player 1 starting position: 6 2 | Player 2 starting position: 7 3 | -------------------------------------------------------------------------------- /day21b/src/main.rs: -------------------------------------------------------------------------------- 1 | const PROB: [usize; 7] = [1, 3, 6, 7, 6, 3, 1]; 2 | 3 | pub fn main() { 4 | let pos = include_str!("../input.txt") 5 | .lines() 6 | .map(|l| l[l.len() - 2..l.len()].trim().parse().unwrap()) 7 | .collect::>(); 8 | 9 | let p = [scores(pos[0]), scores(pos[1])]; 10 | println!( 11 | "{}", 12 | (1..11) 13 | .map(|t| p[0].0[t] * p[1].1[t - 1]) 14 | .sum::() 15 | .max((1..11).map(|t| p[1].0[t - 1] * p[0].1[t - 1]).sum()) 16 | ); 17 | } 18 | 19 | fn scores(pos: usize) -> ([usize; 11], [usize; 11]) { 20 | let mut tab = [[[0; 22]; 11]; 11]; 21 | tab[0][pos][0] = 1; 22 | (1..11).for_each(|t| { 23 | (1..11).for_each(|p| { 24 | (0..21).for_each(|s| { 25 | PROB.iter().enumerate().for_each(|(i, w)| { 26 | let q = ((p + i + 2) % 10) + 1; 27 | let v = (q + s).min(21); 28 | tab[t][q][v] += w * tab[t - 1][p][s]; 29 | }); 30 | }); 31 | }); 32 | }); 33 | 34 | let mut out = ([0; 11], [0; 11]); 35 | tab.iter().enumerate().for_each(|(t, tab)| { 36 | tab[1..].iter().for_each(|tab| { 37 | tab[..21].iter().for_each(|tab| out.1[t] += tab); 38 | out.0[t] += tab[21]; 39 | }); 40 | }); 41 | out 42 | } 43 | -------------------------------------------------------------------------------- /day22a/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day22a" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day22a/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day22a" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day22a/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let mut boxes = Vec::new(); 3 | let tot = include_str!("../input.txt") 4 | .lines() 5 | .map(|line| -> (bool, [(i32, i32); 3]) { 6 | let (on, coords) = line.split_once(' ').unwrap(); 7 | let coords = coords 8 | .splitn(3, ',') 9 | .map(|c| { 10 | let (a, b) = c[2..].split_once("..").unwrap(); 11 | (a.parse().unwrap(), b.parse().unwrap()) 12 | }) 13 | .collect::>() 14 | .try_into() 15 | .unwrap(); 16 | (on == "on", coords) 17 | }) 18 | .filter(|(_, c)| c.iter().all(|c| (c.0 <= 50 && c.1 >= -50))) 19 | .map(|(on, c)| -> (bool, [(i32, i32); 3]) { 20 | ( 21 | on, 22 | c.iter() 23 | .map(|c| (c.0.max(-50), c.1.min(50))) 24 | .collect::>() 25 | .try_into() 26 | .unwrap(), 27 | ) 28 | }) 29 | .fold(0, |mut tot, (on, c)| { 30 | let cuboid = [[c[0].0, c[1].0, c[2].0], [c[0].1, c[1].1, c[2].1]]; 31 | if !boxes.is_empty() { 32 | let mut new = vec![]; 33 | for (boxx, intersect) in boxes 34 | .iter_mut() 35 | .filter_map(|b| intersect(&cuboid, b).map(|i| (b, i))) 36 | { 37 | cut(boxx, &intersect, &mut new); 38 | *boxx = [[0, 0, 0], [i32::MIN, i32::MIN, i32::MIN]]; 39 | tot -= (0..3) 40 | .map(|c| intersect[1][c] as i64 - intersect[0][c] as i64 + 1) 41 | .product::() as u64; 42 | } 43 | boxes.append(&mut new); 44 | } 45 | if on { 46 | boxes.push(cuboid); 47 | tot += (0..3) 48 | .map(|c| cuboid[1][c] as i64 - cuboid[0][c] as i64 + 1) 49 | .product::() as u64 as u64; 50 | } 51 | tot 52 | }); 53 | println!("{}", tot); 54 | } 55 | 56 | fn intersect(a: &[[i32; 3]; 2], b: &[[i32; 3]; 2]) -> Option<[[i32; 3]; 2]> { 57 | Some([ 58 | [ 59 | a[0][0].max(b[0][0]), 60 | a[0][1].max(b[0][1]), 61 | a[0][2].max(b[0][2]), 62 | ], 63 | [ 64 | a[1][0].min(b[1][0]), 65 | a[1][1].min(b[1][1]), 66 | a[1][2].min(b[1][2]), 67 | ], 68 | ]) 69 | .filter(|c| c[0].iter().zip(c[1].iter()).all(|(a, b)| a <= b)) 70 | } 71 | 72 | fn cut(boxx: &[[i32; 3]; 2], cut: &[[i32; 3]; 2], new: &mut Vec<[[i32; 3]; 2]>) { 73 | if cut[0][0] > boxx[0][0] { 74 | new.push([boxx[0], [cut[0][0] - 1, boxx[1][1], boxx[1][2]]]); 75 | } 76 | if cut[1][0] < boxx[1][0] { 77 | new.push([[cut[1][0] + 1, boxx[0][1], boxx[0][2]], boxx[1]]); 78 | } 79 | if cut[1][1] < boxx[1][1] { 80 | new.push([ 81 | [cut[0][0], cut[1][1] + 1, boxx[0][2]], 82 | [cut[1][0], boxx[1][1], boxx[1][2]], 83 | ]); 84 | } 85 | if cut[0][1] > boxx[0][1] { 86 | new.push([ 87 | [cut[0][0], boxx[0][1], boxx[0][2]], 88 | [cut[1][0], cut[0][1] - 1, boxx[1][2]], 89 | ]); 90 | } 91 | if cut[0][2] > boxx[0][2] { 92 | new.push([ 93 | [cut[0][0], cut[0][1], boxx[0][2]], 94 | [cut[1][0], cut[1][1], cut[0][2] - 1], 95 | ]); 96 | } 97 | if cut[1][2] < boxx[1][2] { 98 | new.push([ 99 | [cut[0][0], cut[0][1], cut[1][2] + 1], 100 | [cut[1][0], cut[1][1], boxx[1][2]], 101 | ]); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /day22b/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "day22b" 7 | version = "0.1.0" 8 | -------------------------------------------------------------------------------- /day22b/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "day22b" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [lib] 8 | path = "src/main.rs" 9 | -------------------------------------------------------------------------------- /day22b/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | let mut boxes = Vec::new(); 3 | let tot = include_str!("../input.txt") 4 | .lines() 5 | .map(|line| -> (bool, [(i32, i32); 3]) { 6 | let (on, coords) = line.split_once(' ').unwrap(); 7 | let coords = coords 8 | .splitn(3, ',') 9 | .map(|c| { 10 | let (a, b) = c[2..].split_once("..").unwrap(); 11 | (a.parse().unwrap(), b.parse().unwrap()) 12 | }) 13 | .collect::>() 14 | .try_into() 15 | .unwrap(); 16 | (on == "on", coords) 17 | }) 18 | .fold(0, |mut tot, (on, c)| { 19 | let cuboid = [[c[0].0, c[1].0, c[2].0], [c[0].1, c[1].1, c[2].1]]; 20 | if !boxes.is_empty() { 21 | let mut new = vec![]; 22 | for (boxx, intersect) in boxes 23 | .iter_mut() 24 | .filter_map(|b| intersect(&cuboid, b).map(|i| (b, i))) 25 | { 26 | cut(boxx, &intersect, &mut new); 27 | *boxx = [[0, 0, 0], [i32::MIN, i32::MIN, i32::MIN]]; 28 | tot -= (0..3) 29 | .map(|c| intersect[1][c] as i64 - intersect[0][c] as i64 + 1) 30 | .product::() as u64; 31 | } 32 | boxes.append(&mut new); 33 | } 34 | if on { 35 | boxes.push(cuboid); 36 | tot += (0..3) 37 | .map(|c| cuboid[1][c] as i64 - cuboid[0][c] as i64 + 1) 38 | .product::() as u64 as u64; 39 | } 40 | tot 41 | }); 42 | println!("{}", tot); 43 | } 44 | 45 | fn intersect(a: &[[i32; 3]; 2], b: &[[i32; 3]; 2]) -> Option<[[i32; 3]; 2]> { 46 | Some([ 47 | [ 48 | a[0][0].max(b[0][0]), 49 | a[0][1].max(b[0][1]), 50 | a[0][2].max(b[0][2]), 51 | ], 52 | [ 53 | a[1][0].min(b[1][0]), 54 | a[1][1].min(b[1][1]), 55 | a[1][2].min(b[1][2]), 56 | ], 57 | ]) 58 | .filter(|c| c[0].iter().zip(c[1].iter()).all(|(a, b)| a <= b)) 59 | } 60 | 61 | fn cut(boxx: &[[i32; 3]; 2], cut: &[[i32; 3]; 2], new: &mut Vec<[[i32; 3]; 2]>) { 62 | if cut[0][0] > boxx[0][0] { 63 | new.push([boxx[0], [cut[0][0] - 1, boxx[1][1], boxx[1][2]]]); 64 | } 65 | if cut[1][0] < boxx[1][0] { 66 | new.push([[cut[1][0] + 1, boxx[0][1], boxx[0][2]], boxx[1]]); 67 | } 68 | if cut[1][1] < boxx[1][1] { 69 | new.push([ 70 | [cut[0][0], cut[1][1] + 1, boxx[0][2]], 71 | [cut[1][0], boxx[1][1], boxx[1][2]], 72 | ]); 73 | } 74 | if cut[0][1] > boxx[0][1] { 75 | new.push([ 76 | [cut[0][0], boxx[0][1], boxx[0][2]], 77 | [cut[1][0], cut[0][1] - 1, boxx[1][2]], 78 | ]); 79 | } 80 | if cut[0][2] > boxx[0][2] { 81 | new.push([ 82 | [cut[0][0], cut[0][1], boxx[0][2]], 83 | [cut[1][0], cut[1][1], cut[0][2] - 1], 84 | ]); 85 | } 86 | if cut[1][2] < boxx[1][2] { 87 | new.push([ 88 | [cut[0][0], cut[0][1], cut[1][2] + 1], 89 | [cut[1][0], cut[1][1], boxx[1][2]], 90 | ]); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /runner/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "runner" 3 | version = "0.1.0" 4 | authors = ["Tim Visee <3a4fb3964f@sinenomine.email>"] 5 | edition = "2021" 6 | 7 | [dependencies] 8 | rayon = "1.5" 9 | took = "0.1" 10 | 11 | # Days 12 | day01a = { path = "../day01a" } 13 | day01b = { path = "../day01b" } 14 | day02a = { path = "../day02a" } 15 | day02b = { path = "../day02b" } 16 | day03a = { path = "../day03a" } 17 | day03b = { path = "../day03b" } 18 | day04a = { path = "../day04a" } 19 | day04b = { path = "../day04b" } 20 | day05a = { path = "../day05a" } 21 | day05b = { path = "../day05b" } 22 | day06a = { path = "../day06a" } 23 | day06b = { path = "../day06b" } 24 | day07a = { path = "../day07a" } 25 | day07b = { path = "../day07b" } 26 | day08a = { path = "../day08a" } 27 | day08b = { path = "../day08b" } 28 | day09a = { path = "../day09a" } 29 | day09b = { path = "../day09b" } 30 | day10a = { path = "../day10a" } 31 | day10b = { path = "../day10b" } 32 | day11a = { path = "../day11a" } 33 | day11b = { path = "../day11b" } 34 | day12a = { path = "../day12a" } 35 | day12b = { path = "../day12b" } 36 | day13a = { path = "../day13a" } 37 | day13b = { path = "../day13b" } 38 | day14a = { path = "../day14a" } 39 | day14b = { path = "../day14b" } 40 | day15a = { path = "../day15a" } 41 | day15b = { path = "../day15b" } 42 | day16a = { path = "../day16a" } 43 | day16b = { path = "../day16b" } 44 | day17a = { path = "../day17a" } 45 | day17b = { path = "../day17b" } 46 | day18a = { path = "../day18a" } 47 | day18b = { path = "../day18b" } 48 | day19a = { path = "../day19a" } 49 | day19b = { path = "../day19b" } 50 | day20a = { path = "../day20a" } 51 | day20b = { path = "../day20b" } 52 | day21a = { path = "../day21a" } 53 | day21b = { path = "../day21b" } 54 | day22a = { path = "../day22a" } 55 | day22b = { path = "../day22b" } 56 | #day23a = { path = "../day23a" } 57 | #day23b = { path = "../day23b" } 58 | #day24a = { path = "../day24a" } 59 | #day24b = { path = "../day24b" } 60 | #day25a = { path = "../day25a" } 61 | -------------------------------------------------------------------------------- /runner/src/bin/bench.rs: -------------------------------------------------------------------------------- 1 | use took::{Timer, Took}; 2 | 3 | const RUNS: usize = 100; 4 | 5 | fn main() { 6 | println!("Benchmarking all days with {} runs...", RUNS); 7 | 8 | let times: Vec<_> = runner::jobs() 9 | .iter() 10 | .map(|j| { 11 | ( 12 | j.1, 13 | (0..RUNS) 14 | .map(|_| { 15 | let took = Timer::new(); 16 | j.0(); 17 | took.took().into_std() 18 | }) 19 | .min() 20 | .unwrap(), 21 | ) 22 | }) 23 | .collect(); 24 | 25 | times.iter().for_each(|t| Took::from_std(t.1).describe(t.0)); 26 | Took::from_std(times.into_iter().map(|(_, t)| t).sum()).describe("everything"); 27 | } 28 | -------------------------------------------------------------------------------- /runner/src/bin/runner-par.rs: -------------------------------------------------------------------------------- 1 | use rayon::prelude::*; 2 | use took::Timer; 3 | 4 | fn main() { 5 | // Build threadpool with larger stack size 6 | rayon::ThreadPoolBuilder::new().build_global().unwrap(); 7 | 8 | let jobs = runner::jobs(); 9 | let timer = Timer::new(); 10 | (0..jobs.len()).into_par_iter().for_each(|i| jobs[i].0()); 11 | timer.took().describe("everything"); 12 | } 13 | -------------------------------------------------------------------------------- /runner/src/bin/runner.rs: -------------------------------------------------------------------------------- 1 | use took::Timer; 2 | 3 | fn main() { 4 | let timer = Timer::new(); 5 | runner::jobs().iter().for_each(|j| j.0()); 6 | timer.took().describe("everything"); 7 | } 8 | -------------------------------------------------------------------------------- /runner/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub fn jobs() -> &'static [(fn(), &'static str)] { 2 | &[ 3 | (day01a::main, "day01a"), 4 | (day01b::main, "day01b"), 5 | (day02a::main, "day02a"), 6 | (day02b::main, "day02b"), 7 | (day03a::main, "day03a"), 8 | (day03b::main, "day03b"), 9 | (day04a::main, "day04a"), 10 | (day04b::main, "day04b"), 11 | (day05a::main, "day05a"), 12 | (day05b::main, "day05b"), 13 | (day06a::main, "day06a"), 14 | (day06b::main, "day06b"), 15 | (day07a::main, "day07a"), 16 | (day07b::main, "day07b"), 17 | (day08a::main, "day08a"), 18 | (day08b::main, "day08b"), 19 | (day09a::main, "day09a"), 20 | (day09b::main, "day09b"), 21 | (day10a::main, "day10a"), 22 | (day10b::main, "day10b"), 23 | (day11a::main, "day11a"), 24 | (day11b::main, "day11b"), 25 | (day12a::main, "day12a"), 26 | (day12b::main, "day12b"), 27 | (day13a::main, "day13a"), 28 | (day13b::main, "day13b"), 29 | (day14a::main, "day14a"), 30 | (day14b::main, "day14b"), 31 | (day15a::main, "day15a"), 32 | (day15b::main, "day15b"), 33 | (day16a::main, "day16a"), 34 | (day16b::main, "day16b"), 35 | (day17a::main, "day17a"), 36 | (day17b::main, "day17b"), 37 | (day18a::main, "day18a"), 38 | (day18b::main, "day18b"), 39 | (day19a::main, "day19a"), 40 | (day19b::main, "day19b"), 41 | (day20a::main, "day20a"), 42 | (day20b::main, "day20b"), 43 | (day21a::main, "day21a"), 44 | (day21b::main, "day21b"), 45 | (day22a::main, "day22a"), 46 | (day22b::main, "day22b"), 47 | // (day23a::main, "day23a"), 48 | // (day23b::main, "day23b"), 49 | // (day24a::main, "day24a"), 50 | // (day24b::main, "day24b"), 51 | // (day25a::main, "day25a"), 52 | ] 53 | } 54 | --------------------------------------------------------------------------------