Compare commits

...

39 Commits

Author SHA1 Message Date
50472363cf cleanup 2023-12-27 12:33:32 -05:00
2c4288de42 day25 2023-12-27 12:28:30 -05:00
14c6da72d9 day24 2023-12-27 10:20:20 -05:00
bdc150d0ed day23 2023-12-27 09:04:34 -05:00
b802cf1d16 day22 2023-12-22 10:31:00 -05:00
9db0e3f054 day21 2023-12-21 15:21:44 -05:00
a19a3258c2 day20 2023-12-21 10:10:57 -05:00
d3c11dcbed day19 2023-12-20 12:05:52 -05:00
e3f0f932e4 day18 part2 2023-12-20 10:10:02 -05:00
8b3bbab954 day18 part1 2023-12-20 09:34:15 -05:00
05a71ce349 day17 2023-12-19 16:10:35 -05:00
6e0f7b3c2f day16 2023-12-19 10:57:36 -05:00
e0655bd700 day15 2023-12-18 16:16:26 -05:00
7e082e6558 update day11 2023-12-18 12:16:50 -05:00
4e494e5596 update day10 2023-12-18 12:08:43 -05:00
0645f39e51 update day9 2023-12-18 11:50:21 -05:00
831d97d5b4 update day8 2023-12-18 11:43:37 -05:00
1c4bf97e07 update day7 2023-12-18 09:38:38 -05:00
593851daee update day6 2023-12-18 09:37:54 -05:00
c3849c1ad4 update day5 2023-12-18 09:37:35 -05:00
4980b285e8 update day3 2023-12-18 09:36:31 -05:00
bece6b708b day14 part2 2023-12-14 15:26:10 -05:00
97d8acbad8 day14 part1 2023-12-14 14:31:43 -05:00
ffb43d4860 day13 2023-12-14 12:54:47 -05:00
be7ca6666d day12 2023-12-14 11:39:20 -05:00
39633cc659 rewrote day4 2023-12-14 11:03:55 -05:00
51c64d827b delete accidental submodule 2023-12-14 10:46:45 -05:00
5a87bfb681 Change repo layout 2023-12-14 10:42:19 -05:00
78aab8ab5e day11 part2 2023-12-13 16:01:37 -05:00
8a40f62cf6 day11 part1 2023-12-13 15:40:57 -05:00
f9095fdf8f day10 part2 2023-12-13 12:20:16 -05:00
4984ad4801 day10 part1 2023-12-13 11:35:57 -05:00
2c3840f65a day9 part2 2023-12-11 09:52:06 -05:00
9fd55c3aac day9 part1 2023-12-11 09:43:11 -05:00
d5395fc349 day8 part2 2023-12-10 16:03:23 -05:00
7dec743fbb day8 part1 2023-12-10 15:05:34 -05:00
906b5c7254 day7 part2 2023-12-07 12:58:57 -05:00
4a20a35c2d day7 past1 2023-12-07 12:30:46 -05:00
8272d3b62c cange folder names 2023-12-07 12:30:36 -05:00
52 changed files with 4085 additions and 2232 deletions

5
.gitignore vendored
View File

@@ -1 +1,6 @@
target
input/
# Added by cargo
/target

504
Cargo.lock generated Normal file
View File

@@ -0,0 +1,504 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "advent-of-code-2023"
version = "0.1.0"
dependencies = [
"aoc-runner",
"aoc-runner-derive",
"array2d",
"itertools",
"num",
"prev-iter",
"rand 0.8.5",
"regex",
"rust-crypto",
"strum",
"strum_macros",
]
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "aoc-runner"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d21ef9204ad206a5a3e918e9920da04e1118ad91ce4f23570be964b9d6b9dfcb"
[[package]]
name = "aoc-runner-derive"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba8b944269d3fee645d281b1335e1797044db497bb02d0098cc3fdb8900069cc"
dependencies = [
"aoc-runner-internal",
"proc-macro2",
"quote",
"syn 1.0.109",
]
[[package]]
name = "aoc-runner-internal"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "274b0ba7f3669a45ec0aaacf94eb032a749de880ab776091576cca94037c9982"
dependencies = [
"serde",
"serde_derive",
"serde_json",
]
[[package]]
name = "array2d"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8b39cb2c1bf5a7c0dd097aa95ab859cf87dab5a4328900f5388942dc1889f74"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]]
name = "getrandom"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]]
name = "itertools"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
[[package]]
name = "libc"
version = "0.2.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
[[package]]
name = "memchr"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "num"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
"num-rational",
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-complex"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214"
dependencies = [
"num-traits",
]
[[package]]
name = "num-integer"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
dependencies = [
"autocfg",
"num-traits",
]
[[package]]
name = "num-iter"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252"
dependencies = [
"autocfg",
"num-integer",
"num-traits",
]
[[package]]
name = "num-rational"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "prev-iter"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ceacb352f798299b2044f4b9a894e8ef5d21115ccd293a323d44fc665132ec83"
[[package]]
name = "proc-macro2"
version = "1.0.70"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
dependencies = [
"libc",
"rand 0.4.6",
]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core 0.6.4",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "rust-crypto"
version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
dependencies = [
"gcc",
"libc",
"rand 0.3.23",
"rustc-serialize",
"time",
]
[[package]]
name = "rustc-serialize"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401"
[[package]]
name = "rustversion"
version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
[[package]]
name = "ryu"
version = "1.0.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
[[package]]
name = "serde"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.41",
]
[[package]]
name = "serde_json"
version = "1.0.108"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
dependencies = [
"itoa",
"ryu",
"serde",
]
[[package]]
name = "strum"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn 2.0.41",
]
[[package]]
name = "syn"
version = "1.0.109"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

20
Cargo.toml Normal file
View File

@@ -0,0 +1,20 @@
[package]
name = "advent-of-code-2023"
version = "0.1.0"
edition = "2021"
[lib]
bench = false
[dependencies]
rust-crypto = "0.2.36"
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
itertools = "0.12.0"
array2d = "0.3.0"
strum = "0.25.0"
strum_macros = "0.25"
prev-iter = "0.1.2"
regex = "1.10.2"
num = "0.4.1"
rand = "0.8.5"

7
day1/Cargo.lock generated
View File

@@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day1"
version = "0.1.0"

View File

@@ -1,8 +0,0 @@
[package]
name = "day1"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

File diff suppressed because it is too large Load Diff

7
day2/Cargo.lock generated
View File

@@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day2"
version = "0.1.0"

View File

@@ -1,8 +0,0 @@
[package]
name = "day2"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -1,100 +0,0 @@
Game 1: 1 red, 5 blue, 10 green; 5 green, 6 blue, 12 red; 4 red, 10 blue, 4 green
Game 2: 2 green, 1 blue; 1 red, 2 green; 3 red, 1 blue; 2 blue, 1 green, 8 red; 1 green, 10 red; 10 red
Game 3: 14 red, 9 green, 5 blue; 2 green, 5 red, 7 blue; 1 blue, 14 green; 6 green, 2 red
Game 4: 2 green, 3 blue, 9 red; 1 red, 1 green; 4 red, 4 blue; 1 blue, 19 red; 7 red
Game 5: 1 green, 10 blue, 4 red; 15 green, 4 red, 5 blue; 14 blue, 14 green, 2 red; 15 green, 7 blue, 1 red; 2 red, 9 green, 17 blue
Game 6: 2 red, 2 blue, 4 green; 3 red, 13 blue, 9 green; 1 red, 14 blue, 3 green; 9 green, 11 blue, 3 red; 6 blue, 2 green
Game 7: 11 green, 6 blue, 6 red; 2 blue, 3 red, 9 green; 3 red, 5 blue, 5 green; 6 red, 5 green, 3 blue; 9 red, 6 blue
Game 8: 11 blue, 3 red; 3 blue, 2 green, 13 red; 11 red, 7 blue, 1 green
Game 9: 2 green, 1 blue, 3 red; 9 green, 4 red; 7 red, 5 green; 4 red, 1 blue; 11 green, 16 red; 2 red, 6 green
Game 10: 1 red, 4 blue, 1 green; 7 green, 3 red, 1 blue; 5 blue, 7 red
Game 11: 1 red, 11 blue, 7 green; 6 green, 2 blue, 12 red; 8 blue, 7 green, 5 red
Game 12: 11 red, 5 blue, 4 green; 8 blue, 15 red, 5 green; 9 blue, 11 green, 1 red; 6 blue, 3 red, 9 green; 5 red, 2 blue, 1 green
Game 13: 5 red, 2 blue, 7 green; 1 red, 8 green; 6 green, 4 red
Game 14: 1 green, 2 blue, 2 red; 5 red, 1 blue, 2 green; 4 red, 1 blue
Game 15: 6 green, 1 red; 4 red, 5 blue, 6 green; 1 green, 3 blue, 4 red; 5 green, 8 red
Game 16: 16 red, 10 blue, 3 green; 9 blue, 13 green, 5 red; 14 green, 2 blue, 2 red; 3 blue, 1 green, 1 red; 2 green, 4 blue, 8 red; 1 blue, 17 red, 9 green
Game 17: 6 red, 1 blue, 15 green; 5 red, 5 green; 16 green, 5 red, 4 blue; 5 red, 8 green, 2 blue; 12 blue, 13 green, 3 red
Game 18: 17 green, 5 blue; 2 green, 14 red; 10 green, 9 red, 10 blue; 6 red, 11 green, 6 blue
Game 19: 12 green, 2 blue, 4 red; 1 blue, 16 red; 8 green, 2 blue, 14 red
Game 20: 1 red, 4 green; 5 red, 4 green; 4 green, 1 red; 5 red, 1 blue, 3 green
Game 21: 15 red, 5 blue, 12 green; 10 green, 12 red, 1 blue; 9 red, 14 blue, 1 green; 2 green, 13 red, 7 blue; 12 blue, 11 red, 12 green
Game 22: 8 blue, 3 red; 2 green, 4 red, 3 blue; 1 blue, 2 red, 1 green; 13 blue, 4 red, 2 green
Game 23: 3 blue, 5 green, 3 red; 4 green, 9 red; 3 red, 2 green; 2 blue, 3 green, 2 red; 2 green, 3 blue, 5 red
Game 24: 15 red, 1 green; 1 blue, 14 red, 1 green; 5 green, 14 red; 4 blue, 1 red, 3 green; 1 blue, 4 green, 3 red
Game 25: 3 green, 3 red; 8 green, 1 red, 2 blue; 1 blue, 11 green
Game 26: 3 red, 12 green, 15 blue; 15 blue, 2 red, 2 green; 2 red, 18 blue; 3 red, 14 blue, 7 green
Game 27: 6 green, 15 red, 10 blue; 6 green, 7 red, 4 blue; 14 blue, 12 red, 7 green; 8 red, 14 blue, 17 green; 15 red, 14 blue, 4 green; 5 red, 1 blue, 5 green
Game 28: 5 blue, 3 green; 3 green, 2 blue, 4 red; 8 green, 6 red; 4 red, 2 green, 5 blue; 1 blue, 5 red, 5 green; 1 red, 4 blue, 9 green
Game 29: 4 blue, 9 red, 12 green; 2 red, 14 blue, 13 green; 2 red, 10 green; 5 green, 14 blue, 9 red
Game 30: 3 red, 3 blue, 13 green; 2 blue, 10 green, 4 red; 2 blue, 5 green, 4 red
Game 31: 13 green, 3 red, 8 blue; 15 green; 4 blue, 1 red; 8 red, 4 green, 2 blue; 18 blue, 4 red, 9 green
Game 32: 3 blue, 8 red, 16 green; 2 blue, 13 red, 18 green; 8 red, 9 green
Game 33: 1 red, 7 green, 3 blue; 10 green, 10 red, 10 blue; 5 blue, 8 red, 14 green; 10 blue, 5 green, 2 red; 10 green, 10 red, 16 blue
Game 34: 3 blue, 1 green, 6 red; 2 blue, 5 red; 3 blue, 2 red, 9 green
Game 35: 5 blue, 2 green, 1 red; 7 blue, 3 red, 7 green; 13 green, 4 blue, 3 red; 1 blue, 9 green; 1 red, 13 green, 3 blue
Game 36: 1 red, 1 blue, 13 green; 1 green; 2 blue, 16 green; 3 blue, 17 green, 1 red; 4 blue, 1 red; 5 blue, 1 red
Game 37: 5 red, 8 green, 1 blue; 16 blue, 2 red; 7 blue, 7 red, 6 green; 2 blue, 6 green, 4 red; 4 green, 3 red, 5 blue; 3 green, 9 blue, 3 red
Game 38: 7 green, 3 red, 2 blue; 1 blue, 1 green, 1 red; 15 blue; 4 red, 11 blue; 1 red, 1 green, 2 blue
Game 39: 20 red, 4 blue, 7 green; 11 red, 16 green, 7 blue; 7 red, 15 green, 11 blue; 10 red, 9 blue, 13 green; 12 red, 12 blue, 17 green
Game 40: 5 blue, 4 green; 1 red, 1 blue, 9 green; 9 green, 6 blue, 1 red; 6 blue, 4 green, 1 red
Game 41: 2 blue; 2 blue, 1 green; 4 green, 2 red, 1 blue
Game 42: 7 blue, 12 green, 1 red; 8 blue, 3 green, 1 red; 3 red, 1 blue, 10 green; 7 green, 15 blue
Game 43: 3 blue, 19 green, 7 red; 14 blue, 8 green, 8 red; 2 red, 1 green, 5 blue; 8 red, 8 blue, 17 green; 1 blue, 10 red, 18 green; 4 green, 11 red, 8 blue
Game 44: 12 blue, 4 green; 9 blue, 1 green, 2 red; 2 red, 3 blue, 3 green; 1 red, 4 green, 14 blue
Game 45: 2 red, 1 blue, 7 green; 5 red, 5 green, 1 blue; 2 blue, 6 red, 5 green; 3 green, 2 blue; 6 red, 1 blue; 5 green, 4 red, 1 blue
Game 46: 2 blue, 3 green, 2 red; 1 blue, 4 green, 5 red; 4 green, 3 blue, 6 red
Game 47: 10 green, 12 blue; 3 red, 8 blue, 8 green; 1 green, 10 blue, 2 red; 4 blue, 4 green
Game 48: 5 green, 11 blue, 4 red; 2 blue, 5 green, 7 red; 16 red, 2 green, 5 blue; 2 red, 1 green, 10 blue
Game 49: 11 blue, 5 red, 7 green; 15 green, 9 blue; 3 red, 4 green, 6 blue; 2 green, 14 blue, 6 red; 2 red, 11 green, 4 blue; 12 blue, 10 green
Game 50: 1 red, 13 blue, 4 green; 2 green, 1 red, 6 blue; 6 green, 14 blue
Game 51: 5 blue, 9 green, 1 red; 17 blue, 1 red; 11 green, 13 blue; 7 green, 13 blue; 2 blue, 4 green; 7 blue, 5 green
Game 52: 17 green, 3 blue; 15 green, 5 blue, 1 red; 12 green, 1 red, 4 blue; 1 red, 10 blue, 16 green; 12 green, 6 blue, 1 red
Game 53: 4 red; 2 green, 5 blue, 5 red; 3 red, 5 blue
Game 54: 5 red, 1 green; 16 green, 14 blue, 10 red; 1 red, 15 blue, 15 green
Game 55: 5 green, 14 red; 9 red, 6 green, 1 blue; 9 green, 4 red, 1 blue; 3 green, 1 blue, 7 red; 1 blue, 1 red, 2 green
Game 56: 2 red, 2 blue; 8 red, 5 blue; 6 blue, 1 green, 4 red
Game 57: 1 blue, 1 red; 2 green, 8 red; 7 red, 2 green; 2 blue, 5 green, 5 red
Game 58: 18 blue, 1 red, 6 green; 1 red, 8 green; 5 blue, 7 green; 4 blue, 2 green; 8 blue, 4 green
Game 59: 10 red, 3 blue; 10 red, 3 green, 4 blue; 3 blue, 1 green; 4 red, 3 green, 6 blue; 5 red, 3 green, 5 blue
Game 60: 8 red, 7 green; 11 green, 14 red; 11 red, 1 blue, 7 green; 1 blue, 18 red; 10 red, 12 green, 1 blue
Game 61: 11 blue, 6 green, 1 red; 6 red, 12 green, 6 blue; 14 blue, 6 red; 11 blue, 3 red, 6 green
Game 62: 7 blue, 4 green, 5 red; 2 green, 4 red, 7 blue; 4 red; 1 blue, 5 red
Game 63: 7 green, 10 blue, 11 red; 13 red, 19 blue; 11 green, 11 red; 8 green, 18 blue, 4 red; 5 green, 19 blue, 12 red; 10 green, 6 blue, 2 red
Game 64: 1 green, 5 red; 4 green, 13 blue, 6 red; 5 green, 2 red, 13 blue
Game 65: 1 blue, 2 green, 5 red; 13 red, 4 green, 3 blue; 8 red; 3 green, 1 red; 6 red, 4 green, 2 blue
Game 66: 2 green, 15 red; 3 green, 12 red; 2 blue, 2 green, 4 red; 4 blue, 8 red; 1 green, 4 blue, 14 red; 2 blue, 2 green, 6 red
Game 67: 3 green, 5 blue, 1 red; 5 green, 6 red, 3 blue; 13 red, 9 green, 8 blue; 11 green, 15 red, 3 blue; 16 red, 8 blue, 17 green; 8 green, 5 red
Game 68: 1 red, 3 green; 1 blue; 2 green; 3 red, 1 blue; 1 green, 3 red, 2 blue
Game 69: 2 red, 13 green, 3 blue; 3 red, 2 blue, 7 green; 2 blue, 3 red, 9 green; 7 blue, 1 red, 4 green; 6 red, 14 blue, 2 green; 1 green, 2 red, 14 blue
Game 70: 5 blue, 2 green, 1 red; 1 blue, 6 red, 4 green; 4 red, 2 blue, 6 green; 4 red, 2 blue, 8 green; 4 green, 1 blue
Game 71: 7 green, 3 blue; 2 red, 4 green, 6 blue; 2 red, 5 blue; 1 blue, 5 green
Game 72: 20 green, 4 red; 13 green, 12 blue, 7 red; 15 blue, 16 red, 7 green; 14 green, 13 red, 2 blue; 11 green, 6 red, 8 blue; 10 green, 13 red
Game 73: 10 blue, 13 green, 3 red; 3 red, 16 green, 7 blue; 5 blue, 6 green, 2 red; 4 green, 1 blue, 2 red
Game 74: 2 green, 7 red, 1 blue; 8 red, 10 green; 5 red, 5 blue
Game 75: 4 green, 13 blue, 5 red; 1 red, 2 green, 3 blue; 2 red, 7 green, 14 blue; 1 red, 2 green, 2 blue; 13 blue, 5 red
Game 76: 10 blue, 3 green, 6 red; 12 blue, 1 red, 3 green; 13 green, 16 blue, 4 red
Game 77: 7 green, 4 red, 4 blue; 6 red; 6 red, 4 green, 9 blue; 1 red, 2 blue
Game 78: 3 blue, 11 green; 12 green; 10 green, 4 red, 6 blue
Game 79: 8 green, 12 red, 9 blue; 4 green, 6 blue, 1 red; 9 blue, 4 green; 6 blue, 7 green, 11 red; 11 blue, 18 red, 7 green; 4 green, 11 red, 1 blue
Game 80: 9 green, 1 red, 7 blue; 3 red, 15 blue, 9 green; 3 blue, 1 red, 5 green; 10 red, 15 blue, 3 green
Game 81: 2 red, 3 blue, 2 green; 1 green, 4 blue, 5 red; 7 red, 8 blue; 2 green, 2 blue, 8 red
Game 82: 6 blue, 4 red, 1 green; 1 green, 4 red, 9 blue; 3 green, 8 blue; 3 red, 3 blue; 8 blue, 2 green
Game 83: 2 red, 1 green, 3 blue; 6 blue, 3 red; 2 red, 1 green, 4 blue
Game 84: 1 blue, 10 green; 13 red, 8 green, 4 blue; 7 red, 1 green, 4 blue
Game 85: 7 red, 7 green, 1 blue; 1 red, 5 green, 2 blue; 16 red, 10 green, 4 blue; 1 blue, 12 green, 3 red
Game 86: 15 red, 7 blue, 1 green; 19 blue, 3 red; 2 blue, 1 green, 4 red
Game 87: 9 green; 5 red, 8 green, 1 blue; 1 blue, 5 red, 7 green
Game 88: 16 red, 3 green, 2 blue; 1 blue, 6 green, 14 red; 12 blue, 17 red; 11 blue, 13 red, 5 green; 2 blue, 20 red, 3 green; 9 red, 8 blue, 2 green
Game 89: 7 green, 3 blue, 6 red; 4 green, 7 blue, 5 red; 6 green, 3 red, 7 blue; 5 green, 3 red, 8 blue; 6 red, 9 blue, 11 green
Game 90: 11 green, 4 red, 5 blue; 7 green, 2 red, 1 blue; 4 red, 1 green, 8 blue
Game 91: 2 green, 7 red, 5 blue; 18 red, 3 green, 3 blue; 6 red, 2 blue, 5 green; 6 red, 5 blue, 3 green; 7 green, 6 blue, 8 red
Game 92: 4 red; 3 red, 5 green, 1 blue; 3 red, 2 blue, 2 green
Game 93: 2 green, 15 red, 10 blue; 3 red, 8 blue; 20 red, 5 blue, 2 green; 11 blue, 2 green, 20 red; 7 blue, 18 red
Game 94: 1 red, 4 green, 2 blue; 7 green, 9 red, 2 blue; 3 red, 3 green, 1 blue; 8 red, 2 blue, 2 green; 2 red, 8 green, 2 blue; 5 green, 8 red
Game 95: 2 blue, 4 red; 1 blue, 3 green, 4 red; 5 green, 3 red, 4 blue; 1 green, 4 red, 6 blue
Game 96: 1 green, 1 blue, 2 red; 1 red, 13 blue, 4 green; 3 red, 14 blue, 15 green
Game 97: 3 green, 7 red; 2 red, 3 green, 1 blue; 4 green, 1 blue, 4 red; 1 red
Game 98: 9 blue, 8 red, 3 green; 10 blue, 3 red; 7 blue, 2 green, 7 red; 4 red, 11 blue, 3 green; 8 red, 9 blue, 2 green
Game 99: 5 green, 8 blue; 3 blue, 4 red, 16 green; 1 green, 5 red, 6 blue
Game 100: 6 blue, 9 green; 3 green, 6 blue; 5 blue, 1 red

View File

@@ -1,83 +0,0 @@
use std::{fs, cmp::max};
fn main() {
let input = fs::read_to_string("input.txt").unwrap();
let input: Vec<_> = input.split('\n').collect();
let mut sum = 0;
for line in input {
let split:Vec<_> = line.split(':').collect();
let rounds: Vec<_> = split.last().unwrap().split(';').collect();
let rounds: Vec<_> = rounds.iter()
.map(|x| {
x.split(',').collect::<Vec<_>>()
}).collect();
let rounds: Vec<_> = rounds.iter()
.map(|x| {
x.iter().map(|x| {
x.trim().split(' ').collect::<Vec<_>>()
}).collect::<Vec<_>>()
}).collect();
let (mut r_max, mut g_max, mut b_max) = (0, 0, 0);
for round in rounds {
for set in round {
let color = set.last().unwrap();
let num: i32 = set.first().unwrap().parse().unwrap();
match *color {
"red" => r_max = max(num, r_max),
"blue" => b_max = max(num, b_max),
"green" => g_max = max(num, g_max),
&_ => todo!()
}
}
}
//println!("{}", r_max);
sum += r_max * g_max * b_max;
}
println!("{}", sum);
}
// use std::fs;
// fn main() {
// let input = fs::read_to_string("input.txt").unwrap();
// let input: Vec<_> = input.split('\n').collect();
// let mut game_id = 0;
// let (r_max, g_max, b_max) = (12, 13, 14);
// let mut sum = 0;
// for line in input {
// game_id += 1;
// let split:Vec<_> = line.split(':').collect();
// let rounds: Vec<_> = split.last().unwrap().split(';').collect();
// let rounds: Vec<_> = rounds.iter().map(|x| x.split(',').collect::<Vec<_>>()).collect();
// let rounds: Vec<_> = rounds.iter().map(|x| x.iter().map(|x| x.trim().split(' ').collect::<Vec<_>>()).collect::<Vec<_>>()).collect();
// let mut sad = false;
// for round in rounds {
// let (mut r_cur, mut g_cur, mut b_cur) = (0, 0, 0);
// for set in round {
// let color = set.last().unwrap();
// let num: i32 = set.first().unwrap().parse().unwrap();
// match *color {
// "red" => r_cur += num,
// "blue" => b_cur += num,
// "green" => g_cur += num,
// &_ => todo!()
// }
// }
// if r_cur > r_max || b_cur > b_max || g_cur > g_max {
// sad = true;
// }
// }
// if !sad {
// sum += game_id;
// }
// }
// println!("{}", sum);
// }

