Compare commits

..

73 Commits

Author SHA1 Message Date
fc803d8a0f Day 24 part 2. 2023-11-14 19:35:00 +01:00
3a9379f877 Day 24 part 1. 2023-11-14 18:48:45 +01:00
241c417a77 intermediate 2023-11-14 16:56:16 +01:00
4cbe831115 Removed warnings. 2023-11-14 16:41:54 +01:00
a4c33ae3d2 Day 21 part 2. Shitty bitty. 2023-11-13 23:22:51 +01:00
48ad7e7a96 Day 21 part 1. 2023-11-13 19:52:52 +01:00
caf307bf2d Day 19 part 2 (manually reverse engineered the assembler instructions). 2023-11-12 23:12:46 +01:00
2792304040 Day 19 part 1. 2023-11-12 21:25:31 +01:00
42ead11aa0 Day 16 part 2. 2023-11-12 19:15:31 +01:00
8e1f42205c Day 16 part 1. 2023-11-12 16:14:45 +01:00
c4ae25d579 Updated dependencies. 2023-11-12 12:36:02 +01:00
f472ace665 Day 25 part 1. 2023-11-10 21:15:00 +01:00
a9b3c90a6c Fixed compiler warnings. 2023-11-10 19:17:51 +01:00
30ef81cfac Day 18 part 2 2023-05-27 01:45:15 +02:00
861e31efee Day 18 part 1 2023-05-27 01:00:21 +02:00
d6c728ccfe Day 17 part 2 2023-05-26 22:25:26 +02:00
8bc589488c Day 17 part 1 2023-05-26 22:23:19 +02:00
cfb3ae497e Reformatted 2023-05-26 10:02:22 +02:00
b922b808fc Day 17 stuff 2023-05-26 10:02:17 +02:00
5c4e9a9e9d Day 17 parsing 2023-05-25 23:01:57 +02:00
b480601ee8 clippy fixes
clippy fixes #2

clippy fixed #3

removed unnecessary stuff
2023-05-20 23:28:37 +02:00
ef2340eaae Migrated to rust edition 2021 2023-05-20 22:39:07 +02:00
Johannes
b2a5da3222 day23 part 2 correct intersection test (speed up by factor 2, yay!) 2019-01-03 11:43:38 +01:00
Johannes
9cbbf63eb1 day23 part 2 (with a shortcut that could potentially break some cases)
I'm only using a lower bound on the number of intersections a cube has.
2019-01-01 18:40:00 +01:00
Johannes
c162fcb6d9 day24 p1 wrong (example ok) 2018-12-29 16:43:39 +01:00
Johannes
097cfac516 day24 part1 input parsing 2018-12-26 23:30:39 +01:00
Johannes
2b51e67fc6 day23 hmmm 2018-12-26 22:27:36 +01:00
Johannes
6e438127ec day23 part1 2018-12-25 17:15:51 +01:00
Johannes
21dfc7f630 day22 little speed improvement 2018-12-25 14:32:50 +01:00
Johannes
719db128cf day22 with hashmaps
slower, but more flexible
2018-12-25 14:04:03 +01:00
Johannes
12f32ed232 removed warnings 2018-12-25 14:03:45 +01:00
Johannes
768d328e87 day22 2nd part 2018-12-24 17:19:50 +01:00
Johannes
31075fa449 day22 refactored part1 into extra struct 2018-12-24 15:49:00 +01:00
Johannes
d5aa1ddc74 day22 part1 2018-12-22 15:07:46 +01:00
Johannes Schaefer
8badd4a416 day20 part 2 2018-12-21 11:26:21 +01:00
Johannes
241ca8ea18 day20 part1 fast 2018-12-21 10:32:11 +01:00
Johannes
a35881fb01 day20 part 1 super slow 2018-12-21 10:03:06 +01:00
Johannes
0438a052d2 day20 WIP 2018-12-20 10:19:41 +01:00
Johannes
ba622fd408 day15 part 2 optimized
instead of senselessly trying to find the best starting point, just rely
on the order of neighbor point generation. Since we use a queue
to manage open points and he neighbors are added in the correct
order, they neighbor that has precedence due to reading order will
automatically be the one to be predecessor on a final path, if he is on
a shortest path.
2018-12-18 22:43:10 +01:00
Johannes
cef96d55be day15 part 2 2018-12-18 22:20:03 +01:00
Johannes
3f2ff6e5a2 day15 part1 done 2018-12-18 19:11:55 +01:00
Johannes Schaefer
ac3a741f0d day15 part1 combat with errors 2018-12-18 17:46:44 +01:00
Johannes Schaefer
2bf8edf315 day15 part1 movement 2018-12-18 16:59:41 +01:00
Johannes Schaefer
6f2e046080 day14 both parts 2018-12-17 17:45:35 +01:00
Johannes Schaefer
6f9ca4dfb6 2018-12-17 11:06:12 +01:00
Johannes
807bff7977 day13 part2 2018-12-16 01:37:37 +01:00
Johannes
c1c761f2ba day13 part 1 2018-12-16 01:14:09 +01:00
Johannes Schaefer
2fa6c40f33 day12 part 1 2018-12-14 14:09:57 +01:00
Johannes Schaefer
54103e8fa6 day11 part2 fast 2018-12-11 16:02:22 +01:00
Johannes Schaefer
fc328d82af day11 part2 2018-12-11 11:37:32 +01:00
Johannes Schaefer
267dfb8068 day11 part 1 2018-12-11 11:25:57 +01:00
Johannes
6d4bdccc6e day10 part 2 2018-12-11 09:35:19 +01:00
Johannes
4eb90ac047 day10 part 1 2018-12-10 20:51:13 +01:00
Johannes Schaefer
2cf9933300 day09 part 2 2018-12-10 15:16:06 +01:00
Johannes Schaefer
e5a3a1458a day09 part 1 2018-12-10 13:10:09 +01:00
Johannes Schaefer
d84e3bff27 day08 part 2 2018-12-09 21:34:43 +01:00
Johannes Schaefer
51418b709e day08 part 1 2018-12-09 21:17:29 +01:00
Johannes Schaefer
4946263a37 day07-1 2018-12-07 11:17:48 +01:00
Johannes Schaefer
cd16a42821 push to edition 2018 2018-12-07 09:53:18 +01:00
Johannes Schaefer
5ab8409b5b day06 both 2018-12-06 09:50:35 +01:00
Johannes
5fa344dd55 day05 part 2 prealloc vectors 2018-12-05 20:53:00 +01:00
Johannes Schaefer
d10d36498c day05 performance push part 2 through more efficient case insensitive comparison 2018-12-05 15:19:12 +01:00
Johannes Schaefer
32843531f8 take times 2018-12-05 15:15:18 +01:00
Johannes Schaefer
50cd1d6b00 removed comments 2018-12-05 10:50:27 +01:00
Johannes Schaefer
40957e1252 day05 both parts fast 2018-12-05 10:49:52 +01:00
Johannes
6e92d937a9 day05 part 1 (2 WIP) 2018-12-05 08:44:50 +01:00
Johannes
baacb780ba day04 both 2018-12-04 20:15:20 +01:00
Johannes
43ce26593e day03 both 2018-12-04 18:06:01 +01:00
Johannes
088179a007 day02-2 super-fast 2018-12-02 19:12:01 +01:00
Johannes
062c30ece4 day02-2 linear 2018-12-02 14:25:46 +01:00
Johannes
b89e4f4929 day02 both 2018-12-02 09:17:23 +01:00
Johannes
a0509342ae day01-2 use scan with tuple expansion
The previous problem with this was, that I tried returning
"Some((Ref<i32>, _))" from the lambda. That caused the compiler to complain
about the lifetime of the `current` value, since I tried passing on the Ref
instead of the encapsulated value.
2018-12-01 18:19:07 +01:00
Johannes
0494dee19d day01-2 tuple 2018-12-01 17:54:30 +01:00
51 changed files with 16328 additions and 20 deletions

364
Cargo.lock generated
View File

