Compare commits
39 Commits
c5a765e487
...
main
Author | SHA1 | Date | |
---|---|---|---|
50472363cf | |||
2c4288de42 | |||
14c6da72d9 | |||
bdc150d0ed | |||
b802cf1d16 | |||
9db0e3f054 | |||
a19a3258c2 | |||
d3c11dcbed | |||
e3f0f932e4 | |||
8b3bbab954 | |||
05a71ce349 | |||
6e0f7b3c2f | |||
e0655bd700 | |||
7e082e6558 | |||
4e494e5596 | |||
0645f39e51 | |||
831d97d5b4 | |||
1c4bf97e07 | |||
593851daee | |||
c3849c1ad4 | |||
4980b285e8 | |||
bece6b708b | |||
97d8acbad8 | |||
ffb43d4860 | |||
be7ca6666d | |||
39633cc659 | |||
51c64d827b | |||
5a87bfb681 | |||
78aab8ab5e | |||
8a40f62cf6 | |||
f9095fdf8f | |||
4984ad4801 | |||
2c3840f65a | |||
9fd55c3aac | |||
d5395fc349 | |||
7dec743fbb | |||
906b5c7254 | |||
4a20a35c2d | |||
8272d3b62c |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1 +1,6 @@
|
||||
target
|
||||
input/
|
||||
|
||||
# Added by cargo
|
||||
|
||||
/target
|
||||
|
504
Cargo.lock
generated
Normal file
504
Cargo.lock
generated
Normal 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
20
Cargo.toml
Normal 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
7
day1/Cargo.lock
generated
@@ -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"
|
@@ -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]
|
1000
day1/input.txt
1000
day1/input.txt
File diff suppressed because it is too large
Load Diff
7
day2/Cargo.lock
generated
7
day2/Cargo.lock
generated
@@ -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"
|
@@ -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]
|
100
day2/input.txt
100
day2/input.txt
@@ -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
|
@@ -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
16
day3/Cargo.lock
generated
@@ -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",
|
||||
]
|
@@ -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"
|
140
day3/input.txt
140
day3/input.txt
@@ -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
7
day4/Cargo.lock
generated
@@ -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"
|
@@ -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]
|
215
day4/input.txt
215
day4/input.txt
@@ -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
|
@@ -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
7
day5/Cargo.lock
generated
@@ -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"
|
@@ -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]
|
238
day5/input.txt
238
day5/input.txt
@@ -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
|
@@ -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
7
day6/Cargo.lock
generated
@@ -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"
|
@@ -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]
|
@@ -1,2 +0,0 @@
|
||||
Time: 63 78 94 68
|
||||
Distance: 411 1274 2047 1035
|
@@ -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);
|
||||
// }
|
@@ -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
190
src/day10.rs
Normal 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
144
src/day11.rs
Normal 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
155
src/day12.rs
Normal 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
113
src/day13.rs
Normal 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
159
src/day14.rs
Normal 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
93
src/day15.rs
Normal 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
211
src/day16.rs
Normal 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
115
src/day17.rs
Normal 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
187
src/day18.rs
Normal 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
245
src/day19.rs
Normal 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
114
src/day2.rs
Normal 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
219
src/day20.rs
Normal 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
186
src/day21.rs
Normal 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
133
src/day22.rs
Normal 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
156
src/day23.rs
Normal 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
144
src/day24.rs
Normal 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
109
src/day25.rs
Normal 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);
|
||||
}
|
||||
}
|
@@ -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
93
src/day4.rs
Normal 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
136
src/day5.rs
Normal 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
80
src/day6.rs
Normal 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
207
src/day7.rs
Normal 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
150
src/day8.rs
Normal 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
85
src/day9.rs
Normal 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
33
src/lib.rs
Normal 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
7
src/main.rs
Normal 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 }
|
Reference in New Issue
Block a user