16
day3/Cargo.lock generated
View File

@@ -1,16 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "array2d"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79093d31d0a9c7832c71ad74dd945b7861f721e6f242aa67be253a5eecbac937"
[[package]]
name = "day3"
version = "0.1.0"
dependencies = [
"array2d",
]

View File

@@ -1,9 +0,0 @@
[package]
name = "day3"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
array2d = "0.3.0"

View File

@@ -1,140 +0,0 @@
.......................661.........................485..565.......344.......325.....................................841.....725.............
....*609..131................512.......................*................536*..............462/..-...60..424.........@....$.*................
.316.........*.......39..................@.630......377........919...........98................789..*..*..............788..2.......=..564...
...........431...535...*...............622.-..../.................*..........*.......682...........108.116....@...-...............299.......
.....................428.....378...844.........416...............586.537=..27..........*......$..............871...331..................492.
...878....390....%..............*.*...................739.496=.................867......867..867.........................344......487.../...
...../.....*...558........@..535...644..................+.........404..605.......*................................%.....*...................
........................381............729..726....578........10...*..........818..............................929....934..........119......
.53....31..........734-..........847*.................#.........*...........#............217............/..321....................*.........
.......=.............................509.315.654.................60.........925.747*559..*.....430....226..*...................290...848=...
..........=.......546......664..507......../....#.......337.............................94........=.........359....528*996..................
.....351...638.......*.............*433............337.....................226...859........../............................378..............
.......*..........648.........183.........126........*...........208.954......=....*.......626........499*..........803.../....642.235......
.518*...813..990..............*..............*......699...133....+...............68...............79......838.447...*..........*...*........
................+.696*.........586.6......243.............*..........$224.............392...275.....-.........*...699...#177..230.593.&.....
...........$326.......683.-761.......491......./.........26...........................*.....=.........56.305.262.......................150..
....=.......................................41.908.........................819.785.....276.....&.................%..........................
.618......401$...............-......................599..124......34+.........*..............676..................342...........473.........
....................889......888..454....723/.........*.................141*.....958.......................................416.....*94......
....212.............-................%.........826=....552..................569....*............................728........=............143.
...*......287...................=60.............................872.....886.......171....437......815..680.........*.............633....+...
..234....*.....687..........432........203/.....*...275.65.........*341.@...........................*....%.246......272.....922*..../.......
........967.........495.......*....161.......474.97...*..*..84.400.........*295....805......................@...................915.........
...419.................*.979...932....*.............729.215.#....*.......81........*......554.263*567..........812..........................
.....*..............458....$.........682......................179................348..906.................428.../............798............
...668..................-.........................552............./..................=.......+...........@..........99........*..85.4.......
........29......938..594......107........*171.98.....*..896....$..491...........+..........412..12.............326.*.....705..4....*........
..........*....................+......332......@....949..*...750.......$..974....342.............*....558......#............*..........794..
.......459....342*.........637...........................273.....658..601....*................735....*...............%....627....889...*....
.697..............131....................718.................689.............450....390............994.............793.............*..241...
..............991........89..........14.......*.................*912.............39.+...698.............................953*240...87........
..324.............618.....*...328......*....538.%.....307.920.........515...............*...................................................
.....*386...........*...780..*.......475.........719...*...*...................910...410................384.....999........*756.............
....................268.......701.............72........63.43...193.....+..................674...670$....*........*......95.......893.......
...16.........................................*....663........../....407.....................*........258....264=.298........202*..../......
...&......574................187.......88...53.........931........@......&759....$..672....385..............................................
.....938........192......297....*.723...*.................%......930...........692................283.....................=349.........&981.
......*....................&.207....*...843.736.........................260..........677..389........*..............954..........&..........
......603........713.............745..................411.359.922.......*.............*......*.......718..888..561..=.........182..206......
............896....*.....173*383.......%...145...943...*.....*.........622..382*.......180.141............*...........................*.....
.....89........*...238.............+.714....*........575../.........................@...............$.....539.......114*721.645........471..
.......*307....968..............250......836.....498......59....909..601*..........117...........435../........944..........................
............*...............56*.................+....498..........-......730.882..........975..........680........*...95......152....$517...
...........150.......142.......473.713.+262...........=...577.266...736..........668..$.........70*111......811.165..@......................
.......741.............*.97.......................=.........*.......*....-654..........428..157................................748*823......
.........*............48...*.....772....892.....350....$.....760.148.............................440...........731*563......................
........260..............227...............*..........795..................649.....27.107...219.@.....23@...............226......369........
...41............&...................+...136.....546.......$.920...................+...*...&....../.........981...........@.......*.....454.
...*......635%....782...............560............*....896...........854..+...........694......340...@.498*....................41..959*....
...486..........................63..................810......641....+....*..532....642.......$.......90.....................76=.............
..........325.....................@..............@...........-....539.407.............$......9...........550................................
...787..$....*.$105.126.+810.........497.576...538.............................718.......................*...+....317..519..................
.......303.493...........................................-...........462..647..*...........%..+875....641..644.....*......*.....154.588.....
................./.....-......44.........%...@140.......228...43......*....*..132.794...628.......................669....110....*.....*.....
....579...........348..32.491*.......#...646.......506..........*708......74........#........117..............24*............698....532.....
......*.........................902.722............=....=........................................700....610......878....*...................
.../..885.../..351.............*.........................799.....814*238......*339....428*825......./................965.862......125.......
.723......243.@........852..........757...784.472..814.......603...........151........................279.617....849........................
........................*......./............*.......*.........*....#.............91.......246...384.....*........%.........................
.218.659....113+........128....691...................972......571....934............*......*...................................442..236.....
....*...............455.............868......&379.........................594.......80....654.....................421.456...................
............2*535......*410...553........409......235.173..779......116.....*.................&........*646.418*.....*.................596..
.70#.361......................./....493....$..........*...-.....440.........317...865...323....696..202..........952.......187.....%....#...
..........%...767......318............*................1.............../...........*......*................241......@.147...*.....389.......
..921.....301..*........*............67.540.../....149.........=........827.....=.347....956..........980...............$...204.............
...*............341......154.............*..695.....$.....20.183..............177..................$...$...66......699..........495......296
.460........&.......+............%.......4......+........*.......................................347.........*36...*....912.......*..765....
............142..163......885..480...............805.%...587...........289.310*389........$843..........-..........417....*.....628....*....
.............................*............434........803........482......-.........556.........&.........294...33$.........79........358....
.......................407@...873...............+..................*542....../.41....$./758....176.................*........................
.........842......................442*766.......284.........842...........856...*......................647......422.94..............@.......
....$........799............................&.......433.318*.....576..........111....................................................788....
.720...168.....%........840..............989....................*.......=............468..419...........198.................................
......*..................+..392..............282.......&...............591..........&....*....101.340....-.....187.....-....................
.....746...........................499...779...*....456...........@....................346....*......%...........*..693.......94..72........
.........970..671..696./....................&..999......124..246.434...........................173........@.....165.......925*.../..........
..628.............*....608.....827-.......*..............#....*........634...../418......185.......311...808.........372*............824....
..........694...360.....................43.645.................935........*516...........*....555.....*..................33.........-.......
............*............+........576#.........810*592..740.....................#665..968........*499.775..882+..............998............
....=303.....433.280......147..82.........................*..............................................................751*...............
.................$......................608...560..827...227....................448*..@......................@529.376...........@...........
...........465.....#.............554.....#.......#..#.......................401.......714...../.192.999..................466...28.161....351
..............&....706..157.679.@..........741..............818.811=..............412.......376...&..*.......=..............................
.441.....955....63.........*........=........+.............*..............#..........*..............399.......613.......444........*972.....
........@......*..................697..........600.&965...354.#.....392...827..665....326.................323...........&.......483.........
................381........972..........373*..*................9...&...........................289.........*................................
...........................*....+.............239......................863....................*..........341.....*329...................$...
801..+...638.659........358...29..695.....@........241...680.....863..........................310.#...........941........@216........311....
...*.358.*...*....................@....786....*330................&.........842........11..........279...................................686
.932..........666....533..712..............801.............64.544.....*972.....*353....-..809...........524...........397...............*...
.........795+.......*.......*......394=................586......*.........................................&...........................562...
...................629.......184........796..............=................-946.348.../670............63.........%...........................
.....428-................918.........@..............#.............850.889.........*..............673..#..110.221..........337.560...-.......
.....................926*.........809.........=......627.............*..........344..........343.*........*.......832.......*....*...216....
.....624.....+................................78............915..701.....876.........734.402.....181.193.460.639.....*...558...138..........
.../...*...91....804..324..985......#429......................*..*.............892....................*......*...321.727...........134......
...991............*.........*.............39...........%.633.213.623..........&...........601.919.....378.318...*............@34............
........183.....#.399...+..297..973...622..*........855../......................+684../......*................335.................733.......
..........@..576......597........*.....*....686....................371..98..23$......119................................=.777......*........
.................901%......*...412......102...........754...332.47*......*......861+......539................495@....801...*..404...777.....
.........577..........577..978.................990......*...#............236.............@..............339............../......*........534
..169.....*..687........*..........598..........*..349@.723.....864..........972............196.....491*........$........335.372............
.........339..=......633........29...*.........4............251*.....$..........*.250.........$.908..............356.230...........324.386..
.................943.............-.....=............................325...726.690.*................/.......646........*...214.......=.......
.........&468.......*..................999.......944.........751..........*.......219.837.107..............*...=....271..*..............283.
......*..........210.....*390.....917*.....996*.....+..790...-.........128...............*................905.277.......320....936..835.....
...640.581....*.......167.............392......29......*..........885............................369..................&...........*.$...#...
..............708..........106.223...................817.........*............277.........&.........@..795.-296....172..........633......229
.......82..........@679.......*....*806.................../....10.............*.........456...........*.................95...........3......
..........536....................12........=914..458.......214..........995..97.-735........370.......334..876=.........*.......950#........
.........*.............=.....10.......837...........+..518.................*...................*........................761.................
......414..=.........794.............=................*...................813.394...815.718....759........403...............738.............
............463...........-..238.419............810.41...........452..2=..................&..............&........435.................468...
........................103....*..........................+...11.&....................927...........%.......282...*...234.....229......*....
......301+....................678............100.......954.....*...@....182....@.........*....737...916....-....890....@..118*.......625....
............67...312..865+.............910.....*...382.......516....973....*..874.500..153.....*............................................
.....373+...*.....*...............979..........469....*375..............765...................99....................733................897..
..........828.....669......=.....*...........................................284.189...$..371......*168..............%.......762............
..........................4..565.226........562@....190......281....257.......*.......889./......57........./...#.......210..*..............
......47.......120.............#...................*...........&....*.....169.549............%............414..744......%....503.#208.......
........*.................643.........397...........350..........289....&...*........&.....323.....+..................................856...
.....*...............458....#........................................104.....931..855..............89..469.....882...........=.........*....
..594.777......390...*...........422........355..............654............................81........*...........*......282..630....195....
..................*.568.912........*........*.....377..........*......*877.............419..*.....148.768.......471....+....*...............
.......393......163..........298.820............@..................582.......823......=...........*....................952..................
..........*268.......*733.59...@.............403..........................................14&...502...............481.........$.....231.....
........#.........970.....*......#....981...........711.261=.................=.......................701..244................323.....*......
.396....993.............557.......46.....*...........+..........714*659.....134........623..........*............677.730..............846...
......#......91...405........296..........295..............@..*.......................#..............740............*........%..............
.......345..=........-.792....*..834................100.891....764...697........570......*....620*.@.....................508..295...........
...*13................../...340...#..134..............#................*..........*.......247......660....607....705.....=...........165....
.........521..824...222.............*......372..290.....844.825-.......867..820...627...........................*............128...../...777
...629...*....#..................788...535....*..-.......*.........361......................*......805.......732....914....../...-......@...
...*.....743...........853..................637.......880...-..849*........425............946..590....*302...........*.........748..........
...120.%.......271..............862.....70................207................=......233.......*..................443..263...................
........680....../.825.....&793...........*....................-720.............555........184..509.......22......*.............811.........
..........................................772.272......................134.........*..374.........*............573........*.......*.........
934..231.....*....821...230.....981..............%........707..370....*.....634%..787..*..........93..909..70..........199.59...490.........
.......*....525.........-........*...747...676=..../.......*..........829...............324..952.........%...*..........................%...
.....189.........................791.............236........687.868........................................505..............713......777....

7
day4/Cargo.lock generated
View File

@@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day4"
version = "0.1.0"

View File