@@ -1,4 +1,368 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "aoc_2018"
version = "0.1.0"
dependencies = [
"bmp",
"chrono",
"gcd",
"itertools",
"lazy_static",
"regex",
]
[[package]]
name = "bmp"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69985ff4f58085ac696454692d0b646a66ad1f9cc9be294c91dc51bb5df511ae"
dependencies = [
"byteorder",
]
[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "either"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3be565ca5c557d7f59e7cfcf1844f9e3033650c929c6566f511e8005f205c1d0"
[[package]]
name = "gcd"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0896cb73353671dbe2b17312c97b55b7032831d28c809c703bece4a392b1df3a"
[[package]]
name = "iana-time-zone"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "itertools"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
dependencies = [
"either",
]
[[package]]
name = "js-sys"
version = "0.3.65"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "num-traits"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
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 = "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 = "syn"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasm-bindgen"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b"
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

View File

@@ -2,5 +2,12 @@
name = "aoc_2018"
version = "0.1.0"
authors = ["Johannes <jschaef@mail.uni-paderborn.de>"]
edition = "2021"
[dependencies]
regex = "1.10.2"
chrono = "0.4.31"
itertools = "0.11.0"
gcd = "1.1.0"
lazy_static = "1.4.0"
bmp = "0.5.0"

250
input/day02.txt Normal file
View File

@@ -0,0 +1,250 @@
mvgowxqubnhaefjslkjlrptzyi
pvgowlqubnhaefmslkjdrpteyi
ovgowoqubnhaefmslkjnrptzyi
cvgowxqubnrxefmslkjdrptzyo
cvgowxqubnhaefmsokjdrprzyf
cvgowxqubnhjeflslkjgrptzyi
cvgowxqvbnhaefmslkhdrotzyi
hvgowxqmbnharfmslkjdrptzyi
cvgoaxqubqhaefmslkjdrutzyi
cvxowxqdbnhaefmslkjdgptzyi
cvgikxqubnhaefmslkjdrptzyz
cvgnwxqubnhaqfjslkjdrptzyi
cqgowxqubnhaecmslkjgrptzyi
cvpowxqucnhaefmslkjdrptzyz
fvuoexqubnhaefmslkjdrptzyi
svgowxqubnhaefmsvkjdrttzyi
cvgowxqubnhaefmblkjdfpbzyi
cvkoyxqubnhaefsslkjdrptzyi
bvgowxqublhaefmslkjdrptzfi
xvgewxqubnhaefmslkjdrztzyi
cvgowxqubzhaefmslkkrrptzyi
cvgowxqubnhaefmslkudruuzyi
cvgowxqubnhaefmvlkjdrptwyl
cvgoyxqubnhaefmslkjvrotzyi
cvgowxoubnhaewmslkjdrpbzyi
cvgowxgubnhaefmslijdrptzxi
lvgowxqkbnhaefmslkjdrptzqi
xvgowxqubyhaefmflkjdrptzyi
wvnowxgubnhaefmslkjdrptzyi
cvgowxguwnhaefhslkjdrptzyi
cvgowfquxnhaefmdlkjdrptzyi
cvgywxqubnuaefmsldjdrpfzyi
cvkowxqzbrhaefmslkjdrptzyi
cviowxzubnhaefmslkjdrptqyi
cvgowxqubnhaefmsozjdrptzyc
cvglwxuubnhaewmslkjdrptzyi
cvgowxquknhaebmsfkjdrptzyi
vvgowxqubnhaesmslkjdrptzri
cvgowxoubndaefmslkjdrftzyi
cvgowxqubghaefmslkjdeptzyw
cvgowxqubnhaetmhlkjdrpvzyi
cvgowmquunhaefmslkjdrptzyt
cvgooxqpbniaefmslkjdrptzyi
cvgowxqubnhaeumslkjdkptiyi
cvgrwxqsbnhaemmslkjdrptzyi
cvrowxqubnhaefmslkjdrctcyi
dvgcwxqubnhaefmslkjdrptzyq
cugowxqubnhasfmmlkjdrptzyi
cwgowxqobzhaefmslkjdrptzyi
cvgowxquwnhaefmulkjdrptbyi
nvgowxqmbnhaefmslyjdrptzyi
cvgowxqubniakvmslkjdrptzyi
cvyowxqubnhaefmslejdrptzyx
cvgobxqubghaefeslkjdrptzyi
cvgowxiubnhaebmslkjdfptzyi
cvgosbqubnhaefmslkvdrptzyi
cvgpwxqubnhaefvslkjdrptzyh
cvgowxqubnyaefmslgjdsptzyi
cvgowxqubnhaefmslkjdrprzzp
cvgowxqubwhaemmslkjdrpazyi
cvgowxqpbnhaemmslkjdrpczyi
cvgoqxqubnhaelmslkjdrptzye
cvgowxqubnhaefmslbjdrttzvi
cvgowxqubnhlefmslkvurptzyi
cvgowxqujngaefmslktdrptzyi
cvgowxqubnhaefmsckjdcwtzyi
cvcowxqubnhaetmslkjorptzyi
jvnowxqubnhaefmslkjdrptzyf
cygowxqkbnhaefmslejdrptzyi
cvmowxqubnhaefmslkjdritzoi
cvgowxqubnpaefmslkjdrpnnyi
cvgowxqubnhaefmolkjdrpnzyy
uvgowxoubnhaefmslkjdrptzvi
cvgowxbabehaefmslkjdrptzyi
cvgokxqubnhaefmsckjdrjtzyi
cvgoxwqubahaefmslkjdrptzyi
cvgowxqusnhaefmslijdrptyyi
cvgowxqubmhaeqmslkxdrptzyi
cvgouxhubnhaefmslkjdrjtzyi
cvgowxqubnhaefmslrjdqptzyk
cvgowxiublhaefsslkjdrptzyi
cvgowxqubnxgefmslkadrptzyi
ovgowxqugshaefmslkjdrptzyi
cvgowxquznhaeemslsjdrptzyi
cvkowxqubnhaeomslkjdeptzyi
cvgvwxqubxhaefmslkjdrptzyu
cvglwxqybnhaefmslkjdrptzyb
cvgowxqubnlfwfmslkjdrptzyi
cvaowxqubnhaefmslkjdrvtzbi
cvgowxqubnrmefaslkjdrptzyi
cvgowxqubnhaefmsnkjdfpwzyi
cvgawxqmbnhaefmsykjdrptzyi
chgowmqubnhaefmslkjdrptwyi
cogowxqubnhaefmslkjxrptzri
cvgohxqubnoaesmslkjdrptzyi
cvdowxqubnhaofmslkjdrpvzyi
vvgowrqubnhaefmslkjdrpthyi
cvgowxquknhuefmslkjdoptzyi
cvyowxeubnhaefmslhjdrptzyi
cvglwxqubnhaefmslkjdrptdyq
cvgowxqubnhaefmsikgdrptayi
cvgowxqubnhaefjhlkjdrpczyi
cvgzwxkubnhaefmslkjdjptzyi
cxgowxqubnhaefmslkjdrptwyy
cvgowxqubnhaefeslkjdrmqzyi
cvgowxvubnhaefmilijdrptzyi
cvgowxqzbthaeomslkjdrptzyi
cvgowhqubndaefmglkjdrptzyi
cvgowxvubnhaeamylkjdrptzyi
cvgowiqubnhgefmslkjdrctzyi
cvgowxqubchaefmslksdritzyi
cvgowxqubnhaefmsnkjdreyzyi
cvgowxqubihaefmslkgdrutzyi
cvgowxqjbnhaeamslkjdrptzwi
cvgowxzubnhaefmsxkjdrrtzyi
cvgowxqubyhaetmslnjdrptzyi
cvgowxquhnhaebmslkjdxptzyi
cvgowxqubnhanfmslujdxptzyi
cvgowxqublhnefaslkjdrptzyi
cvgmwxqtbnhaefmslkjsrptzyi
jvgowxqubnhaeamslkjdrpmzyi
cvgowxqubhiaefmsljjdrptzyi
svgowxqubnhaefmswkjdrpozyi
cvgowxqebnhaeqmslkjdiptzyi
cveowxqubnhayzmslkjdrptzyi
cvglwxqubnhaefmxlkjdiptzyi
cvgowkqubdhaefmszkjdrptzyi
cvgowxkxbnhaeffslkjdrptzyi
cugowxqubnnaefmslujdrptzyi
cqgowxwubnhaepmslkjdrptzyi
cvgowxqubnhayfmmlkjwrptzyi
cvgowxquenhaefmsskxdrptzyi
cvgowxqubnhiefmsrkjdtptzyi
mvgowxkubnhaefmjlkjdrptzyi
cvgowkquunhaefmglkjdrptzyi
cvgowxqubqhaexmslgjdrptzyi
jvgowxqubnhaefmslkjddptlyi
cvgiwxqubnhaefmslkjdpptmyi
czgowxqubntaevmslkjdrptzyi
cvgotmqubnhaefmslkjdrpazyi
cvgowxtubnhaefmslkqdtptzyi
cvbowxqhnnhaefmslkjdrptzyi
cvgowkqubshaefmstkjdrptzyi
cvgowqqrbnaaefmslkjdrptzyi
cvgoixqubnhaefmslkjdrpmryi
cvgoxxqubnhaeimsxkjdrptzyi
cvgowxqubzhaebmslkjyrptzyi
cjgewxqubnhaefsslkjdrptzyi
cvgowxqdbnkaefmslwjdrptzyi
cvgowxqzbnhaeamslkjdrftzyi
cvgoixqubnsaewmslkjdrptzyi
cvgswxqubnhaxfmslkjdrptzni
cvwowxmubnhgefmslkjdrptzyi
cvggwxqubnhaefmslqjdbptzyi
cvgzwxqjbnhaefaslkjdrptzyi
cvgowzqubnharfmspkjdrptzyi
cvgowxqubnhawfmslkjdeptzyb
cvuowequbnhaefmslkjdrntzyi
gvgowxqubnxaefmslkjdrjtzyi
cvgowxqubnhmetmsldjdrptzyi
cvgowxqubnhamfmsqkjdrptyyi
cvgoqxqubnhaefmslkjtrpazyi
cvgoexqubhhaefmslkjdrhtzyi
cvgowwqubnhaeflslkjdrptzyf
cvgowlpubnhaefmslkjdrptvyi
cvgowxouunhaebmslkjdrptzyi
cvdowhqubnhaefmslijdrptzyi
cvgowxqubnkatfmslkjdrhtzyi
cvgowxqpbnhxeumslkjdrptzyi
cvgowxqubnhaefmsukjjrptzyn
cvgowxqubnhmefmslzjdrvtzyi
cvtowxqubihaefmclkjdrptzyi
chgowcqubnhayfmslkjdrptzyi
cvguwxqubnhaefmblkjarptzyi
cvgowoqubnhaefmsikjdrytzyi
cvgkwxqubnhaefmslkjdrptchi
cvhowxqubnhaefmslkjdrvlzyi
cvlowxfubnhaefmslkjkrptzyi
cvgowxqubhhaefoslkjdrytzyi
cvgowxsubqhaefmslpjdrptzyi
cvgowxpubnhaefmslhjdrptzyb
cvgowxqubnhrefmjlkddrptzyi
cvgowxqubnhaxfmykkjdrptzyi
mvgowxqubnhakfmslkjdrptnyi
cwgowxqubnhaffmslkadrptzyi
chgowxquwnhaefmslsjdrptzyi
cvgowxqubnhaefmslkjdwpnsyi
cvgawxqubnhaefmslkldyptzyi
cvgowxqubnhiefmslkjdiprzyi
cvgkqxqubnhaefcslkjdrptzyi
cvgovoqubnhaefmslkjdrpuzyi
cvgowxqubnhaefmszkjdrjtzyk
cvgopxqubnhaefmslkjdqpnzyi
cvgtwxqubnhaefmslkjnrptzri
cvgowxqurnhaedmslfjdrptzyi
cvpowxqubnhaefmswkjdrltzyi
cvgowxqujnpaefmslkjdrptdyi
cvgowgqubnhzifmslkjdrptzyi
lvgowxqubnhaenmslkjdbptzyi
ebgowxqubnhaeymslkjdrptzyi
cvgowxtubqhaefmslkedrptzyi
cvgowxqubshaesmslkjdrptryi
cvgowxqubnhaefmflkjmrpkzyi
cvgowxqubngaefmslkjdrytzgi
cvgowxqubnhaefmslklhzptzyi
cveowxqubnhgefmslkjdrpezyi
cvgowxqubnhaeomslkjdrqtzym
cvgowxqubzhaefmslwjdrptfyi
cmgowxqubnhaefmsdkjdrptzui
cvlowxqubnhaefmslsjdrptzwi
cvhowxpubnhaefmslkjhrptzyi
cveosxqurnhaefmslkjdrptzyi
cvgowxqubnhaefgsdkjdrptjyi
cvgvwxqubnhaefmslzjdmptzyi
cviowxqubnhalfmslkjdrptzyr
cvgowxqubchqefmslkjdrptzoi
cvgownqubnhaefmsyktdrptzyi
cvgywxqubnuaefmslkjdrpfzyi
cvgobxqunnhaefmslkjdrptzbi
cvgowxqubshaefgslkjdrxtzyi
cvghwxqubnhaefmslkjdrbtmyi
cvhowxqubnhaefmslkjdrpnzys
cvgowxqubnmaefmslejdrptzyq
cvmrwxqubnhaefmslkjdrpzzyi
cvgowxqubshaefmslkfdrptzyu
cvgowqqubnhaefmslkodrpjzyi
cvgnwnquknhaefmslkjdrptzyi
cvgowxquxnhacfmflkjdrptzyi
ovgowxqubnhaefmslkjmrmtzyi
cvgowxqubneaefmslkedrptzqi
cvgowxqubphweflslkjdrptzyi
cvgowxqudnhaefmplkjdrptdyi
cvwowxbubnhaefmslkjurptzyi
cvgowxtubnhaefmslkjdrwwzyi
cvgowxqubnhkefmslajdrptzyn
cvgowxqxbphaefmslkjdrptzsi
cvgowxquenhaefmslmjwrptzyi
zvgowdqubnhaeftslkjdrptzyi
csgowxqubnhgefmslkjdrptzyy
cvgolxqubahaefmslkjdrpvzyi
cvgoqxquhwhaefmslkjdrptzyi
cvgawxqubghaefmsrkjdrptzyi
cvgozxqubnhaefmslkwdfptzyi
cvgowxqubnhaefmslhjdkptzzi
cvnowxqubnhaefmsqkjdrptqyi
cvpowxqubnhaefmslkpdrptdyi
cvgowxoubnhaermslkjdrctzyi
cvgowxqubnheefmslkjdrctzyr
cvgowxqunnhaqfhslkjdrptzyi
cvgowxqulnhaefmslrjdrntzyi

1285
input/day03.txt Normal file

File diff suppressed because it is too large Load Diff

979
input/day04.txt Normal file
View File

@@ -0,0 +1,979 @@
[1518-07-10 23:54] Guard #3167 begins shift
[1518-04-15 00:20] falls asleep
[1518-09-30 00:49] wakes up
[1518-05-29 00:57] wakes up
[1518-11-03 00:00] Guard #1319 begins shift
[1518-06-07 00:03] Guard #1619 begins shift
[1518-09-02 00:15] falls asleep
[1518-04-26 00:48] wakes up
[1518-11-02 00:56] wakes up
[1518-08-30 00:22] falls asleep
[1518-06-11 00:00] Guard #1319 begins shift
[1518-08-07 00:57] wakes up
[1518-09-08 00:59] wakes up
[1518-11-23 00:00] Guard #2861 begins shift
[1518-05-21 00:39] wakes up
[1518-08-19 23:57] Guard #1319 begins shift
[1518-07-05 00:39] falls asleep
[1518-06-02 23:57] Guard #101 begins shift
[1518-09-02 00:58] wakes up
[1518-11-08 23:59] Guard #263 begins shift
[1518-10-07 00:15] falls asleep
[1518-06-06 00:03] Guard #1319 begins shift
[1518-08-11 00:57] wakes up
[1518-06-01 00:51] falls asleep
[1518-10-24 00:26] wakes up
[1518-05-16 23:57] Guard #1619 begins shift
[1518-11-17 00:13] falls asleep
[1518-04-21 00:37] wakes up
[1518-09-03 00:55] wakes up
[1518-10-30 00:10] wakes up
[1518-04-18 00:49] wakes up
[1518-11-07 00:51] wakes up
[1518-07-05 00:52] falls asleep
[1518-09-09 00:46] wakes up
[1518-06-06 00:33] falls asleep
[1518-06-08 00:42] wakes up
[1518-08-17 00:02] falls asleep
[1518-11-17 00:24] wakes up
[1518-05-28 00:50] falls asleep
[1518-04-27 00:00] Guard #3203 begins shift
[1518-04-20 00:01] Guard #2539 begins shift
[1518-05-25 00:24] falls asleep
[1518-08-13 00:04] falls asleep
[1518-09-05 23:57] Guard #1913 begins shift
[1518-08-31 00:03] Guard #521 begins shift
[1518-05-05 00:42] falls asleep
[1518-10-26 00:01] Guard #1069 begins shift
[1518-07-20 00:03] Guard #809 begins shift
[1518-07-04 00:24] wakes up
[1518-04-01 00:00] Guard #3167 begins shift
[1518-07-07 00:50] falls asleep
[1518-07-12 00:48] wakes up
[1518-10-02 00:16] falls asleep
[1518-04-10 00:17] falls asleep
[1518-09-17 00:06] falls asleep
[1518-10-23 23:50] Guard #3203 begins shift
[1518-08-20 00:48] falls asleep
[1518-08-09 00:15] wakes up
[1518-11-08 00:19] falls asleep
[1518-10-03 00:56] falls asleep
[1518-11-06 00:21] falls asleep
[1518-04-18 00:03] Guard #421 begins shift
[1518-07-15 00:26] wakes up
[1518-09-29 23:49] Guard #1237 begins shift
[1518-05-28 00:04] Guard #2441 begins shift
[1518-10-10 23:52] Guard #3167 begins shift
[1518-04-29 00:42] wakes up
[1518-08-08 00:01] falls asleep
[1518-06-24 23:58] Guard #2221 begins shift
[1518-04-06 00:09] falls asleep
[1518-09-13 00:01] Guard #101 begins shift
[1518-05-10 00:08] falls asleep
[1518-09-05 00:42] falls asleep
[1518-06-02 00:17] falls asleep
[1518-07-30 00:57] wakes up
[1518-09-27 00:07] wakes up
[1518-06-16 23:59] Guard #89 begins shift
[1518-06-02 00:53] wakes up
[1518-09-24 00:00] Guard #1069 begins shift
[1518-08-16 00:54] wakes up
[1518-06-27 00:46] wakes up
[1518-06-08 00:02] Guard #3167 begins shift
[1518-09-02 00:02] Guard #953 begins shift
[1518-10-29 00:18] falls asleep
[1518-09-15 00:59] wakes up
[1518-04-20 00:23] falls asleep
[1518-07-01 00:20] falls asleep
[1518-05-24 00:43] falls asleep
[1518-09-02 00:50] falls asleep
[1518-06-29 00:17] falls asleep
[1518-06-14 00:04] Guard #881 begins shift
[1518-08-04 00:02] Guard #421 begins shift
[1518-08-16 00:02] Guard #263 begins shift
[1518-07-07 00:17] wakes up
[1518-11-21 00:45] falls asleep
[1518-10-04 00:03] falls asleep
[1518-05-07 00:03] Guard #421 begins shift
[1518-08-30 00:24] wakes up
[1518-11-23 00:29] falls asleep
[1518-04-25 00:00] Guard #2381 begins shift
[1518-09-02 00:45] wakes up
[1518-05-15 00:52] falls asleep
[1518-09-05 00:32] falls asleep
[1518-07-01 23:47] Guard #1069 begins shift
[1518-10-08 00:21] falls asleep
[1518-08-13 00:07] wakes up
[1518-06-16 00:40] wakes up
[1518-05-15 23:56] Guard #1601 begins shift
[1518-07-25 00:00] Guard #2221 begins shift
[1518-04-03 00:53] wakes up
[1518-06-15 00:55] wakes up
[1518-04-27 00:59] wakes up
[1518-08-09 23:53] Guard #421 begins shift
[1518-09-01 00:01] Guard #2381 begins shift
[1518-10-05 00:07] falls asleep
[1518-05-28 00:17] falls asleep
[1518-08-12 23:50] Guard #1601 begins shift
[1518-10-11 00:51] wakes up
[1518-08-16 00:13] falls asleep
[1518-05-21 00:50] wakes up
[1518-04-18 23:56] Guard #3203 begins shift
[1518-06-22 00:34] wakes up
[1518-05-31 00:57] wakes up
[1518-10-19 00:42] wakes up
[1518-06-20 00:53] falls asleep
[1518-09-30 00:26] falls asleep
[1518-05-14 00:56] wakes up
[1518-10-23 00:51] wakes up
[1518-06-17 23:59] Guard #421 begins shift
[1518-05-05 00:37] wakes up
[1518-06-12 00:07] falls asleep
[1518-07-09 00:41] falls asleep
[1518-05-13 00:39] falls asleep
[1518-09-04 00:38] wakes up
[1518-09-10 00:00] Guard #881 begins shift
[1518-10-11 00:01] falls asleep
[1518-11-14 00:03] falls asleep
[1518-05-14 00:45] falls asleep
[1518-09-20 23:57] Guard #1601 begins shift
[1518-06-27 00:40] falls asleep
[1518-09-20 00:39] falls asleep
[1518-07-17 00:17] falls asleep
[1518-05-09 00:57] falls asleep
[1518-05-20 00:25] falls asleep
[1518-07-06 00:40] wakes up
[1518-04-06 00:13] wakes up
[1518-07-27 00:50] wakes up
[1518-05-06 00:01] Guard #1069 begins shift
[1518-10-11 00:38] wakes up
[1518-06-13 00:57] falls asleep
[1518-05-18 23:57] Guard #1913 begins shift
[1518-06-07 00:50] falls asleep
[1518-04-29 00:50] falls asleep
[1518-07-20 00:15] falls asleep
[1518-08-22 00:52] wakes up
[1518-04-02 00:38] falls asleep
[1518-05-30 00:23] wakes up
[1518-07-02 00:00] falls asleep
[1518-09-17 00:51] wakes up
[1518-10-10 00:42] wakes up
[1518-07-23 00:50] wakes up
[1518-06-04 00:52] wakes up
[1518-06-03 00:45] wakes up
[1518-09-05 00:33] wakes up
[1518-07-16 00:51] wakes up
[1518-06-28 23:59] Guard #2647 begins shift
[1518-07-06 00:18] falls asleep
[1518-11-13 00:11] falls asleep
[1518-08-11 00:03] Guard #881 begins shift
[1518-08-15 00:46] wakes up
[1518-11-07 23:59] Guard #521 begins shift
[1518-06-01 00:58] wakes up
[1518-06-21 00:44] wakes up
[1518-05-17 00:37] wakes up
[1518-04-25 23:57] Guard #1319 begins shift
[1518-08-02 00:18] falls asleep
[1518-04-11 00:49] wakes up
[1518-06-27 00:56] wakes up
[1518-11-04 00:58] wakes up
[1518-06-28 00:54] wakes up
[1518-10-24 00:19] falls asleep
[1518-05-11 00:06] falls asleep
[1518-10-05 00:52] falls asleep
[1518-08-01 00:03] Guard #331 begins shift
[1518-04-10 00:55] wakes up
[1518-06-30 00:44] wakes up
[1518-07-03 00:57] wakes up
[1518-10-06 00:45] falls asleep
[1518-09-23 00:38] falls asleep
[1518-09-11 00:19] falls asleep
[1518-08-08 23:57] Guard #263 begins shift
[1518-04-06 23:56] Guard #521 begins shift
[1518-08-30 00:29] falls asleep
[1518-10-17 00:53] wakes up
[1518-05-09 00:01] Guard #3203 begins shift
[1518-08-10 00:34] falls asleep
[1518-06-16 00:13] falls asleep
[1518-08-02 00:35] wakes up
[1518-11-03 00:49] wakes up
[1518-09-25 00:55] falls asleep
[1518-05-30 00:35] falls asleep
[1518-09-19 00:38] falls asleep
[1518-08-02 00:54] wakes up
[1518-11-12 23:57] Guard #2861 begins shift
[1518-05-28 23:57] Guard #3203 begins shift
[1518-04-07 00:57] wakes up
[1518-07-17 00:02] falls asleep
[1518-08-18 00:30] falls asleep
[1518-06-30 00:19] falls asleep
[1518-09-17 00:48] falls asleep
[1518-07-05 00:35] wakes up
[1518-08-25 00:58] wakes up
[1518-06-07 00:36] falls asleep
[1518-10-27 23:57] Guard #2221 begins shift
[1518-09-09 00:00] Guard #101 begins shift
[1518-11-21 00:37] falls asleep
[1518-07-15 00:08] falls asleep
[1518-05-25 00:30] wakes up
[1518-10-27 00:28] falls asleep
[1518-05-16 00:53] wakes up
[1518-05-06 00:49] falls asleep
[1518-05-12 00:47] falls asleep
[1518-07-27 00:03] Guard #521 begins shift
[1518-06-24 00:56] wakes up
[1518-07-07 00:57] wakes up
[1518-09-24 00:54] wakes up
[1518-09-23 00:02] Guard #2221 begins shift
[1518-08-06 00:31] wakes up
[1518-10-07 00:56] wakes up
[1518-11-04 00:00] Guard #881 begins shift
[1518-05-09 00:06] falls asleep
[1518-09-21 00:32] falls asleep
[1518-09-04 00:36] falls asleep
[1518-10-18 00:37] wakes up
[1518-06-19 00:04] Guard #521 begins shift
[1518-08-29 00:32] wakes up
[1518-05-20 23:58] Guard #2539 begins shift
[1518-09-12 00:04] Guard #1237 begins shift
[1518-07-15 23:58] Guard #1913 begins shift
[1518-05-10 00:59] wakes up
[1518-10-31 00:30] wakes up
[1518-04-22 00:54] wakes up
[1518-09-24 00:50] falls asleep
[1518-07-29 00:58] wakes up
[1518-07-03 00:49] falls asleep
[1518-04-05 00:47] falls asleep
[1518-08-18 00:36] wakes up
[1518-10-03 00:51] wakes up
[1518-08-27 00:46] wakes up
[1518-06-29 00:54] wakes up
[1518-05-25 00:49] wakes up
[1518-04-14 00:34] falls asleep
[1518-07-18 23:53] Guard #1913 begins shift
[1518-06-06 00:08] falls asleep
[1518-06-21 00:57] wakes up
[1518-08-28 00:54] wakes up
[1518-05-01 00:26] falls asleep
[1518-11-14 00:48] wakes up
[1518-08-02 00:00] Guard #521 begins shift
[1518-09-04 00:01] Guard #953 begins shift
[1518-10-16 23:57] Guard #3203 begins shift
[1518-04-23 00:46] falls asleep
[1518-08-02 00:44] falls asleep
[1518-11-11 00:19] falls asleep
[1518-08-20 23:46] Guard #881 begins shift
[1518-05-03 00:00] Guard #101 begins shift
[1518-04-28 00:33] falls asleep
[1518-07-09 00:59] wakes up
[1518-05-11 00:51] wakes up
[1518-10-03 23:52] Guard #2647 begins shift
[1518-09-26 00:57] wakes up
[1518-10-26 00:56] wakes up
[1518-06-08 00:30] falls asleep
[1518-08-23 00:55] wakes up
[1518-11-12 00:39] wakes up
[1518-04-27 00:54] falls asleep
[1518-05-29 00:19] falls asleep
[1518-05-12 00:59] wakes up
[1518-10-12 00:04] Guard #1069 begins shift
[1518-05-15 00:58] wakes up
[1518-06-01 00:37] wakes up
[1518-10-21 00:03] Guard #1601 begins shift
[1518-08-21 00:03] falls asleep
[1518-10-29 00:04] Guard #2861 begins shift
[1518-05-01 00:46] falls asleep
[1518-04-15 00:02] Guard #953 begins shift
[1518-07-11 00:01] falls asleep
[1518-09-11 00:48] wakes up
[1518-07-18 00:15] falls asleep
[1518-07-17 00:11] wakes up
[1518-07-13 00:41] falls asleep
[1518-04-04 00:37] wakes up
[1518-10-14 00:23] falls asleep
[1518-05-07 00:19] falls asleep
[1518-11-17 00:32] falls asleep
[1518-10-12 00:43] wakes up
[1518-11-01 00:28] falls asleep
[1518-11-15 00:01] Guard #1069 begins shift
[1518-07-17 23:56] Guard #1619 begins shift
[1518-04-04 00:58] wakes up
[1518-05-26 00:49] wakes up
[1518-08-15 00:20] wakes up
[1518-04-12 00:37] falls asleep
[1518-08-12 00:33] wakes up
[1518-05-18 00:30] falls asleep
[1518-08-28 00:04] Guard #1319 begins shift
[1518-07-28 23:49] Guard #1319 begins shift
[1518-11-02 00:45] falls asleep
[1518-04-28 00:51] falls asleep
[1518-06-09 00:25] falls asleep
[1518-10-03 00:00] Guard #1619 begins shift
[1518-06-18 00:24] wakes up
[1518-06-14 00:35] falls asleep
[1518-08-04 00:34] wakes up
[1518-06-12 00:42] wakes up
[1518-08-03 00:46] wakes up
[1518-05-05 00:56] wakes up
[1518-11-09 00:23] falls asleep
[1518-05-19 00:47] falls asleep
[1518-05-21 00:37] falls asleep
[1518-06-27 00:16] falls asleep
[1518-06-11 00:07] falls asleep
[1518-07-22 00:52] wakes up
[1518-11-10 00:26] falls asleep
[1518-09-07 00:00] falls asleep
[1518-09-22 00:59] wakes up
[1518-10-31 00:00] Guard #101 begins shift
[1518-09-23 00:33] wakes up
[1518-11-21 00:29] falls asleep
[1518-09-24 00:35] falls asleep
[1518-11-20 00:34] wakes up
[1518-05-01 00:37] wakes up
[1518-06-15 23:59] Guard #2221 begins shift
[1518-06-04 00:00] Guard #1619 begins shift
[1518-05-14 23:56] Guard #421 begins shift
[1518-10-24 00:45] wakes up
[1518-04-06 00:02] Guard #1069 begins shift
[1518-04-10 23:58] Guard #2861 begins shift
[1518-04-30 00:14] wakes up
[1518-06-23 00:39] wakes up
[1518-05-25 00:38] falls asleep
[1518-04-30 00:00] Guard #2539 begins shift
[1518-10-22 00:33] falls asleep
[1518-04-01 00:54] wakes up
[1518-05-11 00:37] falls asleep
[1518-06-04 00:47] falls asleep
[1518-10-24 00:10] wakes up
[1518-08-11 00:52] wakes up
[1518-08-10 00:55] wakes up
[1518-05-03 23:56] Guard #953 begins shift
[1518-04-20 23:56] Guard #3167 begins shift
[1518-11-20 00:02] falls asleep
[1518-04-01 23:59] Guard #881 begins shift
[1518-08-25 00:30] falls asleep
[1518-04-03 00:43] falls asleep
[1518-04-30 00:41] falls asleep
[1518-07-22 00:04] Guard #953 begins shift
[1518-07-27 23:56] Guard #809 begins shift
[1518-11-09 00:57] wakes up
[1518-09-08 00:51] wakes up
[1518-11-06 23:56] Guard #2647 begins shift
[1518-08-25 00:57] falls asleep
[1518-07-25 00:44] falls asleep
[1518-06-13 00:58] wakes up
[1518-10-18 00:59] wakes up
[1518-04-23 00:00] Guard #2861 begins shift
[1518-10-18 00:00] Guard #1319 begins shift
[1518-05-09 00:59] wakes up
[1518-10-30 00:04] falls asleep
[1518-06-26 00:57] wakes up
[1518-09-02 23:56] Guard #421 begins shift
[1518-09-18 00:02] Guard #3203 begins shift
[1518-08-26 00:01] Guard #2861 begins shift
[1518-08-20 00:14] wakes up
[1518-07-26 00:31] falls asleep
[1518-05-30 00:11] falls asleep
[1518-05-06 00:53] wakes up
[1518-05-31 00:30] falls asleep
[1518-09-07 00:46] wakes up
[1518-09-22 00:34] falls asleep
[1518-08-19 00:58] wakes up
[1518-11-02 00:01] falls asleep
[1518-04-14 00:46] falls asleep
[1518-04-13 00:02] falls asleep
[1518-07-31 00:04] Guard #809 begins shift
[1518-07-15 00:40] falls asleep
[1518-04-02 00:25] falls asleep
[1518-11-21 00:52] wakes up
[1518-10-09 23:50] Guard #1237 begins shift
[1518-10-31 00:58] wakes up
[1518-10-25 00:55] falls asleep
[1518-07-15 00:55] wakes up
[1518-11-12 00:26] falls asleep
[1518-07-04 00:46] falls asleep
[1518-06-23 00:36] falls asleep
[1518-10-02 00:03] Guard #809 begins shift
[1518-10-27 00:53] wakes up
[1518-07-29 00:17] wakes up
[1518-10-24 00:30] falls asleep
[1518-04-07 00:45] falls asleep
[1518-10-12 00:37] falls asleep
[1518-05-16 00:51] falls asleep
[1518-06-10 00:21] falls asleep
[1518-09-19 00:18] falls asleep
[1518-08-24 00:01] Guard #1319 begins shift
[1518-06-26 00:37] wakes up
[1518-04-28 00:00] Guard #3203 begins shift
[1518-04-24 00:41] wakes up
[1518-05-23 00:56] wakes up
[1518-11-23 00:52] falls asleep
[1518-08-22 00:36] wakes up
[1518-07-03 00:53] falls asleep
[1518-05-04 00:43] falls asleep
[1518-07-19 00:27] wakes up
[1518-08-06 23:50] Guard #2861 begins shift
[1518-07-25 00:11] falls asleep
[1518-07-12 00:01] falls asleep
[1518-05-20 00:39] falls asleep
[1518-08-24 00:33] falls asleep
[1518-07-06 00:00] Guard #2861 begins shift
[1518-07-07 00:00] falls asleep
[1518-09-18 00:54] wakes up
[1518-04-16 00:22] falls asleep
[1518-09-03 00:06] falls asleep
[1518-08-13 00:21] falls asleep
[1518-10-08 00:33] wakes up
[1518-09-29 00:00] Guard #1601 begins shift
[1518-11-13 23:54] Guard #1601 begins shift
[1518-07-07 23:47] Guard #3203 begins shift
[1518-04-24 00:01] Guard #881 begins shift
[1518-11-07 00:49] falls asleep
[1518-10-08 00:55] wakes up
[1518-09-23 00:19] falls asleep
[1518-08-17 23:59] Guard #2539 begins shift
[1518-06-22 00:32] falls asleep
[1518-04-07 00:09] falls asleep
[1518-07-27 00:57] falls asleep
[1518-06-05 00:03] Guard #89 begins shift
[1518-09-30 00:07] wakes up
[1518-10-19 00:38] falls asleep
[1518-10-23 00:12] wakes up
[1518-09-30 00:04] falls asleep
[1518-06-07 00:42] wakes up
[1518-10-30 00:25] falls asleep
[1518-10-19 00:54] falls asleep
[1518-09-06 23:46] Guard #263 begins shift
[1518-07-12 00:57] wakes up
[1518-08-15 00:04] Guard #2647 begins shift
[1518-10-28 00:51] wakes up
[1518-07-27 00:58] wakes up
[1518-10-01 00:47] falls asleep
[1518-04-11 00:38] falls asleep
[1518-05-17 00:14] falls asleep
[1518-04-05 00:31] wakes up
[1518-10-25 00:58] wakes up
[1518-04-30 23:59] Guard #2861 begins shift
[1518-09-25 23:59] Guard #3203 begins shift
[1518-11-11 00:50] wakes up
[1518-09-12 00:55] falls asleep
[1518-10-13 00:28] wakes up
[1518-08-27 00:18] falls asleep
[1518-07-08 00:57] wakes up
[1518-08-26 00:15] falls asleep
[1518-05-18 00:03] falls asleep
[1518-11-17 00:27] falls asleep
[1518-05-28 00:43] wakes up
[1518-07-03 23:48] Guard #2861 begins shift
[1518-10-04 00:58] wakes up
[1518-05-01 23:57] Guard #2221 begins shift
[1518-04-22 00:36] falls asleep
[1518-05-28 00:54] wakes up
[1518-05-23 00:04] falls asleep
[1518-09-21 00:34] wakes up
[1518-09-19 00:01] falls asleep
[1518-07-01 00:01] Guard #101 begins shift
[1518-05-16 00:31] falls asleep
[1518-11-23 00:44] wakes up
[1518-07-14 00:44] wakes up
[1518-10-20 00:03] Guard #3167 begins shift
[1518-04-27 00:39] wakes up
[1518-07-22 00:09] falls asleep
[1518-08-29 00:00] Guard #1237 begins shift
[1518-07-05 00:53] wakes up
[1518-11-20 00:54] wakes up
[1518-05-11 23:57] Guard #881 begins shift
[1518-05-11 00:00] Guard #521 begins shift
[1518-06-20 00:00] Guard #1601 begins shift
[1518-09-23 00:48] falls asleep
[1518-06-09 00:00] Guard #3167 begins shift
[1518-06-19 00:20] wakes up
[1518-05-02 00:59] wakes up
[1518-10-12 00:58] wakes up
[1518-05-20 00:34] wakes up
[1518-11-05 00:00] Guard #1619 begins shift
[1518-04-07 00:28] wakes up
[1518-04-22 00:44] falls asleep
[1518-07-31 00:47] wakes up
[1518-07-01 00:23] wakes up
[1518-10-01 00:55] wakes up
[1518-09-10 00:58] wakes up
[1518-10-26 00:52] falls asleep
[1518-10-14 00:45] wakes up
[1518-08-25 00:42] falls asleep
[1518-04-15 00:53] wakes up
[1518-10-13 00:02] Guard #1237 begins shift
[1518-05-27 00:20] falls asleep
[1518-07-26 00:19] falls asleep
[1518-07-28 00:59] wakes up
[1518-04-09 00:18] wakes up
[1518-06-11 00:38] falls asleep
[1518-10-05 00:56] wakes up
[1518-11-04 00:42] wakes up
[1518-09-12 00:57] wakes up
[1518-07-30 00:05] falls asleep
[1518-05-03 00:28] falls asleep
[1518-04-14 00:41] wakes up
[1518-10-13 00:27] falls asleep
[1518-05-01 00:58] wakes up
[1518-08-23 00:40] wakes up
[1518-04-18 00:14] falls asleep
[1518-08-11 00:39] falls asleep
[1518-07-14 00:00] Guard #1601 begins shift
[1518-10-30 00:41] wakes up
[1518-06-16 00:46] falls asleep
[1518-08-07 23:54] Guard #1601 begins shift
[1518-10-28 00:30] falls asleep
[1518-04-06 00:50] wakes up
[1518-05-04 00:55] wakes up
[1518-10-14 00:01] Guard #421 begins shift
[1518-11-15 00:55] falls asleep
[1518-11-20 00:53] falls asleep
[1518-05-29 00:47] wakes up
[1518-11-19 00:44] falls asleep
[1518-05-26 00:30] falls asleep
[1518-07-25 23:58] Guard #2441 begins shift
[1518-08-25 00:35] wakes up
[1518-07-06 00:29] wakes up
[1518-10-26 00:43] wakes up
[1518-11-13 00:49] wakes up
[1518-06-10 00:53] wakes up
[1518-05-22 23:53] Guard #2441 begins shift
[1518-09-26 00:39] falls asleep
[1518-07-19 00:00] falls asleep
[1518-08-25 00:52] wakes up
[1518-09-29 00:49] wakes up
[1518-04-26 00:14] falls asleep
[1518-10-05 00:38] wakes up
[1518-07-06 23:47] Guard #421 begins shift
[1518-09-03 00:46] wakes up
[1518-09-28 00:01] Guard #953 begins shift
[1518-09-18 23:49] Guard #1319 begins shift
[1518-10-10 00:02] wakes up
[1518-06-24 00:30] wakes up
[1518-05-15 00:43] falls asleep
[1518-11-19 00:58] wakes up
[1518-08-21 00:54] wakes up
[1518-06-09 00:47] falls asleep
[1518-06-27 23:57] Guard #2647 begins shift
[1518-07-11 23:50] Guard #881 begins shift
[1518-05-24 23:59] Guard #2221 begins shift
[1518-04-08 00:20] falls asleep
[1518-04-30 00:12] falls asleep
[1518-05-21 00:57] wakes up
[1518-10-13 00:57] wakes up
[1518-04-27 00:15] falls asleep
[1518-09-04 00:54] wakes up
[1518-06-25 00:34] falls asleep
[1518-11-18 00:18] falls asleep
[1518-06-14 00:47] wakes up
[1518-09-08 00:55] falls asleep
[1518-07-06 00:37] falls asleep
[1518-07-19 00:55] wakes up
[1518-08-23 00:08] falls asleep
[1518-04-23 00:56] wakes up
[1518-08-15 00:39] falls asleep
[1518-09-11 00:00] Guard #521 begins shift
[1518-10-08 00:03] Guard #881 begins shift
[1518-10-06 00:56] wakes up
[1518-06-03 00:24] falls asleep
[1518-07-12 00:15] wakes up
[1518-10-25 00:00] Guard #2647 begins shift
[1518-06-10 00:51] falls asleep
[1518-11-09 00:39] wakes up
[1518-08-12 00:54] falls asleep
[1518-07-28 00:53] wakes up
[1518-10-17 00:25] falls asleep
[1518-09-25 00:01] Guard #263 begins shift
[1518-06-12 23:59] Guard #101 begins shift
[1518-11-06 00:34] falls asleep
[1518-08-07 00:00] falls asleep
[1518-08-16 23:52] Guard #521 begins shift
[1518-06-06 00:53] wakes up
[1518-07-24 00:04] Guard #421 begins shift
[1518-11-17 00:04] Guard #1913 begins shift
[1518-08-03 00:41] falls asleep
[1518-05-16 00:56] falls asleep
[1518-11-01 00:03] Guard #2221 begins shift
[1518-08-13 00:48] wakes up
[1518-04-19 00:23] falls asleep
[1518-09-25 00:46] wakes up
[1518-06-16 00:54] wakes up
[1518-07-16 00:17] falls asleep
[1518-09-17 00:20] wakes up
[1518-07-24 00:43] falls asleep
[1518-09-14 00:55] wakes up
[1518-04-04 00:51] falls asleep
[1518-08-05 00:04] Guard #89 begins shift
[1518-05-10 00:55] falls asleep
[1518-07-08 00:00] falls asleep
[1518-07-10 00:23] falls asleep
[1518-07-12 00:18] falls asleep
[1518-10-13 00:35] falls asleep
[1518-04-02 00:29] wakes up
[1518-11-16 00:25] falls asleep
[1518-07-18 00:45] wakes up
[1518-05-08 00:01] Guard #1601 begins shift
[1518-08-22 00:28] falls asleep
[1518-04-29 00:04] Guard #1319 begins shift
[1518-06-11 00:59] wakes up
[1518-06-27 00:03] Guard #809 begins shift
[1518-05-11 00:20] wakes up
[1518-07-10 00:03] Guard #421 begins shift
[1518-10-26 00:06] falls asleep
[1518-11-14 00:54] falls asleep
[1518-11-08 00:10] falls asleep
[1518-04-24 00:37] falls asleep
[1518-08-19 00:57] falls asleep
[1518-11-23 00:57] wakes up
[1518-06-20 00:33] falls asleep
[1518-08-29 23:56] Guard #521 begins shift
[1518-11-15 00:57] wakes up
[1518-04-21 23:56] Guard #521 begins shift
[1518-08-26 23:57] Guard #809 begins shift
[1518-04-16 23:57] Guard #1069 begins shift
[1518-10-26 23:56] Guard #2861 begins shift
[1518-11-17 00:57] wakes up
[1518-11-20 23:56] Guard #1601 begins shift
[1518-11-18 23:59] Guard #3203 begins shift
[1518-05-31 00:02] Guard #1319 begins shift
[1518-07-08 23:46] Guard #953 begins shift
[1518-06-04 00:35] falls asleep
[1518-08-31 00:32] falls asleep
[1518-04-03 00:08] falls asleep
[1518-07-29 00:05] falls asleep
[1518-07-20 00:55] wakes up
[1518-05-16 00:58] wakes up
[1518-06-21 00:18] falls asleep
[1518-11-21 00:34] wakes up
[1518-05-20 00:53] wakes up
[1518-07-23 00:28] falls asleep
[1518-08-19 00:47] wakes up
[1518-04-06 00:24] falls asleep
[1518-11-01 00:48] wakes up
[1518-10-21 00:24] falls asleep
[1518-06-06 00:26] wakes up
[1518-07-05 00:15] falls asleep
[1518-10-02 00:45] wakes up
[1518-08-15 00:19] falls asleep
[1518-04-10 00:00] Guard #881 begins shift
[1518-10-29 23:51] Guard #3167 begins shift
[1518-11-03 00:27] wakes up
[1518-09-08 00:00] Guard #3203 begins shift
[1518-09-17 00:41] falls asleep
[1518-05-31 00:44] falls asleep
[1518-10-15 00:27] falls asleep
[1518-10-06 00:00] Guard #1319 begins shift
[1518-04-14 00:47] wakes up
[1518-07-25 00:26] wakes up
[1518-09-17 00:45] wakes up
[1518-04-30 00:58] wakes up
[1518-05-22 00:15] falls asleep
[1518-04-19 00:48] wakes up
[1518-07-26 00:28] wakes up
[1518-07-31 00:41] falls asleep
[1518-07-17 00:39] wakes up
[1518-07-01 00:28] falls asleep
[1518-10-16 00:01] Guard #1237 begins shift
[1518-08-29 00:30] falls asleep
[1518-04-13 23:59] Guard #2861 begins shift
[1518-07-10 00:28] wakes up
[1518-10-24 00:04] falls asleep
[1518-07-28 00:48] wakes up
[1518-11-10 23:57] Guard #1619 begins shift
[1518-11-09 00:44] falls asleep
[1518-10-10 00:01] falls asleep
[1518-05-06 00:58] wakes up
[1518-09-22 00:54] falls asleep
[1518-09-05 00:54] wakes up
[1518-07-29 23:48] Guard #1619 begins shift
[1518-10-11 00:47] falls asleep
[1518-07-12 00:54] falls asleep
[1518-05-11 00:54] falls asleep
[1518-07-26 00:36] wakes up
[1518-07-28 00:47] falls asleep
[1518-05-31 00:16] wakes up
[1518-09-08 00:11] falls asleep
[1518-06-23 23:58] Guard #263 begins shift
[1518-10-09 00:02] falls asleep
[1518-11-22 00:57] wakes up
[1518-05-08 00:08] falls asleep
[1518-10-23 00:11] falls asleep
[1518-10-09 00:34] wakes up
[1518-08-14 00:04] Guard #2539 begins shift
[1518-04-28 00:54] wakes up
[1518-06-30 00:00] Guard #1069 begins shift
[1518-06-28 00:47] wakes up
[1518-10-15 00:00] Guard #3167 begins shift
[1518-06-25 23:56] Guard #2221 begins shift
[1518-07-18 00:23] wakes up
[1518-08-08 00:49] wakes up
[1518-09-27 00:06] falls asleep
[1518-07-05 00:44] wakes up
[1518-06-11 00:31] wakes up
[1518-07-29 00:50] falls asleep
[1518-09-27 00:02] Guard #2647 begins shift
[1518-07-18 00:30] falls asleep
[1518-06-28 00:52] falls asleep
[1518-06-10 00:24] wakes up
[1518-08-22 00:00] Guard #1601 begins shift
[1518-09-28 00:37] falls asleep
[1518-07-04 00:48] wakes up
[1518-09-15 00:06] falls asleep
[1518-05-04 00:21] falls asleep
[1518-08-14 00:44] wakes up
[1518-10-20 00:35] wakes up
[1518-05-17 23:51] Guard #2647 begins shift
[1518-07-23 00:02] Guard #1619 begins shift
[1518-09-10 00:40] falls asleep
[1518-10-03 00:57] wakes up
[1518-11-16 00:03] Guard #1619 begins shift
[1518-06-22 00:43] falls asleep
[1518-06-22 00:58] wakes up
[1518-09-11 00:39] wakes up
[1518-09-20 00:02] Guard #1619 begins shift
[1518-10-04 00:19] wakes up
[1518-10-31 00:34] falls asleep
[1518-05-14 00:39] wakes up
[1518-11-01 23:49] Guard #1601 begins shift
[1518-04-03 00:00] Guard #881 begins shift
[1518-05-05 00:32] falls asleep
[1518-04-12 00:02] Guard #1619 begins shift
[1518-05-26 00:01] Guard #1913 begins shift
[1518-07-09 00:04] falls asleep
[1518-09-18 00:30] falls asleep
[1518-08-20 00:12] falls asleep
[1518-09-19 00:27] wakes up
[1518-07-15 00:02] Guard #3203 begins shift
[1518-04-08 00:55] wakes up
[1518-04-09 00:00] Guard #881 begins shift
[1518-04-15 00:12] falls asleep
[1518-10-20 00:26] falls asleep
[1518-08-19 00:42] falls asleep
[1518-11-16 00:48] wakes up
[1518-04-16 00:37] wakes up
[1518-05-14 00:27] falls asleep
[1518-09-29 00:23] falls asleep
[1518-11-06 00:27] wakes up
[1518-09-10 00:51] wakes up
[1518-08-09 00:08] falls asleep
[1518-11-10 00:52] wakes up
[1518-08-24 23:57] Guard #1601 begins shift
[1518-11-22 00:45] falls asleep
[1518-11-02 00:23] wakes up
[1518-09-16 00:57] wakes up
[1518-11-06 00:00] Guard #2861 begins shift
[1518-05-18 00:26] wakes up
[1518-08-10 00:26] wakes up
[1518-09-28 00:54] wakes up
[1518-06-01 00:12] falls asleep
[1518-10-23 00:19] falls asleep
[1518-09-05 00:00] Guard #1601 begins shift
[1518-09-11 00:43] falls asleep
[1518-07-28 00:57] falls asleep
[1518-05-10 00:32] wakes up
[1518-10-05 00:04] Guard #881 begins shift
[1518-04-29 00:58] wakes up
[1518-11-04 00:22] falls asleep
[1518-09-25 00:15] falls asleep
[1518-10-23 00:01] Guard #3167 begins shift
[1518-09-30 23:56] Guard #2647 begins shift
[1518-08-10 00:03] falls asleep
[1518-06-20 00:54] wakes up
[1518-10-22 00:02] falls asleep
[1518-05-03 00:48] wakes up
[1518-07-28 00:51] falls asleep
[1518-08-28 00:23] falls asleep
[1518-11-14 00:56] wakes up
[1518-10-21 00:09] falls asleep
[1518-08-31 00:24] falls asleep
[1518-05-16 00:36] wakes up
[1518-04-08 00:00] Guard #521 begins shift
[1518-10-12 00:53] falls asleep
[1518-09-12 00:20] falls asleep
[1518-11-21 23:58] Guard #2221 begins shift
[1518-05-22 00:43] wakes up
[1518-10-22 00:51] wakes up
[1518-04-01 00:53] falls asleep
[1518-06-27 00:51] falls asleep
[1518-07-19 00:48] falls asleep
[1518-04-22 00:30] wakes up
[1518-05-07 00:51] wakes up
[1518-09-21 23:57] Guard #2221 begins shift
[1518-09-09 00:31] falls asleep
[1518-05-04 00:40] wakes up
[1518-06-28 00:32] falls asleep
[1518-08-06 00:19] falls asleep
[1518-05-24 00:00] Guard #421 begins shift
[1518-10-16 00:36] wakes up
[1518-06-24 00:51] falls asleep
[1518-05-09 00:54] wakes up
[1518-05-21 00:54] falls asleep
[1518-04-29 00:18] falls asleep
[1518-06-21 00:49] falls asleep
[1518-04-15 00:13] wakes up
[1518-08-11 00:55] falls asleep
[1518-10-29 00:55] wakes up
[1518-07-09 00:35] wakes up
[1518-07-24 00:53] wakes up
[1518-06-26 00:46] falls asleep
[1518-04-09 00:11] falls asleep
[1518-05-27 00:52] wakes up
[1518-04-02 00:54] wakes up
[1518-10-18 00:46] wakes up
[1518-07-04 00:05] falls asleep
[1518-04-17 00:53] wakes up
[1518-11-03 00:48] falls asleep
[1518-11-18 00:53] wakes up
[1518-05-20 00:03] Guard #1619 begins shift
[1518-07-25 00:53] wakes up
[1518-08-22 00:40] falls asleep
[1518-08-14 00:42] falls asleep
[1518-10-21 00:51] wakes up
[1518-06-20 00:38] wakes up
[1518-08-31 00:27] wakes up
[1518-11-19 23:54] Guard #2441 begins shift
[1518-10-08 00:41] falls asleep
[1518-07-06 00:43] falls asleep
[1518-09-23 00:43] wakes up
[1518-09-06 00:59] wakes up
[1518-09-13 00:51] wakes up
[1518-10-22 00:25] wakes up
[1518-09-13 00:36] falls asleep
[1518-06-22 00:00] Guard #2221 begins shift
[1518-04-03 00:18] wakes up
[1518-05-02 00:52] falls asleep
[1518-06-25 00:46] wakes up
[1518-08-22 23:59] Guard #809 begins shift
[1518-08-30 00:42] wakes up
[1518-08-12 00:58] wakes up
[1518-04-12 00:58] wakes up
[1518-08-24 00:54] wakes up
[1518-05-14 00:02] Guard #1069 begins shift
[1518-05-21 00:43] falls asleep
[1518-11-05 00:18] falls asleep
[1518-07-17 00:45] wakes up
[1518-06-09 00:31] wakes up
[1518-07-11 00:56] wakes up
[1518-04-13 00:56] wakes up
[1518-08-04 00:09] falls asleep
[1518-08-18 23:57] Guard #2647 begins shift
[1518-07-02 00:46] wakes up
[1518-10-06 23:59] Guard #521 begins shift
[1518-08-26 00:53] wakes up
[1518-09-12 00:46] wakes up
[1518-06-14 23:57] Guard #1913 begins shift
[1518-05-08 00:44] wakes up
[1518-06-23 00:01] Guard #2539 begins shift
[1518-04-17 00:51] falls asleep
[1518-11-17 00:29] wakes up
[1518-09-14 00:27] falls asleep
[1518-07-14 00:18] falls asleep
[1518-09-25 00:56] wakes up
[1518-05-12 23:59] Guard #521 begins shift
[1518-07-01 00:34] wakes up
[1518-08-31 00:45] wakes up
[1518-08-12 00:02] Guard #1601 begins shift
[1518-11-03 00:21] falls asleep
[1518-05-31 00:07] falls asleep
[1518-05-05 00:01] Guard #1601 begins shift
[1518-05-10 00:01] Guard #1069 begins shift
[1518-07-20 23:56] Guard #89 begins shift
[1518-09-23 00:53] wakes up
[1518-07-16 23:50] Guard #2539 begins shift
[1518-04-04 23:56] Guard #809 begins shift
[1518-09-24 00:44] wakes up
[1518-05-11 00:56] wakes up
[1518-09-20 00:53] wakes up
[1518-05-19 00:37] falls asleep
[1518-06-26 00:09] falls asleep
[1518-04-24 00:54] wakes up
[1518-07-12 23:59] Guard #2861 begins shift
[1518-10-04 00:43] falls asleep
[1518-05-29 00:53] falls asleep
[1518-05-19 00:39] wakes up
[1518-05-19 00:48] wakes up
[1518-05-26 23:59] Guard #2539 begins shift
[1518-06-11 23:59] Guard #421 begins shift
[1518-10-18 00:42] falls asleep
[1518-07-04 23:56] Guard #2441 begins shift
[1518-07-13 00:48] wakes up
[1518-06-10 00:02] Guard #263 begins shift
[1518-09-10 00:57] falls asleep
[1518-04-21 00:26] falls asleep
[1518-10-16 00:23] falls asleep
[1518-06-27 00:28] wakes up
[1518-11-04 00:51] falls asleep
[1518-08-12 00:28] falls asleep
[1518-11-21 00:38] wakes up
[1518-04-12 23:54] Guard #1319 begins shift
[1518-06-15 00:43] falls asleep
[1518-04-24 00:46] falls asleep
[1518-05-06 00:57] falls asleep
[1518-07-27 00:27] falls asleep
[1518-06-09 00:58] wakes up
[1518-10-10 00:16] falls asleep
[1518-06-21 00:00] Guard #953 begins shift
[1518-05-24 00:52] wakes up
[1518-04-16 00:01] Guard #1069 begins shift
[1518-10-19 00:00] Guard #881 begins shift
[1518-10-15 00:30] wakes up
[1518-05-31 23:59] Guard #2221 begins shift
[1518-09-22 00:50] wakes up
[1518-09-17 00:02] Guard #1619 begins shift
[1518-08-20 00:49] wakes up
[1518-10-21 23:46] Guard #521 begins shift
[1518-06-01 23:57] Guard #1319 begins shift
[1518-10-18 00:30] falls asleep
[1518-05-21 23:56] Guard #1619 begins shift
[1518-09-04 00:44] falls asleep
[1518-04-05 00:52] wakes up
[1518-09-15 23:59] Guard #881 begins shift
[1518-10-21 00:19] wakes up
[1518-06-07 00:54] wakes up
[1518-07-06 00:58] wakes up
[1518-04-04 00:00] Guard #809 begins shift
[1518-06-18 00:09] falls asleep
[1518-09-19 00:55] wakes up
[1518-09-13 23:56] Guard #521 begins shift
[1518-11-12 00:01] Guard #101 begins shift
[1518-09-06 00:31] falls asleep
[1518-06-24 00:11] falls asleep
[1518-09-14 23:56] Guard #2539 begins shift
[1518-06-04 00:44] wakes up
[1518-05-30 00:04] Guard #3203 begins shift
[1518-05-30 00:56] wakes up
[1518-09-16 00:13] falls asleep
[1518-05-08 00:49] falls asleep
[1518-11-10 00:01] Guard #1619 begins shift
[1518-11-05 00:51] wakes up
[1518-05-15 00:48] wakes up
[1518-07-02 23:56] Guard #1619 begins shift
[1518-11-18 00:02] Guard #3203 begins shift
[1518-04-05 00:27] falls asleep
[1518-08-23 00:51] falls asleep
[1518-10-18 00:49] falls asleep
[1518-11-06 00:52] wakes up
[1518-08-06 00:01] Guard #2441 begins shift
[1518-05-13 00:59] wakes up
[1518-04-28 00:37] wakes up
[1518-06-19 00:18] falls asleep
[1518-09-19 00:12] wakes up
[1518-05-08 00:53] wakes up
[1518-04-22 00:40] wakes up
[1518-11-08 00:11] wakes up
[1518-07-03 00:50] wakes up
[1518-10-19 00:59] wakes up
[1518-09-03 00:49] falls asleep
[1518-11-08 00:38] wakes up
[1518-08-03 00:02] Guard #2861 begins shift
[1518-04-22 00:29] falls asleep
[1518-10-08 23:47] Guard #1601 begins shift
[1518-10-31 00:29] falls asleep
[1518-10-03 00:16] falls asleep
[1518-07-17 00:42] falls asleep
[1518-04-20 00:42] wakes up
[1518-04-04 00:30] falls asleep
[1518-05-31 00:40] wakes up
[1518-08-17 00:47] wakes up
[1518-05-18 00:57] wakes up

1
input/day05.txt Normal file

File diff suppressed because one or more lines are too long

50
input/day06.txt Normal file
View File

@@ -0,0 +1,50 @@
152, 292
163, 90
258, 65
123, 147
342, 42
325, 185
69, 45
249, 336
92, 134
230, 241
74, 262
241, 78
299, 58
231, 146
239, 87
44, 157
156, 340
227, 226
212, 318
194, 135
235, 146
171, 197
160, 59
218, 205
323, 102
290, 356
244, 214
174, 250
70, 331
288, 80
268, 128
359, 98
78, 249
221, 48
321, 228
52, 225
151, 302
183, 150
142, 327
172, 56
72, 321
225, 298
265, 300
86, 288
78, 120
146, 345
268, 181
243, 235
262, 268
40, 60

101
input/day07.txt Normal file
View File

@@ -0,0 +1,101 @@
Step B must be finished before step K can begin.
Step F must be finished before step I can begin.
Step T must be finished before step U can begin.
Step R must be finished before step Z can begin.
Step N must be finished before step S can begin.
Step X must be finished before step Y can begin.
Step I must be finished before step Y can begin.
Step K must be finished before step L can begin.
Step U must be finished before step J can begin.
Step G must be finished before step L can begin.
Step W must be finished before step A can begin.
Step H must be finished before step Q can begin.
Step M must be finished before step L can begin.
Step P must be finished before step L can begin.
Step L must be finished before step A can begin.
Step V must be finished before step Y can begin.
Step Q must be finished before step Y can begin.
Step Z must be finished before step J can begin.
Step O must be finished before step D can begin.
Step Y must be finished before step A can begin.
Step J must be finished before step E can begin.
Step A must be finished before step E can begin.
Step C must be finished before step E can begin.
Step D must be finished before step E can begin.
Step S must be finished before step E can begin.
Step B must be finished before step R can begin.
Step U must be finished before step O can begin.
Step X must be finished before step I can begin.
Step C must be finished before step S can begin.
Step O must be finished before step S can begin.
Step J must be finished before step D can begin.
Step O must be finished before step E can begin.
Step Z must be finished before step O can begin.
Step J must be finished before step C can begin.
Step P must be finished before step Y can begin.
Step X must be finished before step S can begin.
Step O must be finished before step Y can begin.
Step J must be finished before step A can begin.
Step H must be finished before step C can begin.
Step P must be finished before step D can begin.
Step Z must be finished before step S can begin.
Step T must be finished before step Z can begin.
Step Y must be finished before step C can begin.
Step X must be finished before step H can begin.
Step R must be finished before step Y can begin.
Step T must be finished before step W can begin.
Step L must be finished before step O can begin.
Step G must be finished before step Z can begin.
Step H must be finished before step P can begin.
Step I must be finished before step U can begin.
Step H must be finished before step V can begin.
Step N must be finished before step Y can begin.
Step Q must be finished before step E can begin.
Step H must be finished before step D can begin.
Step P must be finished before step O can begin.
Step T must be finished before step I can begin.
Step W must be finished before step V can begin.
Step K must be finished before step M can begin.
Step R must be finished before step W can begin.
Step B must be finished before step T can begin.
Step U must be finished before step A can begin.
Step N must be finished before step H can begin.
Step F must be finished before step U can begin.
Step Q must be finished before step O can begin.
Step Y must be finished before step S can begin.
Step V must be finished before step O can begin.
Step W must be finished before step C can begin.
Step Y must be finished before step J can begin.
Step T must be finished before step V can begin.
Step N must be finished before step D can begin.
Step U must be finished before step Q can begin.
Step A must be finished before step C can begin.
Step U must be finished before step M can begin.
Step Q must be finished before step S can begin.
Step P must be finished before step V can begin.
Step B must be finished before step Z can begin.
Step W must be finished before step Q can begin.
Step L must be finished before step S can begin.
Step I must be finished before step P can begin.
Step G must be finished before step P can begin.
Step L must be finished before step C can begin.
Step K must be finished before step A can begin.
Step D must be finished before step S can begin.
Step I must be finished before step H can begin.
Step R must be finished before step M can begin.
Step Q must be finished before step D can begin.
Step K must be finished before step O can begin.
Step I must be finished before step C can begin.
Step N must be finished before step O can begin.
Step R must be finished before step X can begin.
Step P must be finished before step C can begin.
Step B must be finished before step Y can begin.
Step G must be finished before step E can begin.
Step L must be finished before step V can begin.
Step W must be finished before step Y can begin.
Step C must be finished before step D can begin.
Step M must be finished before step J can begin.
Step F must be finished before step N can begin.
Step T must be finished before step Q can begin.
Step I must be finished before step E can begin.
Step A must be finished before step D can begin.

1
input/day08.txt Normal file

File diff suppressed because one or more lines are too long

357
input/day10.txt Normal file
View File

@@ -0,0 +1,357 @@
position=< 50769, -40375> velocity=<-5, 4>
position=< 40697, 10253> velocity=<-4, -1>
position=<-40315, -50495> velocity=< 4, 5>
position=<-40296, -20123> velocity=< 4, 2>
position=< 50760, -50499> velocity=<-5, 5>
position=< 30569, -40366> velocity=<-3, 4>
position=< 10313, 30502> velocity=<-1, -3>
position=<-50447, -10003> velocity=< 5, 1>
position=<-20073, 20369> velocity=< 2, -2>
position=<-40340, 30499> velocity=< 4, -3>
position=< 40673, 10253> velocity=<-4, -1>
position=<-50455, -50492> velocity=< 5, 5>
position=<-50472, -10001> velocity=< 5, 1>
position=< 10280, 30501> velocity=<-1, -3>
position=< -9975, -9994> velocity=< 1, 1>
position=< 10267, -30247> velocity=<-1, 3>
position=<-30171, 20374> velocity=< 3, -2>
position=< 40692, 30497> velocity=<-4, -3>
position=< 50776, -40374> velocity=<-5, 4>
position=< 10269, 20378> velocity=<-1, -2>
position=< -9950, 50741> velocity=< 1, -5>
position=< 30531, -40366> velocity=<-3, 4>
position=< 30571, -50490> velocity=<-3, 5>
position=< 40647, -40375> velocity=<-4, 4>
position=< 30539, -30247> velocity=<-3, 3>
position=< 30568, -30246> velocity=<-3, 3>
position=<-20092, 20374> velocity=< 2, -2>
position=< -9976, -9999> velocity=< 1, 1>
position=< 10320, 20377> velocity=<-1, -2>
position=< 30547, 10254> velocity=<-3, -1>
position=< 40676, 40623> velocity=<-4, -4>
position=< 50769, 40621> velocity=<-5, -4>
position=<-30188, -40371> velocity=< 3, 4>
position=< 30565, -20125> velocity=<-3, 2>
position=<-40329, -20123> velocity=< 4, 2>
position=<-20079, 30501> velocity=< 2, -3>
position=< 50788, 30495> velocity=<-5, -3>
position=<-20075, 10254> velocity=< 2, -1>
position=< 20408, 20378> velocity=<-2, -2>
position=<-20052, 30496> velocity=< 2, -3>
position=<-40344, 40617> velocity=< 4, -4>
position=< 10280, 50744> velocity=<-1, -5>
position=< 40640, -9996> velocity=<-4, 1>
position=< -9974, 50750> velocity=< 1, -5>
position=<-20095, -30242> velocity=< 2, 3>
position=< 20438, 30493> velocity=<-2, -3>
position=< 50796, 10249> velocity=<-5, -1>
position=< -9928, 40620> velocity=< 1, -4>
position=< -9956, 10251> velocity=< 1, -1>
position=< -9968, 30499> velocity=< 1, -3>
position=< 50765, 50749> velocity=<-5, -5>
position=< -9947, -40369> velocity=< 1, 4>
position=< 40676, 20378> velocity=<-4, -2>
position=<-30211, -20126> velocity=< 3, 2>
position=<-50456, -9994> velocity=< 5, 1>
position=<-20092, -30249> velocity=< 2, 3>
position=< 10304, -30247> velocity=<-1, 3>
position=< 50776, 50748> velocity=<-5, -5>
position=<-40295, 10252> velocity=< 4, -1>
position=< -9952, -20119> velocity=< 1, 2>
position=< 50797, 40623> velocity=<-5, -4>
position=<-40300, 20377> velocity=< 4, -2>
position=< 10296, 30493> velocity=<-1, -3>
position=< 50821, 30495> velocity=<-5, -3>
position=<-40355, 30499> velocity=< 4, -3>
position=<-20100, -9999> velocity=< 2, 1>
position=< 50770, 50750> velocity=<-5, -5>
position=<-40311, 50744> velocity=< 4, -5>
position=<-30204, 10248> velocity=< 3, -1>
position=<-50421, -50499> velocity=< 5, 5>
position=< 30552, -10003> velocity=<-3, 1>
position=< 30533, -40367> velocity=<-3, 4>
position=< 30549, 40618> velocity=<-3, -4>
position=< 50802, 50741> velocity=<-5, -5>
position=< 50784, 30494> velocity=<-5, -3>
position=< 40696, -20123> velocity=<-4, 2>
position=<-30205, 30497> velocity=< 3, -3>
position=< 10324, 40621> velocity=<-1, -4>
position=< -9940, 40621> velocity=< 1, -4>
position=<-30179, -50499> velocity=< 3, 5>
position=< 20421, -40371> velocity=<-2, 4>
position=< 50760, 20378> velocity=<-5, -2>
position=< 30538, 50746> velocity=<-3, -5>
position=< -9959, -20120> velocity=< 1, 2>
position=< -9944, -50497> velocity=< 1, 5>
position=< 20420, 40622> velocity=<-2, -4>
position=<-40305, -30242> velocity=< 4, 3>
position=< 20390, 30497> velocity=<-2, -3>
position=<-50428, -40372> velocity=< 5, 4>
position=<-50467, -9994> velocity=< 5, 1>
position=<-20071, -50494> velocity=< 2, 5>
position=< -9965, -9994> velocity=< 1, 1>
position=< 40692, -40374> velocity=<-4, 4>
position=< -9952, -20124> velocity=< 1, 2>
position=< 20396, -10000> velocity=<-2, 1>
position=< 20404, 10250> velocity=<-2, -1>
position=< 10301, -50492> velocity=<-1, 5>
position=< -9968, -9995> velocity=< 1, 1>
position=< 20436, 30501> velocity=<-2, -3>
position=<-20084, 40618> velocity=< 2, -4>
position=< 20428, -20125> velocity=<-2, 2>
position=< -9958, 50745> velocity=< 1, -5>
position=< 40660, 40618> velocity=<-4, -4>
position=< 30522, -40375> velocity=<-3, 4>
position=<-40319, -40372> velocity=< 4, 4>
position=< 40697, 40624> velocity=<-4, -4>
position=<-40295, -30248> velocity=< 4, 3>
position=<-40344, -30247> velocity=< 4, 3>
position=< 30536, 10254> velocity=<-3, -1>
position=< -9952, 10249> velocity=< 1, -1>
position=< -9923, 50747> velocity=< 1, -5>
position=< 40641, 10253> velocity=<-4, -1>
position=<-50452, -50492> velocity=< 5, 5>
position=<-40316, 20373> velocity=< 4, -2>
position=< 10296, -50493> velocity=<-1, 5>
position=< 10313, 40623> velocity=<-1, -4>
position=< 50785, 50747> velocity=<-5, -5>
position=< 20406, -20118> velocity=<-2, 2>
position=<-40313, -20123> velocity=< 4, 2>
position=< 50771, -20123> velocity=<-5, 2>
position=<-20097, -10003> velocity=< 2, 1>
position=< 50792, 30500> velocity=<-5, -3>
position=< -9949, -9999> velocity=< 1, 1>
position=< -9976, 40619> velocity=< 1, -4>
position=<-30195, 50749> velocity=< 3, -5>
position=<-50464, -30246> velocity=< 5, 3>
position=< 30544, -30243> velocity=<-3, 3>
position=< 50792, -40366> velocity=<-5, 4>
position=<-20083, -10000> velocity=< 2, 1>
position=< 50810, 50746> velocity=<-5, -5>
position=<-30180, -20118> velocity=< 3, 2>
position=< 20424, -50495> velocity=<-2, 5>
position=< 20422, 50741> velocity=<-2, -5>
position=<-40304, 40617> velocity=< 4, -4>
position=<-30192, -40372> velocity=< 3, 4>
position=< -9947, 10246> velocity=< 1, -1>
position=<-50464, -9999> velocity=< 5, 1>
position=<-40328, 10248> velocity=< 4, -1>
position=< 50795, -9994> velocity=<-5, 1>
position=<-20107, 40624> velocity=< 2, -4>
position=<-50451, -40375> velocity=< 5, 4>
position=<-40322, -20118> velocity=< 4, 2>
position=< 40653, 10245> velocity=<-4, -1>
position=< 20412, 30502> velocity=<-2, -3>
position=< -9936, -30251> velocity=< 1, 3>
position=< 40665, 20370> velocity=<-4, -2>
position=< 10268, -40369> velocity=<-1, 4>
position=< -9973, -30251> velocity=< 1, 3>
position=< 50813, -40366> velocity=<-5, 4>
position=< 50763, -40370> velocity=<-5, 4>
position=< 10298, -40366> velocity=<-1, 4>
position=<-20087, -20119> velocity=< 2, 2>
position=< 10317, -30249> velocity=<-1, 3>
position=< 30520, -30242> velocity=<-3, 3>
position=<-20057, -20123> velocity=< 2, 2>
position=< 10323, 20369> velocity=<-1, -2>
position=<-50430, 50750> velocity=< 5, -5>
position=< 10324, 40617> velocity=<-1, -4>
position=<-50451, -40374> velocity=< 5, 4>
position=<-20049, -30247> velocity=< 2, 3>
position=<-40295, 10250> velocity=< 4, -1>
position=<-40348, -50499> velocity=< 4, 5>
position=< 50818, -30242> velocity=<-5, 3>
position=< 50795, -10003> velocity=<-5, 1>
position=< -9955, 50742> velocity=< 1, -5>
position=< 10300, 50750> velocity=<-1, -5>
position=<-40324, 40623> velocity=< 4, -4>
position=<-40297, -50495> velocity=< 4, 5>
position=< 50816, 10251> velocity=<-5, -1>
position=<-30207, -20125> velocity=< 3, 2>
position=<-50472, 50741> velocity=< 5, -5>
position=<-30213, 10254> velocity=< 3, -1>
position=<-50460, -50499> velocity=< 5, 5>
position=<-20103, 20369> velocity=< 2, -2>
position=< -9966, 10254> velocity=< 1, -1>
position=< 50808, -50492> velocity=<-5, 5>
position=<-30219, -20127> velocity=< 3, 2>
position=<-40307, -20121> velocity=< 4, 2>
position=< -9951, 40626> velocity=< 1, -4>
position=< 40637, 40619> velocity=<-4, -4>
position=< 30537, 40620> velocity=<-3, -4>
position=<-50432, 50749> velocity=< 5, -5>
position=< 30561, -50490> velocity=<-3, 5>
position=< 50818, 10245> velocity=<-5, -1>
position=< 10317, -40373> velocity=<-1, 4>
position=<-30223, 10245> velocity=< 3, -1>
position=< 30541, -30242> velocity=<-3, 3>
position=< -9935, -30242> velocity=< 1, 3>
position=< -9952, -40373> velocity=< 1, 4>
position=<-30172, 20369> velocity=< 3, -2>
position=<-40300, 50748> velocity=< 4, -5>
position=<-50468, -50495> velocity=< 5, 5>
position=<-50445, 10254> velocity=< 5, -1>
position=<-40348, -20122> velocity=< 4, 2>
position=< 10309, 20371> velocity=<-1, -2>
position=< 50793, -30242> velocity=<-5, 3>
position=< -9983, 30499> velocity=< 1, -3>
position=< 30544, -50492> velocity=<-3, 5>
position=< 20404, 20376> velocity=<-2, -2>
position=< -9976, 30500> velocity=< 1, -3>
position=< 40676, 10254> velocity=<-4, -1>
position=< 40693, -9999> velocity=<-4, 1>
position=<-50420, 40626> velocity=< 5, -4>
position=<-50444, 20373> velocity=< 5, -2>
position=< -9935, -10003> velocity=< 1, 1>
position=<-20065, 50741> velocity=< 2, -5>
position=<-40356, 30502> velocity=< 4, -3>
position=<-20105, 20373> velocity=< 2, -2>
position=< 20440, 10248> velocity=<-2, -1>
position=<-20104, -40369> velocity=< 2, 4>
position=<-30200, 40620> velocity=< 3, -4>
position=< 40660, 20369> velocity=<-4, -2>
position=< 50800, 30500> velocity=<-5, -3>
position=<-50468, -50490> velocity=< 5, 5>
position=< 40676, -9998> velocity=<-4, 1>
position=<-30176, -50493> velocity=< 3, 5>
position=< 40692, 40626> velocity=<-4, -4>
position=<-30228, 50743> velocity=< 3, -5>
position=< 30560, -9996> velocity=<-3, 1>
position=< 30546, 30497> velocity=<-3, -3>
position=<-30200, 20370> velocity=< 3, -2>
position=< 30544, -9999> velocity=<-3, 1>
position=<-20066, 40621> velocity=< 2, -4>
position=<-50472, 50749> velocity=< 5, -5>
position=<-50440, 50750> velocity=< 5, -5>
position=<-30200, -50490> velocity=< 3, 5>
position=< -9939, -50497> velocity=< 1, 5>
position=< 20425, -20122> velocity=<-2, 2>
position=< -9979, 30494> velocity=< 1, -3>
position=<-30222, 30497> velocity=< 3, -3>
position=< 30521, 20378> velocity=<-3, -2>
position=<-40314, 40617> velocity=< 4, -4>
position=< -9959, -50497> velocity=< 1, 5>
position=< 20398, 40617> velocity=<-2, -4>
position=< 50821, -10001> velocity=<-5, 1>
position=< 50811, -9994> velocity=<-5, 1>
position=<-50469, 10249> velocity=< 5, -1>
position=<-40307, 30499> velocity=< 4, -3>
position=<-20107, -9996> velocity=< 2, 1>
position=< -9968, -50492> velocity=< 1, 5>
position=< 40653, 30493> velocity=<-4, -3>
position=<-40316, -50491> velocity=< 4, 5>
position=< -9926, 20373> velocity=< 1, -2>
position=< -9949, -30247> velocity=< 1, 3>
position=< 40668, -30242> velocity=<-4, 3>
position=<-40295, -40368> velocity=< 4, 4>
position=<-20066, -40371> velocity=< 2, 4>
position=<-20084, -40367> velocity=< 2, 4>
position=<-20068, 10245> velocity=< 2, -1>
position=< 20391, 30498> velocity=<-2, -3>
position=< 10298, -20118> velocity=<-1, 2>
position=<-50428, -40372> velocity=< 5, 4>
position=< 50780, 40626> velocity=<-5, -4>
position=< 40688, -40366> velocity=<-4, 4>
position=< 10304, 30495> velocity=<-1, -3>
position=< -9956, 40620> velocity=< 1, -4>
position=<-40298, 30497> velocity=< 4, -3>
position=<-40300, 20377> velocity=< 4, -2>
position=< 10301, -10001> velocity=<-1, 1>
position=< 10304, 10250> velocity=<-1, -1>
position=<-20052, -40369> velocity=< 2, 4>
position=< 20436, 40617> velocity=<-2, -4>
position=<-30191, 20373> velocity=< 3, -2>
position=< 50810, -30251> velocity=<-5, 3>
position=< 40664, -20125> velocity=<-4, 2>
position=< 20400, -30251> velocity=<-2, 3>
position=<-50443, -9997> velocity=< 5, 1>
position=< 40668, 50743> velocity=<-4, -5>
position=<-50419, -50496> velocity=< 5, 5>
position=< 50785, -40368> velocity=<-5, 4>
position=<-30184, 50750> velocity=< 3, -5>
position=< -9931, -40374> velocity=< 1, 4>
position=<-50461, -10003> velocity=< 5, 1>
position=< 30562, -40366> velocity=<-3, 4>
position=< 30571, 10245> velocity=<-3, -1>
position=< 20389, -30248> velocity=<-2, 3>
position=<-40316, 50747> velocity=< 4, -5>
position=<-20064, 40617> velocity=< 2, -4>
position=< -9979, 40626> velocity=< 1, -4>
position=<-40345, -20118> velocity=< 4, 2>
position=< 10264, -50491> velocity=<-1, 5>
position=< 20420, 50746> velocity=<-2, -5>
position=<-50444, -10003> velocity=< 5, 1>
position=< 30544, -50495> velocity=<-3, 5>
position=< -9939, 10246> velocity=< 1, -1>
position=<-20081, -9998> velocity=< 2, 1>
position=< 20404, -9999> velocity=<-2, 1>
position=< 10267, -30247> velocity=<-1, 3>
position=< 20444, -50497> velocity=<-2, 5>
position=< -9952, 10250> velocity=< 1, -1>
position=< 10317, -50498> velocity=<-1, 5>
position=<-20068, 10253> velocity=< 2, -1>
position=< 30544, -30249> velocity=<-3, 3>
position=< -9976, -10002> velocity=< 1, 1>
position=< -9926, 50750> velocity=< 1, -5>
position=<-20107, -20125> velocity=< 2, 2>
position=< 50772, 20378> velocity=<-5, -2>
position=< -9976, 40620> velocity=< 1, -4>
position=<-40338, -20127> velocity=< 4, 2>
position=<-20099, -9999> velocity=< 2, 1>
position=< 40673, 30501> velocity=<-4, -3>
position=< -9984, -30250> velocity=< 1, 3>
position=< 40640, -20124> velocity=<-4, 2>
position=< 10280, -40373> velocity=<-1, 4>
position=< 20417, -20127> velocity=<-2, 2>
position=<-20052, 10250> velocity=< 2, -1>
position=< 10312, -50499> velocity=<-1, 5>
position=< -9963, -20119> velocity=< 1, 2>
position=< 30573, 40623> velocity=<-3, -4>
position=< 10277, -20118> velocity=<-1, 2>
position=< 50778, -50499> velocity=<-5, 5>
position=< 10301, 10247> velocity=<-1, -1>
position=< 50764, -50492> velocity=<-5, 5>
position=< 30520, 50742> velocity=<-3, -5>
position=<-40312, -9999> velocity=< 4, 1>
position=<-50419, 40620> velocity=< 5, -4>
position=< 10321, -20123> velocity=<-1, 2>
position=<-40295, 10246> velocity=< 4, -1>
position=<-20060, -20119> velocity=< 2, 2>
position=<-50439, -10003> velocity=< 5, 1>
position=<-40351, -30250> velocity=< 4, 3>
position=< -9942, 50745> velocity=< 1, -5>
position=< 10304, -40374> velocity=<-1, 4>
position=<-50440, 10248> velocity=< 5, -1>
position=< 20433, -30249> velocity=<-2, 3>
position=<-40299, -20127> velocity=< 4, 2>
position=< 20432, -20127> velocity=<-2, 2>
position=< 10290, -9998> velocity=<-1, 1>
position=<-30200, 20377> velocity=< 3, -2>
position=< 20400, -40375> velocity=<-2, 4>
position=< 30516, 10251> velocity=<-3, -1>
position=< 30517, 20378> velocity=<-3, -2>
position=< 20438, -9998> velocity=<-2, 1>
position=< 40686, -50490> velocity=<-4, 5>
position=< 40638, -50494> velocity=<-4, 5>
position=<-50448, -9996> velocity=< 5, 1>
position=<-40305, 40617> velocity=< 4, -4>
position=<-40340, 30499> velocity=< 4, -3>
position=<-50456, -50499> velocity=< 5, 5>
position=< -9965, -20127> velocity=< 1, 2>
position=<-30176, 40617> velocity=< 3, -4>
position=< -9947, 30496> velocity=< 1, -3>
position=<-50430, -9998> velocity=< 5, 1>
position=< 30529, 50750> velocity=<-3, -5>
position=< 50812, -20127> velocity=<-5, 2>
position=< 10317, 10254> velocity=<-1, -1>
position=< 40644, 30499> velocity=<-4, -3>
position=<-20067, 40617> velocity=< 2, -4>
position=<-40351, -50491> velocity=< 4, 5>
position=< 50816, -30242> velocity=<-5, 3>
position=< 20445, -20118> velocity=<-2, 2>
position=< 20414, -30246> velocity=<-2, 3>
position=< 20439, -10003> velocity=<-2, 1>
position=<-50472, 50747> velocity=< 5, -5>
position=<-20108, -30242> velocity=< 2, 3>
position=<-30195, 10248> velocity=< 3, -1>
position=<-30175, 10254> velocity=< 3, -1>

34
input/day12.txt Normal file
View File

@@ -0,0 +1,34 @@
initial state: ..##.#######...##.###...#..#.#.#..#.##.#.##....####..........#..#.######..####.#.#..###.##..##..#..#
#..#. => .
..#.. => .
..#.# => #
##.#. => .
.#... => #
#.... => .
##### => #
.#.## => .
#.#.. => .
#.### => #
.##.. => #
##... => .
#...# => #
####. => #
#.#.# => .
#..## => .
.#### => .
...## => .
..### => #
.#..# => .
##..# => #
.#.#. => .
..##. => .
###.. => .
###.# => #
#.##. => #
..... => .
.##.# => #
....# => .
##.## => #
...#. => #
.###. => .

150
input/day13.txt Normal file
View File

@@ -0,0 +1,150 @@
/----------------------------------------------------------------------------------------------------------\
| /---------------------\ /-----------------\ |
/-------------------------\ | /--------+-----------\ | | /----------\ | |
| /----------+----+----------------------------------------+--------+-----------+-------\ | | | | | |
| /------------+\ | | /-------------------------+--------+-\ | | | | | | | |
| | || | | /----+-------------------------+--------+-+---------+-------+-+-\ | | | | |
| | /--++--------\| /+---------+----+-------------------------+--------+\| | /--+-+-+---------+-+----------+-\ | |
| | | || /-++---++---------+----+-------------------------+--------+++---------+----+--+-+-+---------+-+----\ | | | |
| | | ||/-----+-++---++---------+----+--\ /------------------+--------+++---------+----+--+-+-+---------+-+----+-----+-+--+\ |
/---------+-+---------+--+++-----+-++---++---------+----+--+---+-\ | ||| | | | | | | | | | | || |
| | | | ||| | || || | | | | | /---------\ | ||| | | | | | | | | | | || |
| | | | ||| /+-++---++---------+----+--+---+-+--+---------+---+--------+++---------+----+--+-+\| | | | | | || |
| | | | ||| || || || | /+--+---+-+--+---------+---+--------+++------\ | | | ||| | \----+-----/ | || |
| /--+-+---------+--+++----++-++---++---------+---++--+---+-+--+-------\ | | ||| | | | | ||| | | | || |
| /---+--+-+---------+--+++----++-++---++->\ | || | | | | | | | ||| | | | | ||| | | | || |
| | | | | | ||| || || || | /---+---++--+---+-+--+-------+-+---+--------+++------+--+----+--+-+++---------+----\ | | || |
| | | | | | ||| || || || | v |/--++--+-\ | | | | | | ||| /---+--+----+--+-+++--------\| | | | || |
| | | | | |/-+++----++-++---++--+--+---++--++--+-+-+-+--+-------+\| | ||| | | | /--+--+-+++--------++----+-+-------+--++--\|
| | | | | /---++-+++----++-++---++--+--+---++--++--+-+-+-+--+--\ ||| | ||| | | | | | | ||| || | | | || ||
| | | | | | || ||| || || || | | || || | | | | | | ||| | ||| | /-+--+-+--+--+-+++--------++----+-+---\ | || ||
| | | | | | || ||| || || || | | || ||/-+-+-+-+--+--+----+++---+--------+++--+-+-+--+-+--+--+-+++--------++-\ | | | | || ||
| | | | | /--+---++-+++----++-++---++--+--+---++--+++-+-+-+-+\ | | /--+++---+--------+++--+-+-+>-+-+--+--+-+++--------++-+--+-+---+---+--++\ ||
| | | | | | /+---++-+++----++\|| \+--+--+---++--+++-+-+-+-++-+--+-+--+++---+--------+/| | | | | | |/-+-+++--------++-+--+-+---+-\ | ||| ||
| | | | | | || || ||| ||||| | | | || ||| | | | || | | | ||| | /------+-+--+-+-+--+-+--++-+-+++--------++-+\ | | | | | ||| ||
| | | | | | || \+-+++----+++/| \--+--+---++--+++-+-+-+-++-+--+-+--+++---+-+------+-+--+-+-+--+-+--++-+-+++--------++-++-+-+-<-+-+-+--+++-+/
| \---+--+-+--+-++----+-+++----+++-+-------/ | /++--+++-+-+-+-++-+--+\| ||| | | \-+--+-+-+--+-+--++-+-/|| || || | | | | | ||| |
| | | | | || | ||| ||| | | ||| ||| | | | || | ||| ||| | | | /+-+-+--+-+--++-+--++--------++-++-+-+--\| | | ||| |
| | | | | || | ||| ||| | | ||| ||| | | | || | ||| ||| | | | || | | | | || | || || || | | || | | ||| |
| | | | | || | ||| ||| | | ||| ||| | | | || | ||| ||| | | /-----+-++-+-+--+-+--++-+--++------\ || || | | || | | ||| |
| | | | |/++----+-+++----+++-+----------+--+++--+++-+-+-+-++-+--+++--+++---+-+--+-----+-++-+-+--+-+--++-+-\|| | || || | | || | | ||| |
| |/-+-+--++++----+-+++----+++-+----------+--+++--+++-+-+-+\|| | ||| ||| | | | | ||/+-+--+-+--++-+-+++-----\| || ||/+-+--++-+-+--+++\|
|/-----++-+-+--++++----+-+++----+++-+----------+--+++\ ||| | | |||| | ||| ||| | | | /---+-++++-+--+-+--++-+-+++-----++-++-++++-+--++-+-+--+++++\
|| || | | ||||/---+-+++----+++-+----------+\ |||| ||| | | |||| | ||| ||| \-+--+-+---+-++++-+--/ | || | ||| || || |||| | || | | ||||||
|| || | | ||||| | ||| |||/+----------++-++++-+++-+-+-++++-+--+++--+++-----+--+-+---+-++++-+----+--++-+-+++-----++-++-++++-+--++-+\| ||||||
|| || | | ||||| | ||| ||||| || ^||| ||| | | |||| | ||| ||| | | | | |||| | | || | ||| || || |||| | || ||| ||||||
|| || | | ||||| | ||| /+++++----------++-++++-+++-+-+-++++-+--+++--+++-----+--+-+---+-++++-+----+--++-+-+++-----++-++-++++\| || ||| ||||||
|| || | |/-+++++---+-+++-\ |||||| || |||| ||| | | |||| | ||| ||| | | | | |||| | | || | ||| || || |||||| || ||| ||||||
|| || | || ||||| | ||| | |||||| ||/++++-+++-+-+-++++-+-\||| ||| | | | /+-++++-+----+--++-+-+++-----++\|| |||||| || ||| ||||||
|| || | || ||||| | ||| | |||||| /-----+++++++-+++-+-+-++++-+-++++--+++-----+--+-+--++-++++-+----+--++-+-+++-----+++++-++++++--++-+++\ ||||||
|| || | || ||||| | ||| | |||||| | ||||||| ||| | | |||| | |||| ||| | | | || |||| | | || | ||| ||||| |||||| || |||| |||||v
|| || | || ||||| | ||| | |||||| /+-----+++++++-+++-+-+-++++-+-++++--+++-----+--+-+--++-++++-+----+--++\| ||| ||||| |||||| || |||| ||||||
|| || | || ||||| | ||| | |||||| || ||||||| ||| | | |||| | |||| ||| | | \--++-++++-+----+--++++-+++-----+++++-++++++--++-++++-+++++/
|| || | || ||||| | ||| | |||||| || ||||||| |||/+-+-++++-+-++++--+++----\| | || |||| | | |||| ||| ||||| |||||| || |||| |||||
|| || | || ||||| | ||| | |||||| || ||||||| \++++-+-++++-+-++++--+++----++--+----++-++++-/ | |||| ||| ||||| |||||| || |||| |||||
|| || \-++-+++++---+-+++-+-+++++/ || /+++++++--++++-+-++++-+-++++--+++----++--+----++-++++------+--++++-+++-----+++++-++++++--++\|||| |||||
|| || || ||||| | |||/+-+++++----++----++++++++--++++-+-++++-+-++++--+++--\ || |/---++-++++------+--++++-+++-----+++++-++++++-\||||||| |||||
|| || || ||||| | ||\++-+++++----++----++++++++--+++/ | |||| |/++++--+++--+-++\ || /-++-++++------+--++++-+++----\||||| |||||| |||||||| |||||
|| || || ||||| | || || ||||| || |||||||| ||| | |||| |||||| ||| | ||| || | || |||| | |||| ||| |||||\-++++++-++++++++-/||||
|| /--++---++-+++++---+-++-++-+++++--\ || |||||||| ||| /+-++++-++++++--+++--+-+++-++-+-++-++++------+--++++-+++----+++++\ |||||| |||||||| ||||
|| | || ||/+++++---+-++-++-+++++--+-++----++++++++--+++-++-++++-++++++--+++--+-+++-++-+-++\|||| | |||| ||| |||||| |||||| |||||||| ||||
|| | || |||||||| | || || ||||| | || |||||||| ||| || |||| |||||| ||| | ||| || | |||||\+------+--++++-+++----+/|||| |||||| |||||||| ||||
|| | || |||||||| |/++-++-+++++--+-++----++++++++--+++-++-++++-++++++--+++--+\||| || | ||||| | | |||| ||| | |||| |||||| |||||||| ||||
|| | || |||||||| |||| || ||||| | || /++++++++--+++-++-++++-++++++--+++--+++++-++-+-+++++-+--\ | |||| ||| | |||| |||||| |||||||| ||||
|| | || |||||||| ||^| || ||||| | || /-+++++++++--+++-++-++++-++++++--+++--+++++-++-+-+++++-+--+---+--++++-+++---\| |||| |||||| |||||||| ||||
|| | || |||||||| |||| || ||||| | || | ||||||||| ||| || |||| |||||| ||| ||||| || | ||||| | | | |||| ||| || |||| |||||| |||||||| ||||
|| | /++---++++++++---++++-++-+++++--+-++-+-+++++++++--+++-++-++++-++++++--+++-\||||| || | ||||| | | | |||| ||| || |||| |||||| |||||||| ||||
|| | ||| |\++++++---++++-+/ ||||| | || | ||||||||| ||| || |||| |||||| ||| |||||| ||/+-+++++-+--+---+--++++-+++---++\|||| |||||| |||||||| ||||
|| /+-+++---+-++++++---++++-+--+++++--+-++-+-+++++++++--+++-++-++++-++++++--+++-++++++-++++-+++++-+--+---+\ |||| ||| ||||||| |||||| |||||||| ||||
|| || |||/--+-++++++---++++-+--+++++--+-++-+-+++++++++--+++-++-++++-++++++--+++-++++++-++++\||||| | | || |||| ||| ||||||| |||||| |||||||| ||||
|| || |||| | |||||| |||| | ||||| | || | ||||||||| ||| || |||| |||||| ||| |||||| |||||||||| | | \+-++++-+++---+++++++-++++++-++++++++--+++/
|| || |||| | |||||| |||| | ||||| | || | ||||||||| ||| || |||| |||||| ||| |||||| |||||||||| | | | |||| ||| ||||||| |||||| |||||||| |||
|| || |||| | |||||| |||| | ||||| | || | ||||||||| \++-++-++++-++++++--+++-++++++-++++++/||| | | | |||| ||| |||||||/++++++-++++++++--+++-\
|| || |||| | |||||| |||| | ||||| | |\-+-+++++++++---++-++-++++-++++++--+++-++++++-++++++-+++-+--+----+-++++-+++->-++++++++++++++-+++++++/ ||| |
|| || |||| | |||||\---++++-+--+++++--+-+--+-+++/||||| || ||/++++-++++++-\||| |||||| |||||| ||| | | | |||| ||| |||||||||||||| ||||||| ||| |
|| || |||| | |||||/---++++-+--+++++--+-+-\| ||\-+++++---++-+++++++-++++++-++++-++++++-++++++-+++-+--+----+-++++-+++---+++++++++++/|| ||||||| ||| |
|| || |\++--+-++++++---++++-+--+++++--+-+-++-++--+++++---++-+++++++<++++++-+/|| |||||| \+++++-+++-+--+----+-++++-+++---+++/||||||\-++-+++++++---++/ |
|| || | || | |||||| |||| | ||||| | | || || ||||| || ||||||| |\++++-+-++-+++++/ ||||| ||| | | | |||| ||| ||| |||||| || ||||||| || |
|| || | || | |||||| /++++-+--+++++--+-+-++-++\ ||||| || ||||||| |/++++-+-++-+++++---+++++-+++-+--+----+-++++-+++---+++-++++++\ || ||||||| || |
|| ||/+-++--+-++++++--+++++-+--+++++--+-+-++-+++-+++++---++-+++++++-++++++\| || ||||| ||||| ||| | | | |||| ||| ||| ||||||| || ||||||| || |
|| |||| || | |||||| ||||| | ||||| | | || ||| ||||| || ||||||| |||||\++-++-+++++---+++++-+++-+--+----+-++++-+++---+++-+++++++-++-+++++++---+/ |
|| |||| || | |||||| ||||| | ||||| |/+-++-+++-+++++---++\||||||| ||||| || || ||||| ||||| ||| | | | |||| ||| ||| ||||||| || ||||||| | |
|| |||| || | |||||| /+++++-+--+++++--+++-++-+++-+++++---++++++++++-+++++-++-++-+++++---+++++-+++-+--+\ | |||| ||| ||| ||||||| || ||||||| | |
|| |||| || ^ |||||| |||||| | ||||| ||| || ||| ||||| /-++++++++++-+++++-++-++-+++++---+++++-+++-+--++\/-+-++++-+++---+++-+++++++-++-+++++++--\| |
|| |||| || | \+++++-++++++-+--+++++--+++-++-+++-+++++-+-++++++++++-+++++-++-++-+++++---+++++-/||/+--++++-+-++++-+++-\ ||| ||||||| || ||||||| || |
|| |||| || | \++++-++++++-+--+++++--+++-++-+++-+++++-+-+++++++++/ ||||| || || ||||| ||||| |||| |||| | |||| ||| | ||| ||||||| || ||||||| || |
|| |||| || | |||| |||||| | ||||| ||| |\-+++-+++++-+-+++++++++--+++++-++-++-+++++---+++++--++++--++++-+-++++-+++-+-/|| ||||||| || ||||||| || |
|| |||| || | |||| |||||| | ||||| |||/+--+++-+++++-+-+++++++++--+++++-++-++-+++++---+++++--++++--++++-+-++++-+++-+--++-+++++++-++-+++++++\ || |
|| |||| || | |||| |||||| | ||||| ||||| ||| ||||| | ||||||||| ||||| || || ||||| ||||| |||| |||| | |||| ||| | || ||||||| || |||||||| || |
|| |||| || /+---++++-++++++-+--+++++--+++++\ ||| ||||| | ||||||||| ||||| || || ||||| ||||| |||| |||| | |||| ||| | || ||||||| || |||||||| || |
|| |||| || || |||| |||||| | |\+++--++++++-+++-+++++-+-+++++++++--+++++-++-++-+++++---+++++--++++--++++-+-++++-+/| | || ||||||| || |||||||| || |
|| |||| \+-++---++++-++++++-+--+-+++--++++++-+++-+++++-+-+++++++/| ||||| || || ||||| ||||| |||| |||| | |||| | | | || ||||||| || |||||||| || |
|| |||| | || |||| |||||| | \-+++--++++++-+++-+++++-+-+++++++-+--+++++-++-++-+++++---+++++--++++--++++-+-++++-+-+-+--++-+++++++-/| |||||||| || |
|| |||| | || |||| |||||| | ||| |||||| ||| ||||| | ||||||| | ||||| || || ||||\---+++++--++++--++++-+-++++-+-+-+--++-+++++/| | |||||||| || |
|| |||| /+-++---++++-++++++-+----+++--++++++\||| ||||| | ||||||| | ||||| || || |||| ||||| |||| |||| | \+++-+-+-+--++-+++++-+--+-++++++/| || |
|| |||| || || |||| |||||| | ||| |||||||||| ||||| | ||||||| | ||||| || || |||| ||||| |||| |||| | ||| | | | || ||||| | | |||||| | || |
|| |||| || || |||| |||||| | ||| |||||||||| ||||| | ||||||| | ||||| || || |||| ||||| |||| |||| | ||| | | | || ||||| | | |||||| | || |
|| |||| || || |||| |||||| | ||| |||||||||| ||||| | ||||||| | ||||| || || |||| ||||\--++++--++++-+--+++-+-+-+--++-/|||| | | |||||| | || |
|| |||| || || |||| |||||| | ||| |||||||||| ||||| | ||||||| | ||||| || || |||| |||| |||| |||| | ||| | | | || |||| | | |||||| | || |
|| |||| || || |||| |||||| | ||| |||||||||| ||||| | ||||||| | ||||| || || |||| |||| |\++--++++-+--+++-+-+-+--++--/||| | | |||||| | || |
|| |||| || || |||| |||||| | ||| |||||||||| |\+++-+-+++++++-+--++++/ || || |||| /-++++---+-++--++++-+--+++-+-+-+--++---+++-+--+-++++++-+-++--\|
|| |||| || || |||| |||||| | ||| |||||||||| | ||| | ||||||| | |||| || || |||| | |||| | || |||| | ||| | | | || ||| | | |||||| | || ||
|| |||| || || |||| |||||| | ||| |||||||||| | ||| | ||||||| | /++++--++-++-++++--+-++++---+-++--++++-+--+++-+-+-+--++---+++-+--+-++++++-+\|| ||
|| ||||/++-++---++++-++++++-+---\\++--++++++++++-+-+++-+-+++++++-+-+++++--++-++-++++--+-++++---+-++--++++-+--+++-+-+-+--++---+++-+--/ |||||| |||| ||
|| ||||||| || |||| |||||| | | || |||||||||| | ||| | ||||||\-+-+++++--++-++-++++--+-++++---+-++--++++-+--+++-+-+-+--++---+++-+----++++++-+++/ ||
|| ||||||| || |||| \+++++-+---+-++--++++++++++-+-+++-+-++++++--+-+++++--++-++-++++--+-++++---+-++--+/|| | ||| | | | || ||| | |||||| ||| ||
|| ||||||| || |||| ||||| | | || |||||||||| | ||| | |||||| | ||||| || || |||| | |||| | |^ | || | ||| | | | || |\+-+----++++++-+++---+/
|| |||\+++-++---++++--+++++-+---+-++--++++++++++-+-+++-+-++++++--+-+++++--++-++-/||| | |||| | || | || | ||| | | | || | | | |||||| ||| |
|| ||| ||| || |||| ||||| | | || |\++++++++-+-+++-+-++/||| | ||||| || || ||| | |||| | || | || | ||| | | | || | v | |||||| ||| |
|| ||| ||| || |||| |||\+-+---+-++--+-++++++++-+-+++-+-++-+++--+-+++++--++-++--+++--+-++++---+-++--+-++-+--++/ | | | || | | | |||||| ||| |
|| ||| ||| || |||| ||| | | | || | |||||||| | ||| | || ||| | |\+++--++-+/ ||| | |||| | || |/++-+--++--+-+-+--++---+-+-+-\ |||||| ||| |
|| ||| ||| || |||| ||| | | | || | |||||||| | ||| | || ||\--+-+-+++--+/ | ||| | |||| | || |||| | || | | |/-++---+-+-+-+--++++++-+++-\ |
|| ||| |||/++---++++--+++-+\| | || | |||||||| | ||| | \+-++---+-+-+++--+--+---+++--+-++++---+-++--++++-+--++--+-+-++-++---+-//+-+--++++++-+++-+\|
|| ||| |||||| |||| ||| ||| | || | |||||||| | ||| | | || | | ||| | | ||| | |||| | || |||| | || | | || || | || | |||||| ||| |||
\+-+++-++++++---++++--+++-+++---+-++--+-++++++++-+-+++-+--+-++---/ | ||| | | ||| | |||| | || |||| | ||/-+-+-++-++---+\ || | |||||| ||| |||
| |\+-++++++---++++--+++-+++---+-++--/ ||||||\+-+-+++-+--+-++-----+-+++--+--+---+++--+-++++---+-++--++++-+--+++-+-+-++-++---++-++-+--+++/|| ||| |||
| | | |||||\---++++--+++-/|| | || |||||| | | ||| | | || | ||| | | ||| | |||| /-+-++--++++-+--+++-+-+-++-++---++-++-+--+++-++\||| |||
| | | ||||| /++++--+++--++---+-++----++++++-+-+\\++-+--+-++-----+-+++--+--+---+++--+-++++-+-+-++--++++-+--+++-+-/ || || || || | ||| |||||| |||
| | | ||||| |||\+--+++--++---+-++----++++++-+-++-++-+--+-++-----+-++/ | | |||/-+-++++-+-+-++--++++\| ||| | || || || || | ||| |||||| |||
| | | ||||| ^|| | ||\--++---+-++----++++++-+-++-++-+--+-++-----+-++---+--+---+/|| | |||| | \-++--++++++--+++-+---++-++---++-++-+--+/| |||||| |||
| | | ||||\---+++-+--++---++---+-++----+++/|| | || || | |/++-----+-++---+--+---+-++-+\|||| | || |||||| ||| | || || || || | | | |||||| |||
| | | |||| ||| | || || | || \++-++-+-++-++-+--++++-----+-++---+--+---+-++-++++++-+---++--++++++--+/| | || || || \+-+--+-+-++++++-+/|
| | | |||| ||| | || || | || || || | || || | \+++-----+-++---+--+---+-/| |||||| | || |||||| | | | || || || | | | | |||||| | |
| | | |||| ||| | |\---++---+-++-----++-++-+-++-++-+---+++-----+-++---+--/ | | |||||| | || |||||| | | | || || || | | | | |||||| | |
| | | |\++----+++-+--+----++---+-++-----++-/| | || \+>+---++/ \-++---+------+--+-++++++-+---++--++++++--+-+-+---++-++---++--+-+--+-+-++++/| | |
| | | | || ||\-+--+----++---+-/| || | | || | | || || | | | |||||| | || |||||| | | | || || || | | | | |||| | | |
| | | | || /-++--+--+----++---+--+-----++--+-+-++--+\| || || | | | |||||| | || |||||| | | | || || /++--+-+--+-+-++++-+-+\|
| | | | || | || |/-+----++---+--+-----++--+-+-++--+++---++--------++---+------+--+-++++++-+--\|| |||||| | | | || || ||| | | | | |||| | |||
| | | | || | || || | || | | || | ^ || ||| || || | | | |||||| | ||| |||||| | | | || || ||| | | | | |||| | |||
| | | | || | || || | || | | || | | || ||| || || | | | |||||| | ||\--++++++--+-+-+---++-++--+++--+-+--+-/ |||| | |||
| | | | || | \+--++-+----++---+--+-----++--+-+-+/ ||| || /------++---+------+--+-++++++-+--++<--++++++--+-+-+---++-++--+++--+-+--+---++++-+-+++-\
| | | | || | | || | || | | || | | | ||| || | || | | | |||\++-+--++---++++++--+-+-+---++-+/ ||| | | | |||| | ||| |
\-+-+-+-++--+--+--++-+----++---+--+-----++--+-+-+---/|| || | || | | | ||| || | || |||||| | | | |\-+---+++--+-+--+---++++-+-/|| |
| | | || | | || | || | | || | | \----++---++-+------+/ | | | ||| || | || |\++++--+-+-+---+--+---+++--+-/ | |||| | || |
| | | || | | || | || | | || | | || || | | | | | ||| || | || | |||| \-+-+---+--+---+++--+----+---/||| | || |
| \-+-++--+--+--++-+----++---+--+-----++--+-+------++---++-+------+----/ | | ||| || | |\---+-++++----+-+---/ | ||| | | ||| | || |
| | || | | || | || | | || | | || || | | | | ||| || | | /+-++++----+-+------+---+++--+----+---\||| | || |
| | || | | || | || | | || | | || || | | | | ||| || | | || |\++----+-+------+---+++--+----+---++++-/ || |
| | || | | || | || | \-----++--+-+------++---++-+------+-----------+--+-+++-++-+--+---++-+-++----+-+------+---+++--+----+---+/|| || |
| | || | | || | || | || | | |\---++-+------+-----------+--+-+++-++-+--+---++-/ || | | | ||| | | | || || |
| | || | | || | || | || \-+------+----++-+------+-----------+--+-+++-++-+--+---+/ || \-+------+---++/ | | | || || |
| | || | | || | || | || | | |\-+------+-----------+--+-+++-++-+--+---+----++------+------+---+/ | | | || || |
| | || | | || | || | || | | | | | | \-+++-++-+--+---+----/| | | | | | | || || |
| | || | | || \----++---+--------++----/ | | | | | /+++-++-+--+---+-----+------+------+---+\ | | | || || |
| | || | | \+------++---+--------+/ /-----+----+--+------+-----------+--\|\++-++-+--+---+-----+------+------+---++---+----+---+-++----+/ |
| | |\--+--+---+------/| | \------+-----+----+--+------+-----------+--++-++-++-+--+---+-----+------+------+---++---+----+---+-+/ | |
| | | | \---+-------+---+--->-----------+-----+----+--+------+-----------+--++-++-++-+--+---+-----+------/ | \+---+----+---+-+-----/ |
| | | | | | | | | | | | | || || || | | | | | | | | | | |
| | | | \-------+---+---------------+-----+----+--+------+-----------+--++-++-++-+--/ | | | | | | | | |
| | | \--------------+---+---------------+-----/ | | | | || || || \------+-----+-------------+----+---+----+---+-/ |
| | | | | | \--+------+-----------+--++-/| || | | | | | | | |
| | | | | | | | | || | \+--------+-----+-------------/ | | | | |
| | | | | | | | | || | | | | | | | | |
\---+-+------------------+---+---------------+-------------+------+-----------+--++--+--+--------+-----/ | | | | |
| \------------------+---+---------------+-------------+------+-----------+--++--+--/ | | | | | |
| | | \-------------+------+-----------+--/| \-----------+------------------------+---+----/ | |
| | | | \-----------+---+--------------+------------------------+---/ | |
| \---+-----------------------------+------------------/ \--------------+------------------------/ | |
\------------------------/ | | | |
| \-------------------------------------/ |
\--------------------------------------------------------------------------------------/

32
input/day15.txt Normal file
View File

@@ -0,0 +1,32 @@
################################
####################.......#####
##################.G.......###.#
##################...G.........#
#############................###
############..............######
############...##......#########
############...G.....#.#########
##..##........G##.........######
##..##.....#.G...........E#..###
##..##.....#.....G......G..E..##
##G............................#
#....G........#####..G.........#
#......#.G...#######..E.......##
#...##..G...#########E.....#####
##...G.#....#########.....######
######G.G...#########..#.#######
######.#...G#########.##########
#####.......#########.##########
#####.GE.....#######..##########
#####.....E...#####...##########
#######....G..........##########
#######..........G..############
######.G............############
#########...........#..#########
############..........##########
############E...E.##...#########
#############.....E..E.#########
##############.........#########
##############...#....##########
###############..#.#############
################################

4261
input/day16.txt Normal file

File diff suppressed because it is too large Load Diff

1470
input/day17.txt Normal file

File diff suppressed because it is too large Load Diff

50
input/day18.txt Normal file
View File

@@ -0,0 +1,50 @@
|#..|#...|..|.#..|###|.....#.|.......||#..|....||.
#||..##.#........||#...##.|..###.|.||...|.#.|.|.#.
##.#.###....##....|..||#.||##.|.###|........||.##.
#.|.||#...|..####......|.#|#..#.#|##...||..#..|...
.....#..#.|.####..#..#...|||...||.|...#......#..|.
.|..#..#.......|...#.|...|.##....|#|..#|###..#..#.
.##..#..##..|.#|||.##..|..#.##..|....#..#|.##|.|#.
|#..|#...|...|.|.......#.#......|...|.#.|||.|||#.#
|....#...|..#..#.....#.|..#.#..|#|.#|...|..|#..|#|
.#...##..|#.##......##...#|||..|.....#.|..|...|..#
#.....|..|...||.|.|.....|....#|..|#...#|...#.....#
...|...###.||......|..#|..|...|.##|........#|#|..|
|.|.#.#......||#|||..|#....|#.|...#|..|.|.#|#.|.|.
###.#.|....|.......##.#|###.|#.#..#.|.#...#...###.
|###...|.....#.|.##..#...|#.#.|.##.#........#..|..
|.||.|...##...##|......#..|.##.##|..#..|#..#.##...
#....|#.....|...|...|............#..#|.....|.#.|.#
...#..|..|||#.|.......#|...#...##|.......####.|...
.#..|..#..|....||#.##.....|||...#..|.#..|.#..|..##
....#...##.........#....|..#.......#...|.....##.#.
|...|...|....#|####||###..|.|..|.||.#......#.|#...
.#.#|.|.|....#.....||...||..|...##.#..|.|.#......|
..|.......|||.|..#.#......|.|..##.||....|###....#.
##....#.......#.|#.##.........|.|....#...|.#|.|.#|
|#.##...|||||#.##.#...#.|#...|.||.|...|..#...#..|.
...#||..#.......||..|.###.#.|#......||..|.#.....#.
#..|.||#.#...|..........#.....#...#...###||.#.....
#..#.|###|#|..|##...##.#......#|.#.#|..#.......|#.
.|.....|.|..#.###|.#|.##.....|.|..|..|..#..|...##.
.|........#...#..|.|..||#....|....#..|.|........|#
....#.|...#|||...#......#...##......|#....#.||.#..
.|.....|....#......#.|#.|.|.|..#.#.|..##.#||.....#
.....#...|.#|..#..#|#.#|.|..|.#........#|..#|....#
|.||..##...|#.#||..|..#.|..|..#..|..#.|.#|.#...|#.
...|#.###...#..|#..##..||....#.||..#.|.|#.#..|..||
......|#|.#.#|.|....#..##|##|#...|.#.|.#....##|#..
#..||.....#....#....#.#.....|.....#....|....|...#.
.#....#.##..........|.||.#.....#|#|||.#..#|......|
..||..|....#..........#.|...#|.|#.|#..|#||.#...|#|
..#..#.#|......#|.....||.#..##.|.#..#.||...|.|||..
.#....|....#.|#...#..||..||.##..#.||....|.#|....|.
..#|.|.....#....#..|..||..#..##.|.||..||||#.#..|.|
.|#.|.||........#|.#|#....||..#||#...|..........##
..#|.|..|||..###..|||.#..#.#||||.#.|##...|#......|
..|...#|...|.#.#|.#...#.|..||##.#..#.|...#.#.#|#..
#..#..|##.#|......#...|#|##..#.|...#.#.....#..##..
..#.|..###|.|#.|........|.....|.....#..|.|.#...|.#
..#|.|#.#.|#..|....|#...|.....|........|.|##.|#||#
#.....##.#..#..#...|#||.#.#.#..|....|||.|.|......#
...#|#....|.#.#..##.|.....#....|.|||..##.|.#.|.##.

37
input/day19.txt Normal file
View File

@@ -0,0 +1,37 @@
#ip 4
addi 4 16 4
seti 1 9 5
seti 1 5 2
mulr 5 2 1
eqrr 1 3 1
addr 1 4 4
addi 4 1 4
addr 5 0 0
addi 2 1 2
gtrr 2 3 1
addr 4 1 4
seti 2 6 4
addi 5 1 5
gtrr 5 3 1
addr 1 4 4
seti 1 2 4
mulr 4 4 4
addi 3 2 3
mulr 3 3 3
mulr 4 3 3
muli 3 11 3
addi 1 5 1
mulr 1 4 1
addi 1 2 1
addr 3 1 3
addr 4 0 4
seti 0 2 4
setr 4 8 1
mulr 1 4 1
addr 4 1 1
mulr 4 1 1
muli 1 14 1
mulr 1 4 1
addr 3 1 3
seti 0 0 0
seti 0 2 4

1
input/day20.txt Normal file

File diff suppressed because one or more lines are too long

32
input/day21.txt Normal file
View File

@@ -0,0 +1,32 @@
#ip 1
seti 123 0 2
bani 2 456 2
eqri 2 72 2
addr 2 1 1
seti 0 0 1
seti 0 3 2
bori 2 65536 5
seti 4843319 1 2
bani 5 255 4
addr 2 4 2
bani 2 16777215 2
muli 2 65899 2
bani 2 16777215 2
gtir 256 5 4
addr 4 1 1
addi 1 1 1
seti 27 4 1
seti 0 7 4
addi 4 1 3
muli 3 256 3
gtrr 3 5 3
addr 3 1 1
addi 1 1 1
seti 25 0 1
addi 4 1 4
seti 17 0 1
setr 4 1 5
seti 7 3 1
eqrr 2 0 4
addr 4 1 1
seti 5 3 1

1000
input/day23.txt Normal file

File diff suppressed because it is too large Load Diff

23
input/day24.txt Normal file
View File

@@ -0,0 +1,23 @@
Immune System:
3400 units each with 1430 hit points (immune to fire, radiation, slashing) with an attack that does 4 radiation damage at initiative 4
138 units each with 8650 hit points (weak to bludgeoning; immune to slashing, cold, radiation) with an attack that does 576 slashing damage at initiative 16
255 units each with 9469 hit points (weak to radiation, fire) with an attack that does 351 bludgeoning damage at initiative 8
4145 units each with 2591 hit points (immune to cold; weak to slashing) with an attack that does 6 fire damage at initiative 12
3605 units each with 10989 hit points with an attack that does 26 fire damage at initiative 19
865 units each with 11201 hit points with an attack that does 102 slashing damage at initiative 10
633 units each with 10092 hit points (weak to slashing, radiation) with an attack that does 150 slashing damage at initiative 11
2347 units each with 3322 hit points with an attack that does 12 cold damage at initiative 2
7045 units each with 3877 hit points (weak to radiation) with an attack that does 5 bludgeoning damage at initiative 5
1086 units each with 8626 hit points (weak to radiation) with an attack that does 69 slashing damage at initiative 13
Infection:
2152 units each with 12657 hit points (weak to fire, cold) with an attack that does 11 fire damage at initiative 18
40 units each with 39458 hit points (immune to radiation, fire, slashing; weak to bludgeoning) with an attack that does 1519 slashing damage at initiative 7
59 units each with 35138 hit points (immune to radiation; weak to fire) with an attack that does 1105 fire damage at initiative 15
1569 units each with 51364 hit points (weak to radiation) with an attack that does 55 radiation damage at initiative 17
929 units each with 23887 hit points (weak to bludgeoning) with an attack that does 48 cold damage at initiative 14
5264 units each with 14842 hit points (immune to cold, fire; weak to slashing, bludgeoning) with an attack that does 4 bludgeoning damage at initiative 9
1570 units each with 30419 hit points (weak to radiation, cold; immune to fire) with an attack that does 35 slashing damage at initiative 1
1428 units each with 21393 hit points (weak to radiation) with an attack that does 29 cold damage at initiative 6
1014 units each with 25717 hit points (weak to fire) with an attack that does 47 fire damage at initiative 3
7933 units each with 29900 hit points (immune to bludgeoning, radiation, slashing) with an attack that does 5 slashing damage at initiative 20

1405
input/day25.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +1,6 @@
extern crate chrono;
extern crate itertools;
extern crate regex;
pub mod tasks;
pub mod utils;

View File

@@ -1,4 +1,3 @@
fn main() {
aoc_2018::tasks::day01::task1();
aoc_2018::tasks::day01::task2();
aoc_2018::tasks::day24::task2();
}

View File

@@ -1,5 +1,5 @@
use crate::utils;
use std::collections::HashSet;
use utils;
pub fn task1() {
let frequency: i32 = utils::read_file("input/day01.txt")
@@ -7,29 +7,24 @@ pub fn task1() {
.map(|line| line.parse::<i32>().unwrap())
.sum();
println!("Result: {}", frequency);
println!("Part 1: {}", frequency);
}
pub fn task2() {
let contents = utils::read_file("input/day01.txt");
let mut seen: HashSet<i32> = HashSet::new();
seen.insert(0);
let start_state = (std::cell::RefCell::new(seen), std::cell::RefCell::new(0));
let final_state = contents
let start_state = (vec![0].into_iter().collect::<HashSet<i32>>(), 0);
let final_state = utils::read_file("input/day01.txt")
.lines()
.map(|line| line.parse::<i32>().unwrap())
.cycle()
.scan(&start_state, |(hash_set, current_freq), freq_change| {
*current_freq.borrow_mut() += freq_change;
if hash_set.borrow_mut().contains(&current_freq.borrow()) {
Some((current_freq.borrow(), true))
.scan(start_state, |(set, current), freq_change| {
*current += freq_change;
if set.insert(*current) {
Some((*current, false))
} else {
let value: i32 = *current_freq.borrow_mut();
hash_set.borrow_mut().insert(value);
Some((current_freq.borrow(), false))
Some((*current, true))
}
}).find(|state| state.1);
})
.find(|state| state.1);
println!("{:?} was there already!", final_state.unwrap().0);
println!("Part 2: {} was there already!", final_state.unwrap().0);
}

174
src/tasks/day02.rs Normal file
View File

@@ -0,0 +1,174 @@
use crate::utils;
use std::collections::HashMap;
use std::collections::HashSet;
pub fn task1() {
let input = utils::read_file("input/day02.txt");
let mut count_two = 0;
let mut count_three = 0;
for line in input.lines() {
let mut counts = [0u8; 26];
for c in line.chars() {
counts[c as usize - 'a' as usize] += 1;
}
if counts.iter().any(|count| *count == 2) {
count_two += 1;
}
if counts.iter().any(|count| *count == 3) {
count_three += 1;
}
}
println!("Part 1: {}", count_two * count_three);
}
pub fn task2() {
let input = utils::read_file("input/day02.txt");
for x in input.lines() {
for y in input.lines() {
let mut diff_index = 0;
let mut diff_count = 0;
for (i, (a, b)) in x.chars().zip(y.chars()).enumerate() {
if a != b {
diff_index = i;
diff_count += 1;
}
}
if diff_count == 1 {
println!(
"Part 2: {}{}",
&x[0..diff_index],
&x[diff_index + 1..x.len()]
);
return;
}
}
}
println!("Part 2: None found!");
}
pub fn task2_linear_asterisk() {
let input = utils::read_file("input/day02.txt");
let mut hashes =
HashSet::<String>::with_capacity(input.len() * input.lines().next().unwrap().len());
for line in input.lines() {
for i in 0..line.len() {
let string: String = line
.chars()
.enumerate()
.map(|(index, c)| if index == i { '*' } else { c })
.collect();
if hashes.contains(&string) {
println!("{} is double", string);
return;
} else {
hashes.insert(string);
}
}
}
}
pub fn task2_linear() {
let input = utils::read_file("input/day02.txt");
// first order of business: create a tree where each input line is sorted
// into every nodes same_prefix, if the path leading from the root to that
// has that prefix.
let mut root = Node::default();
for id in input.lines() {
add_id_to_tree(&mut root, id);
}
// find a match..
let result = find_some_match(&root);
println!("{:?}", result);
}
fn find_some_match(node: &Node) -> Option<String> {
if let Some(result) = check_children_for_match(node) {
Some(result)
} else {
for child in node.outgoing.values() {
if let Some(result) = find_some_match(child) {
return Some(result);
}
}
None
}
}
/// Checks all IDs that have the prefix of this node if they are a match.
/// For this first for every child we look at its collected IDs - those
/// are the potential candidates, e.g. an ID that is in the 'e' child and
/// one that is in the 'f' child, if both have the same suffix.
///
/// We know that there is a unique match. Therefore we can sort out all
/// suffixes that appear more than once in a child node. Then we look at
/// all possible suffixes from all child nodes. If one suffix appears exactly
/// twice, we have a match.
fn check_children_for_match(node: &Node<'_>) -> Option<String> {
let edges: Vec<_> = node.outgoing.keys().collect();
// create a set of candidate suffixes for each edge
let suffix_candidates: HashMap<char, HashSet<&str>> = edges
.iter()
.map(|c| {
let mut suffix_count = HashMap::<&str, HashSet<&str>>::new();
let ids = &node.outgoing.get(c).unwrap().same_prefix;
for id in ids {
suffix_count
.entry(&id[node.depth + 1..])
.or_insert(HashSet::new())
.insert(id);
}
(
**c,
suffix_count
.iter()
.filter(|(_, count)| count.len() == 1)
.map(|(suffix, _)| *suffix)
.collect(),
)
})
.collect();
// go over all suffixes and count their occurrences. If # = 2, match!
let mut suffix_counter: HashMap<&str, usize> = HashMap::new();
for suffix_set in suffix_candidates.values() {
for suffix in suffix_set {
*suffix_counter.entry(suffix).or_insert(0) += 1;
}
}
suffix_counter
.iter()
.find_map(|(suffix, count)| if *count == 2 { Some(suffix) } else { None })
.map(|suffix| format!("{}{}", node.prefix, &suffix))
}
#[derive(Default, Debug)]
struct Node<'a> {
depth: usize,
prefix: &'a str,
same_prefix: HashSet<&'a str>,
outgoing: HashMap<char, Node<'a>>,
}
fn add_id_to_tree<'a>(root: &mut Node<'a>, id: &'a str) {
let mut current = root;
current.same_prefix.insert(id);
for (i, c) in id.chars().enumerate() {
{
let next = current.outgoing.entry(c).or_insert(Node::default());
next.depth = i + 1;
next.same_prefix.insert(id);
next.prefix = &id[..=i];
}
current = { current }.outgoing.get_mut(&c).unwrap();
}
}

100
src/tasks/day03.rs Normal file
View File

@@ -0,0 +1,100 @@
use crate::utils;
use regex::Regex;
use std::collections::HashMap;
#[derive(PartialEq)]
enum Use {
Single(u32),
Multi,
}
pub fn task1() {
let input = utils::read_file("input/day03.txt");
let re = Regex::new(r"^.(\d+) @ (\d+),(\d+): (\d+)x(\d+)").unwrap();
let count = input
.lines()
.map(|line| {
// #12 @ 590,968: 25x14
let m = re.captures(line).unwrap();
let id: u32 = m.get(1).unwrap().as_str().parse().unwrap();
let left: u32 = m.get(2).unwrap().as_str().parse().unwrap();
let top: u32 = m.get(3).unwrap().as_str().parse().unwrap();
let width: u32 = m.get(4).unwrap().as_str().parse().unwrap();
let height: u32 = m.get(5).unwrap().as_str().parse().unwrap();
(id, left, top, width, height)
})
.fold(
HashMap::<(u32, u32), Use>::new(),
|mut map, (id, left, top, width, height)| {
for x in left..left + width {
for y in top..top + height {
if map.get(&(x, y)).is_none() {
map.insert((x, y), Use::Single(id));
} else {
map.insert((x, y), Use::Multi);
}
}
}
map
},
)
.iter()
.filter(|it| *it.1 == Use::Multi)
.count();
println!("Part 1: {}", count);
}
pub fn task2() {
let input = utils::read_file("input/day03.txt");
// example entry: #12 @ 590,968: 25x14
let re = Regex::new(r"^.(\d+) @ (\d+),(\d+): (\d+)x(\d+)").unwrap();
let claims: Vec<_> = input
.lines()
.map(|line| {
let m = re.captures(line).unwrap();
let id: u32 = m.get(1).unwrap().as_str().parse().unwrap();
let left: u32 = m.get(2).unwrap().as_str().parse().unwrap();
let top: u32 = m.get(3).unwrap().as_str().parse().unwrap();
let width: u32 = m.get(4).unwrap().as_str().parse().unwrap();
let height: u32 = m.get(5).unwrap().as_str().parse().unwrap();
(id, left, top, width, height)
})
.collect();
let distribution: HashMap<(u32, u32), Use> = claims.iter().fold(
HashMap::<(u32, u32), Use>::new(),
|mut map, (id, left, top, width, height)| {
for x in *left..*left + *width {
for y in *top..*top + *height {
if map.get(&(x, y)).is_none() {
map.insert((x, y), Use::Single(*id));
} else {
map.insert((x, y), Use::Multi);
}
}
}
map
},
);
let (winner_id, _, _, _, _) = claims
.iter()
.find(|(_id, left, top, width, height)| {
for x in *left..*left + *width {
for y in *top..*top + *height {
if let Some(Use::Multi) = distribution.get(&(x, y)) {
return false;
}
}
}
true
})
.unwrap();
println!("Part 2: {}", winner_id);
}

151
src/tasks/day04.rs Normal file
View File

@@ -0,0 +1,151 @@
use crate::utils;
use chrono::prelude::*;
use chrono::Duration;
use chrono::NaiveDateTime;
use std::collections::HashMap;
enum Activity {
Starts(u32),
FallsAsleep,
Awakens,
}
#[derive(PartialEq)]
enum State {
Asleep,
Awake,
}
pub fn task1() {
use self::Activity::*;
let input = utils::read_file("input/day04.txt");
let mut input: Vec<_> = input
.lines()
.map(|line| {
// [1518-10-26 00:01] Guard #1069 begins shift
let time = NaiveDateTime::parse_from_str(&line[1..=16], "%Y-%m-%d %H:%M").unwrap();
let activity = if line.contains("falls asleep") {
Activity::FallsAsleep
} else if line.contains("wakes up") {
Activity::Awakens
} else {
let number: u32 = line.split(' ').find(|part| part.starts_with('#')).unwrap()[1..]
.parse()
.unwrap();
Activity::Starts(number)
};
(time, activity)
})
.collect();
input.sort_by_key(|it| it.0);
let mut current_id: u32 = 0;
let mut current_state = State::Awake;
let mut last_time = input[0].0;
let mut sleep_map: HashMap<u32, [usize; 60]> = HashMap::new();
let minute = Duration::minutes(1);
for (time, activity) in input.into_iter() {
// for all minutes since last time slot fill arrays
let mut iter_time = last_time;
while iter_time < time {
if current_state == State::Asleep && iter_time.hour() == 0 {
sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1;
}
iter_time += minute;
}
match activity {
Starts(id) => {
current_state = State::Awake;
current_id = id;
}
FallsAsleep => current_state = State::Asleep,
Awakens => current_state = State::Awake,
}
last_time = time;
}
let sleeper = sleep_map
.iter()
.map(|(id, schedule)| (id, schedule.iter().sum::<usize>()))
.max_by_key(|it| it.1)
.unwrap();
println!("Sleeper: {:?}", sleeper);
let worst_minute = sleep_map
.get(sleeper.0)
.unwrap()
.iter()
.enumerate()
.max_by_key(|it| it.1)
.unwrap()
.0;
println!("Worst minute: {}", worst_minute);
println!("Result: {}", *sleeper.0 as usize * worst_minute);
}
pub fn task2() {
use self::Activity::*;
let input = utils::read_file("input/day04.txt");
let mut input: Vec<_> = input
.lines()
.map(|line| {
// [1518-10-26 00:01] Guard #1069 begins shift
let time = NaiveDateTime::parse_from_str(&line[1..=16], "%Y-%m-%d %H:%M").unwrap();
let activity = if line.contains("falls asleep") {
Activity::FallsAsleep
} else if line.contains("wakes up") {
Activity::Awakens
} else {
let number: u32 = line.split(' ').find(|part| part.starts_with('#')).unwrap()[1..]
.parse()
.unwrap();
Activity::Starts(number)
};
(time, activity)
})
.collect();
input.sort_by_key(|it| it.0);
let mut current_id: u32 = 0;
let mut current_state = State::Awake;
let mut last_time = input[0].0;
let mut sleep_map: HashMap<u32, [usize; 60]> = HashMap::new();
let minute = Duration::minutes(1);
for (time, activity) in input.into_iter() {
// for all minutes since last time slot fill arrays
let mut iter_time = last_time;
while iter_time < time {
if current_state == State::Asleep && iter_time.hour() == 0 {
sleep_map.entry(current_id).or_insert([0; 60])[iter_time.minute() as usize] += 1;
}
iter_time += minute;
}
match activity {
Starts(id) => {
current_state = State::Awake;
current_id = id;
}
FallsAsleep => current_state = State::Asleep,
Awakens => current_state = State::Awake,
}
last_time = time;
}
let sleeper = sleep_map
.iter()
.max_by_key(|(_, array)| array.iter().max())
.unwrap();
let worst_minute = sleeper
.1
.iter()
.enumerate()
.max_by_key(|it| it.1)
.unwrap()
.0;
println!("Result 2: {}", *sleeper.0 as usize * worst_minute);
}

64
src/tasks/day05.rs Normal file
View File

@@ -0,0 +1,64 @@
use crate::utils;
use std::time::Instant;
pub fn task1() {
let mut input = utils::read_file("input/day05.txt");
let start = Instant::now();
input = reduce(input.as_str());
println!("Duration: {:?}", Instant::now() - start);
println!("RESULT: {}", input.len());
}
pub fn task2() {
let input = utils::read_file("input/day05.txt");
let start = Instant::now();
let input = reduce(&input);
let best = "abcdefghijklmnopqrstuvwxyz"
.chars()
.map(|c| {
(
c,
reduce(
&input
.chars()
.filter(|ch| ch.eq_ignore_ascii_case(&c))
.collect::<String>(),
)
.len(),
)
})
.min_by_key(|it| it.1)
.unwrap();
println!("Duration: {:?}", Instant::now() - start);
println!("Best: {} (length {})", best.0, best.1);
}
fn reduce(input: &str) -> String {
input
.chars()
.fold(Vec::<char>::with_capacity(input.len()), |mut stack, c| {
let last: Option<char>;
{
if let Some(c) = stack.last() {
last = Some(*c)
} else {
last = None
}
}
if let Some(last) = last {
if c.eq_ignore_ascii_case(&last) && c != last {
stack.pop();
} else {
stack.push(c);
}
} else {
stack.push(c);
}
stack
})
.iter()
.collect()
}

150
src/tasks/day06.rs Normal file
View File

@@ -0,0 +1,150 @@
use std::cmp::Ordering::{Equal, Greater, Less};
use crate::utils;
pub fn task1() {
use self::Bla::*;
let input = utils::read_file("input/day06.txt");
let coordinates: Vec<(u16, u16)> = input
.lines()
.map(|line| {
let mut split = line.split(", ");
(
split.next().unwrap().parse().unwrap(),
split.next().unwrap().parse().unwrap(),
)
})
.collect();
let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0;
let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1;
let mut area: Vec<Vec<Bla>> = Vec::new();
for _ in 0..max_x {
let mut vec = Vec::new();
for _ in 0..max_y {
vec.push(Bla::None);
}
area.push(vec);
}
for (a, b) in coordinates.iter() {
for (x, col) in area.iter_mut().enumerate() {
for (y, cell) in col.iter_mut().enumerate() {
let d = (i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32)) as u16;
*cell = match *cell {
None => Single(d, (*a, *b)),
Single(dd, (aa, bb)) => match dd.cmp(&d) {
Less => Single(dd, (aa, bb)),
Equal => Single(d, (*a, *b)),
Greater => Multi(d),
},
Multi(dd) => {
if d < dd {
Single(d, (*a, *b))
} else {
Multi(dd)
}
}
}
}
}
}
let occupation = coordinates
.iter()
.enumerate()
.map(|(_, (a, b))| {
let count = area
.iter()
.flatten()
.filter(|entry| {
if let Single(_, (x, y)) = entry {
a == x && b == y
} else {
false
}
})
.count();
let infinite = area[0].iter().any(|bla| bla.belongs_to_point(*a, *b))
|| area[area.len() - 1]
.iter()
.any(|bla| bla.belongs_to_point(*a, *b))
|| area.iter().any(|line| line[0].belongs_to_point(*a, *b))
|| area
.iter()
.any(|line| line[line.len() - 1].belongs_to_point(*a, *b));
// println!("{} has size {} (infinite: {:?})", i, count, infinite);
(count, infinite)
})
.collect::<Vec<_>>();
println!(
"Overall occupation: {} of {}",
occupation.iter().map(|(count, _)| *count).sum::<usize>(),
area.len() * area[0].len()
);
let result = occupation
.iter()
.filter(|(_, infinite)| !infinite)
.max_by_key(|x| x.0);
println!("{:?}", result); // 5224 too high
}
#[derive(Debug)]
enum Bla {
None,
/// distance, node
Single(u16, (u16, u16)),
/// distance
Multi(u16),
}
impl Bla {
fn belongs_to_point(&self, x: u16, y: u16) -> bool {
match self {
Bla::Single(_, (a, b)) => *a == x && *b == y,
_ => false,
}
}
}
pub fn task2() {
let input = utils::read_file("input/day06.txt");
let coordinates: Vec<(u16, u16)> = input
.lines()
.map(|line| {
let mut split = line.split(", ");
(
split.next().unwrap().parse().unwrap(),
split.next().unwrap().parse().unwrap(),
)
})
.collect();
let max_x = coordinates.iter().max_by_key(|it| it.0).unwrap().0;
let max_y = coordinates.iter().max_by_key(|it| it.1).unwrap().1;
let result: usize = (0..max_x)
.map(|x| {
(0..max_y)
.map(|y| {
coordinates
.iter()
.map(|(a, b)| {
(i32::abs(*a as i32 - x as i32) + i32::abs(*b as i32 - y as i32))
as usize
})
.sum::<usize>()
})
.filter(|it| *it < 10000)
.count()
})
.sum();
println!("Part 2: {}", result);
}

