diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml deleted file mode 100644 index 9bba3d9..0000000 --- a/.github/workflows/test.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: test - -on: - push: - branches: - - master - - main - pull_request: - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: erlef/setup-beam@v1 - with: - otp-version: "27.0.1" - gleam-version: "1.6.3" - rebar3-version: "3" - # elixir-version: "1.15.4" - - run: gleam deps download - - run: gleam test - - run: gleam format --check src test diff --git a/.gitignore b/.gitignore index a263f17..ea8c4bf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1 @@ -*.beam -*.ez -/build -erl_crash.dump -data/*.txt +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..e2eebe0 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,711 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[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 = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "aoc" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "itertools", + "nom", + "rayon", + "regex", + "serde", + "serde_json", + "tap", + "tokio", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" + +[[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", + "serde", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "crossbeam-deque" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" +dependencies = [ + "cfg-if", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "hermit-abi" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" + +[[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.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "js-sys" +version = "0.3.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[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 = "memoffset" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dce281c5e46beae905d4de1870d8b1509a9142b62eedf18b443b011ca8343d0" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "proc-macro2" +version = "1.0.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rayon" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags", +] + +[[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 = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "smallvec" +version = "1.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys", +] + +[[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 = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tokio" +version = "1.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" + +[[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-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +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" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..d49bc76 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "aoc" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0.75" +chrono = { version = "0.4.31", features = ["serde"] } +itertools = "0.12.0" +nom = "7.1.3" +rayon = "1.8.0" +regex = "1.10.2" +serde = { version = "1.0.193", features = ["derive"] } +serde_json = "1.0.108" +tap = "1.0.1" +tokio = { version = "1.34.0", features = ["full"] } diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 6133265..0000000 --- a/LICENSE +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - advent_of_code - Copyright (C) 2024 sreedevk - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - advent_of_code Copyright (C) 2024 sreedevk - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/README.md b/README.md index 1836783..a4ba895 100644 --- a/README.md +++ b/README.md @@ -1,22 +1,9 @@ -# Advent Of Code 2024 +# Advent of Code 2023 -```sh -# Run Tests Against all solutions (example inputs used) -gleam test +## Usage -# Run the solution against actual input for a particular day -gleam run +```bash +git clone https://github.com/sreedevk/advent-of-code +cd advent-of-code +cargo run -r ``` - -## Solution Status - -1. [x] [Day 01 Historian Hysteria](https://github.com/sreedevk/advent-of-code/blob/main/src/historian_hysteria.gleam) -2. [x] [Day 02 Red Nosed Reports](https://github.com/sreedevk/advent-of-code/blob/main/src/red_nosed_reports.gleam) -3. [x] [Day 03 Mull It Over](https://github.com/sreedevk/advent-of-code/blob/main/src/mull_it_over.gleam) -4. [x] [Day 04 Ceres Search](https://github.com/sreedevk/advent-of-code/blob/main/src/ceres_search.gleam) -5. [x] [Day 05 Print Queue](https://github.com/sreedevk/advent-of-code/blob/main/src/print_queue.gleam) -6. [x] [Day 06 Guard Gallivant](https://github.com/sreedevk/advent-of-code/blob/main/src/guard_gallivant.gleam) -7. [x] [Day 07 Bridge Repair](https://github.com/sreedevk/advent-of-code/blob/main/src/bridge_repair.gleam) -8. [x] [Day 08 Resonant Collinearity](https://github.com/sreedevk/advent-of-code/blob/main/src/resonant_collinearity.gleam) -9. [ ] [Day 09 Disk Fragmenter](https://github.com/sreedevk/advent-of-code/blob/main/src/disk_fragmenter.gleam) -10. [ ] [Day 10 Hoof It](https://github.com/sreedevk/advent-of-code/blob/main/src/hoof_it.gleam) diff --git a/data/day01.txt b/data/day01.txt new file mode 100644 index 0000000..813c4a3 --- /dev/null +++ b/data/day01.txt @@ -0,0 +1,1000 @@ +ninefourone1 +53sevenvvqm +kscpjfdxp895foureightckjjl1 +72fivebt9ndgq +28gtbkszmrtmnineoneightmx +four66jqrbtqcsxjtqjvfjhl1 +four8pzznjbhxlhtz6bhtzdxjlg1 +rgxjrsldrfmzq25szhbldzqhrhbjpkbjlsevenseven +slkjvk4threesevenznjqmmfive +61ppgrkmkfhteightone +1threesix67px +sxbjdbtlnjrmlzgxneightthreepmqxdxhfk8jfrheightwovp +twofour2sevenk +sevenonezknqnkfqbzffjvfivetwo94two +45xj +mp7one6eightvhfnmfive6 +fhtctftxm3threefour2b +2dq7bdmhhs92 +pdnbqlbvtcxgpnfhmsfhzstgm173 +8fourvxkddsrlcvseveneight +15zqpmsix77hlljgfive +jzjv6seven +eight1vbfive +721sixsdzbqtskbpkqbcmgmlpk5psrhr +pqxdxcx5 +twozsf2five +7twosixthree775 +7xtxrch7six +729twofourlqrxtwo +qtvbgtclhnk4ninefourseven5one +jvhngkcdjhnmqghdbqdzqssf5onegzjbbcchboneightn +five8two14five2nine1 +one3twomddthree +8nine9two +7fiveeight9ninesix6fivethree +254kcd61dc4two +7sixonetxvthntlngtwobzkbz23 +8sixnine6 +threedqtgmv2skmvcd +7ptdhpvr1 +lsvmzvzvd9mqxszjmbddkmxzdxsninedmglzlzphtwo +kgdt12seven4xxtttr5 +nrdtgdftjmfour6fxjninenineblqlthvpcx +ninezmstcdfchc11onebmmfdfhvdncrhc +1fiveseven +oneone26twoeight +threefivenine98one9twotbbcq +9cm7ninestc +jcrbmcjtrlzvz7 +nine8nine22 +3nineoneseveneight +58four2three +stwonefourthree9twonine4six5bvxgkxf +ninechzcz4seven +2tgzgmtzzpjdqqz +brsptjppb28qxcxxjbzpeighteight +eightthree3ninejrft4 +sixqsgkzdjmgpfive4threemxltqdxsfive +vxfd2q8 +khqhgqlxslkmbrvljcnineeight1gjgcqmnbdczqb8four +mvbltrgpfourcclxftbb7gcbqcptvgfsevenrdm +61eight +six8fourthree6fourseven6three +jqdfxvhjg3sflkn2sixptxxsqrfml +6jtxs +seven99threeone +five6sevensmbbrjqvdbmkbsqtwonelg +fdvfsndt32fourgllgfrninebhnzzczfive +9hxp9srhjhjjvqljhzprcjpqreightzs1 +djldhkkcn55threethreefourflnxnbzhkzmx +fourfive43chfvjnvjrkpxlgjrfnqbl +fxjgtj4 +1sevenfour2fiveeight +seven43rxxeightb1 +9sevensnxkp3lpzxfxnntkxzkrhk7jzhmtvn6 +25one +threeone7 +1pkfvsxxthreeoneseven +ztbvfqnpz2xdhgdjmgvfourtworqbxqsh47 +8four7sixninesix +threedgl88cczqhqxjnc +nineeightthree4sixfive3sixdqlmscqjk +16crjsdl +tgq2sixhc7three +tzgsqspndt5xnqlthghzfvkkhone +4fxdqrs64ninex34gd +seven22 +kghfkrpvnppfncbhhqpt55bjf +hjhb71bqdrrgsrkqdtsgrxgsscqjmtfzjkzsbp +lgdnt9threeeighteight97 +pvjhnk83sixncvgmsjltwotdmmpxknhvntfndxr +7449 +qdfzv9hkprplzkfh +66three5five4zdsfrcnljqmsxf2 +veightwo27bdbsvseveneightrcqcjxsixeight +1thvkkk +8bnxqfsdhzppblzlzbkfsksfscmb +zseventbdzlmhnnrfive1one +sixxnmntrmp6srcsqbrqnjfiveeightfive +4trnzlshnjtwo5twocxrvfssbj +6two3twonetqt +55qsnx43 +3three23tpctbkrnqv +sixqk4cnfdmtltmlhqxtwo41glkhdhgnt +35fivesevenpfournxzsbbgzthjvlvzrnine +tworkzgkcvcone53nrvgdvgtc +two9llkjbkz8pklrsgqqzr2four +ninecgpbgcnine4tldjqsone4six +2tfjhtfourfour +onebhlhdvvqx1sevenmsixsix9 +pjgjt6jkrgshxltfnine8four45 +4vsqfljrfiveqeightnvbdb +11nfslqvhm +7crrhqxsfive8ctkzbhqnine +vrvtglvthreettrkq5bdlrtpx718 +1btbxlthreedtrzgeightnineqczhqm3 +193 +fcbzxqxxjtmn47ffschdrbeight +twoh1gqkrnm1 +7ninesixpzpsn7 +5kkvzpgqd +three6nine +32fdn +22twoxgvktxpxmbjqtgtbckx +1hdtftwosix +2jfc +six5nvzcgmrscjn5eight4 +nineqhtczsninetwosix4five +9three6sj +hntktlbqmldrphqzxkhfour193 +twotwo5259 +v7six1vtlxnpm +rhsm2 +gprmtxbhlsv8onefournine +2fsrbtdvft15six1kxpqbnqsxh9 +one5onemxthree8 +nineqbxdbznzktxsmstsntzffour3one +9blhkhjsgsfgsblzdtqqfour8 +stz4889563cb +vjrbs6threeptbbmncz7hqhqgfgldtseven5 +vbfs1 +zjqgczjsjpvzvjseven4 +sixfjzbrrhcfqvglxhnsxninedrvtvjbfqjdbrzblkq6three +one3threegcdldjsrsssixonefiveonechngsl +7srxv4hsgjqsqfvv1tdngkpjrczkl4 +5scgdglnjbnsix8fivesixtjccvmkfxfnzvhctgpncjc +4eightfivefive1lgscbj7kpcr1 +eightknfssevenfive6jnpklczrpfeightwol +37qccxllhzshninebvpc8 +1eightmmcthkhf +seven8fourqn7tbgqnmzcc1 +sixsevenone4 +clhdvjnqnine9threesix +onetwoeight9 +81z3threenjsdhnqxvtwonezv +9hqtsb +onekgnlbthreeg3 +eightspnrpjb65fivevzfpvjntbg7drbgjccneight +ninerdlsix7285 +fournineninefive3vbnhmhdvjgdqcm +njzspqxpxrone7four55 +nfdhlqcpvzrrtsmzhgq3 +fourmfdtnpsfbxkjtgtgx5sixrppsqplqdjvnsixdtqvtdm +21onesix6sixnine2 +fffsmvtt8fivenineglrqrmktzzseven +fivefoursevencjxmskrqclz2 +lgk27threefourfsqrbkntbkfourvflgrzhh9 +617hj9 +ninegcxninetwohpfdxrb3tjjjtxtnvtwo +one1gnftc8onehtsxsmg +foneight3fsbhdqzr5twojbsdnntwohd9seven +zkzpfvcxqnbvrg1 +nine36cddqfvrf +rdjlpfk2pschfsdrpz +nine994three8six +three3nvflpftf2eight4 +3nine2 +rxxjdk5354 +hf4eight8qjtcfldnkvtwofivetwothree +7six3twodhnvmxj1nine +57seven3six6 +qklbvzfhclfnllhhgeight8xtvld +5fgzqhkssmkcfour1 +hhvjkdnlffnineeighttwo18twonecs +sevenbfzrgfm1six1 +nine71cskklxvcbnxtskdbqnpgklrxklcgccxjnssksrlkx +hmklhhjdthree77 +3vpxclbgkpone3ninesrclfive +djfqkgjvqpfvdsix5sixtwoeightsix +eightlt7csvgxpnslk +sevenfoureightnld2mxtgpbzpthree1 +11sevenglfmsb6 +onetjjnxvssg1four4drxbxpnpv24 +2zdxs9mfnbgfmjln1threefive +one186ltsbck +6fsbpb9sixhc +nine818 +xzqcpcdprsqjbgknkvztwo419q +39qfdlcnkhg31 +9djnlcrxqxhrcb8mczrxrm +nmb887525seven +jhmv3 +zhvdbn1fivem8seven4sixoneighttsn +6zmmjqmnftclqbcthree +6cpzeight92 +onepqfhtsevencvlfvnczhb91mmtdprqxmcnine1 +tvqdfxn8eight +five6fivercgrpbtjgv87jmcndclbk2six +jgtmrbvl68lpqkpxddqqxvsixfivesix +nine2nlffgkvmp +1frdnhssftg4eightgclxsgqtn +2sixblr94six +94mlfv +6vlqtcsmdd47hpfmlc7fiveeight2 +tklxghxv5bzc4hhcdcpmnine8 +four6one1zzgqghvs412 +xghjpblsfpg19ntpfmcfd +471rbdblzs +69fourhjxkvd7fourfour +jmrscfqdfppfdjskpk61 +five5eightnqpd9ninezknztwo +onelknchr7nrfprgmqzp +svxlxrx9892five2 +3ntkbzzpxhdmrsix8ttgp +ndh7zlnrzpvmnine +one7xlnbmjjmfv62qvqjpfprbvjkpcnine +99three5 +threetwotwo7dhtgtbchc7sixtwo +tmfxxph3eightgdccscdsrkmnhbb75 +joneight4one5 +nine3six +81tqzsqpkv99 +sixvjlq7 +five7bkc +five3811threelfpzztxzk +1fourkkpclqc3 +xgrpbmktcthree46g +bgcp4two8 +jtgeightwo7nine +bkmcrcq3eightrdtvrbglmxmmztqm +7tscmg5one2jhhbfb1 +zt5khcrgqjg5nxxzxzd +five85 +twothree1 +eightsixthreetwo6b3tnjmcqdjfive +onefrlg7 +fivescbjxbdnvslqqsone5bdbvskpmksqmmfsncsmd +two83fourthreefourseventhree +dglrmbtkfltwofive8ninelzmrxvxoneeight +8nine6sixsixtwo7 +sevennine4lbsevenkdnrhpltn +h3fiveeight4cplrnd +vhsgjbqm3ninedfhfsb +93nine7jvjmlzgcztrqlxtwo +zhhhdddbbgcssvfzdhmpone5fivefournine +l9fourvjfbqpdslkmvxsdrnsgcvzpjxm +kxlseven5two +rbtwonegsdgvsjtpnnkone7mdz +phffknvthree2threeqgvfqxgnine7 +2lgglnmthreeseven27three81 +lrgkrxx2 +seventwokxvzkvq6eightthree +5fiveseven +fstwonersngdlngx28nine +49oneninesix8four2q +hfvhzvmjgbfcbsevenrmhjhzkc3 +six84 +8eight2gzblldzvkjfive +6fz3eightzmsqb4qsbbsnthm +fcglpc2one51 +sevendqghclrpxt7pzone48two +three5one +5sevenfivebbzkjlcnxseven8fourmzqlxxgjvc +xgg8one6782 +gggtljnnsix3lkhdqzzpdtdkmjtgjddkpgx4five +qrmsfc13onevnhlbgs +nrtwonethreerbbqffzh62 +5eight81gcdbrx3rlk +mtdtxcmm2bgmqhgqrtxsn8 +onercx2 +9sixoneqgr4 +xmoneightfour2 +six85foursixninetwo +ninetwo8four8six +qchclfzq47 +khrll3two21 +seveneightnine8868four +3rmbmtbxjp12seven +3tsxgvqxmzvxbdvxtgrvdbzqbh +eight7fourjtxx +fmb4one7threekbxeightwoj +vcsevensixseven577 +2dkhlrrtrnbgzrmxm5fiveclhgn1eight +1sevenlmrbnfour17seven +three5jtbvkseightoneseven4df +fourrgqxplbpbxtsgkm7 +fourqdfxchlc371sc2 +fqxlmeighttwo1seven +zvvlftlhfthreesix6three46qkstxvdt +m74pjgccfour1four +plphq933eighteight +cdbqlhbhj3eight +4onevgdkxhz799five9fbljhpqmvk +two6qzgphxl +two1eight +onekxxghlonerqqlrs83threehvvdhsxmfour +npmsvvrdl2673 +fivejthseightsixtwo9vgrvjzbzsrxjv +eight2gqfive7mzjzpxqcvheightjfx +1bxckdpt +dngoneightbtdptfn85 +fourtwovfzgmxjseven935 +8onesix2drgjnlrxbtdlmlznine5 +five4mmpmqlttsx56ljdzldntdvthree +1nxxgtwothree22twothreenine +38eightsevennxctjfstp +8fourvhnps3onellstpnztn6kvjccmv +1bseven93eightfour +5nphkdbhxqb2pqxtkvhxq +nvvx6fourjgkdsczjv +fourxrmq78 +8tjmnvthree3ninetwo2five +p7cvtwoneq +7thbggjbznrsixonethreeninej +xdgm1crqfnklk +onehmqqgh4ninenthjonegfjmvtfgd +sevenbsqtlk9 +8seven9two9hdz29 +fbcjhzdgzdg8jgjvcrmgbcrsixnine +3bssqrj44onedqxvhkfive1 +tmmxtz5dtxbbcjlfivesix +pvfqzksgrs4khmlvtwoeightlsx +psbttsmnpninefour42fivegsixfive +sevenfiveqscr7dfxpninesix5 +xmsjddzfxftsjfq6four6eight6three +seven42 +eighteight1nineeight9 +8c +pmqljjjzvx5znxqnsfour8 +78zlpxnvsqpgmgmk +four7fsgttnrgnlslr +fourtwo3jg2 +qlz18three5lpxfjvnfppqjxh +4fiveonetthree4eight +7lzffxkxnzjrtr +three7nineone46ksnshqgdpt +8dntxkkkgdxggvhxh2onefour5gqzsqkm +tjsixonedbklrxxk2twonxdpjzb8 +mfglbrjrq93 +seven37xhsrxrvcgninexbmdrzxthreeonethree +fivegznvfztszqlhtrsslsmqq43212 +tdthjjjbkeighteightsevenpcbmpfq2 +five1eightq +three13three4vrsrrtp +cgztjgqgdths2 +dhxztfvlonetwokszrv8prdpm2 +dfkcklchjj8twonine52ppvndfcnf6 +three7ninenkxfourfive +93sixlqxctdhmvssixone +oneqbvfrvteightnineninefivethree9 +jskrtmvsrqnpvcgsmxbonecmlrjpdpc4three +crpcfour54xxgzz +9fivefhdpcqsd +fivenineclfctjninefbsh2 +fivexhrzbqpfxl8sixtwoeightllzplcpllk +zxgl5qneightsevenone +sixpdc17thxfive +1twolftpzbmnzvdlkvlsevenhdvgfrjhmthreethreeddkdvht +67twotwo71 +oneeightcgnhtdxpfnsevenoneeight13 +eightthreervd5tnj17 +ssrsmhxrsixeight3gbqggcvfqg29 +6fivecvcdxnxhxxtlzthree +fournrrsix595 +p2qchlvplzdvchkbdzzbnsix7ninefour +fourthreefourtzvlrnr9m94seven +4jxzkrfourvtjpsnrllkjcczmmqnsj4q1two +4627qlpscgpjcnine539 +two6nineeight +63five66fivethree1 +skndgzsbsntwoone1 +threerzgdxgtthree2three +953lsdgn59 +27bk +sixmfmbslpjjsixsvnqrvtxznffive5 +2ninenlgpggxm42six234 +fdzfvkjnchsevenfivethreetscllgjvrtqckfnmz3cszmt4 +7ninetlzsxjsl2nine3 +shsvptqngsevencjjthvfm9six5four +7lsrq36threevzfjc62 +two59threedxmfourjfschvqvnine +khfqjmksxhbvs8sevenhzrmjtkgm +nine2stgflmsm8fkthhhjzlszdnmkmqpnjxrfc4 +twofourthree244nine +eightvt978 +fivefiveninesixnine6513 +2lbtz19fourtshqsvblhrkhxbpfour +ptt7bntxhdvl +mskflsslvdlmndmmqmfourtczqlssnineseven5xxxkfvzd +l329eightsevenfourfivethree +rmlksxsixspp9fourhlcg +8five9q +hqoneightsix19nine6xmjbtgjzgrhmlrxq +six38 +9eight2 +3sixbzhgfcg57sixsixjtqmknd +9fchn58 +vrpftbnvonefour6 +vqgdtrvhnnxxsevenseven9eight +56vnine5rdpsnlqcbq7three +vncrjds2cmrg7 +213sixfivesix +tzclpzdsthree4sxgjvrzcrzcndnfour +4sixseven1three7 +8fbrggzmtqn8 +four79p +twonineqonemfour3dq +5fdgpmrghtksn5onesixtwo +xseightwongqqsxtwo8jslclldvnb +nine1one +9gxjrfourvhqzcxdhrtpxgtwonine +eighthfhtnvchtc7fjkrxsmhtm7rbk +thqxcfjbksix32xqrgqsqtx +6qjqql +jgcreight7eight +6onesix4threeseven +5vcv1twoeight7 +fivesthreebvjntwo9jdxghmxvl +632msc9threenineqfone +dqxfourkb4eight +6stsp3nine +566sevenpdmg +xprjdn55 +9mjtcmhjb +twoninelkjznqztbc3twolnhjhdbfxmhfr +twotczpxn6qlcfdlpnq +4ninefive +1rs44three2gzczjdgq7ssmtgjbgbb +ggmzqbkgsix4five23bftjlmbfbd +threehfcscmmlqvcjtpthree98 +7sixsixone4 +2fivefvrr9four4three +1zt1seven +9hsbthqvhhsnineone23tslqccg +sixbqvd3 +22148four3 +ninejlpbtnfive41rtzqjgfmcbncrrlnn +9sixfour +qnhfivetwofjtqtlxd7lmrlfctq864 +69dqrzhlqssgcsxtz54cpmjvrkcfiveseven +fiveqpv85frkmpgxgc +xxqsscldeightone9ngqtkf1nine +5sixgxbnnjsvhf5dgxgone7 +sixsevensqghlvkfxnfour7 +8gmgvjbfivesevennine +qj796fourone9 +rmpfsppvzdtwo4threetwotwo9 +dqvtrhm3nhtrxxccmfiveonedfzfvcghr +4threejxkhnxcxjoneightp +sevenhkpfgdgsgnvseven3m +qhrvjcnfdbqchrsvchcxfourbkhhq9six1eight +29pqnd +1oneonethree627 +5977rcr2threeeight1 +fournthpqbztrhnine64 +fjnjpgqxr86five4sixxhrtvbp2two +7sdnvlb5two +58vffgzcgx4nineoneeight3 +h1sjgqbhndbz1oneqgncmhnleightwos +gjms21 +onetwodphfznine51 +gxpl3fourzfz3 +five46 +mqsixccffmc9gqk1 +5kvxpqrrpeightthree +threefoursevenfive2dhtbrxlzzl +shhczssbltllsmntntlqfqgnnl98rm +5oneeight3vkqtwo29 +bv69fouronefourone6 +eight6five966 +4xnrtztgfgcmnmnsevensix +gmsvtnjd1sevennine4xxhqfbrjjqbglqjngttc +mdnxhhteightfive5onenineninegqjbqmfd +xonefourtwo4 +onesix61 +sjmnjhkj2892eightnine9 +nzseven39 +99nnjjzdrfsnjhthree1sevenfive +6xmggtbnblnbxdpkzblnvcvjqmhvntwoeightseven +76five6six +chdfjrlfhdzeight778 +xrvrck9five1hrvpfvkdcb7eightnine +foureighttq5sgdfourl2 +4rnbxrhhboneonefournine +5four3 +1b97eight +hlcjghlhsf32tgknm565knxqr +onecqgbgdcmlb2sixsix6nine +kxdkz3 +seven5xvhrxdm +xblqbgkqgsixvgrthreezxnzhknklxhbmgl4 +fvnkc7threethreeseven +bmbqxv24jhdg +97rfphlxvtx +4pgblonelone +ptdpllrddeight3 +9knpjzskrfd4 +twomjqdtbbvmj4shvsqrone3 +9zzh3pjsf6mhxlhm9glglfztjm +cfconeight47fivetdsmndgvsmbqjvszb +21vbqjz374 +sixeightqgfdjbhfd4oneeightone +tbccqdpz78srmcdx4six2 +643gqtvhkljxt +klfjf4qms +zrnhkhqzpczzfqsgsrtxklpbtp72 +1cnqfltrmhphg832three +twoseven5 +mxkmxlcgsixklclrkfr8638fourlrqpzgjq +nkbfkh452pthree +zvcktvd2485four88 +rfxj4 +three6jnr7 +two45rldjnmxkjphtwo7v +fivelncjffdnkzqrshvthreeh3p +ninejgrbmhrbqldeightnine6nine8one +96lvpt2djrkc5 +7seveneightthcxgthreeseven5hpfddktpj +6bvn +sixbjxtphstzgspnmkcvc952one +gmmslrndvltlthree394sevenoneightl +threenine7onefourtwojxhzvqlseveneight +5eightsix4txcczzmg +84seven +skjpkhxggsvjbprhllgjhninetwo6 +72bdpzccvone4zbdzlllnnonernlfvdpq +bvrtmzmtwonine29 +mrlvmdnlxb2814five5fjxzlhpn +lmrpf82rksix611 +tvq18oneqnmmzvtclnthree +jrbjc1zbbpqbrddt26seven1 +lxfivenmdtnhdmf98ptpxsgmgrxkmmznlk +zbmvchmxsevenddddthree2dxlddjp4 +three3onejg2fqgtjmpcgeighteight +three2two9seightfjqtwo +ninefive8sevenvnssix +3cnbxxtgmf5 +kpmjcsfrjfgzhmbpnqmlvrhbhqs8 +3vvcone64 +fvqksdsixthreexbfivetwo3 +sevenseven5 +63twoone8vhbcpmmlfive1 +4ctwo17eightsixkpvlgpj1 +rsgsnone1 +kbvxonemcqfive3eightone +ninenineone45threepvsmrtonejxmbnd +37fklnjkslqk9th9 +fiveoneq8rcgdxtwo8jfkxq6 +rgd7 +7rgkdpvp7qrb +7crtxfmslxxtcxsv +mqdnltb23fiveqcdqtonethree +8seven7 +8cqhqlhndqjznqhdbld2nspnxbj99tqqhp +onelqn7 +bvbjfour7 +ldqzhvhrbgsrrkh5j +kjsjxdcqgjztldjvxxgr9twoxfknxrrrphkdzdl8 +rvscnztblp56ljqtwompclcf +2dbtdgsevenhzctckvkvxvjljz +tvmhhxbbxvvsnlnineqsltjd92one +9twoqdmtvbxhpcthreeeight +81dvnkd87xbct +6mnxqnndcjfivefdckzmppfsevenmqvvvbnrgs +lvl3qjk5 +3fivefive +ktvsqzrf14eightmtnqbcktk5 +sevencdknznbxseventwo8rzggmvpbvlrs +hkhhrdxlml1xzbshninejzqc +eightseven23shkgzdgvvcxxfdv5 +14five1sevenxfmhtptwo3seven +47one +2three3 +f5dszzs2 +xmxffxkxpkninethree8x6seven +glzoneighteightrnjqgjznjm9 +63fznqxdfqt8 +33nine +4vrbmthreefbdzf +fourninethreesixnine9fourlvbgqhjbqncnlbjbz +two848dbvbninenine17 +pqzqgone1two +eight7lmxbhcsix +szr2fcvkljctlghhthree +sk81pxqhhhhvnjvgzfiveseven +cgqqkrz2vpdpzrthqssg7nineeight +498eightfournine +eight85onesvxnineone53 +ninevmchpkcg2 +six2shsvqfivefourtwo +mdzckfvr72cv +twotwo7onethreefourdjtgjg +tworfclmm3 +5sfvnkrmrptsix7four6kzlmclm +1onedkqgzbr89kphvc8 +5seventhree8eight9eight +kvjpgjgrcmpdscbfthreethree4mjqjnnzceightwohh +kjbmh1fdkdtznmsznvlconeznineseven +1fmgpxhxpqznqscvbszhhcmglvtnzhbbjjbzg +1mfqzkfnine5 +rrflkqslxztdlqxqkdnhqd7ps +39123thhsmscbpxr +8vnine4jgqrvqtshg3jhhdnbsrxneight4 +xkqgnfour87 +lsbnjqtzqz7ninenineone73lmkbnkhs +9fiveqqgqblfivehttxk +8twotwognd +4xknbheightfour6358 +4cqtpfjpf72eight3 +ninemjpqpqg8foureightsevenfcvpnrnnpzhcgkm +37twofivedsxrzbpchnkgxqx +oneone57one2k92 +mckoneight9threefour1onefourhdrcrvhqcmngkjnsthree +945 +tmmtwo7 +57 +6twoxzbfftnr27 +threenine4bqpztsixfour +84eight +3jpbnjrqhqfnxckqkqdvls +9gzzjzz +374nine +ninembxeight4sevent +threecq3 +cvn6cvqmpmfflkzphndjnggtktwosn +pgz7four5nineeightsixqrnfkdkgh +6one781vstwothreef +one617fourthreefourxqxnpv +8eightsqmkjkkf5xckcvd4lfnnfour +seven23qhntfmg56onexkjxh +f5s56rfltx282 +twosixninefive1tlzq +threetdhghclfsksql5oneninetwoseven +zbqzxmpb9pxlrthree +r4gxdzjnvzfonejnpmfcpgvxjjvkh8 +five338threejkk67seven +twolntxcnzvfr55sixtwofivesevennine +xhlppbqfr71brvppsixthreefddlgpfslqmdv +kxsklgonefjfpkd4threefive9six4 +6srphqmtdoneh3glthreefour8 +rjzdmj1cqvxnx1nvcvbfctft9 +3fqjdgbpggthreesix53 +9fivesndgmkvckblktzkshglqgdl4ztwoseven +qqrxkqhnzb23two34nine9 +8hrmffgstqpsixeightx1six +jngcsjnrhn2zsvcjmjg +9zfdmhzxdnfour272dcrqgk +lbjbrfhjxhxjphzxsjsix4 +fourthree2seven1two +twosix87 +vrlqqkctddggcvcjcpk6hxbqvbxmtsix +mrcgbpc6dthzqmmthreefour6two +r2zntjxgpfqfmqh +fourseven3 +6nfnsgchjdffttmgfnbvlxzoneseven8 +8sevenqqfiveseven5twojvgk +4rmtkvml4 +bprnine85 +sevenmfpcvlblcnine485fourseven4 +sevenseventhree68fivelhqgjqvcdqkvds +3fourxsgghqnvtssnvfs7nine7 +1fiveone5hpfdgvxb +eight2eight42twotwoonenine +lpdeightxcgpxkkeighthtjpsninemjlxrxtg31 +4smqpjzsixonethree +mr6csbmgrdrjj3onelqd4four1 +5sixvbscchd3 +384sps +4qzgsvmfx4ninevcclvcfrfp6tckcpvj5s +8l5glclltgcjgbhcg6 +3ldtdmjc6threeone +hsrtzl521nine5qqrtpdsp +z4v8threejdsmbfjpbj +9sixln26eightwovmh +848 +kndxtqpfrqxdxtfnqrqznpgvp9ninerlzcdvdtwo84 +kmqs84775seven +5threefourzkg +43five8cq2kprvdqrmxr1 +three4ttjqdh +48nine7sixfive +22x +sixrgtwo3rnbzkrztkdkg +4t +29bjpskmxneightppvthree +zmlzxvtlkt4seveneightbxseven +5two5eightnpszzmbkncnstx4 +9vk98sevenhznkxmlrlk7vdbqgvfjdk +1sixb8sjkvdhfld +one42eight4mrsdnpfjpvdtq +76fourntsrfllxkdfqvm6seven +skqndhr3nm4776 +4xpmfxmvj633eight +83ninecmpt +fourdthree9 +9eightjqnnmthcrseven +7threekgtf1 +xscj7threenmhsixseven5s3 +cqlzjt41 +855threemlmmqkgtfk +ninefzmvjjtvbmgf8nineninetwonegcn +ccpkzcldfourkdtfkjxvfb9fourhbtwonsoneightnl +pkeightwo5seven88rdnzzsdkbjeight9 +threen2fjsfivesix26nine +nine4rz8nine7bglpcmkqfzpseven +eight94six8dpgrv +twodfctf278 +fltqtmdkgjsvf72three +llrtzsixsix4fivetwosixone +qjhtjqjhgkjkzlpxxclsrdnzk1gbqt +sixeight1sixtwo +one5413nkmqjtlbdkz22 +bhtwoneonemzpzkqeighttwooneqkmcmsbq4 +sevensix3three2sixprcqcvm +25tjffdrtwohfqlkhzxlhb +97gcgqgjnpsthfjfdv636jsxq +zggjmjone1297six8drzs +jbpvnineeightntkkshbjvr3nshnqzdlkjmkfive +5four2gkkbxmpthreefour6 +5two15sixfivetzpg +one4fouronemfpvnqseven +9fnlbljdnzzfournine78 +djfljccrtvvqktzzvk61onesd +7twohbkeight +seven1eighttwothreet +4mdcljknhpqgxffqpj5 +nine9jlsmfgdgntwothreeeight4 +136nh +635ninejghg5 +cmone7fdlk9lfivemzvnhkcsp +8eightnlndm +6fourpb892 +fiveseventwosixfourthree7 +5fm +ninegchdnrf63431 +24sgnflnsixninenine8 +snm9 +3fntd721dhhkrqqxsfpstsvzpgonetkhcr +jlzfbml61vdmgb7one +266517 +7fivetwo2vhchmg678nine +cgrp3vzn5ninetwofour +666ninefour +9s +svpcnlktpxtvk42jhsvvdpftxpsk +2qznfzvbdr +foneb7eightfivehlbjjknninethree +kfp6 +l34pxxhxtd7d +rsbcrtwo27twocqlmeight +jkzgvqgpjfdqvmjfx2flnvjmgllxghhrbjjkfour2 +45sevengdnf59twofive +6fivespvkblrxvkcgdxktl +three9dvrssvl5eight4ftsix +seven56gdmlbfbjsl894sevencmc +814 +1one4 +onenine5fivekcrf1gvvfhlncsv +2ctvq9djzddfxcrj +ntdlcqgsixvmfvlc4fourvlhtvvqmnmkrm +9nineseven1seven +lcvzbnfourksvjqvmv47one5 +nine4blvlvlpkl6 +sixnqxrhnztzvpmbzmxjm19five +18jtzhk +rzrhv8four +2npghxvjonebchsprfhsjznrxvxnine +eightngsevencrjkxbhpgtxlzhgb46sevenqhqmlfx +threesffl9fivelgmndjfvseven92 +seven85 +87six9vnshclz +threetwo7915three +one2vkbp6rhqbxvcl7 +bsbr1five91 +qd3mnine +jjvhltxtdh5nineone6 +mbxlnj7bbhnxonejtmtqjfrzqgtrhkeightnine +fourfourqrxdtfive2smnqp +7tvjrszvrhdl5five +four15tvmpvxpvdjnine +sevenvv5tworpvdlseven3dlqvgblqtwo +nkckggninegnlqlnv25threexlhlbzvzk +3vngmhprjseventhreeeightnine +nvqtpzsszrdvttfivenine56oneseven8 +146 +fxfbone59 +f32dhffctkxp6rcngvtfq +sixthreefsixjhckmjqfive495 +42four +65nine984 +5fthreeone9twoqqsfvzmp +ttwonefive4 +one6gfxseightxqcq6 +3sixnrjtwormrncmhxeight +jhdxnmsgsdsevensqsslbsndpdmznmldbgeight3tcvjjv4 +5sixtvpckxzcjzbmrzk9 +pmdmnfgkb3six8xsmstsmxgmm +53onetvlgbglq4zbqpdgsskzdsksd6 +kzjcllvz6skphkfdxfiveqrbhmk +75qqjdgxlmfthreevzbfjdlxkfqqq +seveneightjntpjthzptwo2two +2five4fvrfxxnine4qzkkfkmq +2xlvcltn7 +fnmggtj2rqxzh7three +rzpjkgtml1 +2oneseven4one7xps6 +rljfhfrhmzkjxktnszbkpfspxdkqneight2 +pzgnine49six2 +plxsqeight2 +eight2sevenseveneight8rfcrsdlxb +sevenclpqqfxgjnmtwo9 +9sevenrqsixone8eightrxqgfsbjh +kqtkstrxhtfzbllhl4lqvqkcbr +hfplfpbltczflpp7nfive8 +ninenvqfrvtwo6onel +threev65 +frhn18six9sixninefourrsqzgd +mcxckfg5vpkbs89gbninexjzvlj +fivesixdx28 +7ppbqv +hs9twopcvpgtjnrsvksskpc8 +9mlpckzj2twothreefive +rkrgdclkninetwo6eighttwodc25 +tfivefourtwohkhhgsqlj1dtdcxmxkf +1four6five +fgbvmvxvtsix2twonine2sixfour +foureight66 +s6fourcv +mxl358sixfive8six8 +ztbtwo73sixvxsix9four +eight7qmdlcxfive5 +phgfivekrjxdmnzsqsix9 +1mfqsevenhz +rjhcdgzngtc155bqlttbsxklpknvlmk +qjkdqlrrs6two +sxlmqzxdpxdnj9fivetwo9seven5 +2qtdblb2 +8qgdzrsixtwo598oneightp +1shdb944 +vrlpronek2 +jm52 +8eightfourseven11mvtrmtkr2bmp +mnvnjxrgmrxhztwo2ssrdpqk +ztfive435three6threetwo +tnrrdnbgnbhzljdxhxxfrqkcpeight8js3 +foursix6zcsrztvgjxmp +five7fourgnnkspxcmczcbgsbdf77five +fgbrzkmvgrdbqjqndpfive81onetwomtzlfb +2qbsfd1two3ninetwo2 +8tdjxvfpvdvone33three +lpchnmln56twofive8tfour +cfkfbhppjf6fourdkfxsvdtbcjspzlseven8 +5fivestgkzsevenonedkhhrkthree +37nine8six8onefhvvbkmgdfgtv +26hzz +5glvnsztmnfjmkjseventdm4five +pvnnqrqvftrbcvnnthreenine5 +mgscxxlp3eight +53eighteight +two1oneqlcdkbddfour +jbll3 +8threeseven5tmtrgdhqxd +8twonine6s1 +91seven5pmqrjlhqrtzs +jj3sevensix4482 +jeightwo7lk4three +zchchxmsctzffivefournine9sqhqkgfour +72xct1 +vnsxvsqkhpfvgdseven23gzcmltzgone +xzjqhcvsix1fivecjtxnfivekmvjdc +zdfourgjlhtwo24d5klkpdgqbz +7sdzzdbrxbtonerjcmknnql4dfzqccvqt +tncqzxjq9twofiveqkxdrxrpj894six +dddmkctrzlpfmsszeight8zvbpmpkg +three23ckjhgjc +375jzdhnfcfr19mhsbnplqh +vpbbjlzone5sevenseven33four +onejzfsevenrbskjq1four +seven13one +vcnkfgv979one6zln +rqlxzzbmjb4lmbthreektqsdcfzbmdsfivethreenrxdlkqt +qkoneight8 +5rfourfivenine94fdprsix +onexonelzdh2lcbqpzq6 +six6v +7gtgxqnnine +tsljzhntwo3fourpbjncgmvf3fflvjxp +vfkdone9fivecftvmjdk +xc5three6eight94 +18363one7 +8fiveksshdlfmzhljhcmjrn7kpv5j +xbhmxfhbjnjzmninethree7 +2933mkmdqjcl +6ncvzqxfvgfive +lnine5fivetb4qmfktnqjxs +93187 +5mqninedzkfhbk +two7eightntdbsix298four +sixone3bspxqxggkmkrbcqrhfrxrlgjrlvfl96 +fourfivehqls3nine +threedfklszn2threeqzhh7one +mqmftzglone6kjpgglznhrjz89 +146cvkftscqsevensixnine +nndhdgpd484hxdgjtfsdxxg9 +6mbzckbjphg +eight6jbjtnld2mdjtd +zjtzcqxb736five +jlkdmone8 +gvjnjvmlfvcmvnfb8xcgjcmjqvz1bzcctvsixfzqjlhfkfk6 +vr6onejnjmrrldnsixsix5six +ninembtmtkgbctlfive45cjzzrmgcscfbcgeight +2mdvneightjzgffivefive4 +hmdnbxghxjxt4czshmsfzc +61six18threehrcj +six3five6eightkdfzhxcjkdhq3 +jrhqrqkpd4hsixdsbjdpscclmnnhknqq16 +jflzcxr3three +threefourghvgsktkc93cmjmsgh8one6 +96fivesevenslklhsfmpz +jgkpgfnnbq2pmspdfhsqxfour +g4fourthreerpkdhjhlxlzvnineseven +xkxhkphnkvpdnlncn86srxthree +7sixsevenrfour +5zr72qltsrbdsv +ninervqzdfzqmf6five +8jslpvs73 +ztvlxndlm5twohdhmtrdnhbzdrxb +seven6nine4dpdpvrtrmqvql +jfz1 +5nineeight5onefivecxtqbsdtbthreefour +fourgeight6threeszgseventwo9 +sixfour3 +npl8 +tzjkffsvbjseven5rhmlxonezlx +5dhtpfour +twothreebxtfndvdnine1sixbb9 +five9nineqlzrmtgs5 +9v764nineeight +five4eightlsix6 +3nineeight21 +foureight8btsc +3xgdgtb2 +7threetwonexqk +kkqsix48onefourhlsh8 +onekgtdzgfh2fivenine2onerb +six4zgcnlhmltrxp5xphvtwo9 +eight7cdqggpssix +niner9pzmrbqldkljmgphrrgmdjseven6 +439 +twofoursixrthree5bxppnhqtx +bmpnt3 +fivepkzkzpghrptpksevenseven83two1 +9fiveone8one +fiveseven3lqxghdlskbltrzrstwo +fournine3ninephlghonetwoeightbvmdcconeightq +three2pvklmzqjfh4sixonedrctlsfdfour +three91spjlscscjcxbbpdhrg37 +57qqjpdfppsix1qxrh5mlmncf +4nfone5eight +eightqsix7one +4jtvxfd38hnrmqkbnvfxpp +qmfsspkfour1plmslcrsseventhree +fzckcbfvxbpsix7nine +fzrj4 +4threeqntnineqstzjftnine +tkrh6sixdqflrvtmzmfiveseven9ktmtvprkxhfour +nine4983four +mpllmjrfgv66five3kvhthplrtwo7nkklb +9ngvdjddqbz +5twosix8lbhmzrg +eightsbmcfgm76two4hhc6 +seventwosevenrpm6threeeightwodxs +xkbseventwotwogmkxhpmhm42hvvbfchreight +gcqeightwosix8xdlhrnnbkmsevenqdbrjghz +458ninextfjxvgsq5fltdsk6 +rlgsflhxqd5bdbhclmrthree +twothreemqqbzjn88blvqxbseven +rqrrdrmlfsixfive6 +eight959tzxkgqjd +txdszrn5eight3cqeight1brqr +45122 +jvvslnkdk6qnfzjzvseight55eight +4twoeightgrhhkrvtkrzpfive7seven +three8gsmkpzsmfvf2 +fiveeight5sevenone9twoseven +4seightjjdkdglspz3vg +sevenssrzkspld2 +qnzcvcthrsgjlnzxmxlppjdpnine8seven7 +eight7xhvkrcr +two2tdjdfbqtqxrs119r diff --git a/data/day02.txt b/data/day02.txt new file mode 100644 index 0000000..8a9d45e --- /dev/null +++ b/data/day02.txt @@ -0,0 +1,100 @@ +Game 1: 5 red, 1 green, 2 blue; 2 green, 8 blue, 6 red; 8 red, 3 blue, 2 green; 6 red, 1 green, 19 blue; 1 red, 17 blue +Game 2: 4 red, 5 green, 2 blue; 7 red, 14 green, 3 blue; 2 green, 5 blue, 11 red; 10 blue, 3 green; 9 green, 6 blue, 13 red; 7 red, 5 green, 9 blue +Game 3: 9 green, 18 blue, 1 red; 6 red, 10 blue, 5 green; 4 blue, 4 red, 15 green +Game 4: 1 red, 13 green; 10 green, 2 red; 3 red, 4 green, 2 blue +Game 5: 4 red, 2 green, 1 blue; 4 red, 9 blue; 4 green, 1 red, 6 blue; 3 blue, 2 green, 6 red; 5 red, 4 green, 1 blue +Game 6: 6 red, 3 green, 6 blue; 3 green, 5 blue, 12 red; 3 green, 9 blue, 3 red; 13 red, 8 blue +Game 7: 3 blue, 1 red; 3 blue, 10 green; 4 green, 5 blue +Game 8: 11 green, 4 blue; 4 red, 4 blue, 11 green; 4 green, 3 blue; 1 blue, 6 red, 12 green +Game 9: 1 blue, 4 green, 1 red; 5 green, 3 blue; 9 green, 4 blue; 3 blue, 1 red, 10 green; 6 green, 2 blue +Game 10: 5 green, 6 red, 7 blue; 7 green, 5 blue, 5 red; 8 red, 6 blue, 8 green; 2 blue, 8 green, 6 red; 6 blue, 8 red, 4 green +Game 11: 1 blue, 10 red, 10 green; 11 green, 2 blue, 16 red; 4 blue, 7 red, 14 green +Game 12: 8 green, 9 red, 12 blue; 2 green, 4 blue, 7 red; 1 red, 9 blue, 7 green; 8 green, 2 red, 10 blue; 1 green, 5 red, 5 blue; 6 green, 5 red, 1 blue +Game 13: 3 green, 1 blue, 6 red; 1 green, 10 red; 1 blue, 15 red, 2 green +Game 14: 2 green, 6 blue; 1 green, 2 blue, 2 red; 5 blue, 1 green, 2 red; 4 green, 5 blue, 4 red; 4 red, 5 green, 4 blue; 1 red, 5 green, 6 blue +Game 15: 12 green, 7 blue; 19 green; 11 blue, 16 green, 1 red; 1 red, 2 green, 3 blue; 8 blue, 1 red, 19 green; 14 blue, 3 green, 1 red +Game 16: 2 green, 13 blue, 3 red; 5 red, 12 blue; 6 blue, 8 red; 4 red, 1 green, 4 blue; 1 green, 15 blue; 4 blue, 2 green, 1 red +Game 17: 11 blue, 7 green, 2 red; 12 red, 8 green, 8 blue; 2 red, 6 blue, 6 green +Game 18: 1 green, 2 blue; 2 green, 1 blue, 4 red; 3 green, 16 red; 2 red, 3 green +Game 19: 11 blue, 3 green, 3 red; 11 blue, 5 green; 3 green, 3 red, 8 blue +Game 20: 1 green, 6 blue; 4 blue, 6 green; 1 red, 10 green; 12 green; 5 blue, 1 red, 4 green; 1 green, 5 blue +Game 21: 7 green, 3 blue; 1 red, 5 blue, 6 green; 1 red, 11 green; 8 blue, 1 red, 10 green; 1 red, 5 blue, 3 green +Game 22: 3 red, 1 blue; 3 green, 1 red, 1 blue; 7 green, 2 blue +Game 23: 12 green, 1 red, 2 blue; 10 blue, 1 green, 1 red; 9 blue, 8 green +Game 24: 5 blue, 6 green, 6 red; 3 blue, 1 red; 8 blue, 2 green, 12 red; 1 green, 2 blue, 14 red; 2 blue, 5 green, 15 red +Game 25: 6 red, 13 green; 1 blue, 1 red, 3 green; 1 blue, 12 red, 10 green +Game 26: 16 red, 2 blue, 7 green; 1 blue, 7 green, 8 red; 1 blue, 3 red, 9 green +Game 27: 4 blue, 15 green; 6 green, 2 blue, 1 red; 9 blue, 10 green, 4 red; 3 red, 3 green, 6 blue; 11 blue, 7 red, 11 green; 6 red, 5 green, 13 blue +Game 28: 10 blue, 8 red, 10 green; 4 blue, 11 red, 6 green; 8 red, 9 green, 10 blue; 4 red, 9 green, 2 blue +Game 29: 4 red, 9 green, 7 blue; 10 blue, 6 green, 4 red; 1 green, 2 red, 10 blue; 3 green, 9 blue +Game 30: 6 blue, 9 green, 10 red; 6 blue, 4 red; 5 green, 2 blue; 5 green, 2 red, 2 blue; 6 blue, 8 green +Game 31: 7 blue; 2 green, 6 blue; 1 red, 9 blue, 5 green +Game 32: 8 blue, 2 red, 4 green; 6 red, 2 blue, 1 green; 14 blue, 8 green, 8 red +Game 33: 1 green, 1 red, 1 blue; 2 blue, 1 green, 12 red; 1 green, 1 red; 1 blue, 2 red, 1 green; 7 red, 2 green, 2 blue +Game 34: 3 blue; 2 blue; 10 red, 1 blue, 1 green; 5 red; 1 green, 1 red, 1 blue; 1 green, 2 red +Game 35: 10 green, 1 red, 16 blue; 4 red, 10 blue, 9 green; 1 green, 7 blue, 5 red +Game 36: 1 blue, 3 red, 16 green; 1 blue, 3 red, 1 green; 9 green, 3 red, 8 blue; 14 green, 6 blue, 3 red; 3 red, 12 green, 4 blue +Game 37: 11 red, 3 blue; 15 red, 8 blue, 6 green; 6 green, 19 red, 11 blue; 1 green, 4 blue, 14 red; 12 blue, 5 red, 8 green; 4 blue, 9 red +Game 38: 4 green, 10 blue, 3 red; 1 green, 1 red, 11 blue; 2 red, 12 blue +Game 39: 3 green, 1 red, 4 blue; 9 green, 1 red, 18 blue; 4 red, 4 green, 17 blue; 4 red, 10 blue, 14 green +Game 40: 5 red, 4 green, 8 blue; 1 green, 9 blue; 9 blue, 3 red, 6 green; 8 red, 9 blue, 9 green +Game 41: 1 blue, 9 red, 3 green; 9 red, 10 green, 15 blue; 13 red, 8 green, 8 blue; 19 red, 6 blue, 2 green; 7 green, 5 blue, 12 red +Game 42: 15 blue; 1 red, 1 green, 9 blue; 6 blue, 1 red; 1 green, 4 blue +Game 43: 1 green, 8 blue, 2 red; 1 red, 1 green, 6 blue; 7 blue; 7 blue, 3 red, 1 green; 2 red, 5 blue +Game 44: 7 green, 11 blue, 6 red; 9 green, 8 blue; 4 red, 15 green; 12 green, 14 blue, 8 red +Game 45: 4 red, 4 green; 14 green; 4 green, 2 blue; 1 blue, 12 red, 5 green; 3 red, 6 green; 11 red, 1 green +Game 46: 2 blue, 1 green, 1 red; 1 blue, 6 green, 1 red; 2 blue, 1 red, 1 green; 5 green +Game 47: 1 blue, 1 red; 14 red; 3 green, 2 blue, 17 red; 4 green +Game 48: 1 red, 11 green, 2 blue; 1 red, 11 green, 6 blue; 13 green, 1 blue, 3 red; 3 green, 4 red, 6 blue; 12 green, 5 blue, 1 red; 2 red, 4 green, 4 blue +Game 49: 5 blue, 3 green; 2 green, 8 blue; 5 blue; 4 green, 5 blue, 1 red; 4 green, 7 blue; 1 green, 3 blue +Game 50: 3 red, 5 green, 2 blue; 9 green, 7 red, 4 blue; 3 blue, 6 red, 13 green; 6 blue, 8 red, 9 green +Game 51: 2 green, 11 red, 7 blue; 5 blue, 13 red; 1 green, 2 blue, 3 red; 6 blue, 8 red; 11 red, 2 green, 4 blue +Game 52: 15 blue, 1 green, 4 red; 4 green, 10 blue, 2 red; 6 red, 18 blue, 1 green +Game 53: 2 red, 10 green, 6 blue; 4 green, 3 blue, 3 red; 17 blue, 19 green, 5 red; 6 blue, 6 green, 9 red; 5 blue, 17 green, 7 red +Game 54: 9 blue, 8 red, 6 green; 6 red, 8 green; 1 green, 6 blue, 1 red; 5 red, 4 green, 9 blue; 5 blue, 2 green, 5 red +Game 55: 8 blue, 8 red, 10 green; 3 red, 4 green, 9 blue; 4 red, 3 green, 7 blue +Game 56: 3 red, 6 green, 1 blue; 5 green, 1 blue, 1 red; 1 red, 2 green; 10 green +Game 57: 1 green, 4 blue, 12 red; 17 red, 7 blue, 10 green; 17 red, 5 blue, 3 green +Game 58: 1 red, 5 green, 14 blue; 5 green, 6 red, 7 blue; 4 blue, 8 green; 3 red, 9 green, 7 blue; 8 blue, 8 green, 6 red; 8 green, 7 blue, 5 red +Game 59: 3 green, 5 red; 2 red, 13 green, 1 blue; 19 green, 1 red, 1 blue; 19 green, 1 blue; 18 green, 1 blue, 5 red; 6 red, 9 green +Game 60: 5 red, 1 green, 6 blue; 8 red, 6 blue, 14 green; 8 green, 8 red, 3 blue; 2 blue, 5 green, 3 red; 4 blue, 1 red, 14 green +Game 61: 7 red, 4 blue, 2 green; 2 green, 8 red, 9 blue; 5 blue, 2 green, 8 red; 8 red, 1 green, 8 blue +Game 62: 6 red, 3 blue; 1 blue, 2 red, 2 green; 3 red, 1 blue +Game 63: 2 red, 1 blue, 2 green; 1 blue, 1 green; 2 green, 4 red; 3 green, 2 red; 2 green +Game 64: 5 green, 6 blue, 7 red; 2 red, 5 green, 8 blue; 7 green, 9 blue, 1 red; 4 green, 5 blue; 19 blue, 5 green, 13 red +Game 65: 3 red, 1 blue, 4 green; 5 green, 3 blue; 9 green, 1 red, 10 blue +Game 66: 6 red, 13 green, 2 blue; 2 blue, 5 red, 9 green; 18 red; 2 green, 1 blue, 1 red; 19 red, 10 green; 1 blue, 15 green, 13 red +Game 67: 8 blue, 3 red; 1 red, 12 green, 7 blue; 4 red, 6 blue, 5 green; 11 green, 10 blue, 7 red; 5 red, 9 green, 14 blue +Game 68: 1 red, 3 green; 10 blue, 1 red, 3 green; 1 green, 17 blue; 16 blue; 6 blue +Game 69: 11 green, 5 blue, 8 red; 2 red, 5 green, 1 blue; 10 green, 2 blue; 11 green, 7 red, 4 blue +Game 70: 2 green, 1 blue, 13 red; 16 green, 20 red, 4 blue; 10 red +Game 71: 10 blue, 6 green, 7 red; 5 red, 5 green, 2 blue; 7 green, 4 red, 5 blue; 1 red, 8 blue; 5 red, 1 blue, 8 green; 5 blue, 1 red, 5 green +Game 72: 2 red, 4 green; 2 green, 2 red, 1 blue; 3 blue, 3 green, 2 red; 2 green +Game 73: 5 red, 19 blue; 12 blue, 4 green, 16 red; 14 red, 11 blue, 1 green +Game 74: 2 red, 1 green, 9 blue; 5 blue, 1 green, 2 red; 2 green, 1 red, 13 blue; 2 green, 1 red, 3 blue +Game 75: 7 blue, 1 red, 18 green; 17 green, 8 red, 13 blue; 15 blue, 4 red +Game 76: 1 green, 12 red, 13 blue; 5 green, 11 blue, 12 red; 10 red, 1 green; 10 red, 2 blue; 5 red, 2 green; 2 green, 17 blue, 3 red +Game 77: 2 blue, 1 red, 1 green; 7 red; 7 red, 3 blue, 2 green; 10 green, 1 red; 3 red, 7 blue, 6 green +Game 78: 10 red, 2 blue, 2 green; 1 blue, 6 red, 4 green; 12 red, 8 green; 6 green, 8 red, 7 blue; 11 green, 5 blue, 6 red +Game 79: 7 green, 5 red; 6 blue, 2 green, 15 red; 9 blue, 2 red, 12 green; 1 blue, 4 red, 10 green; 4 blue, 12 green, 11 red; 5 green, 3 red, 5 blue +Game 80: 1 green, 13 blue, 2 red; 2 red, 1 green, 13 blue; 7 blue, 8 red +Game 81: 1 green, 2 red, 11 blue; 5 red, 3 blue; 1 green, 1 red; 14 red, 1 green +Game 82: 12 red, 3 blue, 8 green; 15 red, 9 blue, 8 green; 6 blue, 13 red, 8 green +Game 83: 4 blue, 6 green, 3 red; 7 red, 2 blue, 9 green; 6 green, 3 red +Game 84: 4 green; 3 red, 3 blue; 4 red, 1 blue, 2 green; 1 red, 5 green, 5 blue; 1 red, 5 blue, 3 green +Game 85: 3 red, 4 blue, 15 green; 9 green; 2 red, 4 blue, 6 green; 1 red, 4 green, 7 blue; 3 red, 10 green, 9 blue; 1 red, 13 green, 3 blue +Game 86: 8 red, 6 blue; 3 blue, 3 green, 15 red; 12 red, 6 green, 13 blue; 15 red, 6 green, 10 blue +Game 87: 4 red, 4 blue; 6 red, 2 blue; 5 blue, 3 green; 4 blue, 2 red +Game 88: 4 blue, 7 green; 2 blue, 7 green; 6 green, 4 blue; 1 red, 1 blue, 2 green; 11 green, 3 blue +Game 89: 1 blue, 12 green, 11 red; 3 red, 7 blue, 1 green; 7 green, 8 red; 6 blue, 2 green, 3 red; 7 red, 8 green; 11 blue, 5 red, 12 green +Game 90: 1 green, 12 red, 17 blue; 14 red, 17 blue, 9 green; 6 green, 9 red, 11 blue +Game 91: 3 green, 14 blue; 2 blue, 2 green, 6 red; 1 red, 11 blue, 1 green; 3 green, 4 red, 20 blue; 6 red, 2 green, 3 blue; 10 blue, 12 red +Game 92: 6 blue, 7 red; 2 blue, 4 red, 1 green; 4 red, 1 green, 3 blue; 2 red, 5 blue; 8 red, 6 blue; 1 green, 2 blue, 1 red +Game 93: 4 blue, 1 green, 4 red; 8 red, 4 green, 4 blue; 2 blue, 9 red; 1 blue, 4 red; 4 blue, 2 green, 11 red +Game 94: 5 blue, 1 green, 7 red; 1 green, 11 blue, 1 red; 1 green, 15 blue, 4 red +Game 95: 1 red, 3 blue; 1 red, 1 green, 8 blue; 3 red, 1 green, 3 blue; 3 red, 6 blue; 6 blue +Game 96: 4 green, 1 blue; 7 green, 3 red; 2 blue, 9 red, 16 green; 3 blue, 4 red, 11 green +Game 97: 6 green, 8 blue; 1 blue, 1 green; 3 green, 4 blue; 8 blue, 5 green, 2 red +Game 98: 18 blue, 6 green; 11 green, 3 blue, 7 red; 18 blue, 3 red, 7 green; 5 red, 5 green; 8 blue, 2 green, 11 red +Game 99: 3 red, 2 green, 3 blue; 1 red, 4 green, 1 blue; 2 green, 18 red; 15 red, 1 blue; 2 blue, 9 red, 2 green; 17 red, 3 blue, 4 green +Game 100: 9 blue, 8 red, 16 green; 3 red, 7 green, 8 blue; 1 green, 3 red, 12 blue; 3 green, 14 blue diff --git a/data/.keep b/data/day03.txt similarity index 100% rename from data/.keep rename to data/day03.txt diff --git a/data/day04.txt b/data/day04.txt new file mode 100644 index 0000000..4c0c0ea --- /dev/null +++ b/data/day04.txt @@ -0,0 +1,223 @@ +Card 1: 5 37 16 3 56 11 23 72 7 8 | 3 79 35 45 72 69 15 14 48 88 96 37 11 75 83 56 23 7 16 50 21 91 32 97 17 +Card 2: 1 45 93 96 65 88 78 15 27 26 | 5 84 62 63 45 61 1 80 88 77 40 51 73 21 32 98 74 59 97 9 15 71 25 43 23 +Card 3: 9 99 34 44 37 16 67 43 41 83 | 43 41 5 69 90 50 34 94 86 59 98 16 99 28 44 37 47 57 7 14 83 67 76 9 77 +Card 4: 45 99 64 82 57 9 56 17 78 7 | 75 56 30 88 64 1 98 27 9 57 7 6 77 44 17 78 82 99 16 91 76 94 63 87 45 +Card 5: 76 80 42 88 26 56 79 63 6 37 | 16 4 40 34 46 76 67 69 1 54 5 55 59 24 78 29 26 9 51 44 92 41 63 88 65 +Card 6: 59 23 88 38 49 16 24 18 22 89 | 52 25 88 27 23 79 22 84 72 80 39 17 49 96 56 60 44 45 16 63 78 38 19 5 43 +Card 7: 81 1 37 6 20 76 3 31 93 83 | 74 32 25 76 43 87 52 93 47 85 83 31 17 72 6 99 1 36 20 81 3 69 78 44 37 +Card 8: 74 73 65 29 66 47 43 11 24 38 | 5 3 1 88 29 11 49 67 47 33 31 61 63 75 84 35 18 71 66 92 81 97 8 9 85 +Card 9: 67 68 8 74 17 11 28 47 96 2 | 85 7 37 33 15 18 91 96 4 67 16 47 28 26 80 52 17 97 68 8 11 79 2 46 74 +Card 10: 91 22 85 35 47 26 99 39 72 38 | 5 7 12 14 62 93 61 56 82 4 1 51 86 36 43 29 50 75 68 25 98 77 74 64 24 +Card 11: 4 53 44 83 23 84 40 55 69 82 | 24 48 11 37 60 76 41 29 58 39 45 88 95 67 49 28 36 35 86 33 18 63 51 19 93 +Card 12: 40 45 87 58 72 59 89 55 20 91 | 7 62 2 91 59 78 4 44 25 24 57 94 79 75 51 54 55 90 83 30 68 47 3 69 26 +Card 13: 92 58 35 96 84 62 31 65 95 5 | 22 52 84 98 62 31 75 7 12 78 51 91 37 58 46 85 21 61 95 49 36 5 79 92 4 +Card 14: 75 37 41 53 12 77 97 6 54 29 | 52 65 46 94 20 6 76 75 70 83 29 93 64 1 12 58 89 49 26 16 82 85 74 61 41 +Card 15: 20 88 22 99 28 87 16 78 70 71 | 20 89 56 27 61 32 53 22 78 3 54 28 70 64 33 24 23 17 5 47 55 16 21 88 9 +Card 16: 42 17 35 68 4 78 73 15 88 61 | 42 88 20 57 40 8 71 92 78 45 3 15 17 67 52 43 84 68 4 18 53 79 6 35 24 +Card 17: 19 25 13 51 36 71 56 65 24 50 | 13 82 73 37 83 78 48 88 87 59 97 75 18 53 44 17 84 34 79 95 69 66 76 28 57 +Card 18: 80 99 40 59 75 82 25 70 87 92 | 90 32 27 30 95 33 12 31 78 75 26 44 87 83 39 81 55 43 76 22 61 25 99 69 59 +Card 19: 88 78 95 67 22 4 50 39 58 72 | 74 6 10 21 77 81 53 86 71 56 37 48 23 83 87 55 80 34 89 16 65 8 28 92 97 +Card 20: 54 40 10 45 26 75 88 67 60 3 | 59 69 71 36 95 53 76 80 68 25 96 61 39 65 13 6 49 46 92 28 20 27 7 83 44 +Card 21: 70 48 22 94 63 45 25 85 79 24 | 9 4 82 74 14 65 23 20 10 50 48 81 92 16 27 47 60 22 59 55 2 15 62 41 38 +Card 22: 21 55 81 79 16 64 96 39 56 72 | 28 67 20 18 3 25 29 46 48 83 14 5 64 62 8 45 32 89 85 80 2 55 65 9 61 +Card 23: 17 53 27 13 18 58 81 31 82 35 | 54 78 6 49 75 52 4 19 68 94 80 88 99 89 60 5 83 96 33 23 95 77 27 57 21 +Card 24: 1 12 33 55 68 89 91 43 73 16 | 79 93 14 84 42 80 37 86 44 90 39 81 26 72 46 35 59 28 6 76 19 58 95 7 92 +Card 25: 2 90 83 88 35 17 95 5 9 72 | 72 37 53 51 95 26 16 88 5 66 76 2 84 4 15 22 93 47 6 82 28 9 90 83 23 +Card 26: 63 15 58 95 96 67 27 48 97 40 | 74 96 18 57 14 54 78 40 76 39 10 27 8 87 15 26 66 63 56 49 89 97 95 38 13 +Card 27: 34 21 92 88 66 44 63 2 96 81 | 44 26 88 96 34 51 73 74 72 2 54 60 63 79 62 66 58 70 81 16 7 98 21 92 10 +Card 28: 73 23 8 50 57 31 9 76 89 87 | 76 50 81 44 57 8 18 89 99 83 78 64 72 47 24 14 2 87 56 10 31 13 96 74 68 +Card 29: 52 25 92 30 12 95 38 77 51 36 | 5 7 87 85 70 33 57 10 50 44 61 39 96 65 93 60 79 94 43 52 37 54 6 32 62 +Card 30: 96 10 11 51 58 20 70 91 80 85 | 24 96 98 91 51 11 57 85 95 20 84 80 10 62 6 5 70 34 58 29 42 40 59 55 32 +Card 31: 55 36 29 98 89 58 82 93 94 22 | 9 3 93 56 97 41 15 94 63 13 42 73 55 20 18 98 89 22 77 45 53 12 44 29 36 +Card 32: 92 85 9 6 65 87 59 12 71 55 | 85 96 87 36 93 92 55 88 74 60 71 6 3 65 82 9 94 19 84 59 12 98 28 37 18 +Card 33: 90 3 61 94 8 12 62 77 60 14 | 96 62 81 59 3 8 60 7 90 61 23 12 70 5 51 99 71 14 58 63 94 85 50 57 77 +Card 34: 20 4 44 50 53 19 88 29 68 56 | 9 44 22 56 53 4 50 40 88 29 80 5 1 30 19 20 49 68 63 47 28 92 93 2 83 +Card 35: 26 11 96 48 72 39 19 10 12 70 | 14 56 84 85 30 67 29 90 2 52 20 83 93 73 27 79 82 78 63 3 50 43 6 15 32 +Card 36: 40 77 87 9 24 54 71 97 76 32 | 8 93 19 12 66 97 75 9 76 1 71 11 32 15 54 51 83 50 87 72 24 7 77 47 5 +Card 37: 79 95 36 38 99 60 29 58 88 81 | 38 60 95 50 22 10 87 59 99 88 67 89 15 39 13 12 44 51 34 86 65 90 2 24 58 +Card 38: 33 8 40 69 4 57 79 56 93 9 | 48 11 64 83 95 19 70 36 99 16 30 91 18 4 12 43 38 1 41 44 17 72 98 2 22 +Card 39: 75 80 39 25 90 11 20 46 99 17 | 83 74 29 75 61 33 95 51 80 13 76 46 39 8 44 47 49 6 17 22 2 10 85 66 62 +Card 40: 76 94 24 53 72 92 28 10 34 39 | 85 69 8 81 48 44 27 42 73 83 25 74 28 66 41 98 95 39 52 82 18 67 55 1 26 +Card 41: 92 97 13 88 24 17 54 80 75 79 | 14 41 81 43 39 6 85 56 10 88 27 86 58 7 80 98 97 61 75 93 62 26 59 73 91 +Card 42: 15 42 98 99 10 40 58 74 11 97 | 53 52 57 74 25 36 42 86 97 88 43 15 56 99 83 24 19 60 61 10 68 5 18 98 3 +Card 43: 14 74 56 87 96 66 94 90 40 93 | 10 87 93 57 98 15 36 17 70 12 1 11 33 32 84 65 41 74 83 25 63 77 56 30 72 +Card 44: 24 21 66 99 96 41 84 97 75 78 | 20 78 22 89 71 6 60 35 58 36 18 8 39 4 40 81 34 32 77 26 14 42 53 48 13 +Card 45: 36 15 61 12 68 95 60 90 65 84 | 74 20 90 4 37 11 53 25 34 59 15 45 84 91 58 63 7 27 97 93 73 3 31 65 30 +Card 46: 72 54 37 45 89 8 67 85 39 62 | 69 57 83 24 93 54 33 3 17 13 8 51 98 7 48 11 28 41 19 38 40 60 62 34 84 +Card 47: 29 2 51 82 16 25 46 50 28 6 | 42 24 1 43 87 36 94 74 21 98 15 83 37 50 10 57 62 17 96 33 40 73 93 39 59 +Card 48: 80 77 65 41 73 5 88 37 16 47 | 79 48 55 83 93 62 61 95 66 26 7 32 33 21 14 3 43 36 90 44 15 11 37 4 71 +Card 49: 4 33 50 26 90 86 63 6 81 42 | 28 14 2 29 22 44 24 36 53 54 17 45 78 68 60 93 31 59 85 57 3 16 64 41 84 +Card 50: 65 54 84 16 46 57 47 6 85 81 | 6 69 63 3 91 95 15 34 71 76 81 24 64 94 57 22 19 59 99 1 54 83 65 16 88 +Card 51: 83 48 81 82 55 92 25 76 39 56 | 35 81 96 94 82 25 85 11 39 55 56 76 59 62 84 48 58 37 78 2 27 92 83 69 73 +Card 52: 47 56 99 64 59 13 25 60 81 93 | 61 19 25 60 41 28 67 49 47 13 36 5 56 81 66 23 52 30 59 99 39 6 93 84 64 +Card 53: 59 56 12 96 92 49 1 66 20 2 | 65 66 96 92 56 20 29 59 27 1 97 17 54 53 94 82 75 39 7 34 2 60 49 12 93 +Card 54: 4 29 30 48 99 56 60 27 3 95 | 26 17 59 35 73 66 58 57 2 64 76 67 34 65 10 12 6 53 97 63 19 20 70 86 11 +Card 55: 84 70 37 64 2 43 91 69 5 93 | 5 53 37 46 25 16 45 70 84 34 91 20 3 62 55 64 10 43 94 93 69 42 2 90 40 +Card 56: 57 36 17 21 72 9 39 77 52 53 | 55 47 59 52 85 41 24 74 81 53 42 6 58 51 17 34 54 72 73 2 70 67 10 71 79 +Card 57: 75 15 56 65 21 30 43 83 90 59 | 85 9 83 61 70 69 86 51 47 32 96 23 16 7 67 72 99 13 12 93 91 33 3 48 2 +Card 58: 77 49 71 63 66 72 97 87 24 95 | 4 12 97 98 24 46 72 14 23 71 87 60 89 73 82 20 9 49 27 85 95 75 77 79 8 +Card 59: 81 29 18 22 70 93 59 58 90 31 | 19 90 76 62 15 78 71 52 75 44 4 88 61 73 10 14 25 27 94 50 77 66 89 55 63 +Card 60: 97 95 5 56 63 81 94 7 16 17 | 29 68 83 4 10 69 79 89 47 30 97 58 85 44 14 32 50 78 99 81 52 6 46 71 51 +Card 61: 99 45 17 68 39 48 25 20 38 55 | 23 95 90 64 9 8 71 89 1 31 42 50 74 77 49 33 30 92 94 81 6 61 36 96 68 +Card 62: 64 96 55 52 56 74 28 26 57 27 | 11 33 29 40 70 90 4 64 68 39 35 18 42 85 58 83 23 52 48 6 88 13 74 41 69 +Card 63: 36 80 16 61 89 50 11 2 57 96 | 96 13 35 91 62 81 58 90 55 57 99 73 32 76 61 94 60 89 83 27 48 16 70 86 42 +Card 64: 99 33 85 46 90 54 11 61 76 27 | 43 6 90 87 59 71 74 4 41 82 10 64 97 17 75 29 95 63 91 7 47 12 77 25 32 +Card 65: 30 99 44 66 5 89 8 58 16 78 | 79 36 80 3 24 81 48 22 29 26 33 19 57 6 28 95 86 94 49 51 98 10 55 8 18 +Card 66: 98 95 22 68 25 89 6 88 90 35 | 88 18 75 81 65 60 39 77 47 53 85 33 40 44 8 27 66 82 48 63 64 97 24 49 29 +Card 67: 63 96 55 9 23 17 42 66 12 56 | 14 76 60 70 78 58 42 52 25 18 94 86 31 79 68 57 73 47 51 89 32 12 63 29 28 +Card 68: 75 57 84 29 91 22 36 69 25 32 | 78 28 96 12 42 1 44 54 60 73 48 16 41 23 37 83 31 64 21 92 86 79 33 24 14 +Card 69: 51 7 82 59 78 34 39 42 19 24 | 50 9 41 82 94 46 25 31 32 88 92 75 55 63 69 56 98 65 86 93 79 54 10 43 28 +Card 70: 4 74 46 53 28 9 14 63 73 21 | 2 36 71 91 42 66 7 77 84 86 49 94 16 83 82 96 25 70 58 53 78 29 23 17 13 +Card 71: 21 39 77 83 14 12 5 88 97 47 | 43 38 57 91 3 81 90 30 25 33 84 80 58 10 27 20 28 73 6 54 13 65 31 70 36 +Card 72: 68 33 8 24 59 58 65 57 36 38 | 2 95 17 38 58 24 45 31 36 33 59 83 32 6 37 11 67 78 88 48 57 68 80 26 8 +Card 73: 56 6 28 51 83 64 35 17 60 87 | 51 93 56 43 30 17 67 61 35 97 88 83 64 24 40 6 68 84 87 75 46 95 60 28 89 +Card 74: 82 44 97 85 88 42 61 56 1 40 | 56 12 66 67 44 22 97 40 29 43 24 1 50 42 78 79 7 80 82 88 61 85 89 38 41 +Card 75: 83 90 15 43 93 50 8 37 17 89 | 12 89 90 50 91 83 15 37 94 7 10 88 31 14 17 19 43 3 59 71 46 93 63 52 8 +Card 76: 14 38 56 48 40 2 43 42 44 75 | 8 55 65 79 87 30 95 89 3 39 22 6 99 74 88 32 98 91 9 70 59 92 78 66 24 +Card 77: 36 27 48 94 84 77 75 6 70 22 | 75 48 99 5 45 87 63 6 49 31 94 22 29 37 27 77 50 36 23 80 10 84 70 97 93 +Card 78: 95 18 51 10 43 90 23 99 56 68 | 5 94 49 92 22 87 47 36 62 30 7 32 12 64 31 25 41 73 39 34 14 27 80 50 91 +Card 79: 17 75 70 51 40 42 84 30 38 15 | 17 86 42 15 75 88 70 84 29 51 39 4 59 65 80 1 40 74 92 46 38 71 64 61 30 +Card 80: 36 16 59 77 82 72 87 98 99 32 | 76 9 70 12 97 75 20 30 10 54 74 44 93 22 4 43 32 33 18 17 82 29 28 55 21 +Card 81: 97 82 92 35 20 71 15 78 98 6 | 82 71 43 68 70 20 31 55 90 67 19 24 81 60 15 8 88 18 27 76 63 78 47 91 22 +Card 82: 42 40 60 2 95 56 10 94 14 99 | 75 89 27 40 35 33 42 79 38 14 94 71 25 85 95 56 82 92 60 99 58 65 2 13 57 +Card 83: 60 31 59 4 63 39 23 73 56 24 | 31 23 56 19 59 4 64 42 85 1 34 60 72 35 24 55 16 37 78 52 7 39 2 73 63 +Card 84: 13 89 46 61 4 86 94 47 22 63 | 79 7 67 19 72 77 54 15 29 92 65 17 75 70 91 78 26 63 53 21 58 51 43 23 39 +Card 85: 38 1 35 22 60 19 24 82 99 43 | 21 82 99 56 60 64 44 24 1 83 23 27 40 35 55 47 43 87 85 12 22 39 4 25 63 +Card 86: 32 43 80 27 57 48 65 11 67 90 | 22 67 28 23 36 53 80 39 32 45 43 11 95 2 57 26 40 99 33 27 82 50 48 84 91 +Card 87: 44 76 92 13 51 25 35 15 81 61 | 76 44 16 1 41 35 6 84 67 13 5 30 51 34 8 7 55 15 73 90 60 21 50 25 81 +Card 88: 40 83 37 66 78 56 26 32 38 11 | 82 58 33 2 24 51 79 56 44 29 90 94 11 40 12 83 37 16 66 96 72 10 34 77 65 +Card 89: 75 60 87 69 50 48 91 72 66 64 | 47 30 61 11 17 88 62 71 3 9 67 93 46 13 21 86 23 18 37 4 89 92 51 54 52 +Card 90: 44 58 88 53 37 43 33 74 50 15 | 21 76 69 8 87 20 44 74 84 31 52 63 23 91 29 82 42 57 83 5 11 56 34 97 85 +Card 91: 61 41 52 39 83 93 33 67 11 6 | 49 13 76 15 98 53 62 19 16 14 1 24 66 27 58 79 23 54 77 63 46 25 57 33 50 +Card 92: 10 29 99 80 36 48 74 88 28 5 | 86 22 93 19 24 29 87 92 58 96 10 68 72 75 35 60 26 37 67 79 3 62 63 18 20 +Card 93: 28 31 69 88 94 39 36 99 1 90 | 5 38 46 96 53 26 37 66 65 16 31 79 8 92 11 68 93 27 73 33 51 17 86 1 70 +Card 94: 81 83 18 7 5 12 59 11 41 26 | 2 16 20 74 65 55 23 88 21 99 35 49 12 33 70 25 91 36 50 6 51 15 45 13 34 +Card 95: 14 43 76 25 18 95 15 22 66 83 | 4 45 57 46 33 61 52 17 98 53 37 89 23 27 67 12 86 81 68 9 44 87 24 1 75 +Card 96: 82 98 24 1 85 50 20 57 60 93 | 57 92 59 85 81 20 89 50 28 60 64 38 94 71 61 21 93 98 24 82 58 65 42 76 1 +Card 97: 20 59 25 39 48 12 85 17 44 65 | 56 49 89 58 83 95 25 2 93 26 42 14 37 77 10 11 40 90 86 59 3 61 87 62 16 +Card 98: 56 9 13 23 47 31 54 95 17 58 | 30 59 65 52 23 85 72 75 19 36 95 41 54 49 42 83 64 15 80 31 16 9 27 20 29 +Card 99: 38 82 89 49 24 20 65 87 42 31 | 50 64 92 85 1 14 29 61 18 96 53 10 99 17 15 97 88 74 69 12 72 40 66 54 86 +Card 100: 16 78 53 13 62 18 9 63 61 94 | 16 10 73 6 36 13 24 63 94 57 5 8 18 52 67 20 62 68 29 78 61 69 53 9 38 +Card 101: 20 53 48 71 35 65 26 31 89 44 | 42 10 97 20 1 91 29 96 76 21 78 27 46 3 18 25 68 48 90 41 37 65 28 88 17 +Card 102: 63 31 48 76 34 46 44 99 39 35 | 50 56 53 38 46 39 99 73 61 32 18 65 63 31 74 97 48 41 62 35 44 26 4 34 76 +Card 103: 31 61 96 44 3 32 51 10 74 95 | 60 15 29 39 19 20 68 28 83 40 42 52 50 41 10 36 7 71 11 18 27 16 75 93 99 +Card 104: 38 98 96 64 66 93 53 95 87 73 | 16 45 77 87 92 69 99 3 33 36 31 89 63 93 98 4 83 10 13 51 59 64 37 47 85 +Card 105: 24 86 51 27 23 99 25 97 82 72 | 20 27 7 60 71 94 26 33 52 41 6 48 36 22 46 51 44 64 63 3 50 86 47 12 53 +Card 106: 71 75 52 24 61 13 45 59 30 1 | 6 96 7 20 65 55 95 57 16 29 22 18 87 56 53 81 51 67 66 23 50 11 91 44 72 +Card 107: 47 31 1 45 94 76 35 77 41 96 | 9 47 12 59 89 83 14 5 38 52 39 55 50 90 97 75 87 68 37 26 22 46 27 10 15 +Card 108: 90 35 81 74 7 82 11 79 80 33 | 84 74 82 15 34 26 19 83 25 95 90 81 79 97 71 99 22 35 8 41 65 11 7 55 62 +Card 109: 80 18 68 10 31 61 64 98 84 7 | 81 54 26 20 52 94 68 88 19 15 87 40 12 91 10 61 1 56 45 85 66 25 82 57 92 +Card 110: 79 75 95 63 62 32 78 67 88 3 | 45 80 76 94 10 82 55 26 24 41 65 78 5 47 75 91 38 7 37 88 2 52 97 50 99 +Card 111: 69 4 78 87 15 59 22 90 86 40 | 98 4 27 21 9 71 40 5 67 69 94 38 87 92 91 47 54 17 65 43 30 1 51 72 70 +Card 112: 30 93 66 43 89 12 32 46 1 76 | 79 63 16 15 95 88 44 7 8 59 32 74 19 97 45 80 61 30 34 68 70 1 3 28 55 +Card 113: 36 8 6 21 92 96 67 98 59 34 | 73 44 85 41 11 47 50 53 40 27 90 75 20 79 32 69 3 74 99 78 66 93 56 14 82 +Card 114: 74 31 59 5 70 12 95 33 97 46 | 53 92 99 74 94 78 86 25 73 10 17 58 21 37 2 71 79 90 77 76 50 93 87 52 4 +Card 115: 38 75 68 26 66 52 13 17 76 33 | 73 60 35 27 91 15 39 41 63 36 4 19 61 5 6 3 70 55 24 11 23 71 67 29 51 +Card 116: 73 26 82 27 63 88 34 91 78 59 | 35 56 58 68 71 14 4 94 33 75 72 6 67 55 80 57 28 11 65 84 66 54 3 95 20 +Card 117: 66 2 31 29 64 73 92 10 33 83 | 43 42 55 20 61 51 57 58 94 37 14 15 84 69 41 28 11 10 67 34 65 91 78 18 1 +Card 118: 63 82 19 38 31 57 93 79 32 56 | 1 43 81 72 32 24 79 84 45 94 38 92 56 5 42 70 63 91 93 71 57 96 51 31 83 +Card 119: 34 48 60 44 4 64 3 35 66 30 | 47 3 60 76 67 97 31 1 35 55 84 65 81 52 45 30 50 7 34 71 14 74 89 11 66 +Card 120: 86 93 50 94 55 11 83 84 61 15 | 11 42 14 17 63 36 75 49 86 15 55 94 84 61 50 48 80 6 83 39 23 93 67 87 46 +Card 121: 92 85 58 71 34 94 60 49 14 17 | 34 74 61 77 89 50 99 49 94 60 68 83 71 27 17 56 46 63 76 26 20 70 41 85 39 +Card 122: 99 2 97 77 34 42 35 16 13 33 | 6 42 60 26 9 13 98 30 94 97 33 40 58 91 32 46 47 68 78 34 77 35 93 22 39 +Card 123: 34 16 84 71 29 13 53 57 79 43 | 24 37 74 85 35 7 51 44 97 29 9 70 67 45 61 15 65 77 86 20 90 66 73 11 58 +Card 124: 39 83 88 46 71 8 66 68 67 52 | 75 66 93 8 20 67 3 73 34 39 71 83 45 15 58 55 31 38 69 29 46 40 48 42 68 +Card 125: 73 16 48 77 94 75 79 40 39 22 | 98 37 36 63 10 84 52 53 94 82 46 17 73 2 88 42 16 33 64 62 95 22 77 43 55 +Card 126: 10 84 50 23 39 71 86 74 38 53 | 71 16 38 23 28 86 97 53 43 69 10 84 5 72 4 96 15 37 74 50 83 22 39 49 12 +Card 127: 92 69 94 70 14 35 44 58 3 96 | 18 89 21 14 2 17 76 50 29 72 87 56 39 25 33 37 68 60 55 66 53 80 62 26 38 +Card 128: 58 45 46 29 74 94 61 1 18 72 | 20 76 24 41 14 86 53 85 90 80 83 68 48 10 49 25 75 89 92 93 23 37 38 96 33 +Card 129: 9 19 94 34 58 89 13 1 47 37 | 53 21 17 73 50 79 24 25 2 92 47 75 8 30 98 12 85 80 62 65 86 84 40 49 67 +Card 130: 66 46 68 96 19 2 21 32 63 13 | 82 68 63 21 25 43 44 91 40 97 20 75 2 46 80 83 5 59 66 56 45 93 98 95 47 +Card 131: 13 20 75 52 6 26 90 36 3 82 | 58 98 40 5 12 82 56 64 16 9 17 74 77 76 85 31 53 28 67 4 18 97 47 57 43 +Card 132: 90 86 97 51 21 60 45 8 94 91 | 97 70 38 89 73 14 30 10 39 18 91 8 55 12 86 45 37 54 9 5 23 33 29 51 71 +Card 133: 18 22 20 1 76 64 59 26 73 15 | 75 54 45 77 30 51 32 6 78 11 70 40 22 26 59 79 2 50 94 24 85 29 31 25 73 +Card 134: 61 72 44 50 47 22 78 62 21 32 | 51 61 59 81 67 54 58 55 87 52 85 62 48 34 35 68 74 82 91 11 84 80 98 1 94 +Card 135: 81 98 77 10 91 59 49 66 55 79 | 8 30 40 46 53 50 41 18 66 76 83 72 34 1 49 11 87 9 94 51 79 7 63 90 37 +Card 136: 96 28 21 15 42 65 91 43 82 60 | 95 23 34 51 29 58 31 89 4 16 36 20 5 61 33 47 59 75 80 55 9 67 28 74 45 +Card 137: 53 27 50 59 83 75 48 25 90 89 | 93 87 31 17 35 1 13 24 91 16 90 52 94 99 60 42 4 10 19 32 7 69 80 38 71 +Card 138: 40 8 61 37 83 55 88 50 77 5 | 99 73 66 63 90 78 24 3 29 62 35 75 92 6 39 42 19 95 13 80 25 64 54 49 68 +Card 139: 24 87 36 5 58 46 84 4 80 19 | 31 10 49 87 53 17 67 37 44 80 19 43 46 86 32 4 15 24 58 64 85 66 5 81 82 +Card 140: 92 93 56 21 97 86 5 11 45 3 | 45 21 66 59 56 44 79 16 86 13 8 3 88 71 52 55 54 60 2 37 93 92 97 11 5 +Card 141: 98 73 9 7 74 71 43 63 5 89 | 83 73 44 12 86 97 74 71 43 78 14 98 8 53 16 51 7 20 88 89 93 37 46 58 63 +Card 142: 57 96 47 59 56 58 76 52 1 84 | 80 68 6 61 82 24 42 17 86 79 22 65 31 81 27 41 70 33 77 54 49 99 37 66 64 +Card 143: 34 98 19 48 99 54 66 28 26 33 | 99 89 39 44 81 98 71 67 91 47 48 45 54 7 24 55 51 94 33 34 26 66 19 95 28 +Card 144: 82 37 3 29 57 39 34 44 5 70 | 3 6 39 1 2 10 5 82 37 56 29 50 30 48 47 70 58 12 44 9 69 57 88 51 34 +Card 145: 73 65 86 88 99 81 26 70 11 62 | 86 3 14 88 66 11 90 30 67 80 8 79 23 44 2 1 45 13 32 72 31 26 55 64 70 +Card 146: 8 54 27 20 89 28 51 3 19 40 | 13 81 90 98 9 6 93 88 1 82 79 48 14 31 20 58 65 91 78 38 62 7 73 64 52 +Card 147: 70 63 99 58 80 73 38 95 69 90 | 67 82 72 73 70 92 91 63 80 20 4 69 95 64 38 58 50 10 90 99 78 68 49 1 26 +Card 148: 61 41 24 78 96 40 91 23 70 19 | 28 1 16 76 19 95 60 92 82 41 25 87 63 30 91 96 12 70 77 27 23 90 24 72 61 +Card 149: 43 89 27 28 50 39 6 83 69 45 | 12 43 34 39 73 40 66 95 36 96 74 6 72 81 24 25 78 92 42 22 87 86 59 89 97 +Card 150: 9 14 44 72 64 11 95 68 73 75 | 44 14 60 54 97 64 11 4 57 79 40 53 39 2 51 46 75 42 9 37 6 83 80 25 72 +Card 151: 91 12 67 98 83 16 14 62 69 36 | 35 66 73 90 28 36 43 37 69 24 95 85 27 48 39 44 16 62 53 72 15 1 63 19 5 +Card 152: 42 27 33 9 32 99 76 30 3 53 | 42 43 17 41 5 6 47 8 91 66 85 12 31 9 99 76 58 13 90 11 46 53 54 29 30 +Card 153: 51 60 22 62 57 11 16 85 9 3 | 17 52 62 87 97 73 25 34 65 88 72 16 94 3 32 27 96 86 42 91 80 41 95 79 11 +Card 154: 36 13 59 96 52 90 79 6 14 74 | 28 92 63 4 48 85 12 6 13 91 86 76 44 16 93 97 43 54 52 49 60 84 8 75 21 +Card 155: 91 27 43 97 4 68 6 79 5 72 | 22 77 90 15 50 4 52 70 88 85 24 27 12 80 82 81 74 36 45 92 39 78 54 71 5 +Card 156: 80 45 22 79 4 23 21 63 34 37 | 6 99 74 11 62 54 36 63 59 14 37 70 44 25 31 15 97 12 39 2 75 90 4 46 18 +Card 157: 43 37 94 45 96 99 15 33 54 38 | 18 70 62 12 5 7 17 33 24 8 79 15 51 44 87 57 99 4 25 34 74 65 63 13 76 +Card 158: 21 65 8 67 37 97 99 24 16 68 | 51 85 26 80 72 81 57 37 82 93 46 94 68 54 24 32 18 48 1 69 49 29 27 40 39 +Card 159: 3 2 61 25 92 69 30 10 57 78 | 88 46 33 3 52 89 55 4 24 82 9 98 62 66 54 23 28 13 50 68 39 1 15 63 74 +Card 160: 1 28 51 92 96 79 22 97 17 62 | 64 46 44 75 50 43 39 30 37 91 82 11 4 34 27 71 65 40 81 53 38 52 60 2 23 +Card 161: 26 12 82 16 52 15 97 42 2 20 | 68 22 49 59 32 53 10 72 4 92 25 56 84 65 69 75 88 9 37 86 1 78 89 41 99 +Card 162: 3 32 24 52 49 80 10 39 43 72 | 60 39 23 25 56 21 10 12 24 70 32 83 80 43 19 28 34 22 52 72 49 74 3 15 29 +Card 163: 77 57 96 84 68 59 24 92 60 5 | 66 33 57 73 44 92 60 34 39 62 96 80 2 77 91 5 24 51 31 64 68 59 36 84 88 +Card 164: 76 60 92 78 34 44 23 14 22 1 | 92 17 44 32 53 34 54 28 73 93 89 67 84 18 60 72 85 10 26 21 23 78 33 51 79 +Card 165: 66 99 39 27 18 79 96 7 50 44 | 7 96 41 98 78 57 44 8 61 50 79 68 99 38 40 10 66 31 14 18 27 89 70 39 69 +Card 166: 73 42 83 91 88 21 43 16 10 55 | 73 8 28 10 76 16 99 55 97 62 42 65 35 72 83 52 57 50 91 21 37 74 36 88 96 +Card 167: 64 38 97 19 73 72 67 79 94 21 | 21 38 54 73 66 49 29 25 75 19 85 6 64 34 97 13 30 28 79 67 36 72 94 68 82 +Card 168: 16 37 31 29 99 88 54 66 3 57 | 88 31 38 21 11 79 13 9 36 27 78 47 97 74 64 7 42 32 2 50 46 80 87 96 60 +Card 169: 6 18 54 82 21 27 34 62 91 12 | 52 26 12 56 39 21 5 91 89 6 18 34 43 62 40 67 76 83 27 31 92 82 54 45 55 +Card 170: 31 82 50 80 27 16 34 22 38 54 | 80 22 63 31 23 38 34 66 16 82 9 75 64 54 85 50 99 81 92 53 77 30 13 27 35 +Card 171: 44 50 51 70 77 73 55 41 80 60 | 63 60 69 80 25 48 36 56 96 1 88 14 75 30 7 50 40 95 87 51 41 59 11 65 70 +Card 172: 33 60 55 35 38 86 78 56 31 14 | 60 67 83 33 21 40 14 69 38 94 32 54 3 17 49 19 22 86 31 79 73 71 56 75 78 +Card 173: 75 30 84 6 15 21 76 28 66 83 | 98 94 57 58 26 74 90 69 64 66 51 30 28 38 82 21 86 15 75 78 97 9 19 72 56 +Card 174: 49 63 32 42 78 24 55 70 76 95 | 78 90 82 98 50 60 76 3 49 44 74 18 68 32 55 29 72 24 63 99 96 12 70 59 31 +Card 175: 15 69 87 40 61 58 81 77 21 12 | 27 31 77 43 47 85 80 44 21 1 33 3 84 7 54 51 69 40 70 71 12 49 61 22 15 +Card 176: 40 7 45 71 92 88 27 97 58 8 | 2 82 67 15 81 63 16 49 65 89 35 60 79 29 74 43 56 45 95 84 10 32 92 96 64 +Card 177: 8 70 28 81 60 12 64 98 84 72 | 32 58 80 65 90 79 95 31 56 43 82 45 94 21 92 55 89 96 53 54 19 51 6 52 33 +Card 178: 16 59 30 28 62 24 8 6 92 91 | 96 24 30 28 37 42 50 69 67 62 49 84 92 65 95 34 68 17 47 59 2 60 79 53 16 +Card 179: 68 58 26 30 90 16 9 6 44 92 | 97 4 95 64 12 18 52 96 29 67 84 69 91 23 56 24 10 20 98 87 80 79 65 22 48 +Card 180: 30 32 52 1 10 23 62 43 51 79 | 70 72 87 82 3 83 24 73 34 64 75 71 84 89 26 65 27 47 41 39 81 37 36 18 17 +Card 181: 80 2 77 4 29 98 52 21 86 90 | 46 61 34 66 6 57 8 59 32 16 80 89 86 83 26 27 53 29 55 31 92 84 18 56 14 +Card 182: 77 54 92 15 91 12 89 56 45 87 | 82 13 40 26 15 16 44 97 9 52 33 20 36 63 99 57 49 46 19 22 79 3 32 37 73 +Card 183: 41 43 38 48 97 95 69 98 81 80 | 22 93 36 50 23 37 34 9 27 8 35 49 82 71 65 98 39 56 10 5 69 86 16 88 21 +Card 184: 50 96 62 20 87 19 90 13 41 82 | 52 85 38 89 59 30 64 91 74 6 39 60 61 77 97 18 42 49 12 36 55 56 3 75 96 +Card 185: 43 62 42 28 85 36 21 39 59 16 | 63 1 35 52 15 98 65 68 27 61 40 95 74 80 11 83 94 89 47 90 25 72 32 31 23 +Card 186: 48 6 85 22 91 9 76 2 15 21 | 83 44 33 78 24 96 38 43 20 16 59 67 99 86 36 58 80 31 11 14 28 98 5 57 42 +Card 187: 18 71 35 72 10 45 11 4 44 56 | 16 72 23 30 56 73 45 63 99 10 57 88 65 4 12 8 94 71 11 18 44 35 80 74 78 +Card 188: 89 11 73 22 99 41 28 61 66 52 | 98 85 99 64 97 28 71 66 26 58 53 3 92 95 22 67 83 13 51 11 57 79 25 19 89 +Card 189: 61 49 23 38 82 95 62 2 15 67 | 14 2 68 82 61 11 86 65 70 40 38 95 67 80 23 62 27 36 90 55 25 57 35 49 15 +Card 190: 74 47 34 96 42 10 58 71 82 80 | 32 42 68 58 74 6 93 82 50 91 80 33 71 55 47 30 70 43 62 98 75 11 4 96 10 +Card 191: 48 39 13 22 77 86 8 34 71 6 | 44 20 73 16 31 67 66 1 21 2 80 54 49 42 45 35 30 87 83 57 60 4 50 76 26 +Card 192: 70 77 39 63 81 88 7 78 85 44 | 97 81 85 12 96 71 63 84 88 45 9 77 27 78 51 52 82 44 7 10 80 60 70 39 49 +Card 193: 11 62 85 7 5 47 58 68 88 65 | 98 55 47 5 7 85 22 62 82 46 38 59 68 30 26 84 45 40 58 31 81 11 65 93 88 +Card 194: 60 49 75 21 54 34 40 6 39 67 | 84 60 14 34 65 49 7 39 32 54 74 25 40 75 21 72 6 35 5 41 78 20 26 77 67 +Card 195: 55 11 12 81 4 7 97 61 15 58 | 69 29 95 11 12 77 4 30 55 15 44 39 2 89 38 71 51 25 40 6 21 81 58 7 98 +Card 196: 90 78 2 3 77 24 33 45 32 30 | 16 11 39 27 85 34 79 59 6 33 46 21 48 36 58 99 40 74 63 82 96 42 7 95 90 +Card 197: 21 13 3 45 1 33 54 70 23 22 | 23 73 21 34 76 78 4 1 46 11 60 64 42 26 81 13 90 51 2 79 74 45 3 72 84 +Card 198: 44 17 16 71 52 50 11 69 14 86 | 90 70 65 7 91 17 63 81 24 39 69 42 87 57 36 35 74 31 22 80 50 88 13 41 78 +Card 199: 60 13 93 42 74 66 3 89 40 8 | 43 37 38 54 99 36 44 62 1 91 60 52 76 21 20 86 17 97 98 7 79 57 28 48 35 +Card 200: 40 39 37 63 65 8 25 47 85 12 | 62 35 28 68 63 27 98 40 43 17 78 87 41 86 13 61 5 23 4 20 93 31 66 18 49 +Card 201: 41 57 5 59 95 15 18 44 75 28 | 1 33 29 38 76 73 36 17 19 4 52 84 68 32 35 27 92 58 81 78 2 61 97 85 22 +Card 202: 60 80 88 13 96 57 1 58 39 52 | 52 34 58 2 59 50 79 92 63 98 96 36 62 77 37 56 78 4 54 51 9 76 85 21 57 +Card 203: 39 28 57 98 3 73 22 8 23 68 | 44 9 43 17 50 14 97 1 41 76 61 90 20 62 78 5 89 85 64 55 16 72 19 4 37 +Card 204: 99 82 81 86 88 31 92 8 93 94 | 28 74 53 55 76 77 57 94 97 45 41 17 38 36 98 86 39 24 10 42 27 65 73 34 96 +Card 205: 55 7 8 82 24 95 85 99 22 59 | 58 64 84 42 26 59 20 37 49 57 62 15 18 1 32 2 86 69 96 63 47 77 60 19 93 +Card 206: 73 34 51 18 57 42 91 27 84 95 | 6 88 80 82 98 89 36 10 33 78 37 21 45 96 5 93 15 63 62 92 49 94 1 64 85 +Card 207: 83 32 10 94 28 8 61 98 53 48 | 31 78 60 79 87 37 97 34 11 71 66 1 29 74 24 41 22 42 46 85 80 47 17 54 14 +Card 208: 11 17 75 84 85 40 89 23 54 80 | 31 54 85 61 39 79 27 56 62 64 11 80 3 72 14 73 19 48 99 89 15 42 23 9 97 +Card 209: 30 75 20 84 70 26 72 23 9 97 | 5 76 67 41 18 84 36 54 70 65 75 25 82 23 50 9 7 46 33 85 38 11 97 95 40 +Card 210: 76 25 97 64 92 68 60 43 63 53 | 31 1 91 45 39 62 89 50 77 37 38 25 8 28 71 97 49 99 55 9 27 52 64 76 73 +Card 211: 62 52 55 90 57 38 95 65 39 92 | 67 46 95 3 38 18 26 5 75 55 92 41 85 28 84 42 37 73 64 69 33 14 34 94 35 +Card 212: 91 93 76 59 88 48 97 44 96 78 | 22 20 48 74 61 91 69 25 59 44 6 93 42 36 96 76 60 88 37 32 78 97 16 47 89 +Card 213: 79 33 53 91 63 62 42 3 72 25 | 59 69 60 7 82 68 73 97 23 48 39 38 76 71 9 29 37 53 67 92 85 55 15 13 61 +Card 214: 51 20 73 22 11 83 14 71 26 74 | 85 48 41 50 93 70 21 76 2 16 22 95 6 25 20 19 72 58 11 45 83 54 26 73 51 +Card 215: 47 72 51 32 7 13 99 36 17 48 | 22 47 6 36 8 91 35 11 3 42 30 21 38 43 28 64 99 72 75 18 84 13 52 82 55 +Card 216: 34 39 74 27 3 44 62 85 42 87 | 51 59 19 80 33 89 1 79 84 82 85 60 61 56 6 50 77 92 55 21 34 83 38 98 26 +Card 217: 11 33 54 13 67 99 61 86 57 7 | 95 32 57 34 98 33 7 54 71 26 42 73 52 56 13 79 67 78 75 58 9 81 24 41 96 +Card 218: 50 9 20 47 18 95 63 31 75 30 | 73 5 26 92 74 57 77 20 96 32 8 9 88 71 75 28 17 29 81 27 90 49 25 67 87 +Card 219: 5 55 89 78 12 19 47 64 87 81 | 16 66 55 2 13 10 93 88 39 47 22 54 65 59 8 75 99 19 61 43 68 86 67 49 70 +Card 220: 84 11 98 89 83 95 48 71 45 88 | 14 7 33 52 19 30 66 81 37 57 21 8 47 17 72 95 63 59 29 18 27 26 76 91 73 +Card 221: 78 17 79 4 63 65 56 57 22 92 | 48 94 32 37 26 58 64 87 24 95 19 41 12 25 74 93 30 1 66 27 3 43 50 35 11 +Card 222: 74 14 52 95 73 11 55 26 90 78 | 17 21 93 28 90 61 63 50 19 57 91 66 86 79 62 41 3 23 75 15 56 18 92 83 49 +Card 223: 98 82 47 14 2 48 1 50 18 62 | 67 78 16 58 35 87 93 44 77 13 74 34 32 92 88 54 36 61 91 72 9 59 89 73 5 diff --git a/gleam.toml b/gleam.toml deleted file mode 100644 index 79d3ab7..0000000 --- a/gleam.toml +++ /dev/null @@ -1,24 +0,0 @@ -name = "advent_of_code" -version = "1.0.0" - -# Fill out these fields if you intend to generate HTML documentation or publish -# your project to the Hex package manager. -# -# description = "" -# licences = ["Apache-2.0"] -# repository = { type = "github", user = "", repo = "" } -# links = [{ title = "Website", href = "" }] -# -# For a full reference of all the available options, you can have a look at -# https://gleam.run/writing-gleam/gleam-toml/. - -[dependencies] -gleam_stdlib = ">= 0.34.0 and < 2.0.0" -simplifile = ">= 2.2.0 and < 3.0.0" -gleam_regexp = ">= 1.0.0 and < 2.0.0" -gleam_yielder = ">= 1.1.0 and < 2.0.0" -gleam_otp = ">= 0.14.1 and < 1.0.0" -argv = ">= 1.0.2 and < 2.0.0" - -[dev-dependencies] -gleeunit = ">= 1.0.0 and < 2.0.0" diff --git a/manifest.toml b/manifest.toml deleted file mode 100644 index 3e9655e..0000000 --- a/manifest.toml +++ /dev/null @@ -1,23 +0,0 @@ -# This file was generated by Gleam -# You typically do not need to edit this file - -packages = [ - { name = "argv", version = "1.0.2", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "BA1FF0929525DEBA1CE67256E5ADF77A7CDDFE729E3E3F57A5BDCAA031DED09D" }, - { name = "filepath", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "filepath", source = "hex", outer_checksum = "67A6D15FB39EEB69DD31F8C145BB5A421790581BD6AA14B33D64D5A55DBD6587" }, - { name = "gleam_erlang", version = "0.33.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "A1D26B80F01901B59AABEE3475DD4C18D27D58FA5C897D922FCB9B099749C064" }, - { name = "gleam_otp", version = "0.14.1", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "5A8CE8DBD01C29403390A7BD5C0A63D26F865C83173CF9708E6E827E53159C65" }, - { name = "gleam_regexp", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_regexp", source = "hex", outer_checksum = "A3655FDD288571E90EE9C4009B719FEF59FA16AFCDF3952A76A125AF23CF1592" }, - { name = "gleam_stdlib", version = "0.45.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "206FCE1A76974AECFC55AEBCD0217D59EDE4E408C016E2CFCCC8FF51278F186E" }, - { name = "gleam_yielder", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_yielder", source = "hex", outer_checksum = "8E4E4ECFA7982859F430C57F549200C7749823C106759F4A19A78AEA6687717A" }, - { name = "gleeunit", version = "1.2.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "F7A7228925D3EE7D0813C922E062BFD6D7E9310F0BEE585D3A42F3307E3CFD13" }, - { name = "simplifile", version = "2.2.0", build_tools = ["gleam"], requirements = ["filepath", "gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "0DFABEF7DC7A9E2FF4BB27B108034E60C81BEBFCB7AB816B9E7E18ED4503ACD8" }, -] - -[requirements] -argv = { version = ">= 1.0.2 and < 2.0.0" } -gleam_otp = { version = ">= 0.14.1 and < 1.0.0" } -gleam_regexp = { version = ">= 1.0.0 and < 2.0.0" } -gleam_stdlib = { version = ">= 0.34.0 and < 2.0.0" } -gleam_yielder = { version = ">= 1.1.0 and < 2.0.0" } -gleeunit = { version = ">= 1.0.0 and < 2.0.0" } -simplifile = { version = ">= 2.2.0 and < 3.0.0" } diff --git a/src/advent_of_code.gleam b/src/advent_of_code.gleam deleted file mode 100644 index 6e07c20..0000000 --- a/src/advent_of_code.gleam +++ /dev/null @@ -1,162 +0,0 @@ -import argv -import bridge_repair as day07 -import ceres_search as day04 -import disk_fragmenter as day09 -import gleam/int -import gleam/io -import gleam/result -import guard_gallivant as day06 -import historian_hysteria as day01 -import hoof_it as day10 -import mull_it_over as day03 -import print_queue as day05 -import red_nosed_reports as day02 -import resonant_collinearity as day08 -import simplifile.{read} - -pub fn main() { - case argv.load().arguments { - ["1"] -> { - result.unwrap( - result.map(read("data/day1.txt"), fn(data) { - io.println( - "[1] Historian Hysteria (Part 1): " - <> int.to_string(day01.solve_a(data)), - ) - io.println( - "[1] Historian Hysteria (Part 2): " - <> int.to_string(day01.solve_b(data)), - ) - }), - Nil, - ) - } - ["2"] -> { - result.unwrap( - result.map(read("data/day2.txt"), fn(data) { - io.println( - "[2] Red Nosed Reports (Part 1): " - <> int.to_string(day02.solve_a(data)), - ) - io.println( - "[2] Red Nosed Reports (Part 2): " - <> int.to_string(day02.solve_b(data)), - ) - }), - Nil, - ) - } - ["3"] -> { - result.unwrap( - result.map(read("data/day3.txt"), fn(data) { - io.println( - "[3] Mull It Over (Part 1): " <> int.to_string(day03.solve_a(data)), - ) - io.println( - "[3] Mull It Over (Part 2): " <> int.to_string(day03.solve_b(data)), - ) - }), - Nil, - ) - } - ["4"] -> { - result.unwrap( - result.map(read("data/day4.txt"), fn(data) { - io.println( - "[4] Ceres Search (Part 1): " <> int.to_string(day04.solve_a(data)), - ) - io.println( - "[4] Ceres Search (Part 2): " <> int.to_string(day04.solve_b(data)), - ) - }), - Nil, - ) - } - ["5"] -> { - result.unwrap( - result.map(read("data/day5.txt"), fn(data) { - io.println( - "[5] Print Queue (Part 1): " <> int.to_string(day05.solve_a(data)), - ) - io.println( - "[5] Print Queue (Part 2): " <> int.to_string(day05.solve_b(data)), - ) - }), - Nil, - ) - } - ["6"] -> { - result.unwrap( - result.map(read("data/day6.txt"), fn(data) { - io.println( - "[6] Guard Gallivant (Part 1): " - <> int.to_string(day06.solve_a(data)), - ) - io.println( - "[6] Guard Gallivant (Part 2): " - <> int.to_string(day06.solve_b(data)), - ) - }), - Nil, - ) - } - ["7"] -> { - result.unwrap( - result.map(read("data/day7.txt"), fn(data) { - io.println( - "[7] Bridge Repair (Part 1): " <> int.to_string(day07.solve_a(data)), - ) - io.println( - "[7] Bridge Repair (Part 2): " <> int.to_string(day07.solve_b(data)), - ) - }), - Nil, - ) - } - - ["8"] -> { - result.unwrap( - result.map(read("data/day8.txt"), fn(data) { - io.println( - "[8] Resonant Collinearity (Part 1): " - <> int.to_string(day08.solve_a(data)), - ) - io.println( - "[8] Resonant Collinearity (Part 2): " - <> int.to_string(day08.solve_b(data)), - ) - }), - Nil, - ) - } - ["9"] -> { - result.unwrap( - result.map(read("data/day9.txt"), fn(data) { - io.println( - "[9] Disk Fragmenter (Part 1): " - <> int.to_string(day09.solve_a(data)), - ) - io.println( - "[9] Disk Fragmenter (Part 2): " - <> int.to_string(day09.solve_b(data)), - ) - }), - Nil, - ) - } - ["10"] -> { - result.unwrap( - result.map(read("data/day10.txt"), fn(data) { - io.println( - "[10] Hoof It (Part 1): " <> int.to_string(day10.solve_a(data)), - ) - io.println( - "[10] Hoof It (Part 2): " <> int.to_string(day10.solve_b(data)), - ) - }), - Nil, - ) - } - _ -> io.println_error("invalid arguments!") - } -} diff --git a/src/bridge_repair.gleam b/src/bridge_repair.gleam deleted file mode 100644 index 2a2ff44..0000000 --- a/src/bridge_repair.gleam +++ /dev/null @@ -1,95 +0,0 @@ -import gleam/int -import gleam/list -import gleam/otp/task -import gleam/result -import gleam/string -import utils/list as li - -type Equation { - Equation(target: Int, values: List(String)) -} - -fn parse_eq(line: String) -> Equation { - let assert Ok(#(tar_str, vals_str)) = string.split_once(line, ": ") - let assert Ok(tar_int) = int.parse(tar_str) - let values = string.split(vals_str, " ") - - Equation(target: tar_int, values: values) -} - -fn parse_file(input: String) -> List(Equation) { - input - |> string.trim - |> string.split("\n") - |> list.map(parse_eq) -} - -fn parse_num(x: String) -> Int { - result.unwrap(int.parse(x), 0) -} - -fn mult(lhs: String, rhs: String) -> String { - int.to_string(int.multiply(parse_num(lhs), parse_num(rhs))) -} - -fn add(lhs: String, rhs: String) -> String { - int.to_string(int.add(parse_num(lhs), parse_num(rhs))) -} - -fn solve_part(eq: List(String)) -> List(String) { - case eq { - [lhs, opr, rhs] -> - case opr { - "*" -> list.wrap(mult(lhs, rhs)) - "+" -> list.wrap(add(lhs, rhs)) - "|" -> list.wrap(lhs <> rhs) - _ -> [] - } - _ -> [] - } -} - -fn solve_eq_lr(eq: List(String)) -> List(String) { - case list.length(eq) { - 1 | 0 -> eq - _ -> { - case list.split(eq, 3) { - #(head, tail) -> solve_eq_lr(list.append(solve_part(head), tail)) - } - } - } -} - -fn is_satisfiable(eq: Equation, operators: List(String)) -> Bool { - li.repeated_permutation(operators, list.length(eq.values) - 1) - |> list.map(fn(combo) { list.interleave([eq.values, combo]) }) - |> list.flat_map(solve_eq_lr) - |> list.any(fn(soln) { eq.target == parse_num(soln) }) -} - -fn extract(x: #(Equation, Bool)) { - case x { - #(eq, True) -> Ok(eq.target) - _ -> Error(Nil) - } -} - -fn is_satisfiable_async(eq: Equation, operators: List(String)) { - task.async(fn() { #(eq, is_satisfiable(eq, operators)) }) -} - -pub fn solve_a(input: String) -> Int { - parse_file(input) - |> list.map(is_satisfiable_async(_, ["*", "+"])) - |> list.map(task.await_forever) - |> list.filter_map(extract) - |> list.fold(0, int.add) -} - -pub fn solve_b(input: String) -> Int { - parse_file(input) - |> list.map(is_satisfiable_async(_, ["*", "+", "|"])) - |> list.map(task.await_forever) - |> list.filter_map(extract) - |> list.fold(0, int.add) -} diff --git a/src/ceres_search.gleam b/src/ceres_search.gleam deleted file mode 100644 index 7891bdf..0000000 --- a/src/ceres_search.gleam +++ /dev/null @@ -1,83 +0,0 @@ -import gleam/dict.{type Dict} -import gleam/int -import gleam/list -import gleam/pair -import gleam/result -import gleam/string - -type Point = - #(Int, Int) - -type Grid = - Dict(Point, String) - -fn process_grid(input: String, f: fn(Grid) -> Int) -> Int { - input - |> string.trim() - |> string.split("\n") - |> list.map(string.to_graphemes) - |> list.index_map(fn(line, y) { - use grid, char, x <- list.index_fold(line, dict.new()) - dict.insert(grid, #(x, y), char) - }) - |> list.reduce(dict.merge) - |> result.unwrap(dict.new()) - |> f -} - -fn word(points: List(Point), grid: Grid) -> String { - use word, point <- list.fold(points, "") - string.append(word, result.unwrap(dict.get(grid, point), "")) -} - -fn all_neighbors(point: Point, word: String) -> List(List(Point)) { - let id = fn(x, _d) { x } - use f <- list.map([ - #(int.add, id), - #(int.subtract, id), - #(id, int.subtract), - #(id, int.add), - #(int.subtract, int.subtract), - #(int.add, int.subtract), - #(int.subtract, int.add), - #(int.add, int.add), - ]) - use d <- list.map(list.range(0, string.length(word) - 1)) - let #(x, y) = point - #(pair.first(f)(x, d), pair.second(f)(y, d)) -} - -fn x_neighbors(point: #(Int, Int)) { - let #(x, y) = point - [ - [#(x - 1, y - 1), point, #(x + 1, y + 1)], - [#(x + 1, y - 1), point, #(x - 1, y + 1)], - ] -} - -fn xmas_count_at_point(grid: Grid, point: Point) -> Int { - all_neighbors(point, "XMAS") - |> list.map(word(_, grid)) - |> list.count(fn(w) { w == "XMAS" }) -} - -fn point_has_x_mas(grid: Grid, point: Point) -> Bool { - x_neighbors(point) - |> list.map(word(_, grid)) - |> list.all(fn(w) { w == "MAS" || w == "SAM" }) -} - -pub fn solve_a(input: String) -> Int { - use grid <- process_grid(input) - - dict.keys(grid) - |> list.map(xmas_count_at_point(grid, _)) - |> list.fold(0, int.add) -} - -pub fn solve_b(input: String) -> Int { - use grid <- process_grid(input) - - dict.keys(grid) - |> list.count(point_has_x_mas(grid, _)) -} diff --git a/src/disk_fragmenter.gleam b/src/disk_fragmenter.gleam deleted file mode 100644 index 4134d12..0000000 --- a/src/disk_fragmenter.gleam +++ /dev/null @@ -1,105 +0,0 @@ -import gleam/int -import gleam/list -import gleam/result -import gleam/string -import utils/list as li - -type Block { - File(Int) - None -} - -type Disk = - List(Block) - -fn generate_file_block(block_count, file_index) -> Disk { - case block_count { - "0" -> [] - _ -> - list.range(1, result.unwrap(int.parse(block_count), 0)) - |> list.map(fn(_) { File(file_index / 2) }) - } -} - -fn generate_space_block(block_count) -> Disk { - case block_count { - "0" -> [] - _ -> - list.range(1, result.unwrap(int.parse(block_count), 0)) - |> list.map(fn(_) { None }) - } -} - -fn generate_block(block_count, file_index) -> Disk { - case int.is_even(file_index) { - True -> generate_file_block(block_count, file_index) - False -> generate_space_block(block_count) - } -} - -fn disk_map(input: String) -> Disk { - string.to_graphemes(input) - |> list.index_map(generate_block) - |> list.flatten -} - -fn defrag_complete(disk: List(Block), current_index: Int) -> Bool { - let #(_, after) = list.split(disk, current_index + 1) - - result.is_error(list.find(after, fn(x) { x != None })) -} - -fn rotate_block(disk: Disk, state: Disk) -> Disk { - case li.pop(disk) { - #(Ok(None), rest) -> rotate_block(rest, list.append(state, [None])) - #(Ok(anyval), rest) -> list.append([anyval], list.append(rest, state)) - #(Error(_), _) -> disk - } -} - -fn disk_defrag(disk: Disk, current_index: Int) -> Disk { - case defrag_complete(disk, current_index) { - True -> disk - False -> - case li.at(disk, current_index) { - Ok(None) -> { - let #(defragged, undefragged) = list.split(disk, current_index) - let assert #([None], remaining_undefragged) = - list.split(undefragged, 1) - let new_current_disk_map = - list.append( - defragged, - list.append(rotate_block(remaining_undefragged, []), [None]), - ) - - disk_defrag(new_current_disk_map, current_index + 1) - } - Ok(_) -> disk_defrag(disk, current_index + 1) - Error(_) -> disk - } - } -} - -fn get_blkid(blk: Block) -> Result(Int, Nil) { - case blk { - File(id) -> Ok(id) - None -> Error(Nil) - } -} - -fn checksum(input: Disk) -> Int { - input - |> list.filter_map(fn(x) { get_blkid(x) }) - |> list.index_map(int.multiply) - |> list.fold(0, int.add) -} - -pub fn solve_a(input: String) -> Int { - disk_map(input) - |> disk_defrag(0) - |> checksum -} - -pub fn solve_b(_input: String) -> Int { - 0 -} diff --git a/src/guard_gallivant.gleam b/src/guard_gallivant.gleam deleted file mode 100644 index 4f9bbab..0000000 --- a/src/guard_gallivant.gleam +++ /dev/null @@ -1,217 +0,0 @@ -import gleam/dict.{type Dict} -import gleam/list -import gleam/option.{type Option, Some} -import gleam/otp/task -import gleam/pair.{first as pf, second as ps} -import gleam/result -import gleam/string -import utils/list as li - -type Entity { - Guard - Obstacle - Path - Unknown(String) -} - -type Point = - #(Int, Int) - -type Grid = - Dict(Point, Entity) - -type Direction { - Up - Down - Left - Right -} - -type History = - #(Point, Direction) - -type IterState { - IterState( - point: Point, - direction: Direction, - grid: Grid, - histories: List(History), - max_bound: Int, - looping: Bool, - ) -} - -fn parse_column(line, y) { - use grid, char, x <- list.index_fold(line, dict.new()) - dict.insert(grid, #(x, y), case char { - "." -> Path - "#" -> Obstacle - "^" -> Guard - uchr -> Unknown(uchr) - }) -} - -fn parse_grid(input: String) -> Grid { - input - |> string.trim() - |> string.split("\n") - |> list.map(string.to_graphemes) - |> list.index_map(parse_column) - |> list.reduce(dict.merge) - |> result.unwrap(dict.new()) -} - -fn is_guard_position(pos: Point, g: Grid) -> Bool { - case dict.get(g, pos) { - Ok(Guard) -> True - _ -> False - } -} - -fn init_state(g: Grid) -> IterState { - let assert Ok(gp) = list.find(dict.keys(g), is_guard_position(_, g)) - IterState( - point: gp, - direction: Up, - grid: g, - histories: [#(gp, Up)], - max_bound: li.max(list.map(dict.keys(g), pf)), - looping: False, - ) -} - -fn incr_pos(pos: Point, dir: Direction) -> Point { - case dir { - Up -> #(pf(pos), ps(pos) - 1) - Down -> #(pf(pos), ps(pos) + 1) - Left -> #(pf(pos) - 1, ps(pos)) - Right -> #(pf(pos) + 1, ps(pos)) - } -} - -fn is_obstacle(position: Point, grid: Grid) -> Bool { - case dict.get(grid, position) { - Ok(Obstacle) -> True - _ -> False - } -} - -fn rotate_cw(d: Direction) -> Direction { - case d { - Up -> Right - Down -> Left - Right -> Down - Left -> Up - } -} - -fn next_coordinates(pos: Point, dir: Direction, g: Grid) -> #(Point, Direction) { - let np = incr_pos(pos, dir) - case is_obstacle(np, g) { - True -> next_coordinates(pos, rotate_cw(dir), g) - False -> #(np, dir) - } -} - -fn guard_exited(pos: Point, b: Int) -> Bool { - let #(x, y) = pos - x > b || x < 0 || y < 0 || y > b -} - -fn emulate(is: IterState) -> IterState { - let #(ngp, ngd) = next_coordinates(is.point, is.direction, is.grid) - case guard_exited(ngp, is.max_bound) { - True -> is - False -> - emulate(IterState( - point: ngp, - direction: ngd, - grid: is.grid, - histories: list.append(is.histories, [#(ngp, ngd)]), - max_bound: is.max_bound, - looping: False, - )) - } -} - -fn visited_count(is: IterState) -> Int { - is.histories - |> list.map(pf) - |> list.unique - |> list.length -} - -fn visited_paths(is: IterState) -> #(Grid, List(Point)) { - #(is.grid, list.unique(list.map(is.histories, pf))) -} - -fn iterate(is: IterState) -> IterState { - let #(ngp, ngd) = next_coordinates(is.point, is.direction, is.grid) - let ngh = list.append(is.histories, [#(ngp, ngd)]) - - case guard_exited(ngp, is.max_bound) { - True -> is - False -> - case li.contains(is.histories, #(ngp, ngd)) { - True -> - IterState( - point: ngp, - direction: ngd, - grid: is.grid, - histories: ngh, - max_bound: is.max_bound, - looping: True, - ) - False -> - iterate(IterState( - point: ngp, - direction: ngd, - grid: is.grid, - histories: ngh, - max_bound: is.max_bound, - looping: False, - )) - } - } -} - -fn add_obst(g: Grid, pt: Point) -> Grid { - dict.upsert(g, pt, fn(ent: Option(Entity)) { - case ent { - Some(Guard) -> Guard - _ -> Obstacle - } - }) -} - -fn is_infinite_loop_obstacle(g: Grid, point: Point) { - task.async(fn() { - add_obst(g, point) - |> init_state - |> iterate - |> fn(x) { x.looping } - }) -} - -fn count_infinite_loop_obstacles(info) -> Int { - let #(g, original_path) = info - - original_path - |> list.map(is_infinite_loop_obstacle(g, _)) - |> list.count(task.await_forever) -} - -pub fn solve_a(input: String) -> Int { - parse_grid(input) - |> init_state - |> emulate - |> visited_count -} - -pub fn solve_b(input: String) -> Int { - parse_grid(input) - |> init_state - |> emulate - |> visited_paths - |> count_infinite_loop_obstacles -} diff --git a/src/historian_hysteria.gleam b/src/historian_hysteria.gleam deleted file mode 100644 index c2ae741..0000000 --- a/src/historian_hysteria.gleam +++ /dev/null @@ -1,43 +0,0 @@ -import gleam/int -import gleam/list -import gleam/pair -import gleam/result -import gleam/string - -fn parse_line(line: String) -> List(Int) { - use a <- list.map(string.split(line, " ")) - result.unwrap(int.parse(a), 0) -} - -fn dist(scans: #(Int, Int)) { - int.absolute_value(pair.second(scans) - pair.first(scans)) -} - -fn freq_score_gen(ys: List(Int)) { - fn(x) { x * list.count(ys, fn(y) { y == x }) } -} - -pub fn solve_a(input) -> Int { - input - |> string.trim() - |> string.split("\n") - |> list.map(parse_line) - |> list.transpose() - |> list.map(list.sort(_, int.compare)) - |> list.reduce(fn(x, y) { list.map(list.zip(x, y), dist) }) - |> result.map(list.reduce(_, int.add)) - |> result.flatten() - |> result.unwrap(0) -} - -pub fn solve_b(input) -> Int { - input - |> string.trim() - |> string.split("\n") - |> list.map(parse_line) - |> list.transpose() - |> list.reduce(fn(x, y) { list.map(x, freq_score_gen(y)) }) - |> result.map(list.reduce(_, int.add)) - |> result.flatten() - |> result.unwrap(0) -} diff --git a/src/hoof_it.gleam b/src/hoof_it.gleam deleted file mode 100644 index e566585..0000000 --- a/src/hoof_it.gleam +++ /dev/null @@ -1,7 +0,0 @@ -pub fn solve_a(_: String) -> Int { - 0 -} - -pub fn solve_b(_: String) -> Int { - 0 -} diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..2d13a65 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,49 @@ +mod solutions; + +use anyhow::{anyhow, Result}; +use solutions::cube_conundrum as day02; +use solutions::scratchcards as day04; +use solutions::trebuchet as day01; +use std::env::args; +use std::fs::File; +use std::io::Read; + +fn read_file(path: &str) -> Result { + let mut file = File::open(path)?; + let mut contents = String::new(); + file.read_to_string(&mut contents)?; + + Ok(contents) +} + +fn main() -> Result<()> { + let day = args() + .nth(1) + .expect("[ERR] Solution Day Not Specified!") + .parse::()?; + + match day { + 1 => { + let input: String = read_file("data/day01.txt")?; + println!("Part A => {}", day01::solve_part1(&input)); + println!("Part B => {}", day01::solve_part2(&input)); + + Ok(()) + } + 2 => { + let input: String = read_file("data/day02.txt")?; + println!("Part A => {}", day02::solve_part1(&input)); + println!("Part B => {}", day02::solve_part2(&input)); + + Ok(()) + } + 4 => { + let input: String = read_file("data/day04.txt")?; + println!("Part A => {}", day04::solve_part1(&input)); + println!("Part B => {}", day04::solve_part2(&input)); + + Ok(()) + } + _ => Err(anyhow!("No Solution Found!")), + } +} diff --git a/src/mull_it_over.gleam b/src/mull_it_over.gleam deleted file mode 100644 index b0986db..0000000 --- a/src/mull_it_over.gleam +++ /dev/null @@ -1,45 +0,0 @@ -import gleam/int -import gleam/list -import gleam/pair -import gleam/regexp -import gleam/result - -pub fn process_isr(instr: String) -> Int { - let assert Ok(args_rex) = regexp.from_string("\\d{1,3}") - regexp.scan(args_rex, instr) - |> list.map(fn(x) { x.content }) - |> list.map(fn(x) { result.unwrap(int.parse(x), -1) }) - |> list.fold_right(1, int.multiply) -} - -pub fn process_cond_isr(state: #(Bool, Int), instr: String) -> #(Bool, Int) { - case instr { - "do()" -> #(True, pair.second(state)) - "don't()" -> #(False, pair.second(state)) - _ -> - case pair.first(state) { - True -> #(True, int.add(process_isr(instr), pair.second(state))) - False -> state - } - } -} - -pub fn solve_a(input: String) -> Int { - let assert Ok(rex) = regexp.from_string("(mul\\([0-9]{1,3},[0-9]{1,3}\\))") - - regexp.scan(rex, input) - |> list.map(fn(match) { match.content }) - |> list.map(process_isr) - |> list.reduce(int.add) - |> result.unwrap(0) -} - -pub fn solve_b(input: String) -> Int { - let assert Ok(rex) = - regexp.from_string("(mul\\([0-9]{1,3},[0-9]{1,3}\\)|do\\(\\))|don't\\(\\)") - - regexp.scan(rex, input) - |> list.map(fn(match) { match.content }) - |> list.fold(#(True, 0), process_cond_isr) - |> pair.second -} diff --git a/src/print_queue.gleam b/src/print_queue.gleam deleted file mode 100644 index 4f4b908..0000000 --- a/src/print_queue.gleam +++ /dev/null @@ -1,98 +0,0 @@ -import gleam/bool -import gleam/int -import gleam/list -import gleam/pair.{first as pf, second as ps} -import gleam/result -import gleam/string -import gleam/yielder -import utils/list as li - -type Rule = - #(Int, Int) - -type Order = - List(Int) - -fn parse_rule(input: String) -> Rule { - let assert Ok(#(first, second)) = string.split_once(input, "|") - let assert Ok(fnum) = int.parse(first) - let assert Ok(snum) = int.parse(second) - - #(fnum, snum) -} - -fn parse_order(input: String) -> List(Int) { - use numres <- list.map(string.split(input, ",")) - - result.unwrap(int.parse(numres), 0) -} - -fn parse_file(input: String) -> #(List(Rule), List(Order)) { - let assert Ok(#(rules, orders)) = - string.split_once(string.trim(input), "\n\n") - - let parsed_rules = list.map(string.split(rules, "\n"), parse_rule) - let parsed_orders = list.map(string.split(orders, "\n"), parse_order) - #(parsed_rules, parsed_orders) -} - -fn rule_applicable(order: Order, rule: Rule) -> Bool { - list.all(li.from_pair(rule), li.contains(order, _)) -} - -fn rule_satisfied(order: Order, rule: Rule) -> Bool { - let #(rf, rs) = rule - let assert [x, y] = list.filter(order, fn(x) { x == rf || x == rs }) - - x == rf && y == rs -} - -fn order_follows_rules(order: Order, rules: List(Rule)) -> Bool { - rules - |> list.filter(rule_applicable(order, _)) - |> list.all(rule_satisfied(order, _)) -} - -fn rule_satisfied_or_swap(order: Order, rule: Rule) -> Order { - case rule_satisfied(order, rule) { - True -> order - False -> li.swap(order, pf(rule), ps(rule)) - } -} - -fn make_order_follow_rules(order: Order, rules: List(Rule)) -> Order { - case order_follows_rules(order, rules) { - True -> order - False -> { - list.filter(rules, rule_applicable(order, _)) - |> list.fold(order, rule_satisfied_or_swap) - |> make_order_follow_rules(rules) - } - } -} - -fn middle(order: Order) -> Int { - order - |> yielder.from_list - |> yielder.at(list.length(order) / 2) - |> result.unwrap(0) -} - -pub fn solve_a(input: String) -> Int { - let #(rules, orders) = parse_file(input) - - orders - |> list.filter(order_follows_rules(_, rules)) - |> list.map(middle) - |> list.fold(0, int.add) -} - -pub fn solve_b(input: String) -> Int { - let #(rules, orders) = parse_file(input) - - orders - |> list.filter(fn(order) { bool.negate(order_follows_rules(order, rules)) }) - |> list.map(make_order_follow_rules(_, rules)) - |> list.map(middle) - |> list.fold(0, int.add) -} diff --git a/src/red_nosed_reports.gleam b/src/red_nosed_reports.gleam deleted file mode 100644 index 781f599..0000000 --- a/src/red_nosed_reports.gleam +++ /dev/null @@ -1,56 +0,0 @@ -import gleam/int -import gleam/list -import gleam/pair -import gleam/result -import gleam/string - -fn parse_line(line: String) -> List(Int) { - use a <- list.map(string.split(line, " ")) - result.unwrap(int.parse(a), 0) -} - -fn all_incr(report: List(Int)) -> Bool { - use nums <- list.all(list.window_by_2(report)) - case pair.second(nums) - pair.first(nums) { - x if x > 0 && x < 4 -> True - _ -> False - } -} - -fn all_decr(report: List(Int)) -> Bool { - use nums <- list.all(list.window_by_2(report)) - case pair.first(nums) - pair.second(nums) { - x if x > 0 && x < 4 -> True - _ -> False - } -} - -fn valid(report: List(Int), d: Bool) -> Bool { - case d { - False -> all_incr(report) || all_decr(report) - True -> - valid(report, False) - || { - report - |> list.combinations(list.length(report) - 1) - |> list.any(valid(_, False)) - } - } -} - -pub fn solve_a(input: String) -> Int { - input - |> string.trim() - |> string.split("\n") - |> list.map(parse_line) - |> list.count(valid(_, False)) -} - -pub fn solve_b(input: String) -> Int { - input - |> string.trim() - |> string.split("\n") - |> list.map(parse_line) - |> list.filter(valid(_, True)) - |> list.length() -} diff --git a/src/resonant_collinearity.gleam b/src/resonant_collinearity.gleam deleted file mode 100644 index 425394d..0000000 --- a/src/resonant_collinearity.gleam +++ /dev/null @@ -1,160 +0,0 @@ -import gleam/dict.{type Dict} -import gleam/float -import gleam/int -import gleam/list -import gleam/result -import gleam/string - -type Point = - #(Float, Float) - -type Grid = - Dict(Point, String) - -type Direction { - Forward - Reverse -} - -fn parse_column(line, y) { - use grid, char, x <- list.index_fold(line, dict.new()) - dict.insert(grid, #(int.to_float(x), int.to_float(y)), char) -} - -fn square(input: Float) -> Float { - case float.power(input, 2.0) { - Ok(val) -> val - _ -> 0.0 - } -} - -fn find_collinear_vector( - point_a: Point, - point_b: Point, -) -> #(Float, #(Float, Float)) { - let #(x1, y1) = point_a - let #(x2, y2) = point_b - - let assert Ok(distance) = - float.add(square(float.subtract(x2, x1)), square(float.subtract(y2, y1))) - |> float.square_root - - let assert Ok(dx) = float.divide(float.subtract(x2, x1), distance) - let assert Ok(dy) = float.divide(float.subtract(y2, y1), distance) - - #(distance, #(dx, dy)) -} - -fn find_collinear_in_direction( - points: List(Point), - direction: Direction, -) -> Point { - let assert [point_a, point_b] = points - let #(distance, #(dx, dy)) = find_collinear_vector(point_a, point_b) - let #(x1, y1) = point_a - let #(x2, y2) = point_b - - case direction { - Forward -> #( - float.ceiling(float.add(x2, float.multiply(dx, distance))), - float.ceiling(float.add(y2, float.multiply(dy, distance))), - ) - Reverse -> #( - float.ceiling(float.subtract(x1, float.multiply(dx, distance))), - float.ceiling(float.subtract(y1, float.multiply(dy, distance))), - ) - } -} - -fn find_harmonic_collinear_in_direction( - found: List(Point), - grid: Grid, - direction: Direction, -) -> List(Point) { - let #(head, rest) = list.split(found, 2) - let assert [p1, p2] = head - let collinear_in_direction = find_collinear_in_direction(head, direction) - - case point_within_map(collinear_in_direction, grid) { - True -> - case direction { - Forward -> - find_harmonic_collinear_in_direction( - list.append([p2, collinear_in_direction], list.append(rest, [p1])), - grid, - direction, - ) - Reverse -> - find_harmonic_collinear_in_direction( - list.append([collinear_in_direction, p1], list.append(rest, [p2])), - grid, - direction, - ) - } - False -> found - } -} - -fn find_all_harmonic_collinears(points: List(Point), grid: Grid) -> List(Point) { - list.append( - find_harmonic_collinear_in_direction(points, grid, Forward), - find_harmonic_collinear_in_direction(points, grid, Reverse), - ) -} - -fn find_all_collinears(points: List(Point)) -> List(Point) { - list.wrap(find_collinear_in_direction(points, Forward)) - |> list.append(list.wrap(find_collinear_in_direction(points, Reverse))) -} - -fn find_antenna_locations(antenna: String, grid: Grid) -> List(Point) { - dict.keys(dict.filter(grid, fn(_, ant) { ant == antenna })) -} - -fn point_within_map(point: Point, g: Grid) -> Bool { - result.is_ok(list.find(dict.keys(g), fn(x) { x == point })) -} - -fn collinears_for_antenna(antenna: String, g: Grid) -> List(Point) { - find_antenna_locations(antenna, g) - |> list.combinations(2) - |> list.flat_map(find_all_collinears) - |> list.filter(point_within_map(_, g)) - |> list.unique -} - -fn harmonic_collinears_for_antenna(antenna: String, g: Grid) -> List(Point) { - find_antenna_locations(antenna, g) - |> list.combinations(2) - |> list.flat_map(find_all_harmonic_collinears(_, g)) - |> list.filter(point_within_map(_, g)) -} - -fn parse_input(input: String) -> Grid { - input - |> string.trim() - |> string.split("\n") - |> list.map(string.to_graphemes) - |> list.index_map(parse_column) - |> list.fold(dict.new(), dict.merge) -} - -pub fn solve_a(input: String) -> Int { - let grid = parse_input(input) - - list.filter(list.unique(dict.values(grid)), fn(x) { x != "." }) - |> list.map(collinears_for_antenna(_, grid)) - |> list.flatten - |> list.unique - |> list.length -} - -pub fn solve_b(input: String) -> Int { - let grid = parse_input(input) - - list.filter(list.unique(dict.values(grid)), fn(x) { x != "." }) - |> list.map(harmonic_collinears_for_antenna(_, grid)) - |> list.flatten - |> list.unique - |> list.length -} diff --git a/src/solutions/cube_conundrum.rs b/src/solutions/cube_conundrum.rs new file mode 100644 index 0000000..ac1414f --- /dev/null +++ b/src/solutions/cube_conundrum.rs @@ -0,0 +1,183 @@ +#[derive(Debug, Clone, Hash, PartialEq, Eq)] +enum Cube { + Red(u32), + Blue(u32), + Green(u32), + Invalid, +} + +#[derive(Debug, Clone)] +struct Game { + id: u32, + pub sets: Vec>, +} + +#[derive(Debug, Clone)] +struct Config { + red: u32, + green: u32, + blue: u32, +} + +impl Game { + pub fn is_valid(&self, config: Config) -> bool { + self.sets + .clone() + .into_iter() + .filter(|cubes| { + cubes.iter().any(|cube| match cube { + Cube::Green(count) => count.gt(&config.green), + Cube::Red(count) => count.gt(&config.red), + Cube::Blue(count) => count.gt(&config.blue), + _ => false, + }) + }) + .count() + .eq(&0) + } + + pub fn min_cubes(&self) -> u32 { + Ok::<(u32, u32, u32), anyhow::Error>(self.sets.iter().fold( + (0, 0, 0), + |(max_red, max_blue, max_green), cubes| { + cubes.iter().fold( + (max_red, max_blue, max_green), + |(red, blue, green), cube| match cube { + Cube::Red(x) => (red.max(*x), blue, green), + Cube::Blue(x) => (red, blue.max(*x), green), + Cube::Green(x) => (red, blue, green.max(*x)), + _ => (red, blue, green), + }, + ) + }, + )) + .map(|(max_red, max_blue, max_green)| max_red * max_blue * max_green) + .unwrap_or(0) + } +} + +mod parser { + use super::{Cube, Game}; + use nom::{ + branch::alt, + bytes::complete::tag, + character::complete::{digit1, line_ending, space1}, + combinator::{eof, map_res}, + multi::{many1, separated_list1}, + sequence::{terminated, tuple}, + Err as NomErr, IResult, + }; + pub struct Parser; + + impl Parser { + pub fn games(input: &str) -> IResult<&str, Vec> { + map_res( + many1(tuple((Self::game_id, many1(Self::game_set)))), + |games: Vec<(u32, Vec>)>| { + Ok::, NomErr<&str>>( + games + .into_iter() + .map(|(id, sets)| Game { id, sets }) + .collect(), + ) + }, + )(input) + } + + fn game_id(input: &str) -> IResult<&str, u32> { + map_res( + tuple((tag("Game "), map_res(digit1, str::parse::), tag(":"))), + |(_, id, _)| Ok::>(id), + )(input) + } + + fn game_set(input: &str) -> IResult<&str, Vec> { + map_res( + terminated( + separated_list1( + tag(","), + tuple(( + space1, + map_res(digit1, str::parse::), + space1, + alt((tag("blue"), tag("red"), tag("green"))), + )), + ), + alt((tag(";"), eof, line_ending)), + ), + |combinations: Vec<(&str, u32, &str, &str)>| { + Ok::, NomErr<&str>>( + combinations + .into_iter() + .map(|(_, count, _, color)| match color { + "red" => Cube::Red(count), + "green" => Cube::Green(count), + "blue" => Cube::Blue(count), + _ => Cube::Invalid, + }) + .collect::>(), + ) + }, + )(input) + } + } +} + +use parser::Parser; +pub fn solve_part1(input: &str) -> u32 { + Parser::games(input) + .map(|(_, parsed)| parsed) + .unwrap_or_default() + .into_iter() + .filter(|game| { + game.is_valid(Config { + red: 12, + green: 13, + blue: 14, + }) + }) + .map(|game| game.id) + .sum::() +} + +pub fn solve_part2(input: &str) -> u32 { + Parser::games(input) + .map(|(_, parsed)| parsed) + .unwrap_or_default() + .into_iter() + .map(|game| game.min_cubes()) + .sum::() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_a() { + let test_data = vec![ + "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green", + "Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue", + "Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red", + "Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red", + "Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green", + ] + .join("\n"); + let solution = solve_part1(&test_data); + assert_eq!(solution, 8) + } + + #[test] + fn test_part_b() { + let test_data = vec![ + "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green", + "Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue", + "Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red", + "Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red", + "Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green", + ] + .join("\n"); + let solution = solve_part2(&test_data); + assert_eq!(solution, 2286) + } +} diff --git a/src/solutions/mod.rs b/src/solutions/mod.rs new file mode 100644 index 0000000..254c433 --- /dev/null +++ b/src/solutions/mod.rs @@ -0,0 +1,3 @@ +pub mod cube_conundrum; +pub mod scratchcards; +pub mod trebuchet; diff --git a/src/solutions/scratchcards.rs b/src/solutions/scratchcards.rs new file mode 100644 index 0000000..8d52c0b --- /dev/null +++ b/src/solutions/scratchcards.rs @@ -0,0 +1,116 @@ +use anyhow::Result; + +#[allow(unused)] +#[derive(Debug)] +struct Card { + id: u32, + winning_numbers: Vec, + own_numbers: Vec, +} + +impl Card { + fn points(&self) -> Result { + Ok(self + .winning_numbers + .iter() + .filter(|winnum| self.own_numbers.iter().any(|ownnum| ownnum == *winnum)) + .count()) + .map(|cnt| { + if cnt.eq(&0) { + 0 + } else { + u32::pow(2, (cnt as u32) - 1) + } + }) + } +} + +mod parser { + use super::Card; + use nom::{ + branch::alt, + bytes::complete::tag, + character::complete::{digit1, space0, space1}, + combinator::{eof, map_res}, + multi::many1, + sequence::{terminated, tuple}, + Err, IResult, + }; + + pub struct Parser; + + impl Parser { + fn card_number_parser(inp: &str) -> IResult<&str, u32> { + map_res( + tuple(( + tag("Card"), + space1, + map_res(digit1, |s: &str| -> Result> { + Ok(s.parse::().unwrap()) + }), + tag(": "), + )), + |(_, _, card_id, _)| Ok::>(card_id), + )(inp) + } + + fn own_numbers_parser(inp: &str) -> IResult<&str, Vec> { + terminated( + many1(map_res( + tuple((space0, terminated(digit1, space0))), + |(_, n): (&str, &str)| Ok::>(n.parse::().unwrap()), + )), + alt((tag("\n"), eof)), + )(inp) + } + + fn winning_numbers_parser(inp: &str) -> IResult<&str, Vec> { + terminated( + many1(map_res( + tuple((space0, terminated(digit1, space0))), + |(_, n): (&str, &str)| Ok::>(n.parse::().unwrap()), + )), + tag("| "), + )(inp) + } + + fn card_parser(inp: &str) -> IResult<&str, Card> { + map_res( + tuple(( + Self::card_number_parser, + Self::winning_numbers_parser, + Self::own_numbers_parser, + )), + |(card_id, winning, own)| { + Ok::>(Card { + id: card_id, + winning_numbers: winning, + own_numbers: own, + }) + }, + )(inp) + } + + fn card_list_parser(inp: &str) -> IResult<&str, Vec> { + many1(Self::card_parser)(inp) + } + + pub fn parse(input: &str) -> IResult<&str, Vec> { + Self::card_list_parser(input) + } + } +} + +use parser::Parser; +pub fn solve_part1(input: &str) -> u32 { + Parser::parse(input) + .map(|(_, res)| res) + .unwrap_or_default() + .iter() + .map(|card| Card::points(card).unwrap_or_default()) + .sum::() +} + +pub fn solve_part2(_input: &str) -> i32 { + 0 +} diff --git a/src/solutions/trebuchet.rs b/src/solutions/trebuchet.rs new file mode 100644 index 0000000..dff4a52 --- /dev/null +++ b/src/solutions/trebuchet.rs @@ -0,0 +1,88 @@ +use itertools::Itertools; +use regex::Regex; + +pub fn solve_part1(input: &str) -> u32 { + input + .lines() + .map(|line| { + line.trim() + .chars() + .filter(|c| c.is_numeric()) + .map(|c| c.to_digit(10).unwrap()) + .collect::>() + }) + .map(|n| (10 * n.first().unwrap()) + n.last().unwrap()) + .sum::() +} + +pub fn solve_part2(input: &str) -> u32 { + let patterns = [ + "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", r"\d", + ] + .into_iter() + .map(|pattern| Regex::new(pattern).unwrap()) + .collect::>(); + + let parse_int = |s: &str| -> u32 { + match s { + "one" => 1, + "two" => 2, + "three" => 3, + "four" => 4, + "five" => 5, + "six" => 6, + "seven" => 7, + "eight" => 8, + "nine" => 9, + "zero" => 0, + x => x.parse::().unwrap(), + } + }; + + input + .lines() + .map(|line| { + patterns + .clone() + .iter() + .flat_map(|pattern| { + pattern + .find_iter(line.trim()) + .map(move |m| (m.start(), m.as_str())) + .collect::>() + }) + .sorted_by(|(i1, _), (i2, _)| i1.cmp(i2)) + .map(|(_, s)| parse_int(s)) + .collect::>() + }) + .map(|n| (n.first().unwrap() * 10) + n.last().unwrap()) + .sum::() +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_part_a() { + let test_data = vec!["1abc2", "pqr3stu8vwx", "a1b2c3d4e5f", "treb7uchet"].join("\n"); + let solution = solve_part1(&test_data); + assert_eq!(solution, 142) + } + + #[test] + fn test_part_b() { + let test_data = vec![ + "two1nine", + "eightwothree", + "abcone2threexyz", + "xtwone3four", + "4nineeightseven2", + "zoneight234", + "7pqrstsixteen", + ] + .join("\n"); + let solution = solve_part2(&test_data); + assert_eq!(solution, 281) + } +} diff --git a/src/utils/list.gleam b/src/utils/list.gleam deleted file mode 100644 index f755c3b..0000000 --- a/src/utils/list.gleam +++ /dev/null @@ -1,64 +0,0 @@ -import gleam/list as li -import gleam/pair.{first as pf, second as ps} -import gleam/result as res - -pub fn index(ls: List(a), item: a) -> Result(Int, Nil) { - li.index_map(ls, fn(x, index) { #(index, x) }) - |> li.find(fn(x) { ps(x) == item }) - |> res.map(pf) -} - -pub fn at(ls: List(a), i: Int) -> Result(a, Nil) { - li.index_map(ls, fn(x, ci) { #(x, ci) }) - |> li.find(fn(x) { ps(x) == i }) - |> res.map(pf) -} - -pub fn from_pair(p: #(a, a)) -> List(a) { - [pf(p), ps(p)] -} - -pub fn pop(ls: List(a)) -> #(Result(a, Nil), List(a)) { - case at(ls, li.length(ls) - 1) { - Ok(someval) -> { - #(Ok(someval), li.take(ls, li.length(ls) - 1)) - } - Error(_) -> #(Error(Nil), ls) - } -} - -pub fn index_filter(ls: List(a), f: fn(Int, a) -> Bool) -> List(a) { - li.index_map(ls, fn(item, index) { #(index, item) }) - |> li.filter(fn(x) { f(pf(x), ps(x)) }) - |> li.map(ps) -} - -pub fn contains(ls: List(a), item: a) -> Bool { - res.is_ok(li.find(ls, fn(x) { x == item })) -} - -pub fn swap(ls: List(a), ea: a, eb: a) -> List(a) { - use x <- li.map(ls) - case x { - val if val == ea -> eb - val if val == eb -> ea - val -> val - } -} - -pub fn max(ls: List(Int)) -> Int { - li.fold(ls, 0, fn(cmx, cx) { - case cx { - cxx if cxx > cmx -> cxx - _ -> cmx - } - }) -} - -pub fn repeated_permutation(ls: List(a), n: Int) { - use acc, _ <- li.fold(li.range(1, n), [[]]) - use y <- li.flat_map(acc) - use z <- li.map(ls) - - li.append(y, li.wrap(z)) -} diff --git a/test/advent_of_code_test.gleam b/test/advent_of_code_test.gleam deleted file mode 100644 index ecd12ad..0000000 --- a/test/advent_of_code_test.gleam +++ /dev/null @@ -1,5 +0,0 @@ -import gleeunit - -pub fn main() { - gleeunit.main() -} diff --git a/test/bridge_repair_test.gleam b/test/bridge_repair_test.gleam deleted file mode 100644 index 647462e..0000000 --- a/test/bridge_repair_test.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import bridge_repair as day07 -import gleam/string -import gleeunit/should - -fn test_data() -> String { - string.join( - [ - "190: 10 19", "3267: 81 40 27", "83: 17 5", "156: 15 6", "7290: 6 8 6 15", - "161011: 16 10 13", "192: 17 8 14", "21037: 9 7 18 13", "292: 11 6 16 20", - ], - "\n", - ) -} - -pub fn solve_a_test() { - should.equal(day07.solve_a(test_data()), 3749) -} - -pub fn solve_b_test() { - should.equal(day07.solve_b(test_data()), 11_387) -} diff --git a/test/ceres_search_test.gleam b/test/ceres_search_test.gleam deleted file mode 100644 index 79a3b42..0000000 --- a/test/ceres_search_test.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import ceres_search as day04 -import gleam/string -import gleeunit/should - -fn test_data() -> String { - string.join( - [ - "MMMSXXMASM", "MSAMXMSMSA", "AMXSXMAAMM", "MSAMASMSMX", "XMASAMXAMM", - "XXAMMXXAMA", "SMSMSASXSS", "SAXAMASAAA", "MAMMMXMMMM", "MXMXAXMASX", - ], - "\n", - ) -} - -pub fn solve_a_test() { - should.equal(day04.solve_a(test_data()), 18) -} - -pub fn solve_b_test() { - should.equal(day04.solve_b(test_data()), 9) -} diff --git a/test/disk_fragmenter_test.gleam b/test/disk_fragmenter_test.gleam deleted file mode 100644 index 6f7e85b..0000000 --- a/test/disk_fragmenter_test.gleam +++ /dev/null @@ -1,10 +0,0 @@ -import disk_fragmenter as day09 -import gleeunit/should - -pub fn solve_a_test() { - should.equal(day09.solve_a("2333133121414131402"), 1928) -} - -pub fn solve_b_test() { - should.equal(day09.solve_b("2333133121414131402"), 0) -} diff --git a/test/guard_gallivant_test.gleam b/test/guard_gallivant_test.gleam deleted file mode 100644 index 930ae9b..0000000 --- a/test/guard_gallivant_test.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/string -import gleeunit/should -import guard_gallivant as day05 - -fn test_data() { - string.join( - [ - "....#.....", ".........#", "..........", "..#.......", ".......#..", - "..........", ".#..^.....", "........#.", "#.........", "......#...", - ], - "\n", - ) -} - -pub fn solve_a_test() { - should.equal(day05.solve_a(test_data()), 41) -} - -pub fn solve_b_test() { - should.equal(day05.solve_b(test_data()), 6) -} diff --git a/test/historian_hysteria_test.gleam b/test/historian_hysteria_test.gleam deleted file mode 100644 index ce24da7..0000000 --- a/test/historian_hysteria_test.gleam +++ /dev/null @@ -1,14 +0,0 @@ -import gleeunit/should -import historian_hysteria as day01 - -fn test_data() -> String { - "3 4\n4 3\n2 5\n1 3\n3 9\n3 3" -} - -pub fn solve_a_test() { - should.equal(day01.solve_a(test_data()), 11) -} - -pub fn solve_b_test() { - should.equal(day01.solve_b(test_data()), 31) -} diff --git a/test/hoof_it_test.gleam b/test/hoof_it_test.gleam deleted file mode 100644 index af1258f..0000000 --- a/test/hoof_it_test.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/string -import gleeunit/should -import hoof_it as day10 - -fn test_data() -> String { - string.join( - [ - "89010123", "78121874", "87430965", "96549874", "45678903", "32019012", - "01329801", "10456732", - ], - "\n", - ) -} - -pub fn solve_a_test() { - should.equal(day10.solve_a(test_data()), 36) -} - -pub fn solve_b_test() { - should.equal(day10.solve_b(test_data()), 0) -} diff --git a/test/mull_it_over_test.gleam b/test/mull_it_over_test.gleam deleted file mode 100644 index 1b61b91..0000000 --- a/test/mull_it_over_test.gleam +++ /dev/null @@ -1,14 +0,0 @@ -import gleeunit/should -import mull_it_over as day03 - -pub fn solve_a_test() { - "xmul(2,4)%&mul[3,7]!@^do_not_mul(5,5)+mul(32,64]then(mul(11,8)mul(8,5))" - |> day03.solve_a() - |> should.equal(161) -} - -pub fn solve_b_test() { - "xmul(2,4)&mul[3,7]!^don't()_mul(5,5)+mul(32,64](mul(11,8)undo()?mul(8,5))" - |> day03.solve_b() - |> should.equal(48) -} diff --git a/test/print_queue_test.gleam b/test/print_queue_test.gleam deleted file mode 100644 index c34ac33..0000000 --- a/test/print_queue_test.gleam +++ /dev/null @@ -1,38 +0,0 @@ -import gleam/string -import gleeunit/should -import print_queue as day05 - -fn test_data() -> String { - string.join( - [ - string.join( - [ - "47|53", "97|13", "97|61", "97|47", "75|29", "61|13", "75|53", "29|13", - "97|29", "53|29", "61|53", "97|53", "61|29", "47|13", "75|47", "97|75", - "47|61", "75|61", "47|29", "75|13", "53|13", - ], - "\n", - ), - string.join( - [ - "75,47,61,53,29", "97,61,53,29,13", "75,29,13", "75,97,47,61,53", - "61,13,29", "97,13,75,29,47", - ], - "\n", - ), - ], - "\n\n", - ) -} - -pub fn solve_a_test() { - test_data() - |> day05.solve_a() - |> should.equal(143) -} - -pub fn solve_b_test() { - test_data() - |> day05.solve_b() - |> should.equal(123) -} diff --git a/test/red_nosed_reports_test.gleam b/test/red_nosed_reports_test.gleam deleted file mode 100644 index 5bc090e..0000000 --- a/test/red_nosed_reports_test.gleam +++ /dev/null @@ -1,21 +0,0 @@ -import gleam/string -import gleeunit/should -import red_nosed_reports as day01 - -fn test_data() -> String { - string.join( - [ - "7 6 4 2 1", "1 2 7 8 9", "9 7 6 2 1", "1 3 2 4 5", "8 6 4 4 1", - "1 3 6 7 9", - ], - "\n", - ) -} - -pub fn solve_a_test() { - should.equal(day01.solve_a(test_data()), 2) -} - -pub fn solve_b_test() { - should.equal(day01.solve_b(test_data()), 4) -} diff --git a/test/resonant_collinearity_test.gleam b/test/resonant_collinearity_test.gleam deleted file mode 100644 index 57f2d9d..0000000 --- a/test/resonant_collinearity_test.gleam +++ /dev/null @@ -1,22 +0,0 @@ -import gleam/string -import gleeunit/should -import resonant_collinearity as day08 - -fn test_data() -> String { - string.join( - [ - "............", "........0...", ".....0......", ".......0....", - "....0.......", "......A.....", "............", "............", - "........A...", ".........A..", "............", "............", - ], - "\n", - ) -} - -pub fn solve_a_test() { - should.equal(day08.solve_a(test_data()), 14) -} - -pub fn solve_b_test() { - should.equal(day08.solve_b(test_data()), 34) -}