@@ -1,8 +0,0 @@
[package]
name = "day4"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -1,215 +0,0 @@
Card 1: 66 90 67 76 55 13 91 31 95 4 | 82 98 69 8 15 2 32 24 99 56 46 65 60 72 58 68 54 22 26 5 74 25 84 73 61
Card 2: 94 57 54 45 9 78 71 35 48 44 | 9 56 28 57 55 95 32 48 76 47 94 35 78 91 54 49 38 30 17 63 71 8 16 45 44
Card 3: 44 10 67 65 62 43 47 13 26 95 | 67 55 65 68 26 77 41 43 94 13 62 27 66 81 29 10 69 95 31 47 70 72 44 23 17
Card 4: 47 48 14 30 64 31 81 22 65 60 | 85 23 47 19 60 31 32 68 64 33 14 22 65 48 67 72 87 46 92 83 54 81 66 91 30
Card 5: 43 66 44 76 67 27 52 26 83 39 | 37 83 99 29 48 60 62 2 31 27 4 65 84 89 45 95 78 21 47 44 76 34 96 30 74
Card 6: 38 34 59 52 10 14 57 98 73 90 | 77 32 21 16 15 57 30 97 43 47 91 39 92 42 87 69 82 35 68 60 78 37 46 50 9
Card 7: 94 57 27 45 70 34 83 30 51 17 | 89 30 44 29 17 41 70 87 83 45 51 60 27 48 33 43 88 34 67 54 64 94 85 57 26
Card 8: 64 82 99 10 20 76 25 78 83 48 | 66 62 98 32 48 2 79 97 65 70 89 56 37 44 45 21 75 93 41 9 3 61 92 19 81
Card 9: 93 49 20 77 14 86 89 28 54 82 | 61 67 64 46 28 89 82 25 49 5 92 37 4 41 15 83 44 6 60 36 77 12 68 50 71
Card 10: 50 76 67 32 84 46 54 30 42 74 | 42 82 85 2 74 67 23 48 96 30 73 79 38 40 3 45 49 84 59 99 76 33 58 62 13
Card 11: 55 15 77 31 37 23 2 43 51 35 | 46 93 81 92 48 68 84 75 44 79 26 33 82 59 71 10 65 21 16 40 53 30 80 52 63
Card 12: 18 99 43 33 20 57 72 70 90 60 | 83 5 17 2 67 51 55 77 3 47 12 94 74 45 68 35 38 37 33 14 96 63 71 30 75
Card 13: 98 24 76 47 1 29 71 45 82 75 | 23 9 40 65 28 4 34 97 53 30 77 55 59 61 76 35 54 12 2 58 46 72 86 1 17
Card 14: 71 74 19 46 91 36 35 65 59 98 | 80 70 99 51 94 57 41 62 52 85 9 4 6 92 2 98 24 19 59 90 42 45 66 79 32
Card 15: 79 46 69 60 94 86 18 12 54 88 | 12 53 29 62 27 55 80 22 32 51 66 54 30 23 56 94 68 98 87 21 93 17 49 10 74
Card 16: 7 61 48 28 47 9 37 96 54 15 | 84 62 80 33 65 4 67 61 97 79 58 76 23 38 18 13 75 19 57 83 14 21 26 28 31
Card 17: 18 83 31 73 94 46 56 62 19 78 | 25 86 68 43 93 28 78 71 10 23 50 12 47 35 64 85 4 54 99 14 40 53 83 6 39
Card 18: 21 51 16 99 30 10 95 71 14 35 | 39 96 20 4 28 55 40 31 22 17 78 94 42 62 57 32 37 7 27 77 63 65 82 26 99
Card 19: 90 45 35 36 13 5 87 42 82 34 | 10 17 97 69 43 91 16 72 45 81 19 76 29 1 96 49 15 20 70 51 59 56 14 22 63
Card 20: 40 46 71 56 1 25 29 45 53 52 | 83 79 7 95 93 38 91 62 81 60 73 44 63 15 28 77 32 85 18 10 99 33 4 50 5
Card 21: 51 99 84 13 87 11 34 16 96 88 | 51 59 87 12 34 16 96 84 26 99 69 97 1 21 62 11 81 56 64 88 77 49 50 58 13
Card 22: 85 62 53 30 26 15 94 34 52 74 | 71 12 41 24 94 30 95 93 85 25 53 16 91 27 61 46 32 97 39 52 20 15 74 57 42
Card 23: 45 15 9 83 58 69 20 60 90 99 | 97 89 48 23 5 60 86 59 42 74 66 17 51 28 15 9 92 69 73 62 49 65 33 30 90
Card 24: 11 17 60 88 13 55 56 12 71 51 | 53 5 8 68 55 28 20 14 71 99 60 66 34 4 90 12 41 63 67 25 86 26 2 30 40
Card 25: 91 50 44 43 69 68 77 28 53 25 | 14 35 63 94 58 19 70 47 33 8 27 78 12 46 38 50 25 57 13 74 2 45 4 98 95
Card 26: 37 5 21 95 82 31 90 4 18 40 | 75 83 71 90 63 32 9 26 28 54 25 97 3 5 74 43 27 23 16 6 88 24 52 31 53
Card 27: 74 41 60 91 15 83 62 9 64 40 | 97 44 26 34 71 9 40 94 62 20 33 95 91 43 24 74 57 2 64 41 39 35 86 85 32
Card 28: 23 22 33 9 20 57 78 18 92 66 | 8 38 17 23 61 5 48 32 22 94 92 55 93 14 71 78 46 66 33 97 49 35 64 57 65
Card 29: 61 14 28 80 47 3 86 93 36 7 | 82 22 32 19 79 84 1 39 65 88 95 66 76 56 38 67 11 68 40 91 93 31 94 23 70
Card 30: 6 72 2 10 13 18 95 62 56 33 | 71 75 52 36 38 44 96 1 23 40 81 99 21 41 35 56 13 89 33 88 68 48 18 60 25
Card 31: 79 76 82 11 92 3 61 68 53 91 | 92 56 74 63 38 72 94 19 34 12 51 97 7 53 29 4 9 48 57 87 88 49 44 76 2
Card 32: 93 29 68 58 55 17 21 37 7 27 | 22 83 80 82 87 98 46 57 59 43 90 10 74 28 32 5 41 75 35 55 97 92 81 48 73
Card 33: 55 25 32 46 51 57 59 74 11 44 | 31 43 88 42 10 48 95 54 50 82 68 99 38 24 62 86 3 32 21 75 35 27 81 80 5
Card 34: 26 16 15 35 17 88 62 31 90 25 | 50 40 43 83 74 79 6 93 21 97 86 71 36 18 77 55 82 51 41 73 26 91 13 5 66
Card 35: 30 70 76 69 67 35 25 51 73 41 | 1 80 14 59 11 52 54 99 61 72 63 31 34 78 17 66 75 85 55 92 32 5 82 97 40
Card 36: 88 59 93 81 19 24 63 69 68 57 | 16 99 88 57 90 15 74 40 36 63 72 24 77 30 37 69 44 81 31 93 97 19 39 59 86
Card 37: 44 73 40 12 72 91 79 11 48 69 | 76 48 43 46 75 73 62 45 72 6 67 13 12 66 71 25 11 35 41 31 1 91 44 40 79
Card 38: 44 72 62 80 37 55 24 60 22 20 | 62 24 20 89 22 19 5 3 50 95 92 14 44 36 37 81 84 60 58 80 55 72 98 29 45
Card 39: 83 53 42 66 39 81 10 15 30 78 | 16 70 17 95 11 91 51 84 2 63 35 28 32 68 23 46 75 19 98 43 36 12 8 55 97
Card 40: 96 83 19 99 89 44 42 92 11 49 | 21 27 72 31 83 15 56 66 46 41 73 11 19 4 36 94 60 38 30 92 70 29 99 45 33
Card 41: 25 9 93 73 14 99 84 3 66 71 | 93 8 19 51 37 63 78 68 43 27 81 2 33 54 64 57 92 50 26 7 41 56 76 88 11
Card 42: 35 57 23 5 37 3 96 67 77 38 | 90 31 24 55 99 17 11 27 95 32 65 45 78 21 82 58 85 60 86 73 66 62 93 40 44
Card 43: 94 24 14 17 52 31 86 37 23 67 | 14 5 23 17 45 57 71 42 76 33 19 13 31 94 20 29 48 98 27 37 51 47 2 67 59
Card 44: 27 7 61 68 86 82 60 72 88 89 | 76 14 97 82 16 9 71 7 48 36 94 47 63 33 69 96 40 46 95 25 62 27 87 74 86
Card 45: 1 96 24 71 78 29 63 3 64 56 | 84 68 54 49 31 9 55 40 70 98 48 36 72 21 75 89 39 5 87 86 3 62 78 16 97
Card 46: 9 80 39 5 79 21 3 67 72 82 | 67 5 25 75 18 21 95 41 62 50 32 56 33 7 73 70 43 80 57 69 44 82 35 17 72
Card 47: 53 60 98 80 89 70 14 8 9 32 | 29 44 21 63 80 76 88 51 39 8 95 10 68 58 65 77 66 19 78 50 18 67 6 4 62
Card 48: 3 15 62 22 52 29 81 50 73 67 | 49 8 21 40 68 42 30 51 57 23 2 63 90 31 37 79 43 89 54 94 5 77 86 83 99
Card 49: 52 56 40 51 15 41 59 33 96 19 | 60 74 95 24 70 81 59 55 61 53 69 84 79 72 17 7 90 98 15 47 39 8 9 1 21
Card 50: 29 20 18 89 1 7 78 68 71 61 | 10 13 97 20 8 1 26 90 88 47 5 11 57 48 35 4 72 14 41 91 28 43 53 67 60
Card 51: 5 98 48 56 86 16 19 84 70 58 | 14 57 42 43 26 53 37 80 10 64 73 45 35 8 55 92 44 54 69 49 32 46 65 1 39
Card 52: 59 46 90 42 37 45 40 16 52 60 | 93 44 17 11 79 53 58 13 29 69 51 27 28 34 81 20 6 15 97 49 32 66 77 36 12
Card 53: 96 31 6 18 54 43 3 79 37 89 | 32 1 83 75 40 85 10 91 77 84 7 13 56 68 81 60 78 80 3 24 29 49 20 37 12
Card 54: 23 67 46 81 24 35 56 74 96 52 | 81 80 10 38 43 18 23 68 29 33 76 54 82 84 45 15 19 92 3 13 39 25 14 1 32
Card 55: 60 89 83 18 76 67 27 44 57 28 | 77 11 83 60 7 16 41 28 44 27 76 57 18 81 10 6 39 12 67 65 58 5 86 85 89
Card 56: 34 70 11 38 82 16 46 74 18 21 | 67 38 25 47 6 70 74 46 14 82 66 34 21 35 5 59 77 18 3 30 50 55 11 78 16
Card 57: 49 55 93 8 33 14 50 71 3 41 | 41 81 98 69 79 71 50 67 10 25 88 93 32 49 60 40 3 75 34 23 8 9 55 14 33
Card 58: 50 44 30 4 5 36 13 90 8 71 | 22 14 98 44 50 10 4 61 96 8 15 62 59 3 71 90 19 65 30 13 25 36 82 29 5
Card 59: 4 38 29 79 86 8 93 30 78 50 | 8 16 30 66 29 34 79 78 93 24 15 52 14 95 76 54 38 50 86 4 48 87 89 35 51
Card 60: 64 23 81 78 7 21 53 8 2 11 | 8 86 53 11 62 21 49 73 92 36 2 78 40 1 81 82 64 52 4 48 23 35 7 19 32
Card 61: 82 68 74 65 21 64 48 7 50 22 | 74 5 14 97 72 68 25 44 88 50 90 82 20 64 16 49 31 37 60 7 21 22 53 48 65
Card 62: 33 64 5 18 21 8 29 51 50 65 | 69 65 5 96 71 34 32 79 8 16 64 98 47 33 39 84 18 50 21 61 27 29 82 51 87
Card 63: 38 25 54 51 24 28 68 16 37 76 | 10 38 69 60 4 29 68 12 37 46 51 14 94 35 61 76 79 17 25 63 31 1 40 9 67
Card 64: 30 79 68 31 97 35 23 66 16 1 | 22 29 79 35 31 32 23 80 40 14 72 1 30 97 66 62 68 19 71 38 16 6 70 85 13
Card 65: 30 43 56 72 65 99 4 62 47 44 | 36 56 93 44 68 35 33 30 91 64 81 47 11 79 73 24 50 99 12 52 46 3 48 43 4
Card 66: 68 36 89 8 15 16 14 76 85 42 | 76 48 71 15 23 22 16 74 89 34 81 17 36 68 8 93 14 3 42 31 50 45 67 52 85
Card 67: 98 25 51 35 84 80 87 45 6 92 | 37 82 60 68 56 12 46 41 8 15 83 77 71 74 49 61 65 28 1 93 95 33 21 24 67
Card 68: 79 92 67 17 51 31 7 10 55 33 | 99 51 42 39 92 26 8 17 20 57 53 76 48 59 55 78 14 84 11 31 23 33 83 96 2
Card 69: 1 33 66 73 78 44 37 13 32 34 | 1 5 66 91 94 35 72 89 74 9 44 45 21 37 16 11 33 3 34 27 46 71 55 68 32
Card 70: 65 30 11 25 55 50 35 57 2 27 | 21 86 15 69 37 11 27 38 25 96 79 85 49 95 43 89 77 8 2 88 55 57 47 67 54
Card 71: 60 45 42 75 94 51 6 4 49 82 | 32 64 2 62 18 63 43 73 5 58 16 15 38 44 9 39 87 79 12 57 54 28 22 41 66
Card 72: 47 37 94 28 88 39 57 78 93 33 | 42 53 12 34 86 29 6 67 22 87 56 68 18 7 21 99 2 46 36 35 73 10 78 5 13
Card 73: 97 50 10 80 41 36 76 16 18 88 | 91 66 27 38 6 82 49 86 78 9 63 41 24 60 2 30 94 36 42 72 43 8 35 71 61
Card 74: 49 48 6 43 98 51 45 1 8 17 | 16 81 14 87 68 96 52 59 13 24 65 25 99 10 90 76 63 4 28 84 30 89 75 9 54
Card 75: 21 3 83 9 65 38 17 50 64 62 | 91 38 17 35 19 78 41 27 74 11 12 57 31 60 77 55 37 23 93 26 96 7 18 79 46
Card 76: 84 80 36 74 41 66 81 91 75 70 | 56 67 6 51 18 35 19 97 88 93 13 77 20 7 26 95 90 62 34 22 78 21 94 40 64
Card 77: 39 94 72 35 45 27 65 42 32 17 | 69 19 11 83 67 14 25 86 49 43 61 80 73 12 41 71 68 47 20 40 88 76 1 10 93
Card 78: 95 78 47 69 99 72 73 29 41 83 | 95 2 47 83 53 29 42 25 73 72 26 71 78 93 84 99 49 41 23 87 90 56 11 69 82
Card 79: 55 81 93 35 98 16 2 36 29 40 | 2 41 32 89 65 9 42 33 5 55 87 56 40 85 83 72 11 16 82 86 91 52 71 4 75
Card 80: 66 45 95 59 84 48 91 42 56 89 | 19 49 90 40 41 63 73 81 13 7 58 16 1 33 38 76 15 95 27 31 61 32 43 9 8
Card 81: 85 15 80 4 58 83 32 66 53 13 | 99 1 11 98 87 4 35 60 21 76 80 13 42 53 66 18 5 39 47 32 83 62 38 15 24
Card 82: 40 64 66 27 83 15 39 12 49 4 | 34 68 5 11 57 40 12 61 85 44 78 33 89 22 91 79 66 24 97 48 45 39 87 96 37
Card 83: 95 12 33 99 17 40 88 19 2 31 | 68 91 10 60 23 80 22 41 84 2 17 90 12 99 31 11 19 95 16 79 46 86 53 88 47
Card 84: 59 71 10 49 4 14 38 76 44 47 | 49 62 89 76 8 64 28 55 63 75 95 10 23 13 4 38 47 5 59 14 29 12 24 71 44
Card 85: 63 82 23 43 74 77 48 81 62 67 | 82 27 99 63 15 34 43 80 57 41 64 32 18 19 62 67 74 87 6 48 23 2 22 81 77
Card 86: 34 69 83 79 28 51 13 75 70 44 | 68 28 73 52 95 1 19 79 43 42 41 17 46 83 54 27 24 12 31 92 70 72 10 7 84
Card 87: 21 2 9 61 29 65 74 58 10 17 | 65 95 91 4 14 9 59 46 2 8 21 15 36 58 20 97 17 61 38 39 6 29 74 42 10
Card 88: 26 77 68 61 15 94 51 24 28 17 | 59 4 7 42 11 40 8 3 10 26 82 25 87 58 62 13 47 46 32 19 37 98 78 81 95
Card 89: 19 11 96 61 46 83 90 4 92 40 | 92 83 29 76 64 70 79 4 93 54 87 59 95 12 40 46 96 89 11 19 15 61 90 6 22
Card 90: 49 81 84 37 7 11 88 70 21 39 | 75 54 64 55 35 24 41 25 69 94 56 96 51 57 61 66 17 74 50 78 65 68 6 77 34
Card 91: 43 84 86 78 15 80 4 5 37 61 | 25 20 29 46 97 12 45 27 31 58 38 51 68 52 39 1 30 40 79 73 32 9 74 47 16
Card 92: 44 49 64 3 88 91 93 40 56 54 | 88 3 77 71 66 25 15 86 63 64 7 59 90 44 54 82 38 4 62 40 95 87 97 74 91
Card 93: 84 4 19 88 69 42 94 73 72 36 | 15 49 38 26 31 24 73 92 14 88 85 95 93 36 80 19 29 75 35 1 11 7 9 60 77
Card 94: 62 42 64 25 22 84 65 34 7 55 | 44 28 60 37 71 43 98 7 16 4 99 27 19 23 82 94 6 9 64 59 77 55 74 92 21
Card 95: 1 73 41 6 31 80 45 84 47 29 | 49 78 59 90 81 29 75 7 57 13 36 39 92 37 70 12 60 86 87 17 84 63 74 71 46
Card 96: 15 5 82 24 57 44 6 34 36 28 | 95 90 35 71 16 9 59 37 23 73 87 58 69 78 52 55 4 64 68 79 3 46 99 93 47
Card 97: 81 14 57 71 97 66 48 61 95 83 | 19 47 18 81 49 73 67 40 30 28 54 14 84 52 2 64 66 79 70 36 99 41 48 60 72
Card 98: 71 86 1 44 47 31 34 6 11 41 | 59 13 34 77 20 80 49 8 85 24 45 70 78 61 93 27 84 98 66 26 43 3 16 92 82
Card 99: 94 81 40 4 6 27 78 52 28 86 | 65 61 51 7 46 56 80 16 24 14 59 43 11 34 39 40 81 2 73 75 63 25 77 93 49
Card 100: 22 39 65 11 89 20 95 35 53 5 | 83 40 91 76 8 7 74 67 86 21 12 48 15 3 50 10 44 55 13 88 45 94 81 19 70
Card 101: 25 45 85 81 99 95 35 72 60 31 | 48 75 58 42 88 70 34 26 93 56 97 64 28 61 52 68 67 3 24 80 63 53 23 50 10
Card 102: 50 27 37 96 3 22 13 67 72 77 | 29 81 31 50 71 13 63 22 51 3 35 96 90 59 72 11 67 2 77 56 37 94 27 86 33
Card 103: 70 36 61 83 12 3 67 8 72 25 | 29 87 53 30 8 91 61 66 76 33 36 16 93 81 26 67 98 12 35 89 21 58 24 48 47
Card 104: 3 42 33 96 80 44 48 45 83 31 | 31 2 54 74 49 27 96 60 41 77 33 44 3 80 45 92 63 48 91 87 69 42 83 38 56
Card 105: 17 86 91 68 83 27 66 69 13 78 | 71 95 67 28 83 10 59 17 89 92 34 91 79 19 63 24 11 21 15 5 49 75 97 6 41
Card 106: 39 66 88 52 18 21 23 11 28 10 | 27 23 24 21 9 65 41 47 48 64 55 16 42 52 98 17 39 1 18 37 38 51 91 62 10
Card 107: 10 73 51 30 54 53 85 87 24 62 | 85 62 73 24 41 1 21 90 30 46 66 80 87 54 50 38 51 53 10 43 59 76 11 33 37
Card 108: 86 63 64 34 39 10 49 83 36 55 | 63 3 85 55 33 84 20 39 73 87 68 86 79 18 89 6 9 54 14 47 53 10 50 40 96
Card 109: 87 21 40 83 30 84 81 76 45 42 | 92 23 65 42 64 25 82 80 63 12 67 74 40 72 84 39 99 95 81 30 73 45 9 32 66
Card 110: 48 29 67 41 64 17 10 71 57 80 | 2 19 97 90 11 22 26 45 89 27 33 71 94 30 86 32 15 17 93 74 88 8 99 91 55
Card 111: 14 23 33 84 31 34 51 78 3 53 | 7 30 33 86 50 98 34 93 10 36 17 32 20 79 63 35 62 11 28 47 67 91 53 31 46
Card 112: 41 56 78 9 31 62 97 20 45 51 | 37 53 76 72 78 44 3 68 20 58 1 28 92 69 50 90 81 48 42 84 83 36 17 12 87
Card 113: 42 2 14 49 70 19 25 15 39 67 | 91 60 85 42 14 43 63 62 39 31 77 2 89 1 87 50 13 86 12 3 15 30 40 16 23
Card 114: 86 76 78 65 9 5 88 63 49 85 | 17 24 9 63 65 48 78 59 13 88 19 72 31 67 84 74 49 52 26 86 76 8 60 21 5
Card 115: 63 73 95 71 61 55 49 5 72 3 | 83 76 42 85 23 54 52 99 79 80 60 32 67 31 30 66 97 12 9 15 3 87 19 35 98
Card 116: 1 48 39 69 23 99 28 5 33 49 | 7 26 42 81 49 4 61 65 1 58 3 23 20 28 24 47 75 50 89 68 88 38 54 66 45
Card 117: 78 90 29 34 30 85 58 37 21 79 | 34 37 54 88 90 63 13 35 55 8 75 76 87 23 29 47 95 3 14 48 58 79 38 25 91
Card 118: 3 95 50 45 97 27 39 94 5 93 | 73 69 47 39 20 72 33 57 24 81 35 62 41 37 87 42 79 99 74 55 49 30 54 59 8
Card 119: 58 43 47 41 28 36 86 46 88 2 | 28 93 11 4 14 77 68 78 7 79 92 75 2 86 59 58 57 47 22 20 27 51 81 42 48
Card 120: 94 13 79 25 98 9 45 55 89 49 | 71 48 86 84 14 92 29 53 11 6 2 50 24 3 81 39 57 88 43 63 64 32 98 58 60
Card 121: 74 85 72 79 55 9 88 81 49 82 | 61 6 15 75 80 62 18 27 44 46 66 17 30 4 36 92 65 50 3 38 57 10 37 39 32
Card 122: 89 5 20 30 28 88 35 57 31 94 | 84 27 7 79 28 22 98 85 93 62 38 3 24 59 61 95 78 4 36 53 49 46 83 25 51
Card 123: 1 86 10 20 15 78 14 71 74 38 | 88 28 59 73 6 65 47 9 19 97 42 11 18 66 50 89 39 67 21 60 80 33 30 34 45
Card 124: 70 92 84 40 15 31 27 25 69 85 | 39 4 22 57 26 52 60 83 53 79 8 75 34 33 38 1 37 43 18 80 58 72 88 35 11
Card 125: 30 6 47 27 76 78 9 10 16 5 | 76 9 65 75 5 30 57 14 16 49 70 7 90 33 88 92 10 17 78 47 25 27 32 20 6
Card 126: 8 86 94 98 6 55 69 73 36 19 | 34 95 80 32 84 69 73 47 98 56 92 8 50 26 6 94 4 86 21 7 78 85 55 82 19
Card 127: 10 36 55 88 43 11 34 38 19 24 | 38 34 93 41 88 94 62 56 18 36 3 43 37 58 23 44 50 65 90 71 61 11 25 98 46
Card 128: 11 5 25 36 27 95 71 76 61 97 | 95 71 25 11 5 53 36 27 76 61 8 56 89 30 64 26 48 65 97 83 42 35 96 58 16
Card 129: 66 95 46 45 64 41 22 87 5 19 | 41 27 9 77 19 5 37 90 64 97 7 85 46 45 66 25 21 95 87 22 60 15 84 83 79
Card 130: 7 31 60 38 76 36 3 30 79 37 | 44 83 66 3 37 48 8 95 5 19 36 70 67 98 92 99 76 87 30 35 17 29 46 51 2
Card 131: 94 96 36 85 59 51 12 23 46 74 | 77 2 88 50 93 3 41 4 38 31 1 10 69 54 40 76 95 17 78 30 87 72 27 92 7
Card 132: 67 79 9 7 84 25 35 89 59 60 | 82 74 5 50 25 79 87 4 2 81 1 91 69 37 63 39 76 60 66 47 94 29 49 59 31
Card 133: 74 62 93 36 51 59 71 68 10 38 | 38 36 34 74 20 39 16 62 68 70 63 53 71 59 37 99 80 13 94 23 10 18 75 93 51
Card 134: 39 98 53 93 42 67 55 23 43 92 | 32 39 55 41 30 43 69 26 34 40 74 28 92 71 56 23 53 67 18 78 98 8 36 93 42
Card 135: 19 42 49 63 2 28 55 80 20 79 | 98 55 70 38 97 67 87 76 72 75 79 13 5 40 22 28 88 49 43 14 63 81 2 42 9
Card 136: 58 34 14 24 21 16 3 22 37 17 | 99 88 68 12 55 98 45 69 40 81 80 24 82 42 29 28 54 30 49 59 39 91 6 15 10
Card 137: 3 5 14 68 13 8 9 22 47 55 | 83 1 8 18 93 99 97 80 51 61 69 39 76 33 28 17 4 45 89 75 58 81 73 71 20
Card 138: 39 67 12 77 65 26 61 87 95 37 | 88 61 41 67 37 86 94 32 72 76 22 6 81 80 50 77 87 55 95 4 96 63 39 84 29
Card 139: 57 53 1 29 60 6 13 90 81 36 | 66 48 15 80 67 93 96 8 62 7 78 5 35 11 84 91 46 63 61 31 58 3 37 85 41
Card 140: 32 31 71 34 20 45 23 14 54 65 | 51 61 48 49 32 16 9 80 55 85 53 74 45 26 25 73 84 86 78 59 94 87 17 62 93
Card 141: 56 92 14 27 83 48 2 20 21 81 | 18 86 1 30 70 87 26 73 63 13 7 3 45 39 94 47 29 61 82 67 36 48 5 69 66
Card 142: 80 28 44 37 40 57 46 1 59 77 | 41 8 58 36 70 13 38 48 85 27 25 92 64 18 43 91 45 75 60 39 15 82 72 68 59
Card 143: 63 97 18 25 52 54 27 47 12 92 | 51 74 46 10 28 44 49 54 24 17 29 80 7 11 57 89 91 31 69 35 88 47 32 14 58
Card 144: 42 47 63 79 13 58 10 29 24 98 | 53 62 80 51 88 27 22 90 72 64 48 44 45 57 84 32 14 65 79 82 81 56 31 97 18
Card 145: 71 59 46 50 33 41 91 60 10 42 | 56 80 76 63 12 15 48 27 74 59 69 72 36 61 95 34 50 77 4 43 22 88 39 44 23
Card 146: 64 90 55 17 4 19 91 57 48 18 | 37 36 89 7 73 59 19 58 69 34 85 87 72 1 31 6 29 5 15 45 39 80 20 92 48
Card 147: 93 8 67 36 23 1 91 27 56 11 | 38 53 72 86 62 74 54 41 24 29 18 95 5 83 12 61 80 4 17 13 20 9 98 70 35
Card 148: 58 32 35 18 31 4 20 69 50 84 | 86 91 90 8 71 22 52 67 45 38 77 34 63 66 51 28 11 46 15 95 70 7 14 96 54
Card 149: 16 67 90 91 75 54 32 2 20 98 | 52 75 90 55 32 16 68 19 91 24 49 45 69 54 98 93 76 39 67 47 20 2 92 70 48
Card 150: 19 22 90 99 10 4 43 47 39 37 | 37 82 19 10 39 83 99 13 59 22 94 47 67 27 88 90 53 43 4 95 2 97 30 11 46
Card 151: 89 83 76 54 10 16 20 14 53 55 | 75 33 48 12 25 1 73 43 60 69 35 45 77 40 94 96 28 61 83 37 22 52 2 99 47
Card 152: 79 86 12 80 63 90 53 66 44 74 | 42 46 35 15 82 96 39 65 44 32 76 83 80 28 66 48 74 22 30 89 16 55 79 17 51
Card 153: 88 32 87 77 93 47 33 91 76 17 | 5 89 39 2 93 23 49 12 35 38 45 47 24 1 78 86 60 14 40 75 63 88 90 22 36
Card 154: 4 18 83 74 53 60 26 67 5 43 | 64 44 70 3 87 26 79 46 71 92 63 72 34 15 28 86 75 29 20 61 89 17 6 96 10
Card 155: 77 76 8 1 35 49 21 55 72 63 | 6 97 79 59 93 76 91 68 14 46 23 81 39 49 50 8 4 47 31 37 86 26 22 63 1
Card 156: 5 22 35 87 59 90 78 93 61 48 | 25 57 22 78 38 67 42 93 9 31 87 47 44 5 10 35 39 98 90 65 48 59 61 23 64
Card 157: 23 34 11 19 99 44 30 66 28 25 | 13 34 19 11 69 30 22 46 74 51 66 99 58 25 29 63 90 91 23 80 44 9 88 28 35
Card 158: 11 79 89 50 86 20 8 85 96 92 | 86 40 13 5 50 92 43 85 27 39 77 79 59 18 53 89 28 20 75 11 83 55 36 96 60
Card 159: 70 79 61 17 65 9 7 87 1 91 | 42 34 70 46 89 60 43 40 87 99 73 16 94 5 35 18 91 32 38 61 7 39 98 84 69
Card 160: 25 4 98 71 48 30 15 82 43 83 | 83 78 81 21 85 73 92 57 90 71 36 6 30 12 82 61 50 47 38 74 37 88 11 51 89
Card 161: 70 8 82 32 7 65 21 72 74 87 | 76 21 59 19 58 87 97 77 36 62 88 69 48 68 51 25 64 5 85 15 61 56 52 34 67
Card 162: 73 25 70 52 24 69 50 77 79 99 | 80 52 13 24 66 93 47 77 39 36 72 2 63 25 18 59 55 97 76 21 7 73 37 69 33
Card 163: 87 77 10 26 79 6 67 58 46 49 | 73 33 87 97 27 39 82 23 79 60 28 25 66 98 70 55 40 3 19 5 58 30 74 52 31
Card 164: 3 15 4 21 41 13 30 91 33 69 | 12 97 59 62 93 50 83 3 2 18 11 53 35 74 4 88 89 42 85 55 6 94 84 31 21
Card 165: 68 70 46 1 56 85 86 8 71 65 | 66 25 77 2 61 46 28 85 27 37 48 24 80 95 53 76 40 68 12 41 51 74 4 93 20
Card 166: 86 7 83 63 8 14 31 38 35 49 | 72 10 76 54 52 19 82 81 25 78 66 6 15 11 42 27 33 46 57 91 75 17 98 88 37
Card 167: 1 21 19 11 5 3 52 91 24 25 | 37 50 34 91 23 18 43 78 97 76 84 74 72 83 81 8 85 28 67 7 14 44 68 61 35
Card 168: 89 88 2 98 97 40 94 95 7 28 | 4 86 77 52 10 15 69 53 46 36 38 17 93 43 75 57 48 30 27 78 60 81 96 32 65
Card 169: 56 12 15 19 6 72 29 8 46 77 | 19 45 14 20 18 29 5 1 54 95 84 12 6 50 44 63 73 15 46 56 72 16 8 32 77
Card 170: 18 94 75 79 6 64 85 1 71 29 | 64 18 3 94 85 8 71 6 26 31 47 40 56 29 75 5 28 95 82 58 13 1 66 79 39
Card 171: 88 58 47 35 33 31 34 71 91 59 | 92 11 73 71 34 13 74 35 60 26 50 95 54 3 23 76 18 7 88 83 9 16 33 43 59
Card 172: 56 52 15 39 76 68 30 33 70 19 | 18 68 74 66 60 7 39 56 52 87 90 67 9 33 19 76 23 8 30 15 29 13 70 50 77
Card 173: 93 87 6 11 64 71 81 49 48 21 | 48 66 17 49 21 64 11 71 23 43 93 79 35 87 29 81 37 36 32 88 31 6 82 92 84
Card 174: 68 7 62 39 6 79 20 61 29 96 | 34 86 5 79 23 36 48 98 47 8 29 61 62 72 7 56 44 17 85 78 68 13 33 51 37
Card 175: 96 45 30 33 12 22 82 46 69 52 | 82 20 22 69 96 73 12 54 52 46 4 75 86 37 33 76 45 80 68 6 25 15 30 71 7
Card 176: 61 72 5 46 45 49 94 48 89 95 | 43 45 10 49 62 1 89 79 19 29 18 99 94 5 57 41 25 95 75 87 46 72 26 48 61
Card 177: 93 36 28 85 57 24 27 17 19 68 | 19 28 53 82 20 27 68 73 86 76 48 17 13 41 24 7 34 36 72 8 90 14 45 57 35
Card 178: 52 47 54 9 13 27 82 97 33 5 | 25 9 54 77 86 82 27 52 47 33 76 28 18 93 41 5 97 73 98 87 89 65 4 38 13
Card 179: 38 31 71 4 86 44 36 50 78 21 | 1 3 94 65 4 39 67 88 92 42 81 21 17 78 69 41 87 63 10 86 74 8 75 43 36
Card 180: 41 68 58 43 11 7 3 37 30 76 | 73 37 96 75 83 2 46 15 18 41 26 82 3 61 51 17 49 76 38 80 24 33 22 99 34
Card 181: 36 46 17 50 81 39 49 23 53 29 | 12 30 90 9 16 32 72 84 7 51 71 66 25 89 40 87 60 96 83 97 21 64 34 6 44
Card 182: 66 64 16 37 97 95 77 93 86 30 | 95 31 16 6 5 93 77 37 1 66 27 4 40 86 14 17 78 80 30 47 9 23 92 76 85
Card 183: 23 90 41 96 54 79 46 85 55 45 | 28 61 65 7 46 66 52 19 97 98 96 23 99 12 17 16 35 56 29 33 54 60 44 6 37
Card 184: 69 16 91 59 97 17 77 87 83 35 | 68 6 77 95 85 35 91 24 4 1 16 51 63 34 17 93 32 43 9 67 28 83 69 59 87
Card 185: 86 93 46 12 27 7 50 25 77 83 | 67 61 18 93 19 37 86 6 26 73 36 95 11 23 50 53 32 77 49 56 96 13 20 25 2
Card 186: 62 30 38 84 47 82 66 37 36 77 | 77 79 36 5 19 47 81 85 48 66 10 37 49 40 82 95 31 90 65 60 44 8 56 54 7
Card 187: 26 23 34 78 49 43 97 8 4 24 | 12 4 35 77 99 87 73 38 34 15 50 92 55 21 71 28 10 90 95 22 93 44 59 96 51
Card 188: 89 18 56 10 22 99 57 86 85 80 | 98 88 82 12 67 71 66 87 86 73 97 41 69 57 80 20 9 96 8 99 23 56 19 15 36
Card 189: 9 7 72 87 55 23 79 86 89 37 | 99 35 98 72 62 70 44 41 66 84 11 80 50 51 33 12 8 32 68 95 53 39 73 43 17
Card 190: 73 30 34 92 99 5 71 22 35 10 | 6 85 89 15 65 2 23 69 90 88 56 25 26 68 47 14 24 39 76 84 28 71 49 8 3
Card 191: 88 95 57 69 60 82 68 70 87 40 | 30 51 75 84 11 67 45 81 35 85 50 24 70 93 13 17 76 79 97 72 98 58 38 25 34
Card 192: 56 82 59 30 71 2 70 97 3 51 | 6 88 84 25 9 42 14 93 56 99 69 73 68 76 1 81 35 48 11 87 65 23 66 32 10
Card 193: 89 62 23 74 44 55 92 87 50 91 | 61 77 54 52 39 48 67 82 66 57 30 72 18 35 46 96 81 38 69 32 17 47 27 53 25
Card 194: 43 62 87 49 65 26 10 72 92 66 | 23 49 43 72 35 88 66 65 28 25 62 80 96 13 64 18 34 69 10 59 41 92 6 26 37
Card 195: 23 34 36 91 62 49 81 10 60 21 | 52 60 28 21 49 38 4 10 83 23 13 36 81 68 20 34 31 62 27 14 44 47 67 35 91
Card 196: 46 73 39 86 11 32 17 9 92 35 | 35 73 11 40 54 86 4 19 89 39 23 9 56 17 74 85 5 57 92 46 45 21 27 50 32
Card 197: 67 84 19 32 66 39 37 52 94 64 | 61 17 59 69 90 52 66 55 79 38 12 37 84 16 67 95 36 32 64 94 1 56 51 39 83
Card 198: 4 37 72 50 66 39 56 64 9 41 | 6 50 65 41 21 82 71 56 90 72 2 14 98 64 12 69 89 47 37 4 9 32 39 66 51
Card 199: 7 40 49 60 2 57 78 55 23 25 | 98 23 78 40 55 60 77 25 34 12 43 7 37 75 69 3 57 30 64 42 49 22 71 2 83
Card 200: 91 56 16 83 96 19 27 32 23 55 | 77 64 31 59 27 96 1 4 53 30 15 29 94 60 98 3 22 65 61 6 11 89 54 58 74
Card 201: 20 37 11 66 35 13 83 60 56 63 | 63 82 54 25 56 53 35 22 11 60 40 41 13 20 83 98 29 36 28 78 92 66 37 33 16
Card 202: 80 56 59 24 67 20 79 85 14 18 | 59 85 18 20 24 17 6 66 70 94 67 14 56 93 40 15 7 1 80 58 83 75 79 65 77
Card 203: 90 55 42 62 95 51 54 40 47 29 | 95 34 86 1 68 51 63 30 84 11 37 87 50 49 16 22 78 45 36 58 31 35 59 21 65
Card 204: 15 25 27 81 55 54 8 93 53 96 | 90 57 80 73 5 55 71 47 98 32 87 69 58 13 59 82 29 1 41 25 64 97 30 85 36
Card 205: 50 88 26 77 58 16 6 1 25 62 | 47 67 1 24 17 52 22 39 54 15 14 60 42 6 88 98 58 2 93 51 13 80 36 92 86
Card 206: 20 51 38 73 58 93 40 62 43 71 | 40 1 70 43 51 32 38 14 41 20 30 85 76 65 24 93 34 12 6 21 71 53 75 80 62
Card 207: 10 92 3 99 67 2 83 71 25 17 | 2 88 70 39 18 92 22 99 83 47 17 52 42 5 38 40 77 10 24 7 76 35 71 12 3
Card 208: 25 81 92 55 68 41 18 75 12 67 | 96 6 86 20 76 89 92 40 30 17 77 13 24 69 45 37 70 42 63 88 43 9 75 53 3
Card 209: 35 7 5 56 57 51 75 66 78 85 | 52 23 86 45 59 14 1 16 95 13 56 38 69 8 49 22 72 35 40 26 43 7 15 44 96
Card 210: 35 83 8 27 2 39 47 29 25 61 | 74 21 88 92 35 13 76 29 73 39 62 3 67 71 66 23 16 4 40 7 42 19 72 22 31
Card 211: 38 58 71 14 20 92 85 63 90 34 | 54 93 16 39 1 62 13 51 46 77 42 24 15 41 94 71 3 29 43 19 12 30 78 50 80
Card 212: 54 52 17 49 4 66 55 74 12 39 | 78 59 48 28 60 53 68 33 34 10 84 88 40 41 51 45 67 71 18 64 32 27 3 82 8
Card 213: 53 70 23 28 63 52 88 2 98 29 | 7 26 82 72 14 84 60 78 29 51 1 11 93 89 80 12 55 90 6 2 67 71 35 41 32
Card 214: 14 75 87 20 74 97 99 89 25 64 | 76 59 61 96 63 31 9 83 68 8 65 13 73 23 84 49 11 35 88 98 15 50 36 79 22
Card 215: 33 3 95 82 18 59 74 8 40 62 | 80 28 78 57 81 87 53 86 51 91 32 11 10 99 97 39 1 36 4 14 22 68 21 55 92