42
src/tasks/day07.rs Normal file
View File

@@ -0,0 +1,42 @@
use crate::utils;
use std::collections::{HashMap, HashSet};
pub fn task1() {
let input = utils::read_file("input/day07.txt");
let mut tasks: HashSet<char> = HashSet::new();
let dependencies: Vec<(char, char)> = input
.lines()
.map(|line| (line.chars().nth(5).unwrap(), line.chars().nth(36).unwrap()))
.collect();
let mut depends_on: HashMap<char, HashSet<char>> = HashMap::new();
for (a, b) in dependencies {
depends_on.entry(b).or_insert(HashSet::new()).insert(a);
tasks.insert(a);
tasks.insert(b);
}
let mut open: HashSet<char> = tasks
.iter()
.filter(|task| !depends_on.contains_key(task))
.copied()
.collect();
let mut result = String::new();
while !open.is_empty() {
let next = *open.iter().min().unwrap();
open.remove(&next);
result.push(next);
let newly_open: HashSet<char> = depends_on
.iter()
.filter(|(_task, deps)| deps.iter().all(|dep| result.chars().any(|c| c == *dep)))
.map(|(task, _)| *task)
.collect();
open = open.union(&newly_open).copied().collect();
for c in newly_open {
depends_on.remove(&c);
}
}
println!("{}", result);
}