View File

@@ -1,99 +0,0 @@
use std::fs;
use std::collections::VecDeque;
fn main() {
let input = fs::read_to_string("input.txt").unwrap();
// an array in this format [[card 1: [winning nums][ our nums]]]
let input: Vec<_> = input.split('\n') // split days
.map(|card| &card[(card.find(':').unwrap() + 1)..]) // remove day numbers
.map(|card| card.trim()) // trim extra whitespace
.map(|card| {
card.split('|') // split winning/own numbers
.map(|numbers| {
numbers.trim() // trim whitespace
.split(' ') // split into individual nums
.filter(|x| !x.is_empty()) // remove empty strings
.map(|x| {return x.parse::<i32>().unwrap()}) // convert to i32
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
})
.collect();
let mut queue = VecDeque::from((0..input.len()).collect::<Vec<usize>>());
let mut total_cards = 0;
while !queue.is_empty() {
let card_num = queue.pop_front().unwrap();
let card = input.get(card_num).unwrap();
total_cards += 1;
let mut dup_cards = 0;
let winning_nums = card.first().unwrap();
let our_nums = card.last().unwrap();
//dp would kill here, but im lazy
for num in our_nums {
if winning_nums.contains(num) {
dup_cards += 1;
}
}
for card in (card_num + 1)..=(card_num + dup_cards) {
if card < input.len() {
queue.push_back(card);
}
}
}
println!("{:?}", total_cards);
}
// use std::fs;
// fn main() {
// let input = fs::read_to_string("input.txt").unwrap();
// // an array in this format [[card 1: [winning nums][ our nums]]]
// let input: Vec<_> = input.split('\n') // split days
// .map(|card| &card[(card.find(':').unwrap() + 1)..]) // remove day numbers
// .map(|card| card.trim()) // trim extra whitespace
// .map(|card| {
// card.split('|') // split winning/own numbers
// .map(|numbers| {
// numbers.trim() // trim whitespace
// .split(' ') // split into individual nums
// .filter(|x| !x.is_empty()) // remove empty strings
// .map(|x| {return x.parse::<i32>().unwrap()}) // convert to i32
// .collect::<Vec<_>>()
// })
// .collect::<Vec<_>>()
// })
// .collect();
// let mut total_pts = 0;
// for card in input {
// let mut card_pts = 0;
// let winning_nums = card.first().unwrap();
// let our_nums = card.last().unwrap();
// for num in our_nums {
// if winning_nums.contains(num) {
// if card_pts == 0 {
// card_pts = 1;
// } else {
// card_pts *= 2;
// }
// }
// }
// //println!("{}", card_pts);
// total_pts += card_pts;
// }
// println!("{:?}", total_pts);
// }

7
day5/Cargo.lock generated
View File

@@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day5"
version = "0.1.0"

View File

@@ -1,8 +0,0 @@
[package]
name = "day5"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -1,238 +0,0 @@
seeds: 3943078016 158366385 481035699 103909769 3553279107 15651230 3322093486 189601966 2957349913 359478652 924423181 691197498 2578953067 27362630 124747783 108079254 1992340665 437203822 2681092979 110901631
seed-to-soil map:
2702707184 1771488746 32408643
1838704579 89787943 256129587
3308305769 3945110092 140077818
3628160213 4264964536 30002760
3481822196 4118626519 146338017
2314039806 0 23017018
2094834166 23017018 66770925
13529560 2374830476 266694587
1360948085 2280951884 93878592
2337056824 1405838386 365650360
2735115827 1389537903 16300483
2161605091 1122407194 152434715
2944685788 3581490111 363619981
3448383587 4085187910 33438609
293095451 1923371965 152989927
555976625 1361056107 28481796
0 2076361892 13529560
4055868219 3342391034 239099077
3658162973 2944685788 397705246
446085378 2641525063 109891247
584458421 685760755 436646439
1647644147 2089891452 191060432
1528169571 1832460171 90911794
1619081365 1803897389 28562782
280224147 1348184803 12871304
1021104860 345917530 339843225
1454826677 1274841909 73342894
soil-to-fertilizer map:
370579153 1660655546 474809840
1390384163 3890794774 29044725
3933903064 3062217622 43562309
2579648014 2135465386 381757066
3905615715 3862507425 28287349
4053211235 382332912 208377334
3718132574 4107484155 187483141
3977465373 306587050 75745862
1866333065 230994048 75593002
1268904151 2940737610 121480012
3646057320 3790432171 72075254
845388993 2517222452 423515158
2291172026 769577840 288475988
4261588569 3919839499 33378727
2112304432 590710246 178867594
1419428888 1213751369 446904177
2961405080 3105779931 684652240
230994048 3967899050 139585105
2097623608 3953218226 14680824
1941926067 1058053828 155697541
fertilizer-to-water map:
0 1551952886 33233684
961721436 932763195 63696624
2767354703 3875238046 18117484
3717194106 2676555200 188038931
799543557 483022915 162177879
2428347038 3081230279 28566103
2872288153 3519235797 218585862
215425000 1162608123 279396952
1473270503 411403786 71619129
2762028477 2930057227 5326226
3263853515 2169144956 62130350
3330983617 2935383453 10086546
2522376237 2231275306 106924906
2757818051 2103190872 4210426
3090874015 3187643516 172979500
2785472187 2530367956 37190043
1365587214 49710602 107683289
554985341 330919476 80484310
3639346972 3109796382 77847134
1964878739 1442005075 21531118
2098191120 3737821659 137416387
1832452033 298110266 32809210
2456913141 2864594131 65463096
1025418060 1606654056 340169154
2277580887 2475812485 29651215
2416229303 2107401298 12117735
33233684 176973083 62797441
157085258 239770524 58339742
2307232102 2567557999 108997201
1915168137 0 49710602
2235607507 3893355530 41973380
1865261243 1502045992 49906894
3905233037 3935328910 231121478
494821952 157393891 19579192
514401144 996459819 40584197
4136354515 3360623016 158612781
3503586692 2945469999 135760280
635469651 1463536193 38509799
2629301143 4166450388 128516908
2822662230 2119519033 49625923
3325983865 2098191120 4999752
3341070163 2338200212 137612273
3478682436 2505463700 24904256
96031125 1971548655 36328688
1986409857 1585186570 21467486
673979450 1037044016 125564107
1544889632 645200794 287562401
132359813 1946823210 24725445
water-to-light map:
3326310943 1150412752 87200223
4257088620 4233111242 37878676
3994159838 4060724644 54228568
3876001808 4114953212 90976210
2886658207 1485800780 134153427
3966978018 4205929422 27181820
4048388406 3874470488 149045901
528406865 502600485 237825862
111547576 1241598488 111964267
3068561383 1485461466 339314
3168255879 3056441319 158055064
3504257503 1453325844 32135622
2109734789 3372472386 240074722
3068900697 403245303 99355182
2027101388 740426347 82633401
1219093087 1970502974 808008301
3643122008 1951548756 18954218
2603944924 279757237 123488066
766232727 0 10960493
3712182589 4270989918 1531320
3536393125 2778511275 106728883
3482397575 1237612975 3985513
777193220 1763962961 71462615
1117452579 1680930659 83032302
3413511166 3214496383 46428427
2432743763 2885240158 171201161
0 3260924810 111547576
3486383088 1835425576 17874415
3672475952 3703073187 39706637
848655835 10960493 268796744
4197434307 4023516389 37208255
3459939593 823059748 22457982
2727432990 1853299991 98248765
4234642562 4272521238 22446058
3713713909 3672475952 30597235
2351588880 1353562755 81154883
223511843 845517730 304895022
3744311144 3742779824 131690664
1200484881 1434717638 18608206
3020811634 3612547108 47749749
2349809511 3660296857 1779369
2825681755 1619954207 60976452
light-to-temperature map:
252460180 3718023854 80580651
3778113118 1519654737 306188725
333040831 2573805517 96168275
4084301843 3798604505 210665453
1694244932 1825843462 379128459
1487313708 2669973792 206931224
429209106 2876905016 268167573
3133421217 3610326681 107697173
1486370741 3145072589 942967
697376679 3146015556 464311125
2152115592 836439718 249469053
3241118390 214400336 17576418
214400336 1164650972 38059844
2073373391 1085908771 78742201
1161687804 2248952614 324682937
3258694808 231976754 268511965
3527206773 1312729085 206925652
3133251251 2573635551 169966
2930227394 4091943439 203023857
2484258126 790765872 45673846
2639950241 500488719 290277153
2529931972 1202710816 110018269
2401584645 4009269958 82673481
3734132425 2204971921 43980693
temperature-to-humidity map:
168091833 268406932 76258451
3449803430 2843367435 19310453
2007621581 1615073306 528954706
1947960540 798304921 59661041
3469113883 3441273912 247683303
3980335429 3688957215 155495519
1382488646 1289756018 231480201
1613968847 2144028012 203484286
3030343754 2862677888 310561319
311459258 1257812898 31943120
3716797186 4024477040 263538243
743249314 734822904 63482017
2843367435 4288015283 6952013
244350284 201297958 67108974
806731331 549427536 185395368
33679712 344665383 134412121
1817453133 1521236219 93837087
2850319448 3844452734 180024306
1193424657 2347512298 189063989
992126699 0 201297958
3340905073 3173239207 108898357
343402378 857965962 399846936
0 479077504 33679712
4135830948 3282137564 159136348
1911290220 512757216 36670320
humidity-to-location map:
1586270647 2666237958 31388199
1639118951 2401662894 243114959
673413244 1218441073 9004417
4189219561 4197782169 97185127
339701505 993997384 224443689
2088925654 1227445490 16145987
3048450614 2034241441 196558736
3245009350 3057456069 37064056
1990947272 217743214 23964128
755791330 433456361 436687719
3750378482 1243591477 29460651
1347952933 3094520125 238317714
682417661 3593572644 73373669
1891967948 3494593320 98979324
2746577216 1325573050 27089148
90823161 3346797254 147796066
238619227 1933159163 101082278
2884769306 269775053 163681308
564145194 0 109268050
2014911400 1273052128 12916400
2773666364 1295702566 29870484
0 903174223 90823161
4286404688 3841991082 8562608
1617658846 2644777853 21460105
2714916854 3748178771 31660362
2275934358 3332837839 13959415
2027827800 870144080 33030143
3841991082 4158641967 39140202
3881131284 3850553690 308088277
3390548570 2697626157 359829912
1882233910 1285968528 9734038
2105071641 2230800177 170862717
1192479049 1777685279 155473884
2803536848 3666946313 81232458
2289893773 1352662198 425023081
2060857943 241707342 28067711
3282073406 109268050 108475164

View File

@@ -1,93 +0,0 @@
use std::fs;
fn main() {
let input = fs::read_to_string("input.txt").unwrap();
let mut mappers: Vec<_> = input.split("\n\n")
.map(|maps| &maps[(maps.find(':').unwrap() + 1)..])
.map(|maps| maps.trim())
.map(|maps| {
maps.split('\n')
.map(|range| {
range.split(' ')
.map(|num| num.parse::<i64>().unwrap())
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
})
.collect();
let seeds = mappers.first().unwrap().first().unwrap().clone();
let mappers: &mut [Vec<Vec<i64>>] = mappers.get_mut(1..).unwrap();
for mapper in mappers.into_iter() {
for range in mapper {
range[2] = range[1] + range[2] - 1;
}
}
let mut cur_vals: Vec<_> = Vec::new();
for i in 0..seeds.len() / 2 {
let end = seeds[i * 2] + seeds[(i * 2) + 1];
let mut range: Vec<_> = (seeds[i * 2]..end).collect();
cur_vals.append(&mut range);
}
println!("{}", cur_vals.len());
for mapper in mappers {
for val in cur_vals.iter_mut() {
println!("{}", val);
for range in mapper.into_iter() {
if range[1] <= *val && *val <= range[2] {
let diff = *val - range[1];
*val = range[0] + diff;
break;
}
}
}
}
println!("{:?}", cur_vals.into_iter().min().unwrap())
}
// use std::fs;
// fn main() {
// let input = fs::read_to_string("input.txt").unwrap();
// let mut mappers: Vec<_> = input.split("\n\n")
// .map(|maps| &maps[(maps.find(':').unwrap() + 1)..])
// .map(|maps| maps.trim())
// .map(|maps| {
// maps.split('\n')
// .map(|range| {
// range.split(' ')
// .map(|num| num.parse::<i64>().unwrap())
// .collect::<Vec<_>>()
// })
// .collect::<Vec<_>>()
// })
// .collect();
// let seeds = mappers.first().unwrap().first().unwrap().clone();
// let mappers: &mut [Vec<Vec<i64>>] = mappers.get_mut(1..).unwrap();
// for mapper in mappers.into_iter() {
// for range in mapper {
// range[2] = range[1] + range[2] - 1;
// }
// }
// let mut cur_vals: Vec<_> = seeds;
// for mapper in mappers {
// for val in cur_vals.iter_mut() {
// for range in mapper.into_iter() {
// if range[1] <= *val && *val <= range[2] {
// let diff = *val - range[1];
// *val = range[0] + diff;
// break;
// }
// }
// }
// }
// println!("{:?}", cur_vals.into_iter().min().unwrap())
// }

7
day6/Cargo.lock generated
View File

@@ -1,7 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day6"
version = "0.1.0"

View File

@@ -1,8 +0,0 @@
[package]
name = "day6"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

View File

@@ -1,2 +0,0 @@
Time: 63 78 94 68
Distance: 411 1274 2047 1035

View File

@@ -1,56 +0,0 @@
use std::fs;
fn main() {
let input = fs::read_to_string("input.txt").unwrap();
let input: Vec<_> = input.split('\n') // Separate the Time and Distance lines
.map(|line| {
line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
.split_whitespace() // Split the numbers into their own elements
.flat_map(|s| s.chars()).collect::<String>() // Combine the strings into a single one
.parse::<i64>().expect("Couldn't parse number") // Parse numbers into i32
}).collect(); // Collect into Vec
let time = input[0];
let dist = input[1];
let mut valid = 0;
for remaining_time in 0..time {
if (time - remaining_time) * remaining_time > dist {
valid += 1;
}
}
println!("{}", valid);
}
// use std::fs;
// fn main() {
// let input = fs::read_to_string("input.txt").unwrap();
// let input: Vec<_> = input.split('\n') // Separate the Time and Distance lines
// .map(|line| {
// line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
// .split_whitespace() // Split the numbers into their own elements.
// .map(|num| num.parse::<i32>().expect("Couldn't parse number")) // Parse numbers into i32
// .collect::<Vec<_>>()
// }).collect(); // collect into Vec
// let mut valid_total = 1;
// for round in 0..input.first().unwrap().len() {
// let time = input[0][round];
// let dist = input[1][round];
// let mut valid = 0;
// for remaining_time in 0..time {
// if (time - remaining_time) * remaining_time > dist {
// valid += 1;
// }
// }
// valid_total *= valid;
// }
// println!("{}", valid_total);
// }

View File

@@ -1,9 +1,28 @@
use std::fs;
fn main() {
let input = fs::read_to_string("input.txt").unwrap();
let input = input.split('\n');
let mut sum = 0;
#[aoc_generator(day1)]
pub fn parse_input(input: &str) -> Vec<String> {
input.split('\n')
.map(|line| line.into())
.collect()
}
#[aoc(day1, part1)]
fn solve_part1(input: &[String]) -> u32 {
let mut sum: u32 = 0;
for line in input {
let chars: Vec<_> = line.chars().filter(|char| char.is_numeric()).collect();
let num = chars.first().unwrap().to_string() + &chars.last().unwrap().to_string();
let num: u32 = num.parse().unwrap();
sum += num;
}
sum
}
#[aoc(day1, part2)]
fn solve_part2(input: &[String]) -> u32 {
let mut sum: u32 = 0;
for line in input {
let str_nums: Vec<(&str, &str)> = vec![("one", "1"), ("two", "2"), ("three", "3"), ("four", "4"), ("five", "5"), ("six", "6"), ("seven", "7"), ("eight", "8"), ("nine", "9")];
let mut matches: Vec<(usize, &str)> = vec![];
@@ -20,29 +39,8 @@ fn main() {
// sort by index
matches.sort_by(|lhs, rhs| lhs.cmp(rhs));
let num = (matches.first().unwrap().1).to_owned() + (matches.last().unwrap().1);
sum += num.parse::<i32>().unwrap();
sum += num.parse::<u32>().unwrap();
}
println!("{}", sum);
sum
}
// use std::fs;
// fn main() {
// let input = fs::read_to_string("input.txt").unwrap();
// let input = input.split('\n');
// let mut sum = 0;
// for line in input {
// let chars: Vec<char>= line.chars().filter(|x| x.is_numeric()).collect();
// let mut num = chars.first().unwrap().to_string();
// num += &chars.last().unwrap().to_string();
// let num: u32 = num.parse().unwrap();
// sum += num;
// }
// println!("{}", sum);
// }

190
src/day10.rs Normal file
View File

@@ -0,0 +1,190 @@
use aoc_runner_derive::{aoc, aoc_generator};
use strum::IntoEnumIterator;
use strum_macros::EnumIter;
#[aoc_generator(day10)]
fn parse(input: &str) -> ((usize, usize), Vec<Vec<Vec<Direction>>>) {
let input: Vec<_> = input.split('\n')
.map(|line| {
line.chars()
.map(|char| {
match char {
'|' => vec![Direction::North, Direction::South],
'-' => vec![Direction::East, Direction::West],
'L' => vec![Direction::North, Direction::East],
'J' => vec![Direction::North, Direction::West],
'7' => vec![Direction::South, Direction::West],
'F' => vec![Direction::South, Direction::East],
'.' => vec![],
'S' => vec![Direction::Start],
_ => panic!("Invalid pipe char")
}
}).collect::<Vec<_>>()
}).collect();
let start = find_start(&input);
(start, input)
}
fn find_start(input: &Vec<Vec<Vec<Direction>>>) -> (usize, usize) {
let mut start_point: Option<(usize, usize)> = None;
for i in 0..input.len() {
for j in 0..input[0].len() {
if input[i][j].contains(&Direction::Start) {
start_point = Some((i,j));
}
}
}
match start_point {
Some(x) => x,
None => panic!("No start point found! AHHHHH")
}
}
#[aoc(day10, part1)]
fn part1((start, input): &((usize, usize), Vec<Vec<Vec<Direction>>>)) -> i32 {
let mut start_dirs: Vec<Direction> = vec![];
for dir in Direction::iter().filter(|x| x != &Direction::Start) {
let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0));
if x < 0 || y < 0 {
continue;
}
let neibhor = &input[x as usize][y as usize];
if neibhor.contains(&dir.reverse()) {
start_dirs.push(dir);
}
}
let mut finished = false;
let mut count = 1;
let mut first_pre = start_dirs[0].reverse();
let mut second_pre = start_dirs[1].reverse();
let mut first_pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize);
let mut second_pos = ((start.0 as i32 + start_dirs[1].to_ind().1) as usize, (start.1 as i32 + start_dirs[1].to_ind().0) as usize);
while !finished {
let first_next = &input[first_pos.0][first_pos.1].iter().filter(|x| x != &&first_pre).next().unwrap();
first_pos = ((first_pos.0 as i32 + first_next.to_ind().1) as usize, (first_pos.1 as i32 + first_next.to_ind().0) as usize);
first_pre = first_next.reverse();
let second_next = &input[second_pos.0][second_pos.1].iter().filter(|x| x != &&second_pre).next().unwrap();
second_pos = ((second_pos.0 as i32 + second_next.to_ind().1) as usize, (second_pos.1 as i32 + second_next.to_ind().0) as usize);
second_pre = second_next.reverse();
count += 1;
finished = first_pos == second_pos;
}
count
}
#[aoc(day10, part2)]
fn part2((start, input): &((usize, usize), Vec<Vec<Vec<Direction>>>)) -> i64 {
let mut start_dirs: Vec<Direction> = vec![];
for dir in Direction::iter().filter(|x| x != &Direction::Start) {
let (x, y) = ((start.0 as i32 + dir.to_ind().1), (start.1 as i32 + dir.to_ind().0));
if x < 0 || y < 0 {
continue;
}
let neibhor = &input[x as usize][y as usize];
if neibhor.contains(&dir.reverse()) {
start_dirs.push(dir);
}
}
let mut finished = false;
let mut pre = start_dirs[0].reverse();
let mut pos = ((start.0 as i32 + start_dirs[0].to_ind().1) as usize, (start.1 as i32 + start_dirs[0].to_ind().0) as usize);
let mut the_loop = vec![*start, pos];
let mut area = 0;
while !finished {
let first_next = &input[pos.0][pos.1].iter().filter(|x| x != &&pre).next().unwrap();
pos = ((pos.0 as i32 + first_next.to_ind().1) as usize, (pos.1 as i32 + first_next.to_ind().0) as usize);
pre = first_next.reverse();
finished = pos == *start;
the_loop.push(pos);
}
for win in the_loop.windows(2) {
area += (win[0].1 * win[1].0) as i64;
area -= (win[0].0 * win[1].1) as i64;
}
let area = i64::abs(area) / 2;
let spaces = area - (the_loop.len() as i64 / 2) + 1;
spaces
}
#[derive(Debug, PartialEq, EnumIter)]
enum Direction {
North,
South,
East,
West,
Start
}
impl Direction {
pub fn to_ind(&self) -> (i32, i32) {
match self {
Direction::North => (0,-1),
Direction::South => (0,1),
Direction::East => (1,0),
Direction::West => (-1,0),
Direction::Start => panic!("Start should never be converted to an index. AHH"),
}
}
pub fn reverse(&self) -> Direction {
match self {
Direction::North => Direction::South,
Direction::South => Direction::North,
Direction::East => Direction::West,
Direction::West => Direction::East,
Direction::Start => panic!("Start should never be reversed. AHH"),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"7-F7-
.FJ|7
SJLL7
|F--J
LJ.LJ";
const EX_2: &str = r".F----7F7F7F7F-7....
.|F--7||||||||FJ....
.||.FJ||||||||L7....
FJL7L7LJLJ||LJ.L-7..
L--J.L7...LJS7F-7L7.
....F-J..F7FJ|L7L7L7
....L7.F7||L7|.L7L7|
.....|FJLJ|FJ|F7|.LJ
....FJL-7.||.||||...
....L---J.LJ.LJLJ...";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 8);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX_2)), 8);
}
}

144
src/day11.rs Normal file
View File

@@ -0,0 +1,144 @@
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day11)]
fn parse(input: &str) -> Vec<Vec<char>> {
let input: Vec<_> = input.split('\n')
.map(|x| x.chars().collect::<Vec<char>>())
.collect();
input
}
#[aoc(day11, part1)]
fn part1(input: &Vec<Vec<char>>) -> u32 {
let mut rotate: Vec<Vec<char>> = vec![];
for j in 0..input[0].len() {
let mut tmp: Vec<char> = vec![];
for i in 0..input.len() {
tmp.push(input[i][j]);
}
if tmp.iter().all(|x| x == &'.') {
rotate.push(tmp.clone());
}
rotate.push(tmp);
}
let mut expanded: Vec<Vec<char>> = vec![];
for j in 0..rotate[0].len() {
let mut tmp: Vec<char> = vec![];
for i in 0..rotate.len() {
tmp.push(rotate[i][j]);
}
if tmp.iter().all(|x| x == &'.') {
expanded.push(tmp.clone());
}
expanded.push(tmp);
}
let mut galaxies: Vec<(i32, i32)> = vec![];
for (i, line) in expanded.iter().enumerate() {
for (j, char) in line.iter().enumerate() {
if char == &'#' {
galaxies.push((i as i32,j as i32));
}
}
}
let dist_total = galaxies.clone().into_iter().enumerate()
.fold(0, |mut acc, (i, gal)| {
for next in &galaxies[i + 1..] {
acc += gal.0.abs_diff(next.0) + gal.1.abs_diff(next.1);
}
acc
});
dist_total
}
#[aoc(day11, part2)]
fn part2(input: &Vec<Vec<char>>) -> u64 {
let mut y_expand: Vec<i32> = vec![];
for line in input {
if line.iter().all(|char| char == &'.') {
y_expand.push(1);
} else {
y_expand.push(0);
}
}
let mut x_expand: Vec<i32> = vec![];
for j in 0..input[0].len() {
let mut is_empty = true;
for i in 0..input.len() {
if input[i][j] != '.' {
is_empty = false;
}
}
if is_empty {
x_expand.push(1);
} else {
x_expand.push(0);
}
}
// println!("{:?}", x_expand);
let mut galaxies: Vec<(i64, i64)> = vec![];
let mut y_offset: i64 = 0;
for (i, line) in input.iter().enumerate() {
if y_expand[i] == 1 {
y_offset += 1000000 - 1;
}
let mut x_offset: i64 = 0;
for (j, char) in line.iter().enumerate() {
if x_expand[j] == 1 {
x_offset += 1000000 - 1;
}
if char == &'#' {
galaxies.push((i as i64 + y_offset, j as i64 + x_offset));
}
}
}
let dist_total = galaxies.clone().into_iter().enumerate()
.fold(0, |mut acc, (i, gal)| {
for next in &galaxies[i + 1..] {
acc += gal.0.abs_diff(next.0) + gal.1.abs_diff(next.1);
}
acc
});
dist_total
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"...#......
.......#..
#.........
..........
......#...
.#........
.........#
..........
.......#..
#...#.....";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 374);
}
// #[test]
// fn part2_example() {
// assert_eq!(part2(&parse(EX)), "<RESULT>");
// }
}

155
src/day12.rs Normal file
View File

@@ -0,0 +1,155 @@
use aoc_runner_derive::{aoc, aoc_generator};
use itertools::Itertools;
use std::collections::HashMap;
use std::slice;
#[aoc_generator(day12)]
fn parse(input: &str) -> Vec<(Vec<Condition>, Vec<usize>)> {
let input: Vec<(Vec<Condition>, Vec<usize>)> = input.split('\n')
.map(|line| {
line.split(' ')
.collect_tuple()
.unwrap()
}).map(|(springs, groups)| {
let springs: Vec<Condition> = springs.chars()
.map(|char| {
char.to_condition()
}).collect();
let groups: Vec<_> = groups.split(',')
.map(|num| num.parse::<usize>().expect("Failed to parse group len"))
.collect();
(springs, groups)
}).collect();
input
}
fn possible_count_cache(springs: &[Condition], groups: &[usize], cache: &mut HashMap<(usize, usize), usize>) -> usize {
if let Some(count) = cache.get(&(springs.len(), groups.len())) {
return *count;
}
let mut count = 0;
if groups.is_empty() {
count = if springs.contains(&Condition::Bad) { 0 } else { 1 };
cache.insert((springs.len(), groups.len()), count);
return count;
}
for i in 0..springs.len() {
if springs[0..i].contains(&Condition::Bad) || i + groups[0] > springs.len() {
break;
}
if springs[i..i + groups[0]].contains(&Condition::Good) {
continue;
}
if groups.len() == 1 {
if i + groups[0] == springs.len() {
count += 1;
break;
} else {
count += possible_count_cache(&springs[i + groups[0]..], &[], cache);
continue;
}
} else if i + groups[0] + 1 > springs.len() {
break;
} else if springs[i + groups[0]] == Condition::Bad {
continue;
}
count += possible_count_cache(
&springs[i + groups[0] + 1..],
&groups[1..],
cache,
);
}
cache.insert((springs.len(), groups.len()), count);
count
}
fn possible_count(springs: &[Condition], groups: &[usize]) -> usize {
possible_count_cache(springs, groups, &mut HashMap::new())
}
#[aoc(day12, part1)]
fn part1(input: &Vec<(Vec<Condition>, Vec<usize>)>) -> usize {
input.iter()
.map(|(springs, groups)| possible_count(springs, groups))
.sum()
}
#[aoc(day12, part2)]
fn part2(input: &Vec<(Vec<Condition>, Vec<usize>)>) -> usize {
input.iter()
.map(|(springs, groups)| possible_count(
&[
&springs[..],
slice::from_ref(&Condition::WhoKnows),
&springs[..],
slice::from_ref(&Condition::WhoKnows),
&springs[..],
slice::from_ref(&Condition::WhoKnows),
&springs[..],
slice::from_ref(&Condition::WhoKnows),
&springs[..],
].concat(),
&[
&groups[..],
&groups[..],
&groups[..],
&groups[..],
&groups[..],
].concat()))
.sum()
}
#[derive(Debug, PartialEq, Clone)]
enum Condition {
Good,
Bad,
WhoKnows
}
trait ConditionConvertable {
fn to_condition(self) -> Condition;
}
impl ConditionConvertable for char {
fn to_condition(self) -> Condition {
match self {
'.' => Condition::Good,
'#' => Condition::Bad,
'?' => Condition::WhoKnows,
_ => panic!("Invalid spring char AHHH")
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"???.### 1,1,3
.??..??...?##. 1,1,3
?#?#?#?#?#?#?#? 1,3,1,6
????.#...#... 4,1,1
????.######..#####. 1,6,5
?###???????? 3,2,1";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 21);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 525152);
}
}

113
src/day13.rs Normal file
View File

@@ -0,0 +1,113 @@
use std::collections::HashSet;
use aoc_runner_derive::{aoc, aoc_generator};
type Coordinates = (i32, i32);
#[aoc_generator(day13)]
fn parse(input: &str) -> Vec<HashSet<Coordinates>> {
input.split("\n\n")
.map(|pattern| {
let mut map: HashSet<Coordinates> = HashSet::new();
for (y, line) in pattern.lines().into_iter().enumerate() {
for (x, char) in line.chars().enumerate() {
if char == '#' {
map.insert((x as i32 + 1, y as i32 + 1));
}
}
}
map
}).collect::<Vec<_>>()
}
fn reflection((x, y): &Coordinates, pattern: &HashSet<Coordinates>, max_x: i32, max_y: i32, axis: &i32, is_column: bool) -> bool {
if is_column {
x <= axis && (2 * axis - x + 1 > max_x || pattern.contains(&(2 * axis - x + 1, *y)))
|| x > axis && (2 * axis - x + 1 < 1 || pattern.contains(&(2 * axis - x + 1, *y)))
} else {
y <= axis && (2 * axis - y + 1 > max_y || pattern.contains(&(*x, 2 * axis - y + 1)))
|| y > axis && (2 * axis - y + 1 < 1 || pattern.contains(&(*x, 2 * axis - y + 1)))
}
}
fn calc_summary(pattern: &HashSet<Coordinates>) -> usize {
let max_x = pattern.iter().max_by(|a, b| a.0.cmp(&b.0)).unwrap().0;
let max_y = pattern.iter().max_by(|a, b| a.1.cmp(&b.1)).unwrap().1;
((1..max_x)
.find(|column| {
pattern.iter()
.all(|coords| {
reflection(coords, pattern, max_x, max_y, column, true)
})
}).unwrap_or(0)
+ 100 * (1..max_y)
.find(|row| {
pattern.iter().all(|coordinates| {
reflection(coordinates, pattern, max_x, max_y, row, false)
})
})
.unwrap_or(0)) as usize
}
#[aoc(day13, part1)]
fn part1(input: &Vec<HashSet<Coordinates>>) -> usize {
input.iter().map(calc_summary).sum()
}
fn calc_summary_part2(pattern: &HashSet<Coordinates>) -> usize {
let max_x = pattern.iter().max_by(|a, b| a.0.cmp(&b.0)).unwrap().0;
let max_y = pattern.iter().max_by(|a, b| a.1.cmp(&b.1)).unwrap().1;
((1..max_x)
.find(|column| {
pattern.iter().filter(|coords| {
reflection(coords, pattern, max_x, max_y, column, true)
}).count() == pattern.len() - 1
}).unwrap_or(0)
+ 100 * (1..max_y)
.find(|row| {
pattern.iter().filter(|coordinates| {
reflection(coordinates, pattern, max_x, max_y, row, false)
}).count() == pattern.len() - 1
})
.unwrap_or(0)) as usize
}
#[aoc(day13, part2)]
fn part2(input: &Vec<HashSet<Coordinates>>) -> usize {
input.iter().map(calc_summary_part2).sum()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"#.##..##.
..#.##.#.
##......#
##......#
..#.##.#.
..##..##.
#.#.##.#.
#...##..#
#....#..#
..##..###
#####.##.
#####.##.
..##..###
#....#..#";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 405);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 400);
}
}

159
src/day14.rs Normal file
View File

@@ -0,0 +1,159 @@
use std::collections::HashMap;
use aoc_runner_derive::{aoc, aoc_generator};
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
enum Rock {
Round,
Square,
None
}
trait RockConvertable {
fn to_rock(&self) -> Rock;
}
impl RockConvertable for char {
fn to_rock(&self) -> Rock {
match self {
'O' => Rock::Round,
'#' => Rock::Square,
'.' => Rock::None,
_ => panic!("Invalid rock char")
}
}
}
#[aoc_generator(day14)]
fn parse(input: &str) -> Vec<Vec<Rock>> {
let input: Vec<Vec<Rock>> = input.lines()
.map(|line| {
line.chars().map(|char| {
char.to_rock()
}).collect::<Vec<_>>()
}).collect::<Vec<_>>();
input
}
#[aoc(day14, part1)]
fn part1(input: &Vec<Vec<Rock>>) -> usize {
let mut load: usize = 0;
for j in 0..input[0].len() {
let mut cur_weight = input[0].len() + 1;
for i in 0..input.len() {
match input[i][j] {
Rock::Round => {
cur_weight -= 1;
load += cur_weight;
},
Rock::Square => {
cur_weight = input[0].len() - i;
},
Rock::None => continue
}
}
}
load
}
#[aoc(day14, part2)]
fn part2(input: &Vec<Vec<Rock>>) -> usize {
let mut seen_at = HashMap::new();
let mut next_y = Vec::<usize>::new();
let mut map = input.to_vec();
// Functions to get a Rock using a rotated coordinate space
let cycle_parts: &[(Box<dyn Fn(&mut Vec<Vec<Rock>>, usize, usize) -> &mut Rock>, _, _); 4] = &[
(Box::new(|map: &mut Vec<Vec<Rock>>, x: usize, y: usize| &mut map[y][x]),
map[0].len(), map.len()),
(Box::new(|map: &mut Vec<Vec<Rock>>, x: usize, y: usize| &mut map[x][y]),
map.len(), map[0].len()),
(Box::new(|map: &mut Vec<Vec<Rock>>, x: usize, y: usize| { let h = map.len(); &mut map[h - 1 - y][x] }),
map[0].len(), map.len()),
(Box::new(|map: &mut Vec<Vec<Rock>>, x: usize, y: usize| { let w = map[0].len(); &mut map[x][w - 1 - y] }),
map.len(), map[0].len()),
];
let mut cycle = 0;
const END: u32 = 1000000000;
while cycle < END {
// Handle tilts in each direction
for (getter, width, height) in cycle_parts {
next_y.clear();
next_y.resize(*width, 0);
for y in 0..*height {
for x in 0..*width {
let item = getter(&mut map, x, y);
match *item {
Rock::None => {}
Rock::Square => {
next_y[x] = y + 1;
}
Rock::Round => {
*item = Rock::None;
*getter(&mut map, x, next_y[x]) = Rock::Round;
next_y[x] += 1;
}
}
}
}
}
// More compact representation of the current state, for saving in hashmap
let key = map.iter().enumerate().flat_map(|(y, line)| {
line.iter().enumerate().filter_map(move |(x, &ref rock)| {
if rock == &Rock::Round {
Some((x as u8, y as u8))
} else {
None
}
})
}).collect::<Vec<_>>();
cycle += 1;
if let Some(seen_at_cycle) = seen_at.insert(key, cycle) {
// Current state was identical to one we'd already seen, we can skip forward
let diff = cycle - seen_at_cycle;
let remaining = END - cycle;
let skipped = remaining / diff * diff;
cycle += skipped;
}
}
let height = map.len();
map.into_iter().enumerate().flat_map(|(y, line)| line.into_iter().filter_map(move |rock| {
if rock == Rock::Round {
Some(height - y)
} else {
None
}
})).sum()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"O....#....
O.OO#....#
.....##...
OO.#O....O
.O.....O#.
O.#..O.#.#
..O..#O..O
.......O..
#....###..
#OO..#....";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 136);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 64);
}
}

93
src/day15.rs Normal file
View File

@@ -0,0 +1,93 @@
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day15)]
fn parse(input: &str) -> Vec<String> {
input.split(',').map(|x| x.into()).collect::<Vec<String>>()
}
#[aoc(day15, part1)]
fn part1(input: &Vec<String>) -> u32 {
let mut total = 0;
for step in input {
total += hash(step);
}
total
}
fn hash(string: &str) -> u32 {
let mut cur_val = 0;
for char in string.chars() {
cur_val += char as u32;
cur_val *= 17;
cur_val = cur_val % 256;
}
cur_val
}
#[aoc(day15, part2)]
fn part2(input: &Vec<String>) -> usize {
let mut boxes: [Vec<(String, usize)>; 256] =
std::iter::repeat_with(|| Vec::with_capacity(input.len()))
.take(256)
.collect::<Vec<_>>()
.try_into()
.unwrap();
for step in input {
if let Some(dash) = step.find('-') {
let label = &step[0..dash];
let box_number = hash(label) as usize;
if let Some(position) = boxes[box_number].iter().position(|(l, _)| *l == *label) {
boxes[box_number].remove(position);
}
} else if let Some(equal) = step.find('=') {
let label = &step[0..equal];
let box_number = hash(label) as usize;
let focal_length = &step[equal + 1..].parse::<u32>().unwrap();
if let Some(position) = boxes[box_number].iter().position(|(l, _)| *l == *label) {
let _ = std::mem::replace(
&mut boxes[box_number][position],
(label.to_string(), *focal_length as usize),
);
} else {
boxes[box_number].push((label.to_string(), *focal_length as usize));
}
} else {
panic!("invalid step AHHH {}", step)
}
}
let mut total = 0;
for (index, lens_box) in boxes.iter().enumerate() {
for (slot, (_, focal_len)) in lens_box.iter().enumerate() {
total += (index + 1) * (slot + 1) * focal_len;
}
}
total
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"HASH";
const EX_2: &str = r"rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 52);
}
#[test]
fn part1_example2() {
assert_eq!(part1(&parse(EX_2)), 1320);
}
#[test]
fn part2_example2() {
assert_eq!(part2(&parse(EX_2)), 145);
}
}

211
src/day16.rs Normal file
View File

@@ -0,0 +1,211 @@
use std::collections::{HashSet, VecDeque};
use prev_iter::PrevPeekable;
use aoc_runner_derive::{aoc, aoc_generator};
use strum_macros::Display;
#[derive(Debug, Clone, Copy)]
enum Tile {
None,
MirrorLeft,
MirrorRight,
SplitterVert,
SplitterHori
}
trait TileConvertable {
fn to_tile(&self) -> Tile;
}
impl TileConvertable for char {
fn to_tile(&self) -> Tile {
match self {
'.' => Tile::None,
'/' => Tile::MirrorLeft,
'\\' => Tile::MirrorRight,
'|' => Tile::SplitterVert,
'-' => Tile::SplitterHori,
_ => panic!("invalid tile char: {} AHHH", self)
}
}
}
#[aoc_generator(day16)]
fn parse(input: &str) -> Vec<Vec<Tile>> {
let input = input.lines()
.map(|line| {
line.chars()
.map(|char| char.to_tile())
.collect::<Vec<_>>()
})
.collect::<Vec<_>>();
input
}
#[aoc(day16, part1)]
fn part1(map: &Vec<Vec<Tile>>) -> usize {
let start = (Position{ x:0 , y:0}, Direction::Right);
trace_beams(start, map)
}
fn trace_beams((start_pos, start_dir): (Position, Direction), map: &Vec<Vec<Tile>>) -> usize {
let mut in_progress = VecDeque::from([(start_pos, start_dir)]);
let mut seen: HashSet<(Position, Direction)> = HashSet::new();
while !in_progress.is_empty() {
let mut cur = in_progress.pop_front();
while &cur != &None {
seen.insert(cur.clone().unwrap());
let (next, new_beam) = do_one_step(cur.clone().unwrap(), map);
if let Some(next) = next {
if !seen.contains(&next) {
cur = Some(next);
} else {
cur = None;
}
} else {
cur = None
}
if let Some(new_beam) = new_beam {
in_progress.push_back(new_beam);
}
}
}
seen.iter().map(|x| x.0).collect::<HashSet<_>>().len()
}
fn do_one_step(cur: (Position, Direction), map: &Vec<Vec<Tile>>) -> (Option<(Position, Direction)>, Option<(Position, Direction)>) {
let tile = map[cur.0.y as usize][cur.0.x as usize];
match tile {
Tile::None => (move_and_turn(&cur, None, map), None),
Tile::SplitterHori if {cur.1.is_hori()} => (move_and_turn(&cur, None, map), None),
Tile::SplitterVert if {cur.1.is_vert()} => (move_and_turn(&cur, None, map), None),
Tile::MirrorRight => (move_and_turn(&cur, if cur.1.is_hori() {Some(Direction::Right)} else {Some(Direction::Left)}, map), None),
Tile::MirrorLeft => (move_and_turn(&cur, if cur.1.is_hori() {Some(Direction::Left)} else {Some(Direction::Right)}, map), None),
Tile::SplitterVert => (move_and_turn(&cur, Some(Direction::Left), map), move_and_turn(&cur, Some(Direction::Right), map)),
Tile::SplitterHori => (move_and_turn(&cur, Some(Direction::Right), map), move_and_turn(&cur, Some(Direction::Left), map))
}
}
fn move_and_turn(cur: &(Position, Direction), turn: Option<Direction>, map: &Vec<Vec<Tile>>) -> Option<(Position, Direction)> {
let next_dir = if let Some(turn) = turn {cur.1.turn(turn)} else {cur.1};
let next_pos = cur.0.move_pos(next_dir);
if let Some(line) = map.get(next_pos.y as usize) {
if let Some(_) = line.get(next_pos.x as usize) {
return Some((next_pos, next_dir));
}
}
None
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
struct Position {
x: i32,
y: i32
}
impl Position {
fn move_pos(&self, dir: Direction) -> Position {
let (dx, dy) = match dir {
Direction::Up => (0, -1),
Direction::Down => (0, 1),
Direction::Left => (-1, 0),
Direction::Right => (1, 0),
};
return Position { x: self.x + dx, y: self.y + dy};
}
}
#[derive(Debug, Hash, PartialEq, Eq, Display, Copy, Clone)]
enum Direction {
Up,
Down,
Left,
Right
}
impl Direction {
fn turn(&self, turn: Direction) -> Direction {
const TURN_ORDER: [Direction; 4] = [Direction::Up, Direction::Right, Direction::Down, Direction::Left];
let mut iter = PrevPeekable::new(TURN_ORDER.iter().cycle());
_ = iter.find(|dir| dir == &self).unwrap();
if turn == Direction::Left && *self == Direction::Up {
return Direction::Left;
}
let index = match turn {
Direction::Left => iter.prev(),
Direction::Right => iter.next(),
_ => panic!("Cannot turn {}", turn)
};
return *index.clone().unwrap();
}
fn is_hori(&self) -> bool {
[Direction::Right, Direction::Left].contains(self)
}
fn is_vert(&self) -> bool {
[Direction::Up, Direction::Down].contains(self)
}
}
#[aoc(day16, part2)]
fn part2(map: &Vec<Vec<Tile>>) -> usize {
let x_size = map[0].len();
let y_size = map.len();
let mut edges = vec![];
let mut top = (0..x_size).map(|x| (Position{ x: x as i32, y: 0}, Direction::Down)).collect::<Vec<_>>();
let mut left = (0..y_size).map(|y| (Position{ x: 0, y: y as i32}, Direction::Right)).collect::<Vec<_>>();
let mut bottom = (0..x_size).map(|x| (Position{ x: x as i32, y: (y_size - 1) as i32}, Direction::Down)).collect::<Vec<_>>();
let mut right = (0..y_size).map(|y| (Position{ x: (x_size - 1) as i32, y: y as i32}, Direction::Left)).collect::<Vec<_>>();
edges.append(&mut top);
edges.append(&mut left);
edges.append(&mut bottom);
edges.append(&mut right);
let total = edges.iter().map(|x| trace_beams(*x, map)).collect::<Vec<_>>();
*total.iter().max().unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r".|...\....
|.-.\.....
.....|-...
........|.
..........
.........\
..../.\\..
.-.-/..|..
.|....-|.\
..//.|....";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 46);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 51);
}
}