61
src/tasks/day08.rs Normal file
View File

@@ -0,0 +1,61 @@
use crate::utils;
pub fn both() {
let input: Vec<usize> = utils::read_file("input/day08.txt")
.split(' ')
.map(|x| x.parse().unwrap())
.collect();
let (tree, _) = Node::extract_from(&input);
println!("Metadata sum: {}", tree.metadata_sum());
println!("Task2 sum: {}", tree.task2());
}
struct Node {
metadata: Vec<usize>,
children: Vec<Node>,
}
impl Node {
fn extract_from(input: &[usize]) -> (Self, &[usize]) {
let mut rest_input = &input[2..];
let mut num_children: usize = input[0];
let num_meta: usize = input[1];
let mut children = Vec::new();
while num_children > 0 {
let (node, rest) = Node::extract_from(rest_input);
children.push(node);
rest_input = rest;
num_children -= 1;
}
let metadata = rest_input[..num_meta].to_vec();
(Node { metadata, children }, &rest_input[num_meta..])
}
fn metadata_sum(&self) -> usize {
self.metadata.iter().sum::<usize>()
+ self
.children
.iter()
.map(|child| {
let s: usize = child.metadata_sum();
s
})
.sum::<usize>()
}
fn task2(&self) -> usize {
if !self.children.is_empty() {
self.metadata
.iter()
.map(|meta| match self.children.get(*meta - 1) {
Some(child) => child.task2(),
None => 0,
})
.sum()
} else {
self.metadata_sum()
}
}
}