115
src/day17.rs Normal file
View File

@@ -0,0 +1,115 @@
use std::{collections::BinaryHeap, cmp::Reverse};
use aoc_runner_derive::{aoc, aoc_generator};
#[derive(Debug)]
struct Grid {
data: Box<[u8]>,
offset: usize
}
impl Grid {
fn from_str(s: &str) -> Self {
let mut lines = s.lines().peekable();
let line_len = lines.peek().map_or(0, |line| line.len());
Self {
data: lines.flat_map(str::as_bytes).map(|&char| char - b'0').collect::<Box<_>>(),
offset: line_len
}
}
fn next_pos(&self, p: usize, dir: u8) -> Option<usize> {
Some(match dir {
0 if p > self.offset => p - self.offset,
1 if (p + 1) % self.offset != 0 => p + 1,
2 if p < self.data.len() - self.offset => p + self.offset,
3 if p % self.offset != 0 => p - 1,
_ => { return None }
})
}
fn run(&self, dmin: usize, dmax: usize) -> Option<usize> {
let lp = self.data.len() - 1;
let mut visit = vec![0u8; self.data.len()];
let mut ccache = vec![usize::MAX; 2 * self.data.len()];
let mut q = BinaryHeap::new();
q.push((Reverse(0), 0, 0));
q.push((Reverse(0), 0, 1));
while let Some((Reverse(cost), p, dir)) = q.pop() {
if p == lp {
return Some(cost)
}
if visit[p] & (1u8 << dir) != 0 {
continue;
}
visit[p] |= 1u8 << dir;
let odir = dir ^ 1;
for nd in [odir, odir ^ 2] {
let mut costsum = 0;
let mut np = p;
for dist in 1..=dmax {
if let Some(op) = self.next_pos(np, nd) {
costsum += self.data[op] as usize;
if dist >= dmin {
let ncost = cost + costsum;
let cache_idx = (op << 1) | odir as usize;
if ccache[cache_idx] > ncost {
ccache[cache_idx] = ncost;
q.push((Reverse(ncost), op, odir));
}
}
np = op;
}
}
}
}
None
}
}
#[aoc_generator(day17)]
fn parse(input: &str) -> Grid {
Grid::from_str(input)
}
#[aoc(day17, part1)]
fn part1(input: &Grid) -> usize {
input.run(1, 3).unwrap()
}
#[aoc(day17, part2)]
fn part2(input: &Grid) -> usize {
input.run(4, 10).unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"2413432311323
3215453535623
3255245654254
3446585845452
4546657867536
1438598798454
4457876987766
3637877979653
4654967986887
4564679986453
1224686865563
2546548887735
4322674655533";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 102);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 94);
}
}

187
src/day18.rs Normal file
View File

@@ -0,0 +1,187 @@
use aoc_runner_derive::{aoc, aoc_generator};
use strum_macros::Display;
#[derive(Debug, PartialEq, Eq, Clone)]
struct Step {
dir: Direction,
length: i32
}
#[derive(Debug, Display, PartialEq, Eq, Clone, Copy)]
enum Direction {
Up,
Down,
Left,
Right
}
impl Direction {
fn get_coordinate_modifier(&self) -> (i32, i32) {
match self {
Direction::Up => (0, 1),
Direction::Down => (0, -1),
Direction::Left => (-1, 0),
Direction::Right => (1, 0),
}
}
}
trait DirectionConvertable {
fn to_direction(&self) -> Direction;
}
impl DirectionConvertable for &str {
fn to_direction(&self) -> Direction {
match *self {
"U" => Direction::Up,
"D" => Direction::Down,
"L" => Direction::Left,
"R" => Direction::Right,
_ => panic!("Invalid Direction")
}
}
}
impl DirectionConvertable for i32 {
fn to_direction(&self) -> Direction {
match self {
3 => Direction::Up,
1 => Direction::Down,
2 => Direction::Left,
0 => Direction::Right,
_ => panic!("Invalid Direction")
}
}
}
#[aoc_generator(day18, part1)]
fn parse_part1(input: &str) -> Vec<Step> {
let steps = input.lines()
.map(|line| {
let mut line = line.split(' ');
Step {
dir: line.next().unwrap().to_direction(),
length: line.next().unwrap().parse::<i32>().unwrap(),
}
}).collect::<Vec<_>>();
steps
}
#[aoc(day18, part1)]
fn part1(steps: &Vec<Step>) -> i32 {
let verticies = get_verticies(steps);
let mut area = 0;
for win in verticies.windows(2) {
area += win[0].y * win[1].x;
area -= win[0].x * win[1].y;
}
(area / 2) + (verticies.len() as i32 / 2) + 1
}
#[derive(Debug, PartialEq, Eq, Clone)]
struct Coordinate {
x: i32,
y: i32
}
fn get_verticies(steps: &Vec<Step>) -> Vec<Coordinate> {
let mut cur_pos = Coordinate{ x: 0, y: 0 };
let mut verticies: Vec<Coordinate> = vec![cur_pos.clone()];
for step in steps {
let (x_mod, y_mod) = step.dir.get_coordinate_modifier();
for _ in 0..step.length {
let new_pos = Coordinate{
x: cur_pos.x + x_mod,
y: cur_pos.y + y_mod,
};
cur_pos = new_pos.clone();
verticies.push(new_pos.clone());
}
}
verticies
}
#[aoc_generator(day18, part2)]
fn parse_part2(input: &str) -> Vec<Step> {
let steps = input.lines()
.map(|line| {
let line = line.split(' ');
parse_hex(line.last().unwrap())
}).collect::<Vec<_>>();
steps
}
fn parse_hex(hex: &str) -> Step {
let hex = hex.trim_matches(['(', ')', '#'].as_slice());
let length = "0".to_string() + &hex[0..5];
let length = u32::from_str_radix(&length, 16).expect("Cannot parse Hex value");
let dir = hex.chars().last().unwrap().to_string().parse::<i32>().unwrap().to_direction();
Step {
dir,
length: length as i32
}
}
#[aoc(day18, part2)]
fn part2(steps: &Vec<Step>) -> i64 {
let verticies = get_verticies(steps);
let mut area: i64 = 0;
for win in verticies.windows(2) {
area += win[0].y as i64 * win[1].x as i64;
area -= win[0].x as i64 * win[1].y as i64;
}
(area / 2) + (verticies.len() as i64 / 2) + 1
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"R 6 (#70c710)
D 5 (#0dc571)
L 2 (#5713f0)
D 2 (#d2c081)
R 2 (#59c680)
D 2 (#411b91)
L 5 (#8ceee2)
U 2 (#caa173)
L 1 (#1b58a2)
U 2 (#caa171)
R 2 (#7807d2)
U 3 (#a77fa3)
L 2 (#015232)
U 2 (#7a21e3)";
const EX_2: &str = r"R 6 (#70c710)
D 6 (#0dc571)
L 6 (#5713f0)
U 6 (#d2c081)";
#[test]
fn part1_example() {
assert_eq!(part1(&parse_part1(EX)), 62);
}
#[test]
fn part1_example2() {
assert_eq!(part1(&parse_part1(EX_2)), 49);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse_part2(EX)), 952408144115);
}
}

245
src/day19.rs Normal file
View File

@@ -0,0 +1,245 @@
use std::collections::HashMap;
use regex::{Regex, Match};
enum Rule {
ACCEPTED,
REJECTED,
GOTO(String),
GT(String, usize, String),
LT(String, usize, String),
}
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day19, part1)]
fn parse(input: &str) -> (HashMap<String, Vec<Rule>>, Vec<HashMap<String, usize>>) {
let (workflows_input, ratings_input) = input.split_once("\n\n").unwrap();
let workflows = parse_workflows(workflows_input);
// screw it im using regex
let rer = Regex::new(r"^\{x=(\d+),m=(\d+),a=(\d+),s=(\d+)\}$").unwrap();
let ratings: Vec<HashMap<String, usize>> = ratings_input.lines().map(|line| {
let caps = rer.captures(line).unwrap();
let x = parse_usize(caps.get(1));
let m = parse_usize(caps.get(2));
let a = parse_usize(caps.get(3));
let s = parse_usize(caps.get(4));
let mut vals = HashMap::new();
vals.insert("x".to_string(), x);
vals.insert("m".to_string(), m);
vals.insert("a".to_string(), a);
vals.insert("s".to_string(), s);
vals
}).collect();
(workflows, ratings)
}
fn parse_usize(g: Option<Match>) -> usize {
g.map_or(0, |m| m.as_str().parse().unwrap())
}
fn parse_workflows(workflows_input: &str) -> HashMap<String, Vec<Rule>> {
let mut workflows: HashMap<String, Vec<Rule>> = HashMap::new();
let rew = Regex::new(r"^(.+)\{(.+)\}$").unwrap();
workflows_input.lines().for_each(|line| {
let caps = rew.captures(line).unwrap();
let key = caps.get(1).unwrap().as_str();
let rules_str = caps.get(2).unwrap().as_str();
let rules = rules_str.split(",").map(|expr| {
if expr == "A" {
return Rule::ACCEPTED;
}
if expr == "R" {
return Rule::REJECTED;
}
if !expr.contains(":") {
return Rule::GOTO(expr.to_string());
}
let (rule, to) = expr.split_once(":").unwrap();
return if rule.contains(">") {
let (prop, val) = rule.split_once(">").unwrap();
Rule::GT(prop.to_string(), val.parse().unwrap(), to.to_string())
} else if rule.contains("<") {
let (prop, val) = rule.split_once("<").unwrap();
Rule::LT(prop.to_string(), val.parse().unwrap(), to.to_string())
} else {
panic!("Unknown rule {}", rule)
};
}).collect();
workflows.insert(key.to_string(), rules);
});
workflows
}
#[aoc(day19, part1)]
fn part1((workflows, ratings): &(HashMap<String, Vec<Rule>>, Vec<HashMap<String, usize>>)) -> usize {
let mut accepted: Vec<HashMap<String, usize>> = vec!();
'outer: for rating in ratings {
let mut wf_key = "in";
'middle: loop {
if wf_key == "A" {
accepted.push(rating.clone());
continue 'outer;
} else if wf_key == "R" {
continue 'outer;
}
let rules = workflows.get(wf_key).unwrap();
for rule in rules {
match rule {
Rule::ACCEPTED => {
accepted.push(rating.clone());
continue 'outer;
}
Rule::REJECTED => {
continue 'outer;
}
Rule::GOTO(new_wf_key) => {
wf_key = new_wf_key;
continue 'middle;
}
Rule::GT(prop, val, to) => {
if rating.get(prop.as_str()).unwrap() > val {
wf_key = to;
continue 'middle;
}
}
Rule::LT(prop, val, to) => {
if rating.get(prop.as_str()).unwrap() < val {
wf_key = to;
continue 'middle;
}
}
}
}
}
}
accepted.iter().map(|rating| rating.values().sum::<usize>()).sum::<usize>()
}
#[aoc_generator(day19, part2)]
fn parse_part2(input: &str) -> HashMap<String, Vec<Rule>> {
let (workflows_input, _) = input.split_once("\n\n").unwrap();
parse_workflows(workflows_input)
}
#[aoc(day19, part2)]
fn part2(workflows: &HashMap<String, Vec<Rule>>) -> usize {
let mut stack: Vec<((usize, usize), (usize, usize), (usize, usize), (usize, usize), &str, usize)> =
vec! {((1, 4000), (1, 4000), (1, 4000), (1, 4000), "in", 0)};
let mut accepted: Vec<((usize, usize), (usize, usize), (usize, usize), (usize, usize))> = vec!();
while let Some(range) = stack.pop() {
let (x, m, a, s, wf_key, rule_key) = range;
if wf_key == "A" {
accepted.push((x, m, a, s));
continue;
} else if wf_key == "R" {
continue;
}
if x.0 > x.1 || m.0 > m.1 || a.0 > a.1 || s.0 > s.1 { continue }
let rules = workflows.get(wf_key).unwrap();
let rule = &rules[rule_key];
match rule {
Rule::ACCEPTED => {
accepted.push((x, m, a, s));
continue;
}
Rule::REJECTED => {
continue;
}
Rule::GOTO(new_wf_key) => {
stack.push((x, m, a, s, new_wf_key, 0));
continue;
}
Rule::GT(prop, val, to) => {
match prop.as_str() {
"x" => {
stack.push(((val + 1, x.1), m, a, s, to.as_str(), 0));
stack.push(((x.0, *val), m, a, s, wf_key, rule_key + 1));
}
"m" => {
stack.push((x, (val + 1, m.1), a, s, to.as_str(), 0));
stack.push((x, (m.0, *val), a, s, wf_key, rule_key + 1));
}
"a" => {
stack.push((x, m, (val + 1, a.1), s, to.as_str(), 0));
stack.push((x, m, (a.0, *val), s, wf_key, rule_key + 1));
}
"s" => {
stack.push((x, m, a, (val + 1, s.1), to.as_str(), 0));
stack.push((x, m, a, (s.0, *val), wf_key, rule_key + 1));
}
_ => { panic!("unknown prop {}", prop) }
}
}
Rule::LT(prop, val, to) => {
match prop.as_str() {
"x" => {
stack.push(((x.0, val - 1), m, a, s, to.as_str(), 0));
stack.push(((*val, x.1), m, a, s, wf_key, rule_key + 1));
}
"m" => {
stack.push((x, (m.0, val - 1), a, s, to.as_str(), 0));
stack.push((x, (*val, m.1), a, s, wf_key, rule_key + 1));
}
"a" => {
stack.push((x, m, (a.0, val - 1), s, to.as_str(), 0));
stack.push((x, m, (*val, a.1), s, wf_key, rule_key + 1));
}
"s" => {
stack.push((x, m, a, (s.0, val - 1), to.as_str(), 0));
stack.push((x, m, a, (*val, s.1), wf_key, rule_key + 1));
}
_ => { panic!("unknown prop {}", prop) }
}
}
}
}
accepted.iter().map(|(x, m, a, s)| {
(x.1 - x.0 + 1) * (m.1 - m.0 + 1) * (a.1 - a.0 + 1) * (s.1 - s.0 + 1)
}).sum()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"px{a<2006:qkq,m>2090:A,rfg}
pv{a>1716:R,A}
lnx{m>1548:A,A}
rfg{s<537:gd,x>2440:R,A}
qs{s>3448:A,lnx}
qkq{x<1416:A,crn}
crn{x>2662:A,R}
in{s<1351:px,qqz}
qqz{s>2770:qs,m<1801:hdj,R}
gd{a>3333:R,R}
hdj{m>838:A,pv}
{x=787,m=2655,a=1222,s=2876}
{x=1679,m=44,a=2067,s=496}
{x=2036,m=264,a=79,s=2244}
{x=2461,m=1339,a=466,s=291}
{x=2127,m=1623,a=2188,s=1013}";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 19114);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse_part2(EX)), 167409079868000);
}
}

114
src/day2.rs Normal file
View File

@@ -0,0 +1,114 @@
use itertools::Itertools;
use std::cmp::max;
#[aoc_generator(day2)]
fn parse_input(input: &str) -> Vec<Vec<Vec<(i32, Color)>>> {
input.split('\n')
.map(|line| {
let rounds = &line[line.find(':').unwrap() + 1..];
rounds.split(';')
.map(|game| {
game.split(',')
.map(|round| {
let (number, color) = round.split_whitespace().collect_tuple().unwrap();
let number = number.parse::<i32>().unwrap();
(number, color.into_color())
}).collect::<Vec<_>>()
}).collect::<Vec<_>>()
}).collect::<Vec<_>>()
}
#[aoc(day2, part1)]
fn solve_part1(input: &Vec<Vec<Vec<(i32, Color)>>>) -> usize {
let (r_max, g_max, b_max) = (12, 13, 14);
let mut sum: usize = 0;
for (game_id, rounds) in input.iter().enumerate() {
let mut sad = false;
for round in rounds {
let (mut r_cur, mut g_cur, mut b_cur) = (0, 0, 0);
for (num, color) in round {
match color {
Color::Red => r_cur += num,
Color::Blue => b_cur += num,
Color::Green => g_cur += num
}
}
if r_cur > r_max || b_cur > b_max || g_cur > g_max {
sad = true;
}
}
if !sad {
sum += game_id + 1;
}
}
return sum;
}
#[aoc(day2, part2)]
fn solve_part2(input: &Vec<Vec<Vec<(i32, Color)>>>) -> usize {
let mut sum: usize = 0;
for rounds in input {
let (mut r_max, mut g_max, mut b_max) = (0, 0, 0);
for round in rounds {
for (num, color) in round {
match color {
Color::Red => r_max = max(*num, r_max),
Color::Blue => b_max = max(*num, b_max),
Color::Green => g_max = max(*num, g_max),
}
}
}
sum += (r_max * g_max * b_max) as usize;
}
sum
}
#[derive(Debug)]
enum Color {
Red,
Blue,
Green
}
trait ColorConvertable {
fn into_color(&self) -> Color;
}
impl ColorConvertable for str {
fn into_color(&self) -> Color {
match self {
"red" => Color::Red,
"blue" => Color::Blue,
"green" => Color::Green,
_ => panic!("Invalid Color")
}
}
}
#[cfg(test)]
mod tests {
use super::*;
static TEST_INPUT: &str = r"Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green";
#[test]
fn part1_example() {
assert_eq!(solve_part1(&parse_input(TEST_INPUT)), 8);
}
#[test]
fn part2_example() {
assert_eq!(solve_part2(&parse_input(TEST_INPUT)), 2286);
}
}

219
src/day20.rs Normal file
View File

@@ -0,0 +1,219 @@
use std::collections::{HashMap, VecDeque};
use aoc_runner_derive::{aoc, aoc_generator};
use num::Integer;
#[derive(Debug, Clone)]
enum Module {
FlipFlop { state: bool, dests: Vec<String> },
Conjunction { state: HashMap<String, bool>, dests: Vec<String> },
Broadcast { dests: Vec<String> },
}
#[aoc_generator(day20)]
fn parse(input: &str) -> HashMap<String, Module> {
let mut input: HashMap<_, _> = input.lines().map(|line| {
let (name, dests) = line.split_once("->").unwrap();
let dests = parse_destinations(dests);
let module = parse_module(name.trim(), dests);
(name.trim_matches(['&', '%', ' '].as_slice()).to_string(), module)
}).collect();
collect_inputs(&mut input);
input
}
fn parse_module(name: &str, dests: Vec<String>) -> Module {
match name {
"broadcaster" => Module::Broadcast { dests },
name if name.starts_with('%') => Module::FlipFlop { state: false, dests },
name if name.starts_with('&') => Module::Conjunction { state: HashMap::new(), dests },
_ => panic!("Invalid Module {}", name)
}
}
fn collect_inputs(modules: &mut HashMap<String, Module>) {
for (name, module) in modules.clone() {
let dests = match module {
Module::FlipFlop { state: _, dests: dest } => dest,
Module::Conjunction { state: _, dests: dest } => dest,
Module::Broadcast { dests: dest } => dest,
};
for dest_name in dests {
if let Some(dest_mod) = modules.get_mut(&dest_name) {
match dest_mod {
Module::Conjunction { state, dests: _ } => state.insert(name.to_string(), false),
_ => continue
};
}
}
}
}
fn parse_destinations(dests: &str) -> Vec<String> {
dests.split(',')
.map(|x| x.trim().to_string())
.collect::<Vec<String>>()
}
#[aoc(day20, part1)]
fn part1(modules: &HashMap<String, Module>) -> usize {
let mut modules = modules.clone();
let mut high: usize = 0;
let mut low: usize = 0;
for _ in 0..1000 {
let (high_pulses, low_pulses) = push_the_button(&mut modules);
high += high_pulses;
low += low_pulses;
}
high * low
}
fn push_the_button(modules: &mut HashMap<String, Module>) -> (usize, usize) {
let mut process_queue: VecDeque<(String, bool, String)> = VecDeque::new();
process_queue.push_back(("broadcaster".to_string(), false, "".to_string()));
let mut low_pulses: usize = 0;
let mut high_pulses: usize = 0;
while let Some((module_name, input, sender)) = process_queue.pop_front() {
match input {
true => high_pulses += 1,
false => low_pulses += 1,
}
if let Some(module) = modules.get_mut(&module_name) {
match module {
Module::FlipFlop { state, dests } => {
if !input {
let flipped = !(*state);
*state = flipped;
for dest in dests {
process_queue.push_back((dest.clone(), state.clone(), module_name.clone()));
}
}
},
Module::Conjunction { state, dests } => {
let stored = state.get_mut(&sender.to_string()).unwrap();
*stored = input;
let mut send = true;
if state.values().all(|x| *x) {
send = false;
}
for dest in dests {
process_queue.push_back((dest.clone(), send, module_name.clone()));
}
},
Module::Broadcast { dests } => {
for dest in dests {
process_queue.push_back((dest.clone(), input, module_name.clone()));
}
},
}
}
}
return (high_pulses, low_pulses)
}
#[aoc(day20, part2)]
fn part2(og_modules: &HashMap<String, Module>) -> usize {
let mut lcm = vec![];
let before = ["tr", "xm", "dr", "nh"];
for module_name in before {
let mut modules = og_modules.clone();
let mut count: usize = 1;
while !push_the_button_part2(&mut modules, module_name.to_string()) {
count += 1;
}
lcm.push(count);
}
println!("{:?}", lcm);
let lcm = lcm.iter()
.cloned()
.reduce(|a, b| a.lcm(&b))
.unwrap();
lcm
}
fn push_the_button_part2(modules: &mut HashMap<String, Module>, to_find: String) -> bool {
let mut process_queue: VecDeque<(String, bool, String)> = VecDeque::new();
process_queue.push_back(("broadcaster".to_string(), false, "".to_string()));
while let Some((module_name, input, sender)) = process_queue.pop_front() {
if module_name == to_find && input == false {
return true
}
if let Some(module) = modules.get_mut(&module_name) {
match module {
Module::FlipFlop { state, dests } => {
if !input {
let flipped = !(*state);
*state = flipped;
for dest in dests {
process_queue.push_back((dest.clone(), state.clone(), module_name.clone()));
}
}
},
Module::Conjunction { state, dests } => {
let stored = state.get_mut(&sender.to_string()).unwrap();
*stored = input;
let mut send = true;
if state.values().all(|x| *x) {
send = false;
}
for dest in dests {
process_queue.push_back((dest.clone(), send, module_name.clone()));
}
},
Module::Broadcast { dests } => {
for dest in dests {
process_queue.push_back((dest.clone(), input, module_name.clone()));
}
},
}
}
}
return false
}
#[cfg(test)]
mod tests {
use super::*;
const EX_1: &str = r"broadcaster -> a, b, c
%a -> b
%b -> c
%c -> inv
&inv -> a";
const EX_2: &str = r"broadcaster -> a
%a -> inv, con
&inv -> b
%b -> con
&con -> rx";
#[test]
fn part1_example1() {
assert_eq!(part1(&parse(EX_1)), 32000000);
}
#[test]
fn part1_example2() {
assert_eq!(part1(&parse(EX_2)), 11687500);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX_2)), 1);
}
}

186
src/day21.rs Normal file
View File

@@ -0,0 +1,186 @@
use std::collections::HashSet;
use aoc_runner_derive::{aoc, aoc_generator};
const STEPS: i32 = 64;
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct Position(i32, i32);
#[derive(Debug, PartialEq)]
struct Garden {
rocks: HashSet<Position>,
start: Position,
extents: (Position, Position),
}
#[aoc_generator(day21, part1)]
fn parse(input: &str) -> Garden {
let mut rocks: HashSet<Position> = HashSet::new();
let mut start: Position = Position(0, 0);
for (row, line) in input.lines().enumerate() {
for (col, ch) in line.chars().enumerate() {
match ch {
'#' => {
rocks.insert(Position(row as i32, col as i32));
}
'S' => {
start = Position(row as i32, col as i32);
}
_ => {}
};
}
}
let mut trans_rocks: HashSet<Position> = HashSet::new();
for rock in rocks.iter() {
let trans_rock = Position(rock.0 - start.0, start.1 - rock.1);
trans_rocks.insert(trans_rock);
}
rocks = trans_rocks;
let num_rows = input.lines().count() as i32;
let num_cols = input.lines().next().unwrap().chars().count() as i32;
let extents = (
Position(-num_rows / 2, -num_cols / 2),
Position(num_rows / 2, num_cols / 2),
);
Garden {
rocks,
start: Position(0, 0),
extents,
}
}
#[aoc(day21, part1)]
fn part1(map: &Garden) -> u32 {
let mut visited: HashSet<Position> = HashSet::new();
visited.insert(map.start);
for _ in 0..STEPS {
let mut new_visited = HashSet::new();
for pos in visited.iter().clone() {
let neighbors = [
Position(pos.0 - 1, pos.1),
Position(pos.0 + 1, pos.1),
Position(pos.0, pos.1 - 1),
Position(pos.0, pos.1 + 1),
]
.into_iter()
.filter(|p| in_bounds(*p, map.extents) && !map.rocks.contains(p));
for neighbor in neighbors {
new_visited.insert(neighbor);
}
}
visited = new_visited;
}
visited.len() as u32
}
fn in_bounds(pos: Position, extents: (Position, Position)) -> bool {
pos.0 >= extents.0 .0 && pos.0 <= extents.1 .0 && pos.1 >= extents.0 .1 && pos.1 < extents.1 .1
}
fn in_bounds_part2(pos: Position, extents: Position) -> bool {
pos.0 >= 0 && pos.0 <= extents.0 && pos.1 >= 0 && pos.1 < extents.1
}
struct GardenPart2 {
rocks: HashSet<Position>,
start: Position,
extents: Position,
}
#[aoc_generator(day21, part2)]
fn parse_part2(input: &str) -> GardenPart2 {
let mut rocks: HashSet<Position> = HashSet::new();
for (row, line) in input.lines().enumerate() {
for (col, ch) in line.chars().enumerate() {
match ch {
'#' => {
rocks.insert(Position(row as i32, col as i32));
}
_ => {}
};
}
}
let num_rows = input.lines().count() as i32;
let num_cols = input.lines().next().unwrap().chars().count() as i32;
let mut expanded_rocks: HashSet<Position> = HashSet::new();
for rock in rocks.iter() {
for row_mul in 0..5 {
for col_mul in 0..5 {
let expanded_rock = Position(
rock.0 + (num_rows * row_mul as i32),
rock.1 + (num_cols * col_mul as i32),
);
expanded_rocks.insert(expanded_rock);
}
}
}
GardenPart2 {
rocks: expanded_rocks,
start: Position(num_rows * 5 / 2, num_cols * 5 / 2),
extents: Position(num_rows * 5, num_cols * 5),
}
}
#[aoc(day21, part2)]
fn part2(map: &GardenPart2) -> i64 {
let b0: i64 = walk(&map, 65) as i64;
let b1: i64 = walk(&map, 65 + 131) as i64;
let b2: i64 = walk(&map, 65 + 2 * 131) as i64;
let n: i64 = 202300;
// below uses Cramer's Rule to solve for x0, x1, x2
let det_a: f64 = -2.0;
let det_a0: f64 = -b0 as f64 + 2.0 * b1 as f64 - b2 as f64;
let det_a1: f64 = 3.0 * b0 as f64 - 4.0 * b1 as f64 + b2 as f64;
let det_a2: f64 = -2.0 * b0 as f64;
let x0: i64 = (det_a0 / det_a) as i64;
let x1: i64 = (det_a1 / det_a) as i64;
let x2: i64 = (det_a2 / det_a) as i64;
x0 * n * n + x1 * n + x2
}
fn walk(garden: &GardenPart2, steps: u32) -> u32 {
let mut visited: HashSet<Position> = HashSet::new();
visited.insert(garden.start);
for _ in 0..steps {
let mut new_visited = HashSet::new();
for pos in visited.iter().clone() {
let neighbors = [
Position(pos.0 - 1, pos.1),
Position(pos.0 + 1, pos.1),
Position(pos.0, pos.1 - 1),
Position(pos.0, pos.1 + 1),
]
.into_iter()
.filter(|p| in_bounds_part2(*p, garden.extents) && !garden.rocks.contains(p));
for neighbor in neighbors {
new_visited.insert(neighbor);
}
}
visited = new_visited;
}
visited.len() as u32
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"...........
.....###.#.
.###.##..#.
..#.#...#..
....#.#....
.##..S####.
.##..#...#.
.......##..
.##.#.####.
.##..##.##.
...........";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 16);
}
}

133
src/day22.rs Normal file
View File

@@ -0,0 +1,133 @@
use std::collections::VecDeque;
use aoc_runner_derive::{aoc, aoc_generator};
use regex::Regex;
pub struct Brick {
up: Vec<Vec<usize>>,
down: Vec<Vec<usize>>,
}
#[aoc_generator(day22)]
fn parse(input: &str) -> Brick {
let re: Regex = Regex::new(r"\d+").unwrap();
let mut bricks: Vec<[usize; 6]> = input.lines().map(|line| {
re.captures_iter(line)
.map(|c| c.extract::<0>().0.parse::<usize>().unwrap())
.collect::<Vec<_>>().try_into().unwrap()
}).collect::<Vec<_>>();
let mut heights = [[0; 10]; 10];
let mut indices = [[usize::MAX; 10]; 10];
let mut up = vec![Vec::new(); bricks.len()];
let mut down = vec![Vec::new(); bricks.len()];
bricks.sort_unstable_by_key(|b| b[2]);
for (i, &[x1, y1, z1, x2, y2, z2]) in bricks.iter().enumerate() {
let height = z2 - z1 + 1;
let mut top = 0;
let mut previous = usize::MAX;
for x in x1..=x2 {
for y in y1..=y2 {
top = top.max(heights[x][y]);
}
}
for x in x1..=x2 {
for y in y1..=y2 {
if heights[x][y] == top {
let index = indices[x][y];
if index != previous {
up[index].push(i);
down[i].push(index);
previous = index;
}
}
heights[x][y] = top + height;
indices[x][y] = i;
}
}
}
Brick { up , down }
}
#[aoc(day22, part1)]
fn part1(input: &Brick) -> usize {
let Brick { down, .. } = input;
let mut safe = vec![true; down.len()];
for underneath in down {
if underneath.len() == 1 {
safe[underneath[0]] = false;
}
}
safe.iter().filter(|&&b| b).count()
}
#[aoc(day22, part2)]
fn part2(input: &Brick) -> usize {
let Brick { up, down } = input;
let mut safe = vec![true; down.len()];
for underneath in down {
if underneath.len() == 1 {
safe[underneath[0]] = false;
}
}
let mut result = 0;
let mut todo = VecDeque::new();
let mut removed = vec![usize::MAX; down.len()];
for (start, &safe) in safe.iter().enumerate() {
if safe {
continue;
}
todo.push_back(start);
removed[start] = start;
while let Some(current) = todo.pop_front() {
for &next in &up[current] {
if removed[next] != start && down[next].iter().all(|&i| removed[i] == start) {
result += 1;
removed[next] = start;
todo.push_back(next);
}
}
}
}
result
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"1,0,1~1,2,1
0,0,2~2,0,2
0,2,3~2,2,3
0,0,4~0,2,4
2,0,5~2,2,5
0,1,6~2,1,6
1,1,8~1,1,9";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 5);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 7);
}
}

156
src/day23.rs Normal file
View File

@@ -0,0 +1,156 @@
use std::collections::HashMap;
use aoc_runner_derive::{aoc, aoc_generator};
const NEIGHBORS: &[(i64,i64)] = &[(-1,0),(0,1),(1,0),(0,-1)];
use itertools::Itertools;
#[aoc_generator(day23)]
fn parse(input: &str) -> Vec<Vec<char>> {
input.lines().map(|x| x.chars().collect::<Vec<_>>()).collect::<Vec<_>>()
}
fn dfs(graph: &HashMap<(usize,usize), Vec<(usize,usize,usize)>>, seen: &mut Vec<Vec<bool>>, (r,c): (usize, usize)) -> Option<usize> {
if r == seen.len() - 1 {
return Some(0);
}
let mut max_dist = None;
for &(rr, cc, d) in &graph[&(r,c)] {
if !seen[rr][cc] {
seen[rr][cc] = true;
if let Some(dist) = dfs(graph, seen, (rr,cc)) {
max_dist = Some(max_dist.unwrap_or(0).max(d+dist))
}
seen[rr][cc] = false;
}
}
max_dist
}
#[aoc(day23, part1)]
fn part1(grid: &Vec<Vec<char>>) -> usize {
let mut graph = HashMap::<_,Vec<_>>::new();
for (r, c) in (0..grid.len()).cartesian_product(0..grid[0].len()) {
let neighbors = match grid[r][c] {
'#' => continue,
'.' => NEIGHBORS,
'^' => &NEIGHBORS[0..][..1],
'>' => &NEIGHBORS[1..][..1],
'v' => &NEIGHBORS[2..][..1],
'<' => &NEIGHBORS[3..][..1],
_ => unreachable!(),
};
let e = graph.entry((r,c)).or_default();
for (dr, dc) in neighbors {
let rr = (r as i64 + dr) as usize;
let cc = (c as i64 + dc) as usize;
if grid.get(rr).and_then(|row| row.get(cc)).is_some_and(|&t| t != '#') {
e.push((rr,cc,1));
}
}
}
let corridors = graph.iter()
.filter(|(_, n)| n.len() == 2)
.map(|(&node, _)| node)
.collect::<Vec<_>>();
for (r,c) in corridors {
let neighbors = graph.remove(&(r,c)).unwrap();
let (r1, c1, d1) = neighbors[0];
let (r2, c2, d2) = neighbors[1];
let n1 = graph.get_mut(&(r1,c1)).unwrap();
if let Some(i) = n1.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
n1[i] = (r2,c2,d1+d2);
}
let n2 = graph.get_mut(&(r2,c2)).unwrap();
if let Some(i) = n2.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
n2[i] = (r1,c1,d1+d2);
}
}
dfs(&graph, &mut vec![vec![false; grid[0].len()]; grid.len()], (0,1)).unwrap()
}
#[aoc(day23, part2)]
fn part2(grid: &Vec<Vec<char>>) -> usize {
let mut graph = HashMap::<_,Vec<_>>::new();
for (r, c) in (0..grid.len()).cartesian_product(0..grid[0].len()) {
let neighbors = match grid[r][c] {
'#' => continue,
_ => NEIGHBORS,
};
let e = graph.entry((r,c)).or_default();
for (dr, dc) in neighbors {
let rr = (r as i64 + dr) as usize;
let cc = (c as i64 + dc) as usize;
if grid.get(rr).and_then(|row| row.get(cc)).is_some_and(|&t| t != '#') {
e.push((rr,cc,1));
}
}
}
let corridors = graph.iter()
.filter(|(_, n)| n.len() == 2)
.map(|(&node, _)| node)
.collect::<Vec<_>>();
for (r,c) in corridors {
let neighbors = graph.remove(&(r,c)).unwrap();
let (r1, c1, d1) = neighbors[0];
let (r2, c2, d2) = neighbors[1];
let n1 = graph.get_mut(&(r1,c1)).unwrap();
if let Some(i) = n1.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
n1[i] = (r2,c2,d1+d2);
}
let n2 = graph.get_mut(&(r2,c2)).unwrap();
if let Some(i) = n2.iter().position(|&(rr,cc,_)| (rr,cc) == (r,c)) {
n2[i] = (r1,c1,d1+d2);
}
}
dfs(&graph, &mut vec![vec![false; grid[0].len()]; grid.len()], (0,1)).unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"#.#####################
#.......#########...###
#######.#########.#.###
###.....#.>.>.###.#.###
###v#####.#v#.###.#.###
###.>...#.#.#.....#...#
###v###.#.#.#########.#
###...#.#.#.......#...#
#####.#.#.#######.#.###
#.....#.#.#.......#...#
#.#####.#.#.#########v#
#.#...#...#...###...>.#
#.#.#v#######v###.###v#
#...#.>.#...>.>.#.###.#
#####v#.#.###v#.#.###.#
#.....#...#...#.#.#...#
#.#########.###.#.#.###
#...###...#...#...#.###
###.###.#.###v#####v###
#...#...#.#.>.>.#.>.###
#.###.###.#.###.#.#v###
#.....###...###...#...#
#####################.#";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 94);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 154);
}
}

144
src/day24.rs Normal file
View File

@@ -0,0 +1,144 @@
use std::ops::RangeInclusive;
use aoc_runner_derive::{aoc, aoc_generator};
//const RANGE: RangeInclusive<f64> = 7.0..=27.0;
const RANGE: RangeInclusive<f64> = 200_000_000_000_000.0..=400_000_000_000_000.0;
#[aoc_generator(day24)]
fn parse(input: &str) -> Vec<[f64; 6]> {
let input: Vec<[f64; 6]> = input.lines()
.map(|line| {
line.split("@")
.flat_map(|components| {
components.split(",")
.map(str::trim)
.map(|num| num.parse::<f64>().unwrap())
})
.collect::<Vec<_>>().try_into().unwrap()
}).collect::<Vec<_>>();
input
}
#[aoc(day24, part1)]
fn part1(input: &[[f64; 6]]) -> u32 {
let mut total = 0;
// It's just solve the linear equations. I'm using a matrix.
for i in 1..input.len() {
for j in 0..i {
let [a, b, _, d, e, _] = input[i];
let [g, h, _, j, k, _] = input[j];
let determinant = e * j - d * k;
if determinant == 0.0 {
continue;
}
let t = (j * (h - b) - k * (g - a)) / determinant;
let u = (d * (h - b) - e * (g - a)) / determinant;
let x = a + t * d;
let y = b + t * e;
if t >= 0.0 && u >= 0.0 && RANGE.contains(&x) && RANGE.contains(&y) {
total += 1;
}
}
}
total
}
#[aoc(day24, part2)]
fn part2(input: &[[f64; 6]]) -> f64 {
let [a, b, c, d, e, f] = input[0];
let [g, h, i, j, k, l] = input[1];
let [m, n, o, p, q, r] = input[2];
let mut matrix = [
[0.0, l - f, e - k, 0.0, c - i, h - b, e * c - b * f + h * l - k * i],
[0.0, r - f, e - q, 0.0, c - o, n - b, e * c - b * f + n * r - q * o],
[f - l, 0.0, j - d, i - c, 0.0, a - g, a * f - d * c + j * i - g * l],
[f - r, 0.0, p - d, o - c, 0.0, a - m, a * f - d * c + p * o - m * r],
[k - e, d - j, 0.0, b - h, g - a, 0.0, d * b - a * e + g * k - j * h],
[q - e, d - p, 0.0, b - n, m - a, 0.0, d * b - a * e + m * q - p * n],
];
// Use Gaussian elimination to solve for the 6 unknowns.
// Forward elimination, processing columns from left to right.
// This will leave a matrix in row echelon form.
// That's right, I got a D in applied linear algebra.
for pivot in 0..6 {
// Make leading coefficient of each row positive to make subsequent calculations easier.
for row in &mut matrix[pivot..] {
if row[pivot] < 0.0 {
row.iter_mut().for_each(|num| *num = -*num);
}
}
loop {
let column = matrix.map(|row| row[pivot]);
// If only one non-zero coefficient remaining in the column then we're done.
if column[pivot..].iter().filter(|&&c| c > 0.0).count() == 1 {
// Move this row into the pivot location
let index = column.iter().rposition(|&c| c > 0.0).unwrap();
matrix.swap(pivot, index);
break;
}
// Find the row with the lowest non-zero leading coefficient.
let min = *column[pivot..].iter().filter(|&&c| c > 0.0).min_by(|a, b| a.total_cmp(b)).unwrap();
let index = column.iter().rposition(|&c| c == min).unwrap();
// Subtract as many multiples of this minimum row from each other row as possible
// to shrink the coefficients of our column towards zero.
for row in pivot..6 {
if row != index && column[row] != 0.0 {
let factor = column[row] / min;
for col in pivot..7 {
matrix[row][col] -= factor * matrix[index][col];
}
}
}
}
}
// Back substitution, processing columns from right to left.
// This will leave the matrix in reduced row echelon form.
// The solved unknowns are then in the 7th column.
for pivot in (0..6).rev() {
matrix[pivot][6] /= matrix[pivot][pivot];
for row in 0..pivot {
matrix[row][6] -= matrix[pivot][6] * matrix[row][pivot];
}
}
(matrix[0][6] + matrix[1][6] + matrix[2][6]).floor()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"19, 13, 30 @ -2, 1, -2
18, 19, 22 @ -1, -1, -2
20, 25, 34 @ -2, -2, -4
12, 31, 28 @ -1, -2, -1
20, 19, 15 @ 1, -5, -3";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 2);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 47.0);
}
}

109
src/day25.rs Normal file
View File

@@ -0,0 +1,109 @@
use std::collections::{HashSet, HashMap};
use rand::Rng;
use aoc_runner_derive::{aoc, aoc_generator};
#[derive(Debug, Clone)]
struct Graph {
edges: Vec<(String, String)>,
vertex_count: usize
}
impl Graph {
fn cut(&mut self) -> (usize, usize, usize) {
let mut contracted_edges = self.edges.clone();
let mut contracted_vertex_count = self.vertex_count;
let mut contracted: HashMap<String, Vec<String>> = HashMap::new();
while contracted_vertex_count > 2 {
let random = rand::thread_rng().gen_range(0..contracted_edges.len());
let edge_to_contract = contracted_edges[random].clone();
if contracted.contains_key(&edge_to_contract.0) {
contracted.get_mut(&edge_to_contract.0.clone()).unwrap().push(edge_to_contract.1.clone());
} else {
contracted.insert(edge_to_contract.0.clone(), vec![edge_to_contract.1.clone()]);
}
if contracted.contains_key(&edge_to_contract.1) {
let mut to_append = contracted.clone().get_mut(&edge_to_contract.1).unwrap().clone();
contracted.get_mut(&edge_to_contract.0).unwrap().append(&mut to_append);
contracted.remove(&edge_to_contract.1);
}
let mut new_edges: Vec<(String, String)> = vec![];
for edge in contracted_edges {
if edge.1 == edge_to_contract.1 {
new_edges.push((edge.0.clone(), edge_to_contract.0.clone()));
} else if edge.0 == edge_to_contract.1 {
new_edges.push((edge_to_contract.0.clone(), edge.1.clone()));
} else {
new_edges.push(edge.clone());
}
}
let tmp = new_edges.iter().cloned().filter(|x| x.0 != x.1).collect::<Vec<_>>();
contracted_edges = tmp;
contracted_vertex_count -= 1;
}
let counts = contracted.iter().map(|x| x.1.len() + 1).collect::<Vec<_>>();
return (contracted_edges.len(), counts[0], *counts.last().unwrap());
}
}
#[aoc_generator(day25)]
fn parse(input: &str) -> Graph {
let input = input.lines().flat_map(|line| {
let line = line.split(' ').map(|x| x.trim_end_matches(':').to_string()).collect::<Vec<_>>();
line[1..].iter().cloned().map(|x| (line[0].clone(), x)).collect::<Vec<_>>()
}).collect::<Vec<_>>();
let vertex_count = input.clone().into_iter().flat_map(|x| vec![x.0, x.1]).collect::<HashSet<_>>().len();
Graph {
edges: input,
vertex_count
}
}
#[aoc(day25, part1)]
fn part1(graph: &Graph) -> usize {
let graph = &mut graph.clone();
let mut min_cut = usize::MAX;
let mut count1 = 0;
let mut count2 = 0;
while min_cut != 3 {
(min_cut, count1, count2) = graph.cut();
}
count1 * count2
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"jqt: rhn xhk nvd
rsh: frs pzl lsr
xhk: hfx
cmg: qnr nvd lhk bvb
rhn: xhk bvb hfx
bvb: xhk hfx
pzl: lsr hfx nvd
qnr: nvd
ntq: jqt hfx bvb xhk
nvd: lhk
lsr: lhk
rzs: qnr cmg lsr rsh
frs: qnr lhk lsr";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 54);
}
}

View File