94
src/tasks/day09.rs Normal file
View File

@@ -0,0 +1,94 @@
const PLAYERS: usize = 468;
const MODULO: usize = 23;
const HIGHEST_MARBLE: usize = 7184300;
pub fn task1() {
let mut player_score = [0usize; PLAYERS];
let mut current_player = 1;
let mut current_index: usize = 0;
let mut deck: Vec<usize> = Vec::new();
deck.push(0);
for marble in 1..=HIGHEST_MARBLE {
if marble % MODULO == 0 {
current_index = rem(current_index, 7, deck.len());
player_score[current_player] += marble;
player_score[current_player] += deck.remove(current_index);
} else {
current_index = (current_index + 2) % deck.len();
deck.insert(current_index, marble);
}
current_player = (current_player + 1) % PLAYERS;
if marble % 10000 == 0 {
println!("{} ({}%)", marble, marble as f32 / HIGHEST_MARBLE as f32);
}
}
let result = player_score.iter().max().unwrap();
println!("The highest score is {}", result);
}
pub fn rem(a: usize, sub: usize, m: usize) -> usize {
if sub > a {
(a + m - sub) % m
} else {
(a - sub) % m
}
}
pub fn task2() {
let _dummy_node = ListNode {
value: 0,
id_left: 0,
id_right: 0,
};
let mut player_score = [0usize; PLAYERS];
let mut current_player = 1;
let mut nodes = Vec::with_capacity(HIGHEST_MARBLE);
nodes.push(ListNode {
value: 0,
id_left: 0,
id_right: 0,
});
let mut current_node = &nodes[0];
for marble in 1..=HIGHEST_MARBLE {
if marble % MODULO == 0 {
for _ in 0..7 {
current_node = &nodes[current_node.id_left];
}
player_score[current_player] += marble;
player_score[current_player] += current_node.value;
let id_left = current_node.id_left;
let id_right = current_node.id_right;
nodes[id_left].id_right = id_right;
nodes[id_right].id_left = id_left;
current_node = &nodes[id_right];
} else {
let id_left = current_node.id_right;
let id_right = nodes[current_node.id_right].id_right;
let new = ListNode {
value: marble,
id_left,
id_right,
};
nodes.push(new);
let id_new = nodes.len() - 1;
nodes[id_left].id_right = id_new;
nodes[id_right].id_left = id_new;
current_node = &nodes[id_new];
}
current_player = (current_player + 1) % PLAYERS;
}
let result = player_score.iter().max().unwrap();
println!("The highest score is {}", result);
}
#[derive(Debug)]
struct ListNode {
value: usize,
id_left: usize,
id_right: usize,
}