@@ -1,51 +1,22 @@
use std::collections::HashMap;
use std::fs;
use aoc_runner_derive::{aoc, aoc_generator};
use array2d::Array2D;
// pub fn main() {
// let input = fs::read_to_string("input.txt").unwrap();
// let array_2d = get_map(&input);
// // let mut r = Vec::new();
// let mut stars_count: HashMap<(usize, usize), Vec<u32>> = HashMap::new();
// for (y, row_iter) in array_2d.rows_iter().enumerate() {
// let mut checked = false;
// for (x, element) in row_iter.enumerate() {
// let d: char = element.clone();
// if d.is_digit(10) && !checked {
// let star_vec = get_neighboring_star(x, y, &array_2d);
// if !star_vec.is_empty() {
// let (x_star, y_star, _) = star_vec.first().unwrap().clone();
// let key = (x_star, y_star);
// let gear = get_number(x, y, &array_2d);
// if stars_count.contains_key(&key) {
// let mut v: Vec<u32> = stars_count.get(&(x_star, y_star)).unwrap().clone();
// v.push(gear);
// stars_count.insert(key, v);
// } else {
// stars_count.insert(key, vec![gear]);
// }
// checked = true
// }
// } else if !d.is_digit(10) {
// checked = false;
// }
// }
// }
// let r = stars_count.iter().fold(0u32, |acc, (_, gears)| {
// if gears.len() == 2 {
// acc + gears.first().unwrap() * gears.last().unwrap()
// } else {
// acc
// }
// });
#[aoc_generator(day3)]
fn parse(input: &str) -> Array2D<char> {
let rows: Vec<&str> = input.split("\n").collect();
let mut array = Vec::new();
for row in rows {
let row_vec: Vec<char> = row.chars().collect();
array.push(row_vec);
}
// println!("{}", r);
// }
Array2D::from_rows(&array).unwrap()
}
pub fn main() {
let input = fs::read_to_string("input.txt").unwrap();
let array_2d = get_map(&input);
#[aoc(day3, part1)]
fn part1(array_2d: &Array2D<char>) -> u32 {
let mut r = 0;
for (y, row_iter) in array_2d.rows_iter().enumerate() {
let mut checked = false;
@@ -63,18 +34,7 @@ pub fn main() {
}
}
println!("{}", r);
}
fn get_map(input: &str) -> Array2D<char> {
let rows: Vec<&str> = input.split("\n").collect();
let mut array = Vec::new();
for row in rows {
let row_vec: Vec<char> = row.chars().collect();
array.push(row_vec);
}
Array2D::from_rows(&array).unwrap()
r
}
fn get_number(x: usize, y: usize, array2d: &Array2D<char>) -> u32 {
@@ -130,31 +90,10 @@ fn get_neighbors(x: usize, y: usize, array2d: &Array2D<char>) -> Vec<&char> {
.collect()
}
fn get_neighboring_star(x: usize, y: usize, array2d: &Array2D<char>) -> Vec<(usize, usize, Option<&char>)> {
let mut neighbors: Vec<(usize, usize, Option<&char>)> = Vec::new();
neighbors.push((x.checked_add(1).unwrap(), y, array2d.get(y, x.checked_add(1).unwrap())));
if x > 0 {
neighbors.push((x.checked_sub(1).unwrap(), y, array2d.get(y, x.checked_sub(1).unwrap())));
neighbors.push((x.checked_sub(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_sub(1).unwrap())));
}
if y > 0 {
neighbors.push((x, y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x)));
neighbors.push((x.checked_add(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_add(1).unwrap())));
}
if x > 0 && y > 0 {
neighbors.push((x.checked_sub(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_sub(1).unwrap())));
}
neighbors.push((x, y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x)));
neighbors.push((x.checked_add(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_add(1).unwrap())));
neighbors
.into_iter()
.filter(|(_, _, c)| c.is_some() && c.unwrap() == &'*')
.collect::<Vec<(usize, usize, Option<&char>)>>()
}
pub fn part_two(input: &str) -> Option<u32> {
let array_2d = get_map(input);
#[aoc(day3, part2)]
fn part2(array_2d: &Array2D<char>) -> u32 {
// let mut r = Vec::new();
let mut stars_count: HashMap<(usize, usize), Vec<u32>> = HashMap::new();
for (y, row_iter) in array_2d.rows_iter().enumerate() {
@@ -189,5 +128,54 @@ pub fn part_two(input: &str) -> Option<u32> {
}
});
Some(r)
r
}
fn get_neighboring_star(x: usize, y: usize, array2d: &Array2D<char>) -> Vec<(usize, usize, Option<&char>)> {
let mut neighbors: Vec<(usize, usize, Option<&char>)> = Vec::new();
neighbors.push((x.checked_add(1).unwrap(), y, array2d.get(y, x.checked_add(1).unwrap())));
if x > 0 {
neighbors.push((x.checked_sub(1).unwrap(), y, array2d.get(y, x.checked_sub(1).unwrap())));
neighbors.push((x.checked_sub(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_sub(1).unwrap())));
}
if y > 0 {
neighbors.push((x, y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x)));
neighbors.push((x.checked_add(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_add(1).unwrap())));
}
if x > 0 && y > 0 {
neighbors.push((x.checked_sub(1).unwrap(), y.checked_sub(1).unwrap(), array2d.get(y.checked_sub(1).unwrap(), x.checked_sub(1).unwrap())));
}
neighbors.push((x, y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x)));
neighbors.push((x.checked_add(1).unwrap(), y.checked_add(1).unwrap(), array2d.get(y.checked_add(1).unwrap(), x.checked_add(1).unwrap())));
neighbors
.into_iter()
.filter(|(_, _, c)| c.is_some() && c.unwrap() == &'*')
.collect::<Vec<(usize, usize, Option<&char>)>>()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 4361);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 467835);
}
}

93
src/day4.rs Normal file
View File

@@ -0,0 +1,93 @@
use std::collections::VecDeque;
#[aoc_generator(day4)]
fn parse(input: &str) -> Vec<Vec<Vec<i32>>> {
let input: Vec<Vec<Vec<i32>>> = input.lines()
.map(|card| &card[(card.find(':').unwrap() + 1)..])
.map(|card| card.trim())
.map(|card| {
card.split('|')
.map(|numbers| {
numbers.split_whitespace()
.map(|num| num.parse::<i32>().unwrap())
.collect::<Vec<_>>()
}).collect::<Vec<_>>()
}).collect::<Vec<_>>();
input
}
#[aoc(day4, part1)]
fn part1(input: &Vec<Vec<Vec<i32>>>) -> i32 {
let mut total_pts = 0;
for card in input {
let mut card_pts = 0;
let winning = card.first().unwrap();
let ours = card.last().unwrap();
for num in ours {
if winning.contains(num) {
if card_pts == 0 {
card_pts = 1;
} else {
card_pts *= 2;
}
}
}
total_pts += card_pts;
}
total_pts
}
#[aoc(day4, part2)]
fn part2(input: &Vec<Vec<Vec<i32>>>) -> i32 {
let mut queue = VecDeque::from((0..input.len()).collect::<Vec<usize>>());
let mut total_cards = 0;
while !queue.is_empty() {
let card_num = queue.pop_front().unwrap();
let card = input.get(card_num).unwrap();
total_cards += 1;
let mut dup_cards = 0;
let winning_nums = card.first().unwrap();
let our_nums = card.last().unwrap();
for num in our_nums {
if winning_nums.contains(num) {
dup_cards += 1;
}
}
for card in (card_num + 1)..=(card_num + dup_cards) {
if card < input.len() {
queue.push_back(card);
}
}
}
total_cards
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53
Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19
Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1
Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83
Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36
Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 13);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 30);
}
}

136
src/day5.rs Normal file
View File

@@ -0,0 +1,136 @@
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day5)]
fn parse(input: &str) -> Vec<Vec<Vec<i64>>> {
let mappers: Vec<Vec<Vec<i64>>> = input.split("\n\n")
.map(|maps| &maps[(maps.find(':').unwrap() + 1)..])
.map(|maps| maps.trim())
.map(|maps| {
maps.split('\n')
.map(|range| {
range.split(' ')
.map(|num| num.parse::<i64>().unwrap())
.collect::<Vec<_>>()
})
.collect::<Vec<_>>()
})
.collect();
mappers
}
#[aoc(day5, part1)]
fn part1(mappers: &Vec<Vec<Vec<i64>>>) -> i64 {
let seeds = mappers.first().unwrap().first().unwrap().clone();
let mut borrow_work_around: Vec<Vec<Vec<i64>>> = Vec::new();
mappers.clone_into(&mut borrow_work_around);
let mappers: &mut [Vec<Vec<i64>>] = &mut borrow_work_around.get_mut(1..).unwrap();
for mapper in mappers.into_iter() {
for range in mapper {
range[2] = range[1] + range[2] - 1;
}
}
let mut cur_vals: Vec<_> = seeds;
for mapper in mappers {
for val in cur_vals.iter_mut() {
for range in mapper.into_iter() {
if range[1] <= *val && *val <= range[2] {
let diff = *val - range[1];
*val = range[0] + diff;
break;
}
}
}
}
cur_vals.into_iter().min().unwrap()
}
#[aoc(day5, part2)]
fn part2(mappers: &Vec<Vec<Vec<i64>>>) -> i64 {
let seeds = mappers.first().unwrap().first().unwrap().clone();
let mut borrow_work_around: Vec<Vec<Vec<i64>>> = Vec::new();
mappers.clone_into(&mut borrow_work_around);
let mappers: &mut [Vec<Vec<i64>>] = &mut borrow_work_around.get_mut(1..).unwrap();
for mapper in mappers.into_iter() {
for range in mapper {
range[2] = range[1] + range[2] - 1;
}
}
let mut cur_vals: Vec<_> = Vec::new();
for i in 0..seeds.len() / 2 {
let end = seeds[i * 2] + seeds[(i * 2) + 1];
let mut range: Vec<_> = (seeds[i * 2]..end).collect();
cur_vals.append(&mut range);
}
println!("{}", cur_vals.len());
for mapper in mappers {
for val in cur_vals.iter_mut() {
println!("{}", val);
for range in mapper.into_iter() {
if range[1] <= *val && *val <= range[2] {
let diff = *val - range[1];
*val = range[0] + diff;
break;
}
}
}
}
cur_vals.into_iter().min().unwrap()
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"seeds: 79 14 55 13
seed-to-soil map:
50 98 2
52 50 48
soil-to-fertilizer map:
0 15 37
37 52 2
39 0 15
fertilizer-to-water map:
49 53 8
0 11 42
42 0 7
57 7 4
water-to-light map:
88 18 7
18 25 70
light-to-temperature map:
45 77 23
81 45 19
68 64 13
temperature-to-humidity map:
0 69 1
1 0 69
humidity-to-location map:
60 56 37
56 93 4";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 35);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 46);
}
}

80
src/day6.rs Normal file
View File

@@ -0,0 +1,80 @@
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day6, part1)]
fn parse(input: &str) -> Vec<Vec<i32>> {
let input: Vec<Vec<i32>> = input.split('\n') // Separate the Time and Distance lines
.map(|line| {
line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
.split_whitespace() // Split the numbers into their own elements.
.map(|num| num.parse::<i32>().expect("Couldn't parse number")) // Parse numbers into i32
.collect::<Vec<_>>()
}).collect::<Vec<_>>(); // collect into Vec
input
}
#[aoc(day6, part1)]
fn part1(input: &Vec<Vec<i32>>) -> i32 {
let mut valid_total = 1;
for round in 0..input.first().unwrap().len() {
let time = input[0][round];
let dist = input[1][round];
let mut valid = 0;
for remaining_time in 0..time {
if (time - remaining_time) * remaining_time > dist {
valid += 1;
}
}
valid_total *= valid;
}
valid_total
}
#[aoc_generator(day6, part2)]
fn parse_part2(input: &str) -> Vec<i64> {
let input: Vec<i64> = input.split('\n') // Separate the Time and Distance lines
.map(|line| {
line[line.find(':').unwrap() + 1..] // Drop "Time:" and "Distance:"
.split_whitespace() // Split the numbers into their own elements
.flat_map(|s| s.chars()).collect::<String>() // Combine the strings into a single one
.parse::<i64>().expect("Couldn't parse number") // Parse numbers into i32
}).collect(); // Collect into Vec
input
}
#[aoc(day6, part2)]
fn part2(input: &Vec<i64>) -> i32 {
let time = input[0];
let dist = input[1];
let mut valid = 0;
for remaining_time in 0..time {
if (time - remaining_time) * remaining_time > dist {
valid += 1;
}
}
valid
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"Time: 7 15 30
Distance: 9 40 200";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 288);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse_part2(EX)), 71503);
}
}

207
src/day7.rs Normal file
View File

@@ -0,0 +1,207 @@
use std::collections::HashMap;
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day7)]
fn parse(input: &str) -> Vec<Vec<String>> {
let input: Vec<Vec<String>> = input.split('\n')
.map(|line| line.split(' ').map(|x| x.into()).collect::<Vec<String>>())
.collect::<Vec<_>>();
input
}
#[aoc(day7, part1)]
fn part1(input: &Vec<Vec<String>>) -> usize {
let mut tmp: Vec<Vec<String>> = Vec::new();
input.clone_into(&mut tmp);
let mut input = tmp;
for line in 0..input.len() {
let hand = &input[line][0];
let mut card_freq: HashMap<char, i16> = HashMap::new();
for card in hand.chars() {
card_freq.entry(card)
.and_modify(|count| *count += 1)
.or_insert(1);
}
let mut set_count: HashMap<i16, i16> = HashMap::new();
for i in 1..=5 {
let card_count = card_freq.values().filter(|x| **x == i).count().try_into().unwrap();
if card_count != 0 {
set_count.insert(i, card_count);
}
}
let power = match set_count {
x if x.contains_key(&5) => "7",
x if x.contains_key(&4) => "6",
x if x.contains_key(&3) && x.contains_key(&2) => "5",
x if x.contains_key(&3) => "4",
x if x.get(&2).unwrap_or(&0) >= &2 => "3",
x if x.get(&2).unwrap_or(&0) == &1 => "2",
HashMap { .. } => "1"
};
input[line].push(power.into());
}
input.sort_by(|lhs, rhs| {
let lhs_power: i32 = lhs[2].parse().unwrap();
let rhs_power: i32 = rhs[2].parse().unwrap();
if lhs_power != rhs_power {
return lhs_power.cmp(&rhs_power);
}
let lhs_hand: Vec<i32> = lhs[0].chars().map(card_value).collect();
let rhs_hand: Vec<i32> = rhs[0].chars().map(card_value).collect();
for i in 0..5 {
if lhs_hand[i] == rhs_hand[i] { continue; }
return lhs_hand[i].cmp(&rhs_hand[i]);
}
panic!("Should not be reachable");
});
let mut total_winnings = 0;
for i in 0..input.len() {
let bid: usize = input[i][1].parse().unwrap();
total_winnings += (i + 1) * bid;
}
total_winnings
}
fn card_value(card: char) -> i32 {
match card {
'A' => 13,
'K' => 12,
'Q' => 11,
'J' => 10,
'T' => 9,
'9' => 8,
'8' => 7,
'7' => 6,
'6' => 5,
'5' => 4,
'4' => 3,
'3' => 2,
'2' => 1,
_ => panic!("invalid card")
}
}
#[aoc(day7, part2)]
fn part2(input: &Vec<Vec<String>>) -> usize {
let mut tmp: Vec<Vec<String>> = Vec::new();
input.clone_into(&mut tmp);
let mut input = tmp;
for line in 0..input.len() {
let hand = &input[line][0];
if hand == "JJJJJ" {
input[line].push("7".to_string());
continue;
}
let mut card_freq: HashMap<char, i16> = HashMap::new();
let joker_count: i16 = hand.chars().filter(|c| c == &'J').count().try_into().unwrap();
for card in hand.chars().filter(|c| c != &'J') {
card_freq.entry(card)
.and_modify(|count| *count += 1)
.or_insert(1);
}
// The most helpful place for the jokers will always be with the max card count
let max = card_freq.clone().into_iter().max_by(|a, b| a.1.cmp(&b.1)).unwrap();
card_freq.entry(max.0)
.and_modify(|count| *count += joker_count);
let mut set_count: HashMap<i16, i16> = HashMap::new();
for i in 1..=5 {
let card_count = card_freq.values().filter(|x| **x == i).count().try_into().unwrap();
if card_count != 0 {
set_count.insert(i, card_count);
}
}
let power = match set_count {
x if x.contains_key(&5) => "7",
x if x.contains_key(&4) => "6",
x if x.contains_key(&3) && x.contains_key(&2) => "5",
x if x.contains_key(&3) => "4",
x if x.get(&2).unwrap_or(&0) >= &2 => "3",
x if x.get(&2).unwrap_or(&0) == &1 => "2",
HashMap { .. } => "1"
};
input[line].push(power.to_string());
}
input.sort_by(|lhs, rhs| {
let lhs_power: i32 = lhs[2].parse().unwrap();
let rhs_power: i32 = rhs[2].parse().unwrap();
if lhs_power != rhs_power {
return lhs_power.cmp(&rhs_power);
}
let lhs_hand: Vec<i32> = lhs[0].chars().map(card_value_pt2).collect();
let rhs_hand: Vec<i32> = rhs[0].chars().map(card_value_pt2).collect();
for i in 0..5 {
if lhs_hand[i] == rhs_hand[i] { continue; }
return lhs_hand[i].cmp(&rhs_hand[i]);
}
panic!("Should not be reachable");
});
let mut total_winnings = 0;
for i in 0..input.len() {
let bid: usize = input[i][1].parse().unwrap();
total_winnings += (i + 1) * bid;
}
total_winnings
}
fn card_value_pt2(card: char) -> i32 {
match card {
'A' => 13,
'K' => 12,
'Q' => 11,
'T' => 10,
'9' => 9,
'8' => 8,
'7' => 7,
'6' => 6,
'5' => 5,
'4' => 4,
'3' => 3,
'2' => 2,
'J' => 1,
_ => panic!("invalid card")
}
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"32T3K 765
T55J5 684
KK677 28
KTJJT 220
QQQJA 483";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 6440);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 5905);
}
}

150
src/day8.rs Normal file
View File

@@ -0,0 +1,150 @@
use std::collections::{HashMap, VecDeque};
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day8)]
fn parse(input: &str) -> (Vec<Direction>, HashMap<String, (String, String)>) {
let input: Vec<_> = input.split("\n\n").collect();
let (directions, nodes) = (input[0], input[1]);
let directions: Vec<Direction> = directions.chars().map(|char| {
match char {
'L' => Direction::Left,
'R' => Direction::Right,
_ => panic!("Invalid direction!")
}
}).collect::<Vec<_>>();
let nodes: HashMap<String, (String, String)> = nodes.split('\n')
.map(|line| {
let line = line.split('=').map(|x| x.trim()).collect::<Vec<_>>();
let children = line[1].trim_matches(|c| c == '(' || c == ')').split(", ").collect::<Vec<_>>();
(line[0].into(), (children[0].into(), children[1].into()))
}).collect();
(directions, nodes)
}
#[derive(Debug, Clone)]
enum Direction {
Left,
Right
}
#[aoc(day8, part1)]
fn part1((directions, nodes): &(Vec<Direction>, HashMap<String, (String, String)>)) -> i64 {
let mut cur_node = "AAA";
let mut step_queue = VecDeque::from(directions.clone());
let mut step_count = 0;
while cur_node != "ZZZ" {
step_count += 1;
let cur_step = step_queue.pop_front().unwrap();
match cur_step {
Direction::Left => cur_node = &nodes[cur_node].0,
Direction::Right => cur_node = &nodes[cur_node].1,
}
step_queue.push_back(cur_step);
}
println!("{}", step_count);
step_count
}
#[aoc(day8, part2)]
fn part2((directions, nodes): &(Vec<Direction>, HashMap<String, (String, String)>)) -> i64 {
let starts: Vec<_> = nodes.keys().filter(|x| x.ends_with('A')).collect();
let dists: Vec<_> = starts.iter().map(|start| dist(&start, &directions, nodes)).collect();
let gcf = gcf(&dists);
let step_count = gcf * dists.iter().map(|value| value / gcf).product::<i64>();
step_count
}
fn gcf(values: &Vec<i64>) -> i64 {
let mut gcf = values[0];
for val in values {
gcf = find_gcf(gcf, *val);
if gcf == 1 {
return 1;
}
}
gcf
}
fn find_gcf(a: i64, b: i64) -> i64 {
if a == 0 {
return b;
}
find_gcf(b % a, a)
}
fn dist(cur_node: &str, directions: &Vec<Direction>, nodes: &HashMap<String, (String, String)>) -> i64 {
let mut cur_node = cur_node;
let mut step_queue: VecDeque<Direction> = VecDeque::from(directions.clone());
let mut step_count = 0;
while !cur_node.ends_with('Z') {
step_count += 1;
let cur_step = step_queue.pop_front().unwrap();
match cur_step {
Direction::Left => cur_node = &nodes[cur_node].0,
Direction::Right => cur_node = &nodes[cur_node].1,
}
step_queue.push_back(cur_step);
}
return step_count;
}
#[cfg(test)]
mod tests {
use super::*;
const EX_1: &str = r"RL
AAA = (BBB, CCC)
BBB = (DDD, EEE)
CCC = (ZZZ, GGG)
DDD = (DDD, DDD)
EEE = (EEE, EEE)
GGG = (GGG, GGG)
ZZZ = (ZZZ, ZZZ)";
const EX_2: &str = r"LLR
AAA = (BBB, BBB)
BBB = (AAA, ZZZ)
ZZZ = (ZZZ, ZZZ)";
const EX_3: &str = r"LR
11A = (11B, XXX)
11B = (XXX, 11Z)
11Z = (11B, XXX)
22A = (22B, XXX)
22B = (22C, 22C)
22C = (22Z, 22Z)
22Z = (22B, 22B)
XXX = (XXX, XXX)";
#[test]
fn part1_example1() {
assert_eq!(part1(&parse(EX_1)), 2);
}
#[test]
fn part1_example2() {
assert_eq!(part1(&parse(EX_2)), 6);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX_3)), 6);
}
}

85
src/day9.rs Normal file
View File

@@ -0,0 +1,85 @@
use aoc_runner_derive::{aoc, aoc_generator};
#[aoc_generator(day9)]
fn parse(input: &str) -> Vec<Vec<i64>> {
let input: Vec<_> = input.split('\n')
.map(|line| {
line.split_whitespace()
.map(|num| num.parse::<i64>().unwrap())
.collect::<Vec<_>>()
}).collect();
input
}
#[aoc(day9, part1)]
fn part1(input: &Vec<Vec<i64>>) -> i64 {
let mut total = 0;
for line in input {
let mut line_enders: Vec<i64> = vec![*line.last().unwrap()];
let mut cur_line: Vec<i64> = line.to_vec();
while !cur_line.iter().all(|x| *x == 0) {
let mut next_line: Vec<i64> = vec![];
for i in 1..cur_line.len() {
let diff = cur_line[i] - cur_line[i-1];
next_line.push(diff)
}
line_enders.push(*next_line.last().unwrap());
cur_line = next_line;
}
let mut sum = 0;
for i in (1..line_enders.len()).rev() {
sum = sum + line_enders[i - 1];
}
total += sum;
}
total
}
#[aoc(day9, part2)]
fn part2(input: &Vec<Vec<i64>>) -> i64 {
let mut total = 0;
for line in input {
let mut line_starters: Vec<i64> = vec![*line.first().unwrap()];
let mut cur_line: Vec<i64> = line.to_vec();
while !cur_line.iter().all(|x| *x == 0) {
let mut next_line: Vec<i64> = vec![];
for i in 1..cur_line.len() {
let diff = cur_line[i] - cur_line[i-1];
next_line.push(diff)
}
line_starters.push(*next_line.first().unwrap());
cur_line = next_line;
}
let mut sum = 0;
for i in (1..line_starters.len()).rev() {
sum = line_starters[i - 1] - sum;
}
total += sum;
}
total
}
#[cfg(test)]
mod tests {
use super::*;
const EX: &str = r"0 3 6 9 12 15
1 3 6 10 15 21
10 13 16 21 30 45";
#[test]
fn part1_example() {
assert_eq!(part1(&parse(EX)), 114);
}
#[test]
fn part2_example() {
assert_eq!(part2(&parse(EX)), 2);
}
}

33
src/lib.rs Normal file
View File

@@ -0,0 +1,33 @@
mod day25;
mod day24;
mod day23;
mod day22;
mod day21;
mod day20;
mod day19;
mod day18;
mod day17;
mod day16;
mod day15;
mod day14;
mod day13;
mod day12;
mod day11;
mod day10;
mod day9;
mod day8;
mod day7;
mod day6;
mod day5;
mod day4;
mod day3;
mod day2;
mod day1;
extern crate aoc_runner;
#[macro_use]
extern crate aoc_runner_derive;
extern crate crypto;
aoc_lib!{ year = 2023 }

7
src/main.rs Normal file
View File

@@ -0,0 +1,7 @@
extern crate advent_of_code_2023;
extern crate aoc_runner_derive;
extern crate aoc_runner;
use aoc_runner_derive::aoc_main;
aoc_main! { lib = advent_of_code_2023 }