95
src/tasks/day10.rs Normal file
View File

@@ -0,0 +1,95 @@
use crate::utils;
use regex::Regex;
pub fn task1() {
let input = utils::read_file("input/day10.txt");
// position=<-4, 3> velocity=< 2, 0>
let regex = Regex::new(
r"position=<\s*(?P<x>-?\d+),\s*(?P<y>-?\d+)> velocity=<\s*(?P<vx>-?\d+),\s*(?P<vy>-?\d+)>",
)
.unwrap();
let mut lights: Vec<Light> = input
.lines()
//.inspect(|line| println!("{}", line))
.map(|line| {
let cap = regex.captures(line).unwrap();
Light {
x: cap["x"].parse::<i32>().unwrap(),
y: cap["y"].parse::<i32>().unwrap(),
vx: cap["vx"].parse::<i32>().unwrap(),
vy: cap["vy"].parse::<i32>().unwrap(),
}
})
.collect();
// for light in lights.iter() {
// println!("{:?}", light);
// }
let mut old_area = get_area(&lights);
let mut time = 0;
loop {
time += 1;
let new_lights: Vec<Light> = lights.iter().map(|light| light.move_copy()).collect();
// print_lights(&new_lights);
let new_area = get_area(&new_lights);
// println!("Area: {} ", new_area);
if new_area > old_area {
break;
} else {
lights = new_lights;
old_area = new_area;
}
}
println!("Found a minimum after {} seconds", time - 1);
print_lights(&lights);
}
fn get_area(lights: &[Light]) -> usize {
let xmin = lights.iter().map(|it| it.x).min().unwrap();
let xmax = lights.iter().map(|it| it.x).max().unwrap();
let ymin = lights.iter().map(|it| it.y).min().unwrap();
let ymax = lights.iter().map(|it| it.y).max().unwrap();
(xmax - xmin) as usize * (ymax - ymin) as usize
}
fn print_lights(lights: &[Light]) {
let xmin = lights.iter().map(|it| it.x).min().unwrap();
let xmax = lights.iter().map(|it| it.x).max().unwrap();
let ymin = lights.iter().map(|it| it.y).min().unwrap();
let ymax = lights.iter().map(|it| it.y).max().unwrap();
let width = xmax - xmin + 1;
let height = ymax - ymin + 1;
let mut screen: Vec<Vec<u8>> = Vec::with_capacity(height as usize);
for _ in 0..=height {
let mut chars = Vec::with_capacity(width as usize);
chars.resize(width as usize + 1, b'.');
screen.push(chars);
}
lights
.iter()
.for_each(|light| screen[(light.y - ymin) as usize][(light.x - xmin) as usize] = b'#');
for line in screen.iter() {
println!("{}", String::from_utf8(line.clone()).unwrap());
}
}
#[derive(Debug)]
struct Light {
x: i32,
y: i32,
vx: i32,
vy: i32,
}
impl Light {
fn move_copy(&self) -> Self {
Light {
x: self.x + self.vx,
y: self.y + self.vy,
vx: self.vx,
vy: self.vy,
}
}
}

124
src/tasks/day11.rs Normal file
View File

@@ -0,0 +1,124 @@
pub fn task1() {
let square_size = 3;
let serial = 6392;
let result = (1..=300 - square_size)
.flat_map(|x: i32| (1..=300 - square_size).map(move |y: i32| (x, y)))
.map(|(x, y)| {
let power: i32 = (x..x + square_size)
.map(|x| {
(y..y + square_size)
.map(move |y| fuel_level(x, y, serial))
.sum::<i32>()
})
.sum();
(x, y, power)
})
.max_by_key(|(_, _, value)| *value);
println!("{:?}", result);
}
pub fn task2() {
let serial = 6392;
let mut values: Vec<Vec<i32>> = Vec::with_capacity(301);
for x in 0..=300 {
let mut v: Vec<i32> = Vec::with_capacity(301);
for y in 0..=300 {
v.push(fuel_level(x, y, serial));
}
values.push(v);
}
let values = &values;
let result = (1..300)
.map(|square_size| {
let result = (1..=300 - square_size)
.flat_map(|x: i32| (1..=300 - square_size).map(move |y: i32| (x, y)))
.map(|(x, y)| {
let power: i32 = (x..x + square_size)
.map(|x| {
(y..y + square_size)
.map(move |y| values[x as usize][y as usize])
.sum::<i32>()
})
.sum();
(x, y, power)
})
.max_by_key(|(_, _, value)| *value)
.unwrap();
(result.0, result.1, result.2, square_size)
})
.max_by_key(|result| result.2);
println!("{:?}", result);
}
pub fn task2_fast() {
let serial = 6392;
let mut cache: Vec<Vec<i32>> = Vec::with_capacity(301);
for x in 0_usize..=300 {
let mut v: Vec<i32> = Vec::with_capacity(301);
for y in 0_usize..=300 {
if x == 0 || y == 0 {
v.push(0);
} else {
v.push(
fuel_level(x as i32, y as i32, serial) + v[v.len() - 1] + cache[x - 1][y]
- cache[x - 1][y - 1],
)
}
}
cache.push(v);
}
let values = &cache;
for x in 0_usize..=300 {
for y in 0_usize..=300 {
if x != 0 && y != 0 {
let cached = area_sum(values, x, y, 1);
let calc = fuel_level(x as i32, y as i32, serial);
//println!("{},{}: {} ({})", x, y, values[x][y], calc);
assert_eq!(calc, cached);
}
}
}
let result = (1..=300)
.map(|square_size| {
let result = (1..=301 - square_size)
.flat_map(|x: usize| (1..=301 - square_size).map(move |y: usize| (x, y)))
.map(|(x, y)| (x, y, area_sum(values, x, y, square_size)))
.max_by_key(|(_, _, value)| *value)
.unwrap();
(result.0, result.1, result.2, square_size)
})
.max_by_key(|result| result.2);
println!("{:?}", result);
}
fn area_sum(values: &[Vec<i32>], x: usize, y: usize, length: usize) -> i32 {
values[x + length - 1][y + length - 1] + values[x - 1][y - 1]
- values[x - 1][y + length - 1]
- values[x + length - 1][y - 1]
}
fn fuel_level(x: i32, y: i32, serial: i32) -> i32 {
let rack_id = x + 10;
let mut power = rack_id * y;
power += serial;
power *= rack_id;
power = power / 100 % 10;
power -= 5;
power
}
mod test {
#[test]
fn name() {
use super::fuel_level;
assert_eq!(fuel_level(3, 5, 8), 4);
assert_eq!(fuel_level(122, 79, 57), -5);
assert_eq!(fuel_level(217, 196, 39), 0);
assert_eq!(fuel_level(101, 153, 71), 4);
}
}

54
src/tasks/day12.rs Normal file
View File

@@ -0,0 +1,54 @@
use crate::utils;
use std::collections::HashMap;
use std::ops::Add;
pub fn task1() {
let input = utils::read_file("input/day12.txt");
let mut input = input.lines();
let num_generations = 20;
let mut state: Vec<char> = "."
.repeat(num_generations)
.add(&input.next().unwrap()[15..])
.add(&".".repeat(num_generations + 2))
.chars()
.collect();
let mut transformations: HashMap<String, char> = HashMap::new();
input.next();
for line in input {
let key = line.split(" => ").next().unwrap();
transformations.insert(key.to_string(), line.chars().last().unwrap());
}
for _ in 0..num_generations {
println!("{}", state.iter().collect::<String>());
let mut new_state = state.clone();
for (i, c) in new_state[2..state.len() - 2].iter_mut().enumerate() {
let next = transformations.get(&state[i..i + 5].iter().collect::<String>());
if let Some(cc) = next {
*c = *cc;
} else {
*c = '.';
}
}
state = new_state;
}
println!("{}", state.iter().collect::<String>());
let sum: isize = state
.iter()
.enumerate()
.map(|(i, c)| {
if *c == '#' {
i as isize - (num_generations as isize)
} else {
0
}
})
.sum();
println!("Result: {}", sum);
}

146
src/tasks/day13.rs Normal file
View File

@@ -0,0 +1,146 @@
use crate::utils;
use std::collections::HashMap;
pub fn task1() {
let (map, mut carts) = read_input();
println!("We have {} carts initially", carts.len());
loop {
perform_round(&map, &mut carts);
}
}
fn read_input() -> (Vec<Vec<char>>, Vec<Cart>) {
let input = utils::read_file("input/day13.txt");
let input: Vec<&str> = input.lines().collect();
let width = input[0].len();
let height = input.len();
let mut map = Vec::new();
let mut inner_vec = Vec::new();
inner_vec.resize(height, ' ');
map.resize(width, inner_vec);
let mut carts = Vec::new();
let tiles = vec!['|', '-', '/', '\\', '+'];
for (y, line) in input.iter().enumerate() {
for (x, c) in line.chars().enumerate() {
if tiles.contains(&c) {
map[x][y] = c;
} else if c != ' ' {
map[x][y] = match c {
'>' => '-',
'<' => '-',
'^' => '-',
'v' => '-',
_ => panic!("{} is invalid input char at this point", c),
};
carts.push(Cart {
x,
y,
direction: c,
intersections_visited: 0,
active: true,
});
}
}
}
(map, carts)
}
#[derive(Debug)]
struct Cart {
x: usize,
y: usize,
direction: char,
intersections_visited: usize,
active: bool,
}
fn perform_round(map: &[Vec<char>], carts: &mut Vec<Cart>) {
carts.sort_unstable_by(|a, b| {
if a.y == b.y {
a.x.cmp(&b.x)
} else {
a.y.cmp(&b.y)
}
});
let mut positions: HashMap<(usize, usize), usize> = carts
.iter()
.enumerate()
.filter(|(_, cart)| cart.active)
.map(|(i, cart)| ((cart.x, cart.y), i))
.collect();
for cart_index in 0..carts.len() {
let cart = &mut carts[cart_index];
if !cart.active {
continue;
}
let pos_old = (cart.x, cart.y);
match cart.direction {
'>' => cart.x += 1,
'<' => cart.x -= 1,
'^' => cart.y -= 1,
'v' => cart.y += 1,
c => panic!("invalid direction {}", c),
}
cart.direction = match (cart.direction, map[cart.x][cart.y]) {
('>', '/') => '^',
('>', '\\') => 'v',
('<', '/') => 'v',
('<', '\\') => '^',
('^', '/') => '>',
('^', '\\') => '<',
('v', '/') => '<',
('v', '\\') => '>',
(direction, '+') => {
let new_direction = match cart.intersections_visited % 3 {
0 => match direction {
'>' => '^',
'^' => '<',
'<' => 'v',
'v' => '>',
_ => panic!("Invalid direction"),
},
1 => direction,
2 => match direction {
'>' => 'v',
'^' => '>',
'<' => '^',
'v' => '<',
_ => panic!("Invalid direction"),
},
_ => panic!("modulo 3 cannot be larger than 2"),
};
cart.intersections_visited += 1;
new_direction
}
(_, _) => cart.direction,
};
if positions.contains_key(&(cart.x, cart.y)) {
// Task1: panic here with coordinates
println!("We have a collision at {},{}!", cart.x, cart.y);
let other_index = positions[&(cart.x, cart.y)];
cart.active = false;
if !carts[other_index].active {
panic!("that one crashed already before!");
}
carts[other_index].active = false;
positions.remove(&(carts[cart_index].x, carts[cart_index].y));
positions.remove(&pos_old);
println!(
"{} carts left",
carts.iter().filter(|cart| cart.active).count()
);
} else {
positions.remove(&pos_old);
positions.insert((cart.x, cart.y), cart_index);
}
}
if carts.iter().filter(|cart| cart.active).count() == 1 {
panic!(
"exactly one active cart left: {:?}",
carts.iter().find(|cart| cart.active)
);
}
}

55
src/tasks/day14.rs Normal file
View File

@@ -0,0 +1,55 @@
pub fn task1() {
let input: usize = 509671;
let mut scores = vec![3, 7];
let mut recipes = vec![0, 1];
while scores.len() < input + 10 {
let mut score: usize = recipes.iter().map(|recipe| scores[*recipe]).sum();
if score >= 10 {
scores.push(1);
score -= 10;
}
scores.push(score);
for recipe in recipes.iter_mut() {
*recipe = (*recipe + 1 + scores[*recipe]) % scores.len();
}
}
let result = scores[input..input + 10]
.iter()
.map(|s| s.to_string())
.collect::<String>();
println!("Last 10 for {}: {}", input, result);
}
pub fn task2() {
let input = vec![5, 0, 9, 6, 7, 1];
let mut scores = vec![3, 7];
let mut recipes = vec![0, 1];
while scores.len() < 7
|| scores[scores.len() - 6..] != input[..]
&& scores[scores.len() - 7..scores.len() - 1] != input[..]
{
let mut score: usize = recipes.iter().map(|recipe| scores[*recipe]).sum();
if score >= 10 {
scores.push(1);
score -= 10;
}
scores.push(score);
for recipe in recipes.iter_mut() {
*recipe = (*recipe + 1 + scores[*recipe]) % scores.len();
}
}
if scores[scores.len() - 6..] != input[..] {
println!("{}", scores.len() - 7)
} else {
println!("{}", scores.len() - 8)
}
// 20227890 too high
}

488
src/tasks/day15.rs Normal file
View File

@@ -0,0 +1,488 @@
use crate::utils;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::VecDeque;
use std::fmt::Display;
const HEALTH: i32 = 200;
pub fn task1() {
let input = utils::read_file("input/day15.txt");
let mut game = Game::from_input(&input.lines().collect(), 3, 3);
println!("{}", game);
let mut round = 0;
while game.round() {
round += 1;
// println!("{}", game);
// println!("round was {}", round);
}
println!("Final full round was {}", round);
println!(
"Result: {}",
game.units.iter().map(|it| it.health).sum::<i32>() * round
);
}
pub fn task2() {
let input = utils::read_file("input/day15.txt");
let input = input.lines().collect();
let mut highest_fail = 3;
let mut lowest_win = None::<i32>;
while lowest_win.is_none() || lowest_win.unwrap() - 1 > highest_fail {
let attack = match lowest_win {
Some(upper) => highest_fail + (upper - highest_fail) / 2,
None => 2 * highest_fail,
};
let mut game = Game::from_input(&input, 3, attack);
let initial_elve_count = game
.units
.iter()
.filter(|unit| unit.warrior_type == WarriorType::Elve)
.count();
let mut round = 0;
while game.round() {
round += 1;
}
if game
.units
.iter()
.filter(|unit| unit.warrior_type == WarriorType::Elve)
.count()
== initial_elve_count
{
lowest_win = Some(attack);
} else {
highest_fail = attack;
}
println!(
"Result: {}",
game.units.iter().map(|it| it.health).sum::<i32>() * round
);
}
println!("Searching stopped with lowest win {:?}", lowest_win); // 7169 too low
}
#[derive(Clone, PartialEq)]
enum Tile {
Empty,
Wall,
}
#[derive(Clone, Copy, PartialEq, Debug)]
enum WarriorType {
Elve,
Goblin,
}
impl WarriorType {
fn enemy_type(&self) -> Self {
use self::WarriorType::*;
match self {
Elve => Goblin,
Goblin => Elve,
}
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
struct Position(usize, usize);
impl Position {
fn neighbors(&self, width: usize, height: usize) -> Vec<Position> {
vec![
(self.0 as isize, self.1 as isize - 1),
(self.0 as isize - 1, self.1 as isize),
(self.0 as isize + 1, self.1 as isize),
(self.0 as isize, self.1 as isize + 1),
]
.into_iter()
.filter(|p| p.0 > 0 && p.0 < width as isize - 1 && p.1 > 0 && p.1 < height as isize - 1)
.map(|it| Position(it.0 as usize, it.1 as usize))
.collect()
}
fn manhattan_distance(&self, other: &Self) -> usize {
let a = if self.0 > other.0 {
self.0 - other.0
} else {
other.0 - self.0
};
let b = if self.1 > other.1 {
self.1 - other.1
} else {
other.1 - self.1
};
a + b
}
}
impl PartialOrd for Position {
fn partial_cmp(&self, other: &Self) -> std::option::Option<std::cmp::Ordering> {
if self.1 == other.1 {
Some(self.0.cmp(&other.0))
} else {
Some(self.1.cmp(&other.1))
}
}
}
impl Ord for Position {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
if self.1 == other.1 {
self.0.cmp(&other.0)
} else {
self.1.cmp(&other.1)
}
}
}
#[derive(Debug)]
struct Warrior {
warrior_type: WarriorType,
position: Position,
health: i32,
attack: i32,
}
struct Game {
units: Vec<Warrior>,
/// [x, y]
tiles: Vec<Vec<Tile>>,
width: usize,
height: usize,
}
impl Game {
fn closest_fighting_position(
&self,
from: Position,
target_type: WarriorType,
) -> Option<Position> {
let mut map = Map::from_game(self, from);
for unit in self.units.iter() {
if unit.warrior_type == target_type {
for neighbor in unit.position.neighbors(self.width, self.height) {
if map.fields[neighbor.0][neighbor.1] == MapTile::Empty {
map.fields[neighbor.0][neighbor.1] = MapTile::TargetNonOccupied;
}
}
}
}
map.find_closest_target(from)
}
fn next_position(&self, from: Position, to: Position) -> Option<Position> {
if from == to {
return Some(from);
}
// let input = vec![
// (1, Position(from.0, from.1 - 1)),
// (2, Position(from.0 - 1, from.1)),
// (3, Position(from.0 + 1, from.1)),
// (4, Position(from.0, from.1 + 1)),
// ];
// if let Some((_, best)) = input
// .iter()
// .filter_map(|(delta, start)| {
// let map = Map::from_game(&self, from);
// if let Some(path) = map.shortest_path(*start, to) {
// Some((delta + path.len() * 10, *path.first().unwrap_or(start)))
// } else {
// None
// }
// })
// .min_by_key(|(d, _)| *d)
// {
// Some(best)
// } else {
// None
// }
let map = Map::from_game(self, from);
map.shortest_path(from, to)
.map(|path| *path.get(1).unwrap_or(&from))
}
/// Returns true if a full round was played, false if the round aborted because all
/// enemies of one party are dead
fn round(&mut self) -> bool {
self.units.sort_unstable_by_key(|it| it.position);
let mut curr = 0;
while curr < self.units.len() {
if !self
.units
.iter()
.any(|warrior| warrior.warrior_type == self.units[curr].warrior_type.enemy_type())
{
println!("There are no enemies anymore!");
return false;
}
// movement phase
if let Some(next_target_position) = self.closest_fighting_position(
self.units[curr].position,
self.units[curr].warrior_type.enemy_type(),
) {
if self.units[curr].position != next_target_position {
if let Some(next_position) =
self.next_position(self.units[curr].position, next_target_position)
{
// println!(
// "{:?} moves to {:?} via {:?}",
// self.units[curr].position, next_target_position, next_position
// );
self.units[curr].position = next_position;
} else {
panic!("We have a reachable target but no path to it! {:?} wants to go to {:?}", self.units[curr], next_target_position);
}
}
}
// attack phase
let neighbors = self.units[curr].position.neighbors(self.width, self.height);
let mut close_enemies: Vec<usize> = self
.units
.iter()
.enumerate()
.filter(|(_, it)| it.warrior_type == self.units[curr].warrior_type.enemy_type())
.filter(|(_, it)| neighbors.contains(&it.position))
.map(|(i, _)| i)
.collect();
close_enemies.sort_unstable_by(|a, b| {
let a = &self.units[*a];
let b = &self.units[*b];
if a.health == b.health {
a.position.cmp(&b.position)
} else {
a.health.cmp(&b.health)
}
});
if let Some(closest_index) = close_enemies.first() {
if self.units[*closest_index]
.position
.manhattan_distance(&self.units[curr].position)
> 1
{
panic!("Distance WTF")
}
let attack = self.units[curr].attack;
let enemy = &mut self.units[*closest_index];
enemy.health -= attack;
if enemy.health <= 0 {
let enemy = self.units.remove(*closest_index);
if *closest_index < curr {
curr -= 1;
}
self.tiles[enemy.position.0][enemy.position.1] = Tile::Empty;
}
}
curr += 1;
}
true
}
fn from_input(input: &Vec<&str>, goblin_attack: i32, elve_attack: i32) -> Self {
use self::Tile::*;
use self::WarriorType::*;
let width = input[0].len();
let height = input.len();
let mut inner_vec = Vec::new();
inner_vec.resize(height, Empty);
let mut tiles = Vec::new();
tiles.resize(width, inner_vec);
let mut units = Vec::new();
for (y, line) in input.iter().enumerate() {
for (x, c) in line.chars().enumerate() {
tiles[x][y] = match c {
'.' => Empty,
'#' => Wall,
'E' => {
units.push(Warrior {
warrior_type: Elve,
position: Position(x, y),
health: HEALTH,
attack: elve_attack,
});
Empty
}
'G' => {
units.push(Warrior {
warrior_type: Goblin,
position: Position(x, y),
health: HEALTH,
attack: goblin_attack,
});
Empty
}
c => panic!("Unexpected input character '{}'", c),
}
}
}
Game {
units,
tiles,
width,
height,
}
}
}
impl Display for Game {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
use self::Tile::*;
for y in 0..self.height {
let mut line = String::with_capacity(self.width);
for x in 0..self.width {
if let Some(warrior) = self.units.iter().find(|it| it.position == Position(x, y)) {
line.push(match warrior.warrior_type {
WarriorType::Elve => 'E',
WarriorType::Goblin => 'G',
});
} else {
line.push(match &self.tiles[x][y] {
Empty => '.',
Wall => '#',
});
}
}
f.write_str(&line)?;
f.write_str("\n")?;
}
Ok(())
}
}
#[derive(Debug)]
struct Map {
fields: Vec<Vec<MapTile>>,
width: usize,
height: usize,
}
#[derive(PartialEq, Debug)]
enum MapTile {
Empty,
TargetNonOccupied,
Occupied,
}
impl Display for Map {
fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
use self::MapTile::*;
for y in 0..self.height {
let mut line = String::with_capacity(self.width);
for x in 0..self.width {
line.push(match &self.fields[x][y] {
Empty => '.',
Occupied => 'X',
TargetNonOccupied => 'o',
});
}
f.write_str(&line)?;
f.write_str("\n")?;
}
Ok(())
}
}
impl Map {
fn from_game(game: &Game, clear: Position) -> Self {
let mut fields = Vec::with_capacity(game.width);
for x in 0..game.width {
let mut new = Vec::with_capacity(game.height);
for y in 0..game.height {
new.push(match &game.tiles[x][y] {
Tile::Empty => MapTile::Empty,
Tile::Wall => MapTile::Occupied,
});
}
fields.push(new);
}
for warrior in game.units.iter() {
fields[warrior.position.0][warrior.position.1] = MapTile::Occupied;
}
fields[clear.0][clear.1] = MapTile::Empty;
Map {
fields,
width: game.width,
height: game.height,
}
}
fn shortest_path(&self, from: Position, to: Position) -> Option<Vec<Position>> {
if to == from {
return Some(vec![]);
}
if self.fields[from.0][from.1] != MapTile::Empty {
return None;
}
let mut open: VecDeque<(Option<Position>, Position)> = VecDeque::new();
open.push_back((None, from));
let mut predecessors: HashMap<Position, Option<Position>> = HashMap::new();
while let Some((predecessor, curr_pos)) = open.pop_front() {
predecessors.insert(curr_pos, predecessor);
if curr_pos == to {
break;
}
if self.fields[curr_pos.0][curr_pos.1] != MapTile::Empty {
continue;
}
for pos in curr_pos.neighbors(self.width, self.height) {
if !predecessors.contains_key(&pos) && !open.iter().any(|it| it.1 == pos) {
open.push_back((Some(curr_pos), pos));
}
}
}
if let Some(Some(_)) = predecessors.get(&to) {
let mut result: Vec<Position> = Vec::new();
let mut current = to;
result.push(current);
while let Some(Some(predecessor)) = predecessors.get(&current) {
result.push(*predecessor);
current = *predecessor;
}
result.reverse();
Some(result)
} else {
None
}
}
fn find_closest_target(&self, from: Position) -> Option<Position> {
let mut open: VecDeque<(usize, Position)> = VecDeque::new();
open.push_back((0, from));
let mut visited: HashSet<Position> = HashSet::new();
let mut current_found_distance = usize::max_value();
let mut candidates: Vec<Position> = Vec::new();
while let Some((curr_dist, curr_pos)) = open.pop_front() {
if curr_dist > current_found_distance {
break;
}
if self.fields[curr_pos.0][curr_pos.1] == MapTile::TargetNonOccupied {
candidates.push(curr_pos);
current_found_distance = curr_dist;
// all others would have a higher distance and therefore are not relevant
continue;
}
if self.fields[curr_pos.0][curr_pos.1] == MapTile::Occupied {
continue;
}
for pos in curr_pos.neighbors(self.width, self.height) {
if !visited.contains(&pos) && !open.iter().any(|it| it.1 == pos) {
open.push_back((curr_dist + 1, pos));
}
}
visited.insert(curr_pos);
}
candidates.sort_unstable();
candidates.first().copied()
}
}

630
src/tasks/day16.rs Normal file
View File

@@ -0,0 +1,630 @@
use std::collections::{HashMap, HashSet};
use std::ops::{BitAnd, BitOr};
use itertools::Itertools;
pub fn task1() {
let count = include_str!("../../input/day16.txt")
.split_once("\n\n\n\n")
.unwrap()
.0
.split("\n\n")
.map(|sample_input| parse(sample_input))
.map(matches_count)
.filter(|count| *count >= 3)
.count();
println!("Day 16 part1: {count}");
}
pub fn task2() {
let (samples, program) = include_str!("../../input/day16.txt")
.split_once("\n\n\n\n")
.unwrap();
let code_to_op_candidates = samples
.split("\n\n")
.map(|sample_input| parse(sample_input))
.map(|sample| (sample.1.opcode, matches_ops(sample)))
.into_group_map_by(|x| x.0);
// let code_to_op: HashMap<usize, HashSet<Op>> =
let mut code_to_op_candidates: HashMap<_, _> = code_to_op_candidates
.into_iter()
.map(|(code, ops)| {
let mut set: HashSet<_> = HashSet::from_iter(OPS.iter().map(ToOwned::to_owned));
for (_, candidate_set) in ops {
set = set
.intersection(&candidate_set)
.map(ToOwned::to_owned)
.collect();
}
(code, set)
})
.collect();
let mut codes_to_op: HashMap<usize, Op> = HashMap::new();
loop {
let single = code_to_op_candidates.iter().find(|(_, ops)| ops.len() == 1);
let Some(single) = single else {
break;
};
let code = *single.0;
let op = *single.1.iter().next().unwrap();
codes_to_op.insert(code, op);
code_to_op_candidates.iter_mut().for_each(|(_, ops)| {
ops.remove(&op);
});
}
if codes_to_op.len() != OPS.len() {
panic!("Bad final opcode assignments: {codes_to_op:?}");
}
let program: Vec<Instruction> = program.lines().map(parse_instruction).collect();
let mut registers = Registers([0, 0, 0, 0]);
for instruction in program {
let op: Op = codes_to_op[&instruction.opcode];
registers = op.process(registers, instruction);
}
println!("Day 16 part 2: {}", registers.0[0]);
}
fn parse(sample: &str) -> Sample {
let (before, instruction, after) = sample.lines().collect_tuple().unwrap();
let before: Vec<_> = before
.trim_start_matches("Before: [")
.trim_end_matches("]")
.split(", ")
.collect();
let before = Registers::from(before);
let after: Vec<_> = after
.trim_start_matches("After: [")
.trim_end_matches("]")
.split(", ")
.collect();
let after = Registers::from(after);
let instruction = parse_instruction(instruction);
Sample(before, instruction, after)
}
fn parse_instruction(instruction: &str) -> Instruction {
let instruction: Vec<usize> = instruction.split(" ").map(|x| x.parse().unwrap()).collect();
let instruction = Instruction {
opcode: instruction[0],
a: instruction[1],
b: instruction[2],
c: instruction[3],
};
instruction
}
fn matches(sample: Sample, op: Op) -> bool {
op.process(sample.0, sample.1) == sample.2
}
fn matches_count(sample: Sample) -> usize {
let vec = OPS.iter().filter(|op| matches(sample, **op)).collect_vec();
vec.len()
}
fn matches_ops(sample: Sample) -> HashSet<Op> {
OPS.iter()
.filter(|op| matches(sample, **op))
.map(|op| op.to_owned())
.collect()
}
const OPS: &[Op] = &[
Op::AddR,
Op::AddI,
Op::MulR,
Op::MulI,
Op::BanR,
Op::BanI,
Op::BorR,
Op::BorI,
Op::SetR,
Op::SetI,
Op::GtIR,
Op::GtRI,
Op::GtRR,
Op::EqIR,
Op::EqRI,
Op::EqRR,
];
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
enum Op {
AddR,
AddI,
MulR,
MulI,
BanR,
BanI,
BorR,
BorI,
SetR,
SetI,
GtIR,
GtRI,
GtRR,
EqIR,
EqRI,
EqRR,
}
impl Op {
fn process(&self, registers: Registers, instruction: Instruction) -> Registers {
let mut result = registers.0.clone();
match self {
Op::AddR => {
result[instruction.c] = result[instruction.a] + result[instruction.b];
}
Op::AddI => {
result[instruction.c] = result[instruction.a] + instruction.b as i32;
}
Op::MulR => {
result[instruction.c] = result[instruction.a] * result[instruction.b];
}
Op::MulI => {
result[instruction.c] = result[instruction.a] * instruction.b as i32;
}
Op::BanR => {
result[instruction.c] = result[instruction.a].bitand(result[instruction.b]);
}
Op::BanI => {
result[instruction.c] = result[instruction.a].bitand(instruction.b as i32);
}
Op::BorR => {
result[instruction.c] = result[instruction.a].bitor(result[instruction.b]);
}
Op::BorI => {
result[instruction.c] = result[instruction.a].bitor(instruction.b as i32);
}
Op::SetR => {
result[instruction.c] = result[instruction.a];
}
Op::SetI => {
result[instruction.c] = instruction.a as i32;
}
Op::GtIR => {
result[instruction.c] = if instruction.a as i32 > result[instruction.b] {
1
} else {
0
}
}
Op::GtRI => {
result[instruction.c] = if result[instruction.a] > instruction.b as i32 {
1
} else {
0
}
}
Op::GtRR => {
result[instruction.c] = if result[instruction.a] > result[instruction.b] {
1
} else {
0
}
}
Op::EqIR => {
result[instruction.c] = if instruction.a as i32 == result[instruction.b] {
1
} else {
0
}
}
Op::EqRI => {
result[instruction.c] = if result[instruction.a] == instruction.b as i32 {
1
} else {
0
}
}
Op::EqRR => {
result[instruction.c] = if result[instruction.a] == result[instruction.b] {
1
} else {
0
}
}
}
Registers(result)
}
}
#[derive(Copy, Clone)]
struct Sample(Registers, Instruction, Registers);
#[derive(Eq, PartialEq, Copy, Clone, Debug)]
struct Registers([i32; 4]);
impl From<Vec<&str>> for Registers {
fn from(value: Vec<&str>) -> Self {
let values: Vec<_> = value.iter().map(|x| x.parse().unwrap()).collect();
Registers([values[0], values[1], values[2], values[3]])
}
}
#[derive(Copy, Clone)]
struct Instruction {
opcode: usize,
a: usize,
b: usize,
c: usize,
}
#[cfg(test)]
mod test {
use crate::tasks::day16::{matches_count, parse, Instruction, Op, Registers};
#[test]
fn example1() {
let input = "Before: [3, 2, 1, 1]\n\
9 2 1 2\n\
After: [3, 2, 2, 1]";
assert_eq!(matches_count(parse(input)), 3);
}
#[test]
#[allow(non_snake_case)]
fn test_AddR() {
let op = Op::AddR;
let result = op.process(
Registers([3, 4, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1,
c: 3,
},
);
assert_eq!(7, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_AddI() {
let op = Op::AddI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1337,
c: 3,
},
);
assert_eq!(1338, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_MulR() {
let op = Op::MulR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 2,
c: 3,
},
);
assert_eq!(6, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_MulI() {
let op = Op::MulI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1337,
c: 3,
},
);
assert_eq!(2 * 1337, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_BanR() {
let op = Op::BanR;
let result = op.process(
Registers([0x10101, 0x10110, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1,
c: 3,
},
);
assert_eq!(0x10100, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_BanI() {
let op = Op::BanI;
let result = op.process(
Registers([0x10101, 2, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 0x10110,
c: 3,
},
);
assert_eq!(0x10100, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_BorR() {
let op = Op::BorR;
let result = op.process(
Registers([0x10101, 0x10110, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 1,
c: 3,
},
);
assert_eq!(0x10111, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_BorI() {
let op = Op::BorI;
let result = op.process(
Registers([0x10101, 2, 3, 4]),
Instruction {
opcode: 0,
a: 0,
b: 0x10110,
c: 3,
},
);
assert_eq!(0x10111, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_SetR() {
let op = Op::SetR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(2, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_SetI() {
let op = Op::SetI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1234,
b: 1,
c: 3,
},
);
assert_eq!(1234, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_GtIR_true() {
let op = Op::GtIR;
let result = op.process(
Registers([1, 29, 3, 4]),
Instruction {
opcode: 0,
a: 30,
b: 1,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_GtIR_false() {
let op = Op::GtIR;
let result = op.process(
Registers([1, 1337, 3, 4]),
Instruction {
opcode: 0,
a: 1337,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_GtRI_true() {
let op = Op::GtRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 2,
b: 1,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_GtRI_false() {
let op = Op::GtRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 2,
b: 3,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_GtRR_true() {
let op = Op::GtRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 0,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_GtRR() {
let op = Op::GtRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_EqIR_true() {
let op = Op::EqIR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 0,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_EqIR_false() {
let op = Op::EqIR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_EqRI_true() {
let op = Op::EqRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 2,
b: 3,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_EqRI_false() {
let op = Op::EqRI;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_EqRR_true() {
let op = Op::EqRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 1,
c: 3,
},
);
assert_eq!(1, result.0[3]);
}
#[test]
#[allow(non_snake_case)]
fn test_EqRR_false() {
let op = Op::EqRR;
let result = op.process(
Registers([1, 2, 3, 4]),
Instruction {
opcode: 0,
a: 1,
b: 2,
c: 3,
},
);
assert_eq!(0, result.0[3]);
}
}

198
src/tasks/day17.rs Normal file
View File

@@ -0,0 +1,198 @@
use bmp::Image;
use itertools::Itertools;
use regex::Regex;
use crate::utils;
use std::{collections::HashMap, fmt::Display};
use Tile::*;
fn horizontal(line: &str) -> Option<(i32, i32, i32)> {
let regex = Regex::new(r"y=(?P<y>\d+), x=(?P<x1>\d+)..(?P<x2>\d+)").unwrap();
regex.captures(line).map(|m| {
(
m.name("y").unwrap().as_str().parse::<i32>().unwrap(),
m.name("x1").unwrap().as_str().parse::<i32>().unwrap(),
m.name("x2").unwrap().as_str().parse::<i32>().unwrap(),
)
})
}
fn vertical(line: &str) -> Option<(i32, i32, i32)> {
let regex = Regex::new(r"x=(?P<y>\d+), y=(?P<x1>\d+)..(?P<x2>\d+)").unwrap();
regex.captures(line).map(|m| {
(
m.name("y").unwrap().as_str().parse::<i32>().unwrap(),
m.name("x1").unwrap().as_str().parse::<i32>().unwrap(),
m.name("x2").unwrap().as_str().parse::<i32>().unwrap(),
)
})
}
pub fn task1() {
let input = utils::read_file("input/day17.txt");
let mut clay_tiles: HashMap<Pos, Tile> =
input.lines().fold(HashMap::new(), |mut tiles, line| {
if let Some((x, y1, y2)) = vertical(line) {
for y in y1..=y2 {
tiles.insert(Pos(x, y), Clay);
}
}
if let Some((y, x1, x2)) = horizontal(line) {
for x in x1..=x2 {
tiles.insert(Pos(x, y), Clay);
}
}
tiles
});
let (y_min, y_max) = clay_tiles
.keys()
.map(|p| p.1)
.minmax()
.into_option()
.unwrap();
flow(&mut clay_tiles, y_max, Pos(500, 0), Pos(500, 0));
let water_count = clay_tiles
.iter()
.filter(|(_, tile)| **tile == StuckWater || **tile == FallingWater)
.filter(|(p, _)| (y_min..=y_max).contains(&p.1))
.count();
println!("part 1 water count: {water_count}");
// print_tiles(&clay_tiles);
// 30605 too low
print_bmp(&clay_tiles);
let stuck_water = clay_tiles
.iter()
.filter(|(_, tile)| **tile == StuckWater)
.filter(|(p, _)| (y_min..=y_max).contains(&p.1))
.count();
println!("part 2 water count: {stuck_water}");
}
#[allow(dead_code)]
fn print_tiles(tiles: &HashMap<Pos, Tile>) {
let (x_min, x_max) = tiles.keys().map(|p| p.0).minmax().into_option().unwrap();
let (_y_min, y_max) = tiles.keys().map(|p| p.1).minmax().into_option().unwrap();
for y in 0..=y_max {
for x in x_min..=x_max {
let s = match tiles.get(&Pos(x, y)) {
Some(t) => format!("{t}"),
None => " ".to_string(),
};
print!("{s}");
}
print!("\n");
}
}
fn print_bmp(tiles: &HashMap<Pos, Tile>) {
let (x_min, x_max) = tiles.keys().map(|p| p.0).minmax().into_option().unwrap();
let (y_min, y_max) = tiles.keys().map(|p| p.1).minmax().into_option().unwrap();
let mut img = Image::new((x_max - x_min + 1) as u32, (y_max - y_min + 1) as u32);
for y in 0..=y_max {
for x in x_min..=x_max {
let color = match tiles.get(&Pos(x, y)) {
Some(t) => match t {
Clay => bmp::consts::BROWN,
FallingWater => bmp::consts::LIGHT_BLUE,
StuckWater => bmp::consts::DARK_BLUE,
},
None => bmp::consts::WHITE,
};
img.set_pixel((x - x_min) as u32, (y - y_min) as u32, color);
}
}
img.save("final.bmp").unwrap();
}
/// returns true iff going left/right and hit a wall
fn flow(tiles: &mut HashMap<Pos, Tile>, y_max: i32, pos: Pos, from: Pos) -> bool {
if pos.1 > y_max {
return false;
}
if let Some(Clay) = tiles.get(&pos) {
return true;
}
if let Some(StuckWater) = tiles.get(&pos) {
return true;
}
if tiles.contains_key(&pos) {
return false;
}
tiles.insert(pos, FallingWater);
// println!();
// print_tiles(tiles);
if flow(tiles, y_max, pos.down(), pos) {
let bumped_left = flow(tiles, y_max, pos.left(), pos);
let bumped_right = flow(tiles, y_max, pos.right(), pos);
if from.down() == pos {
if bumped_right && bumped_left {
fill(tiles, pos);
// println!();
// print_tiles(tiles);
return true;
}
} else if from.right() == pos && bumped_right {
return true;
} else if from.left() == pos && bumped_left {
return true;
}
}
false
}
fn fill(tiles: &mut HashMap<Pos, Tile>, pos: Pos) {
if let Some(FallingWater) = tiles.get(&pos) {
tiles.insert(pos, StuckWater);
fill(tiles, pos.left());
fill(tiles, pos.right());
}
}
#[derive(PartialEq, Eq)]
enum Tile {
Clay,
FallingWater,
StuckWater,
}
impl Display for Tile {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let s = match self {
Clay => "#",
FallingWater => "|",
StuckWater => "~",
};
f.write_str(s)
}
}
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
struct Pos(i32, i32);
impl Pos {
fn left(&self) -> Self {
Pos(self.0 - 1, self.1)
}
fn right(&self) -> Self {
Pos(self.0 + 1, self.1)
}
fn down(&self) -> Self {
Pos(self.0, self.1 + 1)
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn part1() {
assert_eq!(horizontal("y=10, x=5..20"), Some((10, 5, 20)));
assert_eq!(vertical("x=10, y=5..20"), Some((10, 5, 20)));
}
}

145
src/tasks/day18.rs Normal file
View File

@@ -0,0 +1,145 @@
use std::collections::HashMap;
use itertools::Itertools;
use crate::utils;
pub fn task1() {
let initial = load_initial_map();
let fin = (0..10).fold(initial, |map, _| next_map(map));
let (trees, lumberyards) = resource_value(fin);
println!("Part 1 - {trees} x {lumberyards} = {}", trees * lumberyards);
}
pub fn task2() {
let mut map = load_initial_map();
const MINUTES: i32 = 1000000000;
let mut maps_at_time: HashMap<String, i32> = HashMap::new();
let mut minute = 0;
while minute < MINUTES {
if let Some(time) = maps_at_time.get(&hash(&map)) {
let delta = minute - time;
let remaining_minutes = MINUTES - minute;
let remaining_cycles = remaining_minutes / delta;
minute += remaining_cycles * delta;
}
maps_at_time.insert(hash(&map), minute);
minute += 1;
map = next_map(map);
}
let (trees, lumberyards) = resource_value(map);
println!("Part 1 - {trees} x {lumberyards} = {}", trees * lumberyards);
}
fn hash(map: &HashMap<Pos, char>) -> String {
let mut result = String::new();
let (x_min, x_max) = map.keys().map(|p| p.0).minmax().into_option().unwrap();
let (_y_min, y_max) = map.keys().map(|p| p.1).minmax().into_option().unwrap();
for y in 0..=y_max {
for x in x_min..=x_max {
let s = map[&Pos(x, y)];
result.push(s);
}
}
result
}
fn resource_value(fin: HashMap<Pos, char>) -> (usize, usize) {
let trees = fin.values().filter(|c| **c == '|').count();
let lumberyards = fin.values().filter(|c| **c == '#').count();
(trees, lumberyards)
}
fn load_initial_map() -> HashMap<Pos, char> {
let input = utils::read_file("input/day18.txt");
let initial: HashMap<Pos, char> = input
.lines()
.enumerate()
.flat_map(|(y, line)| {
line.chars()
.enumerate()
.map(|(x, c)| (Pos(x as i32, y as i32), c))
.collect_vec()
})
.collect();
initial
}
fn next_map(map: HashMap<Pos, char>) -> HashMap<Pos, char> {
map.keys()
.map(|p| {
let old = map[p];
let new = match old {
'.' => {
if neighbors(&map, *p)
.into_iter()
.filter(|c| *c == '|')
.count()
>= 3
{
'|'
} else {
'.'
}
}
'|' => {
if neighbors(&map, *p)
.into_iter()
.filter(|c| *c == '#')
.count()
>= 3
{
'#'
} else {
'|'
}
}
'#' => {
if neighbors(&map, *p).contains(&'#') && neighbors(&map, *p).contains(&'|') {
'#'
} else {
'.'
}
}
_ => panic!("unknown type"),
};
(*p, new)
})
.collect()
}
#[allow(dead_code)]
fn printmap(map: &HashMap<Pos, char>) {
println!();
let (x_min, x_max) = map.keys().map(|p| p.0).minmax().into_option().unwrap();
let (_y_min, y_max) = map.keys().map(|p| p.1).minmax().into_option().unwrap();
for y in 0..=y_max {
for x in x_min..=x_max {
let s = map[&Pos(x, y)];
print!("{s}");
}
print!("\n");
}
}
#[derive(Hash, Eq, PartialEq, Clone, Copy)]
struct Pos(i32, i32);
fn neighbors(map: &HashMap<Pos, char>, p: Pos) -> Vec<char> {
[
Pos(p.0 - 1, p.1 - 1),
Pos(p.0 - 1, p.1),
Pos(p.0 - 1, p.1 + 1),
Pos(p.0, p.1 - 1),
Pos(p.0, p.1 + 1),
Pos(p.0 + 1, p.1 - 1),
Pos(p.0 + 1, p.1),
Pos(p.0 + 1, p.1 + 1),
]
.into_iter()
.flat_map(|pos| map.get(&pos).map(|c| *c))
.collect_vec()
}

243
src/tasks/day19.rs Normal file
View File

@@ -0,0 +1,243 @@
use std::ops::{BitAnd, BitOr};
pub fn task1() {
let input = include_str!("../../input/day19.txt");
let result = run1(input, 1);
println!("Day 19 part 1: {result}");
}
pub fn task2() {
let mut a = 1i64;
let mut d = 948;
if a == 1 {
d += 10550400;
a = 0;
}
let mut f = 1;
'outer: loop {
let mut c = 1;
'inner: loop {
let b = f * c;
if b == d {
a = a + f;
} else if b > d {
// this is the important part: break the loop because otherwise we count and count
// and count ... but cannot reach the b == d condition without resetting c.
break 'inner;
}
c += 1;
if c > d {
break 'inner;
}
}
f += 1;
if f > d {
break 'outer;
}
}
println!("Day 19 part 2: {a}");
}
fn run1(input: &str, start_value: i32) -> i32 {
let (config, program) = input.split_once("\n").unwrap();
let ip_register: usize = config.split_once(" ").unwrap().1.parse().unwrap();
let program: Vec<Instruction> = program.lines().map(parse_instruction).collect();
let mut registers: Registers = [start_value, 0, 0, 0, 0, 0];
let mut ip = 0;
let mut count = 0;
loop {
//print!("ip={ip}, {registers:?}");
registers[ip_register] = ip as i32;
let instruction = program.get(ip).unwrap();
if ip == 2 {
println!("{registers:?}");
}
//print!("{instruction:?}");
let op: Op = instruction.opcode;
registers = op.process(registers, *instruction);
//println!("{registers:?}");
ip = registers[ip_register] as usize;
ip += 1;
if program.get(ip).is_none() {
break;
}
count += 1;
}
println!("executed instructions: {count}");
registers[0]
}
fn parse_instruction(instruction: &str) -> Instruction {
let instruction: Vec<_> = instruction.split(" ").collect();
let opcode = match instruction[0] {
"addr" => Op::AddR,
"addi" => Op::AddI,
"mulr" => Op::MulR,
"muli" => Op::MulI,
"banr" => Op::BanR,
"bani" => Op::BanI,
"borr" => Op::BorR,
"bori" => Op::BorI,
"setr" => Op::SetR,
"seti" => Op::SetI,
"gtir" => Op::GtIR,
"gtri" => Op::GtRI,
"gtrr" => Op::GtRR,
"eqir" => Op::EqIR,
"eqri" => Op::EqRI,
"eqrr" => Op::EqRR,
&_ => {
panic!("unknown op {}", instruction[0])
}
};
let instruction = Instruction {
opcode,
a: instruction[1].parse().unwrap(),
b: instruction[2].parse().unwrap(),
c: instruction[3].parse().unwrap(),
};
instruction
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
enum Op {
AddR,
AddI,
MulR,
MulI,
BanR,
BanI,
BorR,
BorI,
SetR,
SetI,
GtIR,
GtRI,
GtRR,
EqIR,
EqRI,
EqRR,
}
impl Op {
fn process(&self, registers: Registers, instruction: Instruction) -> Registers {
let mut result = registers.clone();
match self {
Op::AddR => {
result[instruction.c] = result[instruction.a] + result[instruction.b];
}
Op::AddI => {
result[instruction.c] = result[instruction.a] + instruction.b as i32;
}
Op::MulR => {
result[instruction.c] = result[instruction.a] * result[instruction.b];
}
Op::MulI => {
result[instruction.c] = result[instruction.a] * instruction.b as i32;
}
Op::BanR => {
result[instruction.c] = result[instruction.a].bitand(result[instruction.b]);
}
Op::BanI => {
result[instruction.c] = result[instruction.a].bitand(instruction.b as i32);
}
Op::BorR => {
result[instruction.c] = result[instruction.a].bitor(result[instruction.b]);
}
Op::BorI => {
result[instruction.c] = result[instruction.a].bitor(instruction.b as i32);
}
Op::SetR => {
result[instruction.c] = result[instruction.a];
}
Op::SetI => {
result[instruction.c] = instruction.a as i32;
}
Op::GtIR => {
result[instruction.c] = if instruction.a as i32 > result[instruction.b] {
1
} else {
0
}
}
Op::GtRI => {
result[instruction.c] = if result[instruction.a] > instruction.b as i32 {
1
} else {
0
}
}
Op::GtRR => {
result[instruction.c] = if result[instruction.a] > result[instruction.b] {
1
} else {
0
}
}
Op::EqIR => {
result[instruction.c] = if instruction.a as i32 == result[instruction.b] {
1
} else {
0
}
}
Op::EqRI => {
result[instruction.c] = if result[instruction.a] == instruction.b as i32 {
1
} else {
0
}
}
Op::EqRR => {
result[instruction.c] = if result[instruction.a] == result[instruction.b] {
1
} else {
0
}
}
}
result
}
}
type Registers = [i32; 6];
#[derive(Copy, Clone, Debug)]
struct Instruction {
opcode: Op,
a: usize,
b: usize,
c: usize,
}
#[cfg(test)]
mod test {
use crate::tasks::day19::run1;
#[test]
fn example1() {
let input = "#ip 0\n\
seti 5 0 1\n\
seti 6 0 2\n\
addi 0 1 0\n\
addr 1 2 3\n\
setr 1 0 0\n\
seti 8 0 4\n\
seti 9 0 5";
assert_eq!(run1(input, 0), 6);
}
}

257
src/tasks/day20.rs Normal file
View File

@@ -0,0 +1,257 @@
use self::Tile::*;
#[allow(unused_imports)]
use crate::utils;
use std::collections::VecDeque;
use std::collections::{HashMap, HashSet};
pub fn task1() {
let input = utils::read_file("input/day20.txt");
// let input = "^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$".to_string();
let input = &input[1..];
let mut map: HashMap<Point, Tile> = HashMap::new();
add_default_neighbors_for_room(&mut map, Point(0, 0));
parse_input(&mut map, input, Point(0, 0));
// print_map(&map);
println!(
"Most distant point: {:?}",
longest_shortest_path(&map, Point(0, 0))
);
println!(
"Rooms with minimal distance >= 1000: {}",
count_long_distances(&map, Point(0, 0), 1000)
);
}
/// Returns the end points of the parsed input
fn parse_input(map: &mut HashMap<Point, Tile>, input: &str, position: Point) -> HashSet<Point> {
// println!("{}, {:?}", input, position);
if input == "$" {
println!("End of the road.");
return vec![position].into_iter().collect();
}
let mut position = position;
let mut input = input;
let iterator = input.chars();
for c in iterator {
match c {
'(' => {
let (parts, rest) = split_parts(input);
let mut middle_points: HashSet<Point> = HashSet::new();
for part in parts {
if !part.is_empty() {
for x in parse_input(map, part, position) {
middle_points.insert(x);
}
}
}
let mut end_points: HashSet<Point> = HashSet::new();
for point in middle_points {
if !rest.is_empty() {
for x in parse_input(map, rest, point) {
end_points.insert(x);
}
}
}
return end_points;
}
'N' => {
position = Point(position.0, position.1 - 2);
add_default_neighbors_for_room(map, position);
map.insert(Point(position.0, position.1 + 1), Door);
input = &input[1..];
}
'E' => {
position = Point(position.0 + 2, position.1);
add_default_neighbors_for_room(map, position);
map.insert(Point(position.0 - 1, position.1), Door);
input = &input[1..];
}
'S' => {
position = Point(position.0, position.1 + 2);
add_default_neighbors_for_room(map, position);
map.insert(Point(position.0, position.1 - 1), Door);
input = &input[1..];
}
'W' => {
position = Point(position.0 - 2, position.1);
add_default_neighbors_for_room(map, position);
map.insert(Point(position.0 + 1, position.1), Door);
input = &input[1..];
}
'$' => break,
c => panic!(
"Stumbled upon a '{}' when reading input where it shouldn't be",
c
),
}
}
vec![position].into_iter().collect()
}
/// Splits the input by '|', but only by those that are not enclosed by further parenthesises.
/// The second return value is the rest after the closing parenthesis
fn split_parts(input: &str) -> (Vec<&str>, &str) {
// println!("Splitting '{}'", input);
let mut count = 0;
let mut closing_index = None::<usize>;
let mut last_separator = 0;
let mut parts = Vec::new();
for (i, c) in input.chars().enumerate() {
match c {
'(' => count += 1,
')' => {
count -= 1;
if count == 0 {
closing_index = Some(i);
parts.push(&input[last_separator + 1..i]);
break;
}
}
'|' => {
// println!("| at {} (depth {})", i, count);
if count == 1 {
parts.push(&input[last_separator + 1..i]);
last_separator = i;
}
}
_ => {}
}
}
let closing_index =
closing_index.unwrap_or_else(|| panic!("No matching closing parenthesis in {}", input));
(parts, &input[closing_index + 1..])
}
fn add_default_neighbors_for_room(map: &mut HashMap<Point, Tile>, position: Point) {
map.insert(position, Room);
for p in position.diagonals() {
map.insert(p, Wall);
}
for p in position.neighbors() {
map.entry(p).or_insert(Unknown);
}
}
#[allow(dead_code)]
fn print_map(map: &HashMap<Point, Tile>) {
let xmin = map.keys().min_by_key(|it| it.0).unwrap().0;
let xmax = map.keys().max_by_key(|it| it.0).unwrap().0;
let ymin = map.keys().min_by_key(|it| it.1).unwrap().1;
let ymax = map.keys().max_by_key(|it| it.1).unwrap().1;
for y in ymin..=ymax {
for x in xmin..=xmax {
if x == 0 && y == 0 {
print!("X")
} else {
print!(
"{}",
match map.get(&Point(x, y)) {
None => " ",
Some(Wall) => "#",
Some(Room) => ".",
Some(Unknown) => "#",
Some(Door) => {
if y % 2 == 0 {
"|"
} else {
"-"
}
}
}
);
}
}
println!();
}
}
fn longest_shortest_path(map: &HashMap<Point, Tile>, start: Point) -> Option<(Point, usize)> {
let mut distances: HashMap<Point, usize> = HashMap::with_capacity(map.len());
let mut open: VecDeque<(usize, Point)> = VecDeque::new();
let mut visited: HashSet<Point> = HashSet::new();
open.push_back((0, start));
visited.insert(start);
while let Some((distance, predecessor)) = open.pop_front() {
distances.insert(predecessor, distance);
for p in predecessor.neighbors() {
if let Some(Door) = map.get(&p) {
let room = predecessor.next_room(&p);
if !visited.contains(&room) {
visited.insert(room);
open.push_back((distance + 1, room));
}
}
}
}
if let Some((point, distance)) = distances.iter().max_by_key(|it| it.1) {
Some((*point, *distance))
} else {
None
}
}
fn count_long_distances(map: &HashMap<Point, Tile>, start: Point, threshold: usize) -> usize {
let mut distances: HashMap<Point, usize> = HashMap::with_capacity(map.len());
let mut open: VecDeque<(usize, Point)> = VecDeque::new();
let mut visited: HashSet<Point> = HashSet::new();
open.push_back((0, start));
visited.insert(start);
while let Some((distance, predecessor)) = open.pop_front() {
distances.insert(predecessor, distance);
for p in predecessor.neighbors() {
if let Some(Door) = map.get(&p) {
let room = predecessor.next_room(&p);
if !visited.contains(&room) {
visited.insert(room);
open.push_back((distance + 1, room));
}
}
}
}
distances
.iter()
.filter(|(_, distance)| **distance >= threshold)
.count()
}
#[derive(Eq, PartialEq, Hash, Clone, Copy, Debug)]
struct Point(i32, i32);
impl Point {
fn diagonals(&self) -> Vec<Point> {
vec![
Point(self.0 - 1, self.1 - 1),
Point(self.0 - 1, self.1 + 1),
Point(self.0 + 1, self.1 - 1),
Point(self.0 + 1, self.1 + 1),
]
}
fn neighbors(&self) -> Vec<Point> {
vec![
Point(self.0 - 1, self.1),
Point(self.0 + 1, self.1),
Point(self.0, self.1 - 1),
Point(self.0, self.1 + 1),
]
}
fn next_room(&self, other: &Self) -> Self {
Point(
self.0 + 2 * (other.0 - self.0),
self.1 + 2 * (other.1 - self.1),
)
}
}
enum Tile {
Unknown,
Room,
Wall,
Door,
}

229
src/tasks/day21.rs Normal file
View File

@@ -0,0 +1,229 @@
use std::collections::HashSet;
use std::ops::{BitAnd, BitOr};
pub fn task1() {
let input = include_str!("../../input/day21.txt");
let result = run1(input, 3007673);
println!("{result:?}");
}
fn run1(input: &str, start_value: i64) -> (i64, usize) {
let (config, program) = input.split_once("\n").unwrap();
let ip_register: usize = config.split_once(" ").unwrap().1.parse().unwrap();
let program: Vec<Instruction> = program.lines().map(parse_instruction).collect();
let mut registers: Registers = [start_value, 0, 0, 0, 0, 0];
let mut ip = 0;
let mut count = 0usize;
let mut seen: HashSet<_> = HashSet::new();
let mut last = 0;
loop {
//print!("ip={ip}, {registers:?}");
registers[ip_register] = ip as i64;
let instruction = program.get(ip).unwrap();
//print!("{instruction:?}");
let op: Op = instruction.opcode;
registers = op.process(registers, *instruction);
//println!("{registers:?}");
ip = registers[ip_register] as usize;
ip += 1;
// Part 1: uncomment this and print look at register 2 to find the value for register 0
// that would cause the program to halt
// if ip == 28 {
// println!("Value in register 2: {}", registers[2]);
// }
// Part 2: 9969507 too high
// 16774755 highest value
// Store all values of register 2 at the possible exit point. Once you see one you already
// saw: you've seen all (there is a loop). The one before that was the one it took the longest
// to reach without seeing anything twice.
if ip == 28 {
if seen.contains(&registers[2]) {
println!("First double: {registers:?}");
println!("Last was {last}");
break;
} else {
seen.insert(registers[2]);
last = registers[2];
}
}
if program.get(ip).is_none() {
println!("exit by leaving instruction space");
break;
}
count += 1;
}
println!("executed instructions: {count}");
(registers[0], count)
}
fn parse_instruction(instruction: &str) -> Instruction {
let instruction: Vec<_> = instruction.split(" ").collect();
let opcode = match instruction[0] {
"addr" => Op::AddR,
"addi" => Op::AddI,
"mulr" => Op::MulR,
"muli" => Op::MulI,
"banr" => Op::BanR,
"bani" => Op::BanI,
"borr" => Op::BorR,
"bori" => Op::BorI,
"setr" => Op::SetR,
"seti" => Op::SetI,
"gtir" => Op::GtIR,
"gtri" => Op::GtRI,
"gtrr" => Op::GtRR,
"eqir" => Op::EqIR,
"eqri" => Op::EqRI,
"eqrr" => Op::EqRR,
&_ => {
panic!("unknown op {}", instruction[0])
}
};
let instruction = Instruction {
opcode,
a: instruction[1].parse().unwrap(),
b: instruction[2].parse().unwrap(),
c: instruction[3].parse().unwrap(),
};
instruction
}
#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
enum Op {
AddR,
AddI,
MulR,
MulI,
BanR,
BanI,
BorR,
BorI,
SetR,
SetI,
GtIR,
GtRI,
GtRR,
EqIR,
EqRI,
EqRR,
}
impl Op {
fn process(&self, registers: Registers, instruction: Instruction) -> Registers {
let mut result = registers.clone();
match self {
Op::AddR => {
result[instruction.c] = result[instruction.a] + result[instruction.b];
}
Op::AddI => {
result[instruction.c] = result[instruction.a] + instruction.b as i64;
}
Op::MulR => {
result[instruction.c] = result[instruction.a] * result[instruction.b];
}
Op::MulI => {
result[instruction.c] = result[instruction.a] * instruction.b as i64;
}
Op::BanR => {
result[instruction.c] = result[instruction.a].bitand(result[instruction.b]);
}
Op::BanI => {
result[instruction.c] = result[instruction.a].bitand(instruction.b as i64);
}
Op::BorR => {
result[instruction.c] = result[instruction.a].bitor(result[instruction.b]);
}
Op::BorI => {
result[instruction.c] = result[instruction.a].bitor(instruction.b as i64);
}
Op::SetR => {
result[instruction.c] = result[instruction.a];
}
Op::SetI => {
result[instruction.c] = instruction.a as i64;
}
Op::GtIR => {
result[instruction.c] = if instruction.a as i64 > result[instruction.b] {
1
} else {
0
}
}
Op::GtRI => {
result[instruction.c] = if result[instruction.a] > instruction.b as i64 {
1
} else {
0
}
}
Op::GtRR => {
result[instruction.c] = if result[instruction.a] > result[instruction.b] {
1
} else {
0
}
}
Op::EqIR => {
result[instruction.c] = if instruction.a as i64 == result[instruction.b] {
1
} else {
0
}
}
Op::EqRI => {
result[instruction.c] = if result[instruction.a] == instruction.b as i64 {
1
} else {
0
}
}
Op::EqRR => {
result[instruction.c] = if result[instruction.a] == result[instruction.b] {
1
} else {
0
}
}
}
result
}
}
type Registers = [i64; 6];
#[derive(Copy, Clone, Debug)]
struct Instruction {
opcode: Op,
a: usize,
b: usize,
c: usize,
}
#[cfg(test)]
mod test {
use crate::tasks::day21::run1;
#[test]
fn example1() {
let input = "#ip 0\n\
seti 5 0 1\n\
seti 6 0 2\n\
addi 0 1 0\n\
addr 1 2 3\n\
setr 1 0 0\n\
seti 8 0 4\n\
seti 9 0 5";
assert_eq!(run1(input, 0).0, 6);
}
}

246
src/tasks/day22.rs Normal file
View File

@@ -0,0 +1,246 @@
use crate::tasks::day22::Equipment::*;
use core::cmp::Ordering;
use std::collections::BinaryHeap;
use std::collections::HashMap;
use std::time::Instant;
pub fn both() {
let start = Instant::now();
let mut cave = Cave::create(3879, Node(8, 713, Torch));
println!("#{:?}", Instant::now() - start);
let x = Instant::now();
println!("Sum of erosion indexes: {}", cave.erosion_sum());
println!("#{:?}", Instant::now() - x);
let x = Instant::now();
println!("Shortest path length: {}", cave.shortest_path_length());
println!("#{:?}", Instant::now() - x);
println!("#Overall run time: {:?}", Instant::now() - start);
}
#[derive(PartialEq, Clone, Copy, Debug, Eq, Hash)]
enum Equipment {
Torch,
Climbing,
Neither,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
struct Node(usize, usize, Equipment);
struct Cave {
map: HashMap<(usize, usize), usize>,
target: Node,
depth: usize,
}
impl Cave {
fn create(depth: usize, target: Node) -> Self {
if target.2 != Torch {
panic!("A valid target point needs the torch equipped");
}
let map = HashMap::with_capacity((target.0 + 1) * (target.1 + 1));
Cave { map, target, depth }
}
fn erosion_sum(&mut self) -> usize {
(0..=self.target.0)
.map(|x| {
(0..=self.target.1)
.map(|y| self.field_type(x, y))
.sum::<usize>()
})
.sum()
}
fn field_type(&mut self, x: usize, y: usize) -> usize {
self.erosion_index(x, y) % 3
}
fn erosion_index(&mut self, x: usize, y: usize) -> usize {
if let Some(value) = self.map.get(&(x, y)) {
*value
} else {
let geo_index = match (x, y) {
(0, 0) => 0,
_ if self.target.0 == x && self.target.1 == y => 0,
(x, 0) => x * 16807,
(0, y) => y * 48271,
(x, y) => self.erosion_index(x - 1, y) * self.erosion_index(x, y - 1),
};
let erosion_index = (geo_index + self.depth) % 20183;
self.map.insert((x, y), erosion_index);
erosion_index
}
}
fn shortest_path_length(&mut self) -> usize {
self.map.reserve(
std::cmp::max(self.target.0, self.target.1)
* std::cmp::max(self.target.0, self.target.1)
- self.map.len(),
);
let start = Node(0, 0, Torch);
let mut open: BinaryHeap<State> = BinaryHeap::new();
let mut distances: HashMap<Node, usize> = HashMap::new();
// let mut rightmost = 0;
// let mut lowest = 0;
// let mut visited_counter = 0;
distances.insert(start, 0);
open.push(State {
cost: 0,
position: start,
});
// Examine the frontier with lower cost nodes first (min-heap)
while let Some(State { cost, position }) = open.pop() {
// if position.0 > rightmost {
// rightmost = position.0;
// }
// if position.1 > lowest {
// lowest = position.1;
// }
// visited_counter += 1;
// Alternatively we could have continued to find all shortest paths
if position == self.target {
// println!(
// "Visited {} nodes ({}, {})",
// visited_counter, rightmost, lowest
// );
return cost;
}
// Important as we may have already found a better way
if cost > *distances.entry(position).or_insert(usize::max_value()) {
continue;
}
// For each node we can reach, see if we can find a way with
// a lower cost going through this node
for edge in self.neighbors(position) {
let next = State {
cost: cost + edge.cost,
position: edge.node,
};
// If so, add it to the frontier and continue
let current_distance = distances.entry(edge.node).or_insert(usize::max_value());
if next.cost < *current_distance {
open.push(next);
// Relaxation, we have now found a better way
*current_distance = next.cost;
}
}
}
unreachable!("There is always a path");
}
fn neighbors(&mut self, position: Node) -> Vec<Edge> {
let mut result = Vec::new();
// add all variants of the current position
result.push(Edge {
cost: 7,
node: self.other_node_for_region(position),
});
// for any neighbor position: if it allows the same equipment and is within bounds: add it
[
(position.0 as i32 - 1, position.1 as i32),
(position.0 as i32 + 1, position.1 as i32),
(position.0 as i32, position.1 as i32 - 1),
(position.0 as i32, position.1 as i32 + 1),
]
.iter()
.filter_map(|(x, y)| {
if *x >= 0 && *y >= 0 {
Some(Node(*x as usize, *y as usize, position.2))
} else {
None
}
})
.for_each(|node| {
if self.equipment_allowed_for_region(node.0, node.1, node.2) {
result.push(Edge { cost: 1, node })
}
});
result
}
fn equipment_allowed_for_region(&mut self, x: usize, y: usize, equipment: Equipment) -> bool {
let field_type = self.field_type(x, y);
match field_type {
// rocky
0 => equipment == Torch || equipment == Climbing,
// wet
1 => equipment == Climbing || equipment == Neither,
//narrow
2 => equipment == Torch || equipment == Neither,
_ => panic!("not a valid type!"),
}
}
fn other_node_for_region(&mut self, position: Node) -> Node {
let field_type = self.field_type(position.0, position.1);
Node(
position.0,
position.1,
match field_type {
0 => match position.2 {
Climbing => Torch,
Torch => Climbing,
_ => panic!(),
},
1 => match position.2 {
Climbing => Neither,
Neither => Climbing,
_ => panic!(),
},
2 => match position.2 {
Torch => Neither,
Neither => Torch,
_ => panic!(),
},
_ => panic!("not a valid type"),
},
)
}
}
#[derive(Debug)]
struct Edge {
cost: usize,
node: Node,
}
#[derive(Copy, Clone, Eq, PartialEq, Debug)]
struct State {
cost: usize,
position: Node,
}
// The priority queue depends on `Ord`.
// Explicitly implement the trait so the queue becomes a min-heap
// instead of a max-heap.
impl Ord for State {
fn cmp(&self, other: &State) -> Ordering {
// Notice that the we flip the ordering on costs.
// In case of a tie we compare positions - this step is necessary
// to make implementations of `PartialEq` and `Ord` consistent.
other
.cost
.cmp(&self.cost)
.then_with(|| self.position.0.cmp(&other.position.0))
}
}
// `PartialOrd` needs to be implemented as well.
impl PartialOrd for State {
fn partial_cmp(&self, other: &State) -> Option<Ordering> {
Some(self.cmp(other))
}
}

221
src/tasks/day23.rs Normal file
View File

@@ -0,0 +1,221 @@
use crate::utils;
extern crate regex;
use regex::Regex;
use std::collections::BinaryHeap;
pub fn task1() {
let input = utils::read_file("input/day23.txt");
let regex =
Regex::new(r"^pos=<(?P<x>-?\d+),(?P<y>-?\d+),(?P<z>-?\d+)>, r=(?P<range>\d+)$").unwrap();
let bots: Vec<Bot> = input
.lines()
.map(|line| {
let m = regex.captures(line).unwrap();
let x = m["x"].parse::<isize>().unwrap();
let y = m["y"].parse::<isize>().unwrap();
let z = m["z"].parse::<isize>().unwrap();
let range = m["range"].parse::<isize>().unwrap();
Bot {
center: Point::new(x, y, z),
range,
}
})
.collect();
let big_bot = bots.iter().max_by_key(|it| it.range).unwrap();
println!("The bot with largest range is {:?}", big_bot);
let bots_in_range = bots
.iter()
.filter(|other| big_bot.distance(other) <= big_bot.range)
.count();
println!("There are {} bots in range of the big bot.", bots_in_range);
}
pub fn task2() {
let input = utils::read_file("input/day23.txt");
let regex =
Regex::new(r"^pos=<(?P<x>-?\d+),(?P<y>-?\d+),(?P<z>-?\d+)>, r=(?P<range>\d+)$").unwrap();
let bots: Vec<Bot> = input
.lines()
.map(|line| {
let m = regex.captures(line).unwrap();
let x = m["x"].parse::<isize>().unwrap();
let y = m["y"].parse::<isize>().unwrap();
let z = m["z"].parse::<isize>().unwrap();
let range = m["range"].parse::<isize>().unwrap();
Bot {
center: Point::new(x, y, z),
range,
}
})
.collect();
let mut heap: BinaryHeap<Candidate> = BinaryHeap::new();
heap.push(Candidate {
count: bots.len(),
cube: Cube::new(-1 << 32, -1 << 32, -1 << 32, 1 << 33),
});
let mut candidate_points: Vec<(Point, usize)> = Vec::new();
let mut best_candidate_count = 0;
while let Some(Candidate { count, cube }) = heap.pop() {
// println!("{:?}: {} ({})", cube, count, best_candidate_count);
if count < best_candidate_count {
break;
}
if cube.len == 1 {
let count = bots
.iter()
.filter(|bot| bot.center.distance(&cube.base) <= bot.range)
.count();
if count > best_candidate_count {
candidate_points.push((cube.base, count));
println!("pushed with {}!", count);
best_candidate_count = count;
}
} else {
for child in cube.children() {
heap.push(Candidate {
count: bots.iter().filter(|bot| child.intersects(bot)).count(),
cube: child,
})
}
}
}
let origin = Point::new(0, 0, 0);
println!(
"Found {} candidates - best is {}.",
candidate_points.len(),
best_candidate_count
);
let best = candidate_points
.iter()
.filter(|(_, count)| *count == best_candidate_count)
.min_by_key(|(point, _)| origin.distance(point));
println!("{:?}", best);
if let Some((best, _)) = best {
println!("{}", best.x + best.y + best.z);
}
// wrong: 37446460,43177892,57318660; 137943012; 102224079;
}
#[derive(Eq, PartialEq)]
struct Candidate {
count: usize,
cube: Cube,
}
impl Ord for Candidate {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.count.cmp(&other.count)
}
}
impl PartialOrd for Candidate {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.count.cmp(&other.count))
}
}
#[derive(Debug)]
struct Bot {
center: Point,
range: isize,
}
impl Bot {
fn distance(&self, other: &Self) -> isize {
self.dist(&other.center)
}
fn dist(&self, p: &Point) -> isize {
self.center.distance(p)
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
struct Point {
x: isize,
y: isize,
z: isize,
}
impl Point {
fn new(x: isize, y: isize, z: isize) -> Self {
Point { x, y, z }
}
fn distance(&self, other: &Point) -> isize {
(other.x - self.x).abs() + (other.y - self.y).abs() + (other.z - self.z).abs()
}
}
#[derive(PartialEq, Eq, Debug)]
struct Cube {
base: Point,
len: isize,
}
impl Cube {
fn new(x: isize, y: isize, z: isize, len: isize) -> Self {
if len < 1 {
panic!("The side length of a cube has to be at least 1");
}
if (len & (len - 1)) != 0 {
panic!("The side length has to be a power of two");
}
Cube {
base: Point::new(x, y, z),
len,
}
}
fn children(&self) -> Vec<Self> {
let l = self.len / 2;
let x = self.base.x;
let y = self.base.y;
let z = self.base.z;
vec![
Cube::new(x + l, y + l, z, l),
Cube::new(x + l, y + l, z + l, l),
Cube::new(x + l, y, z, l),
Cube::new(x + l, y, z + l, l),
Cube::new(x, y + l, z, l),
Cube::new(x, y + l, z + l, l),
Cube::new(x, y, z, l),
Cube::new(x, y, z + l, l),
]
}
fn intersects(&self, bot: &Bot) -> bool {
((self.base.x - bot.center.x).abs()
+ (self.base.x + self.len - bot.center.x).abs()
+ (self.base.y - bot.center.y).abs()
+ (self.base.y + self.len - bot.center.y).abs()
+ (self.base.z - bot.center.z).abs()
+ (self.base.z + self.len - bot.center.z).abs()
- 3 * self.len)
/ 2
<= bot.range
}
}
mod test {
#[test]
fn intersection() {
use super::*;
let cube = Cube::new(0, 0, 0, 16);
let bot = Bot {
center: Point::new(8, 8, 8),
range: 4,
};
assert!(cube.intersects(&bot));
}
}

307
src/tasks/day24.rs Normal file
View File

@@ -0,0 +1,307 @@
use std::cmp::Reverse;
use std::collections::HashMap;
use itertools::Itertools;
use crate::utils;
pub fn task1() {
let input = utils::read_file("input/day24.txt");
let result = play(&input, 0);
println!("Standing units after the game: {}", result.unwrap().1);
}
pub fn task2() {
let input = utils::read_file("input/day24.txt");
let immune_final_count = (0..)
.map(|boost| play(&input, boost))
.find(|result| result.map(|(team, _)| team) == Some(Team::ImmuneSystem))
.unwrap()
.unwrap()
.1;
println!("Immune systems final count: {immune_final_count}");
}
fn play(input: &str, boost: i64) -> Option<(Team, i64)> {
let mut game = Game::create(&input, boost);
println!(
"Immune start units: {}",
game.groups
.iter()
.filter(|(_, it)| it.team == Team::ImmuneSystem)
.map(|(_, it)| it.units)
.sum::<i64>()
);
println!(
"Infection start units: {}",
game.groups
.iter()
.filter(|(_, it)| it.team == Team::Infection)
.map(|(_, it)| it.units)
.sum::<i64>()
);
while !game.is_over() {
game.round();
if game.draw {
return None;
}
}
Some((game.winning_team(), game.remaining_units()))
}
#[derive(Debug)]
struct Game {
groups: HashMap<usize, Group>,
draw: bool,
}
impl Game {
fn remaining_units(&self) -> i64 {
self.groups.values().map(|it| it.units).sum::<i64>()
}
fn winning_team(&self) -> Team {
let teams: Vec<Team> = self
.groups
.values()
.map(|group| group.team)
.unique()
.collect();
if teams.len() != 1 {
panic!("No winning team. Remaining teams: {teams:?}");
}
teams[0]
}
fn create(input: &str, boost: i64) -> Self {
let mut groups = HashMap::new();
let mut team = Team::ImmuneSystem;
for (id, line) in input.lines().enumerate() {
match line {
"Immune System:" => {
team = Team::ImmuneSystem;
}
"Infection:" => {
team = Team::Infection;
}
"" => (),
group => {
if let Some(mut group) = Group::from_str(group, team, id) {
if group.team == Team::ImmuneSystem {
group.attack_damage += boost;
}
groups.insert(id, group);
} else {
panic!("bad group: {group}");
}
}
}
}
Game {
groups,
draw: false,
}
}
fn round(&mut self) {
let mut target: HashMap<usize, usize> = HashMap::new();
// lock targets ordered by effective power
let mut all_by_power: Vec<&Group> = self.groups.values().collect();
all_by_power.sort_unstable_by_key(|a| Reverse((a.effective_power(), a.initiative)));
// for group in all_by_power.iter() {
// println!(
// "{}: {} ({})",
// group.id,
// group.effective_power(),
// group.initiative
// );
// }
// println!("{:?}", all_by_power);
for group in all_by_power.iter() {
if let Some(t) = self
.groups
.values()
.filter(|it| it.team != group.team)
.filter(|it| !target.values().any(|t| *t == it.id))
// .inspect(|it| {
// println!(
// "{} would deal {} damage to {}",
// group.id,
// group.compute_attack_damage_to(it),
// it.id
// )
// })
.max_by_key(|it| {
(
group.compute_attack_damage_to(it),
it.effective_power(),
it.initiative,
)
})
{
if group.compute_attack_damage_to(t) <= 0 {
// println!(
// "Didn't find a target where {:?} can deal positive damage.",
// group
// );
continue;
} else {
target.insert(group.id, t.id);
}
}
}
// attack ordered by initiative
let mut all_ids_by_initiative: Vec<usize> = self.groups.values().map(|it| it.id).collect();
all_ids_by_initiative.sort_unstable_by_key(|id| Reverse(self.groups[id].initiative));
self.draw = true;
for active_id in all_ids_by_initiative {
if !self.groups[&active_id].alive() {
// was killed in this round
// println!("Group {} already dead", active_id);
continue;
}
if let Some(enemy_id) = target.get(&active_id) {
let enemy = &self.groups[enemy_id];
let damage: i64 = self.groups[&active_id].compute_attack_damage_to(enemy);
let dying_units = damage / enemy.hp_each;
self.groups.get_mut(enemy_id).unwrap().units -= dying_units;
if dying_units > 0 {
self.draw = false;
}
// println!(
// "{} dealt {} ({} units) damage to {}",
// active_id, damage, dying_units, enemy_id
// );
}
}
// clean up dead groups
self.groups.retain(|_, it| it.alive());
// println!("{:?}", self.groups);
}
fn is_over(&self) -> bool {
self.groups.iter().all(|(_, it)| it.team == Team::Infection)
|| self
.groups
.iter()
.all(|(_, it)| it.team == Team::ImmuneSystem)
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
enum Team {
Infection,
ImmuneSystem,
}
#[derive(Debug, Clone)]
struct Group {
id: usize,
team: Team,
units: i64,
hp_each: i64,
weaknesses: Vec<String>,
immunities: Vec<String>,
attack_damage: i64,
attack_type: String,
initiative: u64,
}
impl Group {
fn from_str(input: &str, team: Team, id: usize) -> Option<Self> {
// 801 units each with 4706 hit points (weak to radiation) with an attack that does 116 bludgeoning damage at initiative 1
// 2347 units each with 3322 hit points with an attack that does 12 cold damage at initiative 2
use regex::Regex;
let regex = Regex::new(r"(\d+) units each with (\d+) hit points(.*)with an attack that does (\d+) (\w+) damage at initiative (\d+)").unwrap();
if let Some(m) = regex.captures(input) {
let units: i64 = m[1].parse().unwrap();
let hp_each: i64 = m[2].parse().unwrap();
let attack_damage: i64 = m[4].parse().unwrap();
let attack_type = m[5].to_string();
let initiative: u64 = m[6].parse().unwrap();
let mut weaknesses: Vec<String> = Vec::new();
let mut immunities: Vec<String> = Vec::new();
let attributes = m[3].trim().trim_start_matches("(").trim_end_matches(")");
for part in attributes.split("; ") {
if let Some(stripped) = part.strip_prefix("weak to ") {
weaknesses = stripped.split(", ").map(|it| it.to_string()).collect();
} else if let Some(stripped) = part.strip_prefix("immune to ") {
immunities = stripped.split(", ").map(|it| it.to_string()).collect();
}
}
let group = Group {
id,
team,
units,
hp_each,
weaknesses,
immunities,
attack_damage,
attack_type,
initiative,
};
Some(group)
} else {
None
}
}
fn alive(&self) -> bool {
self.units > 0
}
fn effective_power(&self) -> i64 {
if !self.alive() {
panic!("I have no power, im dead!")
}
self.units * self.attack_damage
}
fn compute_attack_damage_to(&self, other: &Self) -> i64 {
if self.alive() {
if other.weaknesses.contains(&self.attack_type) {
self.effective_power() * 2
} else if other.immunities.contains(&self.attack_type) {
0
} else {
self.effective_power()
}
} else {
panic!("I'm not alive, I cannot attack anyone")
}
}
}
#[cfg(test)]
mod test {
use crate::tasks::day24::play;
const INPUT: &str = "Immune System:
17 units each with 5390 hit points (weak to radiation, bludgeoning) with an attack that does 4507 fire damage at initiative 2
989 units each with 1274 hit points (immune to fire; weak to bludgeoning, slashing) with an attack that does 25 slashing damage at initiative 3
Infection:
801 units each with 4706 hit points (weak to radiation) with an attack that does 116 bludgeoning damage at initiative 1
4485 units each with 2961 hit points (immune to radiation; weak to fire, cold) with an attack that does 12 slashing damage at initiative 4";
#[test]
fn example1() {
assert_eq!(5216, play(INPUT, 0).unwrap().1);
}
#[test]
fn example2() {
assert_eq!(51, play(INPUT, 1570).unwrap().1);
}
}

122
src/tasks/day25.rs Normal file
View File

@@ -0,0 +1,122 @@
use std::collections::VecDeque;
use crate::utils;
pub fn task1() {
println!("{}", solve(&utils::read_file("input/day25.txt")));
}
fn solve(input: &str) -> u32 {
let mut points: Vec<STP> = input.lines().map(STP::from).collect();
let mut constellations = 0;
while let Some(next_origin) = points.pop() {
constellations += 1;
let mut queue = VecDeque::new();
queue.push_back(next_origin);
while let Some(next) = queue.pop_front() {
let (neighbors, remainder) = points.into_iter().partition(|p| next.is_neighbor_to(p));
points = remainder;
for n in neighbors {
queue.push_back(n);
}
}
}
constellations
}
#[derive(Hash, Eq, PartialEq, Debug)]
struct STP(i32, i32, i32, i32);
impl STP {}
impl STP {
fn distance(&self, other: &Self) -> u32 {
((self.0 - other.0).abs()
+ (self.1 - other.1).abs()
+ (self.2 - other.2).abs()
+ (self.3 - other.3).abs()) as u32
}
fn is_neighbor_to(&self, other: &Self) -> bool {
self.distance(other) <= 3
}
}
impl From<&str> for STP {
fn from(value: &str) -> Self {
let mut split = value.split(",");
STP(
split.next().unwrap().parse().unwrap(),
split.next().unwrap().parse().unwrap(),
split.next().unwrap().parse().unwrap(),
split.next().unwrap().parse().unwrap(),
)
}
}
#[cfg(test)]
mod test {
use crate::tasks::day25::solve;
#[test]
fn example1() {
let input = "0,0,0,0
3,0,0,0
0,3,0,0
0,0,3,0
0,0,0,3
0,0,0,6
9,0,0,0
12,0,0,0";
assert_eq!(solve(input), 2);
}
#[test]
fn example2() {
let input = "-1,2,2,0
0,0,2,-2
0,0,0,-2
-1,2,0,0
-2,-2,-2,2
3,0,2,-1
-1,3,2,2
-1,0,-1,0
0,2,1,-2
3,0,0,0";
assert_eq!(solve(input), 4);
}
#[test]
fn example3() {
let input = "1,-1,0,1
2,0,-1,0
3,2,-1,0
0,0,3,1
0,0,-1,-1
2,3,-2,0
-2,2,0,0
2,-2,0,-1
1,-1,0,-1
3,2,0,2
";
assert_eq!(solve(input), 3);
}
#[test]
fn example4() {
let input = "1,-1,-1,-2
-2,-2,0,1
0,2,1,3
-2,3,-2,1
0,2,3,-2
-1,-1,1,-2
0,-2,-1,0
-2,2,3,-1
1,2,2,0
-1,-2,0,-2
";
assert_eq!(solve(input), 8);
}
}

View File

@@ -1 +1,25 @@
pub mod day01;
pub mod day02;
pub mod day03;
pub mod day04;
pub mod day05;
pub mod day06;
pub mod day07;
pub mod day08;
pub mod day09;
pub mod day10;
pub mod day11;
pub mod day12;
pub mod day13;
pub mod day14;
pub mod day15;
pub mod day16;
pub mod day17;
pub mod day18;
pub mod day19;
pub mod day20;
pub mod day21;
pub mod day22;
pub mod day23;
pub mod day24;
pub mod day25;

View File

@@ -2,7 +2,7 @@ use std::fs::File;
use std::io::prelude::*;
pub fn read_file(path: &str) -> String {
let mut f = File::open(path).expect(&format!("file '{}' not found", path));
let mut f = File::open(path).unwrap_or_else(|_| panic!("file '{}' not found", path));
let mut contents = String::new();
f.read_to_string(&mut contents)