Compare commits

...

28 Commits

Author SHA1 Message Date
e85f9131be Completed day 14 2019-08-25 15:58:16 -04:00
3872264523 Completed day 13 part 2 2019-08-13 00:06:04 -04:00
4b2a232f11 Completed day 13 part 1 2019-08-12 23:32:34 -04:00
e5f615cf48 Completed day 12 part 1 2019-08-04 22:33:16 -04:00
0d84ff39b8 Fix day 11 tests 2019-08-04 19:24:57 -04:00
fa882266a6 Speed up day 11 with summed area table 2019-08-04 18:55:17 -04:00
55c949f796 Benchmark day 11 2019-08-04 18:54:11 -04:00
6190b9742c Completed day 11 2019-08-03 15:53:36 -04:00
f615a47bb6 Fix day 10 tests 2019-08-03 13:58:57 -04:00
f5aa9aad9b Completed day 10 2019-08-03 01:54:17 -04:00
21a0815fd7 Day 9 part 2
Switch to using a `VecDeque` instead and rotate it on each turn.
2019-02-16 15:49:30 -05:00
d0fe734212 Day 9 part 1 2019-02-16 15:09:13 -05:00
dc5e1c6427 Day 9 WIP working on test example
Still need to handle a special case for the full example.
2019-02-16 02:27:38 -05:00
af6709d2a8 Rustfmt day 8 2019-02-15 23:48:12 -05:00
f155273a5b Day 8 part 2 2019-02-15 23:47:02 -05:00
e82f8b3820 Day 8 part 1 2019-02-15 23:15:19 -05:00
33c926887d Completed day 7 part 2 2019-01-26 02:59:01 -05:00
595605daaf Use char instead of String for step letter
More efficient and ergonomic.
2019-01-26 00:20:42 -05:00
f00091cbf0 Switch to a less verbose input error handling 2019-01-04 00:04:39 -05:00
0f2e4bdf47 rustfmt and fix clippy warnings 2019-01-03 01:10:10 -05:00
f4392d62c0 Completed day 7 part 1 2019-01-02 01:32:44 -05:00
e3ab089ce3 Completed day 6 part 2 2019-01-02 01:32:15 -05:00
bd6c348581 Completed day 6 part 1 2019-01-01 21:00:04 -05:00
41eaeb8192 WIP day 6 filling grid single coord, mult failing 2018-12-26 01:38:00 -05:00
35af0175f0 WIP day 6: debugging infinite fill recursion 2018-12-24 12:20:22 -05:00
7307f6a76e WIP day 6: reading coords, creating grid 2018-12-23 23:34:59 -05:00
57d8189964 Day 5 part 2 2018-12-20 00:46:36 -05:00
20ab475034 Day 5 part 1 2018-12-20 00:21:04 -05:00
33 changed files with 4007 additions and 12 deletions

461
Cargo.lock generated
View File

@ -1,8 +1,12 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "advent-of-code-2018"
version = "0.1.0"
dependencies = [
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -14,6 +18,49 @@ dependencies = [
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayvec"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "atty"
version = "0.2.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bstr"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "byteorder"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cast"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.6"
@ -29,6 +76,142 @@ dependencies = [
"time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "clap"
version = "2.33.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cloudabi"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "criterion"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
"tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "criterion-plot"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-deque"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-epoch"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-queue"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "crossbeam-utils"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "csv"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "csv-core"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "itertools"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "1.2.0"
@ -49,6 +232,19 @@ dependencies = [
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memoffset"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "nodrop"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num-integer"
version = "0.1.39"
@ -62,6 +258,95 @@ name = "num-traits"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num_cpus"
version = "1.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
version = "0.4.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_core"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rand_os"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand_xoshiro"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rayon-core"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.44"
@ -79,6 +364,14 @@ dependencies = [
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-automata"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "regex-syntax"
version = "0.6.4"
@ -87,6 +380,88 @@ dependencies = [
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ryu"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "same-file"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "scopeguard"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.98"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "syn"
version = "0.15.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
version = "0.3.6"
@ -105,11 +480,30 @@ dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tinytemplate"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ucd-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-width"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "utf8-ranges"
version = "1.0.2"
@ -120,6 +514,16 @@ name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
version = "2.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.3.6"
@ -134,6 +538,14 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-util"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@ -141,21 +553,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
"checksum bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0a692f1c740e7e821ca71a22cf99b9b2322dfa94d10f71443befb1797b3946a"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394"
"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e"
"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9"
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
"checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929"
"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70"
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113"
"checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c"
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e"
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c"
"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20"
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@ -6,4 +6,12 @@ edition = "2018"
[dependencies]
chrono = "0.4"
lazy_static = "1.2.0"
regex = "1"
[dev-dependencies]
criterion = "0.2"
[[bench]]
name = "day_11"
harness = false

14
benches/day_11.rs Normal file
View File

@ -0,0 +1,14 @@
#[macro_use]
extern crate criterion;
use criterion::Criterion;
#[path = "../src/day11.rs"]
mod day11;
fn criterion_benchmark(c: &mut Criterion) {
c.bench_function("day 11", |b| b.iter(|| day11::solve_part2()));
}
criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

313
inputs/10.txt Normal file
View File

@ -0,0 +1,313 @@
position=<-52775, 31912> velocity=< 5, -3>
position=<-52816, 10731> velocity=< 5, -1>
position=< 42573, -31652> velocity=<-4, 3>
position=<-31611, 31918> velocity=< 3, -3>
position=< 42585, -31656> velocity=<-4, 3>
position=<-10428, 53102> velocity=< 1, -5>
position=< 31958, -10460> velocity=<-3, 1>
position=<-21020, 10723> velocity=< 2, -1>
position=<-52770, 10731> velocity=< 5, -1>
position=< 21400, 10728> velocity=<-2, -1>
position=<-10427, -42253> velocity=< 1, 4>
position=< 21343, 42515> velocity=<-2, -4>
position=<-10417, -52846> velocity=< 1, 5>
position=< 42558, -42251> velocity=<-4, 4>
position=<-21008, 53106> velocity=< 2, -5>
position=<-10443, 31912> velocity=< 1, -3>
position=<-31584, 31919> velocity=< 3, -3>
position=<-31604, 10726> velocity=< 3, -1>
position=<-52786, -21055> velocity=< 5, 2>
position=<-10394, 31918> velocity=< 1, -3>
position=<-52786, 53109> velocity=< 5, -5>
position=<-52770, 10722> velocity=< 5, -1>
position=<-21007, -10464> velocity=< 2, 1>
position=< 21392, -31657> velocity=<-2, 3>
position=< 53180, 31913> velocity=<-5, -3>
position=<-10393, 21319> velocity=< 1, -2>
position=<-10430, 10724> velocity=< 1, -1>
position=<-20985, -42245> velocity=< 2, 4>
position=<-31610, -10468> velocity=< 3, 1>
position=<-20989, -42247> velocity=< 2, 4>
position=<-21006, 21317> velocity=< 2, -2>
position=< 10752, -31651> velocity=<-1, 3>
position=< 42577, 31912> velocity=<-4, -3>
position=<-42196, -21059> velocity=< 4, 2>
position=< 10744, -10460> velocity=<-1, 1>
position=<-10443, -31658> velocity=< 1, 3>
position=< 53185, 31912> velocity=<-5, -3>
position=<-52790, -21063> velocity=< 5, 2>
position=< 31990, -21060> velocity=<-3, 2>
position=< 10776, -52845> velocity=<-1, 5>
position=<-31636, 21324> velocity=< 3, -2>
position=<-10395, -42249> velocity=< 1, 4>
position=<-31591, 31912> velocity=< 3, -3>
position=<-10430, -21063> velocity=< 1, 2>
position=<-10422, 31912> velocity=< 1, -3>
position=< 10800, -42250> velocity=<-1, 4>
position=<-42199, -42248> velocity=< 4, 4>
position=< 31950, 42515> velocity=<-3, -4>
position=< 31982, 53104> velocity=<-3, -5>
position=< 31982, -52845> velocity=<-3, 5>
position=< 10752, 42510> velocity=<-1, -4>
position=< 31958, -21054> velocity=<-3, 2>
position=< 10752, -10467> velocity=<-1, 1>
position=< 31977, -31649> velocity=<-3, 3>
position=<-10438, -10460> velocity=< 1, 1>
position=<-20983, 10726> velocity=< 2, -1>
position=<-10385, 53109> velocity=< 1, -5>
position=< 42590, -52839> velocity=<-4, 5>
position=<-42180, 21317> velocity=< 4, -2>
position=<-31592, -21063> velocity=< 3, 2>
position=<-52782, -10466> velocity=< 5, 1>
position=<-31604, -42251> velocity=< 3, 4>
position=<-42198, -52848> velocity=< 4, 5>
position=<-31632, 42513> velocity=< 3, -4>
position=<-31601, -10468> velocity=< 3, 1>
position=<-31632, 21320> velocity=< 3, -2>
position=<-52773, 10725> velocity=< 5, -1>
position=<-42205, -10459> velocity=< 4, 1>
position=< 42533, 21322> velocity=<-4, -2>
position=< 53181, 53106> velocity=<-5, -5>
position=< 42533, 53102> velocity=<-4, -5>
position=< 53185, -42248> velocity=<-5, 4>
position=< 10797, 10730> velocity=<-1, -1>
position=< 53137, 21326> velocity=<-5, -2>
position=< 10776, 42508> velocity=<-1, -4>
position=< 21387, -42249> velocity=<-2, 4>
position=< 10805, -42250> velocity=<-1, 4>
position=<-20990, 42512> velocity=< 2, -4>
position=<-52801, 53102> velocity=< 5, -5>
position=< 42554, 53111> velocity=<-4, -5>
position=<-52809, 53106> velocity=< 5, -5>
position=<-31588, -42249> velocity=< 3, 4>
position=<-31595, 31921> velocity=< 3, -3>
position=< 42553, -10468> velocity=<-4, 1>
position=<-52818, -42249> velocity=< 5, 4>
position=<-20999, -42244> velocity=< 2, 4>
position=< 53127, 10731> velocity=<-5, -1>
position=< 21347, -52842> velocity=<-2, 5>
position=<-52794, 21323> velocity=< 5, -2>
position=<-42214, 31912> velocity=< 4, -3>
position=< 42558, -52847> velocity=<-4, 5>
position=<-10414, -42244> velocity=< 1, 4>
position=<-21025, 10728> velocity=< 2, -1>
position=<-10398, 10727> velocity=< 1, -1>
position=<-52794, -21056> velocity=< 5, 2>
position=< 10800, 53103> velocity=<-1, -5>
position=< 42556, -21059> velocity=<-4, 2>
position=<-31610, 42516> velocity=< 3, -4>
position=< 10780, 42507> velocity=<-1, -4>
position=< 31987, -52840> velocity=<-3, 5>
position=< 31952, 53102> velocity=<-3, -5>
position=<-21033, -42250> velocity=< 2, 4>
position=<-52773, -10466> velocity=< 5, 1>
position=<-42199, 42511> velocity=< 4, -4>
position=< 21355, -10467> velocity=<-2, 1>
position=<-21029, -10459> velocity=< 2, 1>
position=<-52775, 10727> velocity=< 5, -1>
position=<-21009, 31915> velocity=< 2, -3>
position=<-10389, -10464> velocity=< 1, 1>
position=< 53156, 31921> velocity=<-5, -3>
position=< 31995, 31920> velocity=<-3, -3>
position=<-31620, -52839> velocity=< 3, 5>
position=< 53158, -31654> velocity=<-5, 3>
position=<-42205, 42512> velocity=< 4, -4>
position=< 31950, 10725> velocity=<-3, -1>
position=<-10430, -42250> velocity=< 1, 4>
position=<-42206, 53102> velocity=< 4, -5>
position=< 42573, 10730> velocity=<-4, -1>
position=<-42178, 53111> velocity=< 4, -5>
position=<-10385, 53106> velocity=< 1, -5>
position=< 31955, 21320> velocity=<-3, -2>
position=< 42558, 10731> velocity=<-4, -1>
position=< 42585, -31656> velocity=<-4, 3>
position=< 42558, -21063> velocity=<-4, 2>
position=<-31612, -10461> velocity=< 3, 1>
position=<-10398, 31921> velocity=< 1, -3>
position=<-52765, 10724> velocity=< 5, -1>
position=< 42553, 53109> velocity=<-4, -5>
position=<-52810, -21061> velocity=< 5, 2>
position=<-42181, -31654> velocity=< 4, 3>
position=<-42175, -21058> velocity=< 4, 2>
position=<-10427, -10468> velocity=< 1, 1>
position=< 42529, -21055> velocity=<-4, 2>
position=< 10752, 53109> velocity=<-1, -5>
position=< 42561, 53107> velocity=<-4, -5>
position=< 31958, -31649> velocity=<-3, 3>
position=< 31968, -21063> velocity=<-3, 2>
position=<-10402, -52840> velocity=< 1, 5>
position=< 42565, -52848> velocity=<-4, 5>
position=< 53184, 31916> velocity=<-5, -3>
position=<-52797, 53111> velocity=< 5, -5>
position=< 42558, -52847> velocity=<-4, 5>
position=<-10394, 53106> velocity=< 1, -5>
position=<-42199, -42252> velocity=< 4, 4>
position=<-31592, -42250> velocity=< 3, 4>
position=< 10765, 53104> velocity=<-1, -5>
position=<-52794, 42509> velocity=< 5, -4>
position=< 21371, 53107> velocity=<-2, -5>
position=<-31616, -21063> velocity=< 3, 2>
position=<-42170, 31913> velocity=< 4, -3>
position=<-42199, 42513> velocity=< 4, -4>
position=< 10797, 53104> velocity=<-1, -5>
position=<-42175, 42511> velocity=< 4, -4>
position=<-20993, 21326> velocity=< 2, -2>
position=<-31588, 42513> velocity=< 3, -4>
position=<-20989, 31919> velocity=< 2, -3>
position=< 53140, 42509> velocity=<-5, -4>
position=< 53172, -10464> velocity=<-5, 1>
position=< 53128, 10724> velocity=<-5, -1>
position=<-31592, 42512> velocity=< 3, -4>
position=< 21347, 10724> velocity=<-2, -1>
position=<-52818, -21058> velocity=< 5, 2>
position=< 10794, 31912> velocity=<-1, -3>
position=<-10414, -52845> velocity=< 1, 5>
position=<-42219, 21326> velocity=< 4, -2>
position=< 31952, 31912> velocity=<-3, -3>
position=<-10413, 42507> velocity=< 1, -4>
position=< 21387, -31657> velocity=<-2, 3>
position=< 42557, -21054> velocity=<-4, 2>
position=<-20997, 53104> velocity=< 2, -5>
position=<-21014, -10468> velocity=< 2, 1>
position=<-10442, 10723> velocity=< 1, -1>
position=< 42572, -21054> velocity=<-4, 2>
position=<-20991, -42249> velocity=< 2, 4>
position=<-10435, -31649> velocity=< 1, 3>
position=< 10770, -10463> velocity=<-1, 1>
position=< 31958, 10730> velocity=<-3, -1>
position=<-21015, -42244> velocity=< 2, 4>
position=<-21039, 53111> velocity=< 2, -5>
position=<-31592, 31919> velocity=< 3, -3>
position=<-21022, -42249> velocity=< 2, 4>
position=< 31966, 10729> velocity=<-3, -1>
position=< 53167, -10468> velocity=<-5, 1>
position=<-42183, 21324> velocity=< 4, -2>
position=< 31955, 31915> velocity=<-3, -3>
position=< 42572, 53111> velocity=<-4, -5>
position=<-42170, 53102> velocity=< 4, -5>
position=< 42590, -10466> velocity=<-4, 1>
position=<-31609, 53106> velocity=< 3, -5>
position=< 42533, -10467> velocity=<-4, 1>
position=<-42215, 10731> velocity=< 4, -1>
position=<-42170, 10722> velocity=< 4, -1>
position=<-21004, 53102> velocity=< 2, -5>
position=< 53167, 10722> velocity=<-5, -1>
position=< 53132, -52844> velocity=<-5, 5>
position=< 42529, -21055> velocity=<-4, 2>
position=< 31960, 21322> velocity=<-3, -2>
position=<-42175, 42507> velocity=< 4, -4>
position=< 21342, 21326> velocity=<-2, -2>
position=<-52774, 31916> velocity=< 5, -3>
position=< 21355, -42248> velocity=<-2, 4>
position=< 53140, 10727> velocity=<-5, -1>
position=< 21368, 21317> velocity=<-2, -2>
position=< 42585, -42246> velocity=<-4, 4>
position=< 10805, -10459> velocity=<-1, 1>
position=< 21383, -52845> velocity=<-2, 5>
position=< 53133, -31649> velocity=<-5, 3>
position=<-31580, -31658> velocity=< 3, 3>
position=< 10792, -10463> velocity=<-1, 1>
position=< 10768, -52840> velocity=<-1, 5>
position=<-10420, -52848> velocity=< 1, 5>
position=<-42203, 31912> velocity=< 4, -3>
position=< 31974, -42245> velocity=<-3, 4>
position=<-52778, 42515> velocity=< 5, -4>
position=<-42170, 53106> velocity=< 4, -5>
position=<-10398, -10462> velocity=< 1, 1>
position=<-52799, -52848> velocity=< 5, 5>
position=<-42175, 42515> velocity=< 4, -4>
position=< 53142, -21059> velocity=<-5, 2>
position=< 10772, 42510> velocity=<-1, -4>
position=< 53137, 42516> velocity=<-5, -4>
position=<-42187, -21062> velocity=< 4, 2>
position=< 10805, 31914> velocity=<-1, -3>
position=< 21348, 10731> velocity=<-2, -1>
position=<-21023, 10726> velocity=< 2, -1>
position=< 31950, -31655> velocity=<-3, 3>
position=<-10386, -31654> velocity=< 1, 3>
position=<-21025, -21062> velocity=< 2, 2>
position=< 31966, 21318> velocity=<-3, -2>
position=<-52776, 31912> velocity=< 5, -3>
position=< 42569, -52841> velocity=<-4, 5>
position=<-31592, 10724> velocity=< 3, -1>
position=<-10429, 21317> velocity=< 1, -2>
position=<-31584, 10729> velocity=< 3, -1>
position=<-52818, 21320> velocity=< 5, -2>
position=<-21016, -10468> velocity=< 2, 1>
position=<-52791, 42507> velocity=< 5, -4>
position=<-42199, 42515> velocity=< 4, -4>
position=< 31982, -10467> velocity=<-3, 1>
position=<-10442, -52848> velocity=< 1, 5>
position=< 42565, 10726> velocity=<-4, -1>
position=<-42187, -10468> velocity=< 4, 1>
position=< 42561, -52841> velocity=<-4, 5>
position=< 42549, 31916> velocity=<-4, -3>
position=< 53180, -52842> velocity=<-5, 5>
position=< 21347, 21326> velocity=<-2, -2>
position=< 53151, 31921> velocity=<-5, -3>
position=< 31938, 10726> velocity=<-3, -1>
position=< 31942, -52848> velocity=<-3, 5>
position=< 10788, -10464> velocity=<-1, 1>
position=< 42590, 53103> velocity=<-4, -5>
position=< 53180, -21055> velocity=<-5, 2>
position=< 31935, 10731> velocity=<-3, -1>
position=<-52802, -31651> velocity=< 5, 3>
position=<-52776, -42249> velocity=< 5, 4>
position=< 53185, -21062> velocity=<-5, 2>
position=< 53159, 42511> velocity=<-5, -4>
position=< 10772, 10722> velocity=<-1, -1>
position=<-31593, 31912> velocity=< 3, -3>
position=< 10795, 21322> velocity=<-1, -2>
position=<-10436, -10459> velocity=< 1, 1>
position=< 21388, -42249> velocity=<-2, 4>
position=<-10405, 31921> velocity=< 1, -3>
position=<-52801, 42513> velocity=< 5, -4>
position=< 42573, 31915> velocity=<-4, -3>
position=< 21355, 53109> velocity=<-2, -5>
position=<-21025, 21323> velocity=< 2, -2>
position=< 53140, -10467> velocity=<-5, 1>
position=<-52767, 10726> velocity=< 5, -1>
position=< 21347, 31912> velocity=<-2, -3>
position=<-42183, 53107> velocity=< 4, -5>
position=< 31942, -10460> velocity=<-3, 1>
position=<-10401, 53102> velocity=< 1, -5>
position=< 21400, -10459> velocity=<-2, 1>
position=< 42579, 10722> velocity=<-4, -1>
position=< 31936, 42516> velocity=<-3, -4>
position=< 53128, -21056> velocity=<-5, 2>
position=<-20997, -42253> velocity=< 2, 4>
position=<-52777, -31658> velocity=< 5, 3>
position=<-10430, 21325> velocity=< 1, -2>
position=< 42545, -10464> velocity=<-4, 1>
position=<-21017, -52839> velocity=< 2, 5>
position=<-31584, 31912> velocity=< 3, -3>
position=< 53168, -21056> velocity=<-5, 2>
position=<-42199, -10459> velocity=< 4, 1>
position=< 10803, 53106> velocity=<-1, -5>
position=< 21371, 21317> velocity=<-2, -2>
position=<-21040, -42244> velocity=< 2, 4>
position=<-31577, 42511> velocity=< 3, -4>
position=< 42573, 21322> velocity=<-4, -2>
position=< 31990, 10728> velocity=<-3, -1>
position=< 53175, -52844> velocity=<-5, 5>
position=< 42561, 21323> velocity=<-4, -2>
position=<-42223, -52840> velocity=< 4, 5>
position=< 53152, -10468> velocity=<-5, 1>
position=<-52785, 53111> velocity=< 5, -5>
position=<-31632, -31656> velocity=< 3, 3>
position=<-21009, -10466> velocity=< 2, 1>
position=<-21025, -31651> velocity=< 2, 3>
position=< 10795, 53106> velocity=<-1, -5>
position=< 31978, -52844> velocity=<-3, 5>
position=<-52774, -21059> velocity=< 5, 2>
position=<-42211, -42253> velocity=< 4, 4>
position=<-31580, 53107> velocity=< 3, -5>
position=< 53172, 53102> velocity=<-5, -5>
position=<-52773, 42508> velocity=< 5, -4>
position=<-10398, -21054> velocity=< 1, 2>
position=<-31607, -10466> velocity=< 3, 1>
position=<-52801, 53108> velocity=< 5, -5>
position=<-52813, -21054> velocity=< 5, 2>
position=<-31600, 42511> velocity=< 3, -4>
position=<-31631, 21317> velocity=< 3, -2>
position=< 42532, -31649> velocity=<-4, 3>

31
inputs/10_test.txt Normal file
View File

@ -0,0 +1,31 @@
position=< 9, 1> velocity=< 0, 2>
position=< 7, 0> velocity=<-1, 0>
position=< 3, -2> velocity=<-1, 1>
position=< 6, 10> velocity=<-2, -1>
position=< 2, -4> velocity=< 2, 2>
position=<-6, 10> velocity=< 2, -2>
position=< 1, 8> velocity=< 1, -1>
position=< 1, 7> velocity=< 1, 0>
position=<-3, 11> velocity=< 1, -2>
position=< 7, 6> velocity=<-1, -1>
position=<-2, 3> velocity=< 1, 0>
position=<-4, 3> velocity=< 2, 0>
position=<10, -3> velocity=<-1, 1>
position=< 5, 11> velocity=< 1, -2>
position=< 4, 7> velocity=< 0, -1>
position=< 8, -2> velocity=< 0, 1>
position=<15, 0> velocity=<-2, 0>
position=< 1, 6> velocity=< 1, 0>
position=< 8, 9> velocity=< 0, -1>
position=< 3, 3> velocity=<-1, 1>
position=< 0, 5> velocity=< 0, -1>
position=<-2, 2> velocity=< 2, 0>
position=< 5, -2> velocity=< 1, 2>
position=< 1, 4> velocity=< 2, 1>
position=<-2, 7> velocity=< 2, -2>
position=< 3, 6> velocity=<-1, -1>
position=< 5, 0> velocity=< 1, 0>
position=<-6, 0> velocity=< 2, 0>
position=< 5, 9> velocity=< 1, -2>
position=<14, 7> velocity=<-2, 0>
position=<-3, 6> velocity=< 2, -1>

1
inputs/10_test_one.txt Normal file
View File

@ -0,0 +1 @@
position=< 0, 1> velocity=< 0, 0>

1
inputs/11.txt Normal file
View File

@ -0,0 +1 @@
8979

34
inputs/12.txt Normal file
View File

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

16
inputs/12_test.txt Normal file
View File

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

150
inputs/13.txt Normal file
View File

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

6
inputs/13_test.txt Normal file
View File

@ -0,0 +1,6 @@
/->-\
| | /----\
| /-+--+-\ |
| | | | v |
\-+-/ \-+--/
\------/

1
inputs/14.txt Normal file
View File

@ -0,0 +1 @@
236021

1
inputs/5.txt Normal file

File diff suppressed because one or more lines are too long

1
inputs/5_test.txt Normal file
View File

@ -0,0 +1 @@
dabAcCaCBAcCcaDA

50
inputs/6.txt Normal file
View File

@ -0,0 +1,50 @@
84, 212
168, 116
195, 339
110, 86
303, 244
228, 338
151, 295
115, 49
161, 98
60, 197
40, 55
55, 322
148, 82
86, 349
145, 295
243, 281
91, 343
280, 50
149, 129
174, 119
170, 44
296, 148
152, 160
115, 251
266, 281
269, 285
109, 242
136, 241
236, 249
338, 245
71, 101
254, 327
208, 231
289, 184
282, 158
352, 51
326, 230
88, 240
292, 342
352, 189
231, 141
280, 350
296, 185
226, 252
172, 235
137, 161
207, 90
101, 133
156, 234
241, 185

6
inputs/6_test.txt Normal file
View File

@ -0,0 +1,6 @@
1, 1
1, 6
8, 3
3, 4
5, 5
8, 9

101
inputs/7.txt Executable file
View File

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

7
inputs/7_test.txt Normal file
View File

@ -0,0 +1,7 @@
Step C must be finished before step A can begin.
Step C must be finished before step F can begin.
Step A must be finished before step B can begin.
Step A must be finished before step D can begin.
Step B must be finished before step E can begin.
Step D must be finished before step E can begin.
Step F must be finished before step E can begin.

1
inputs/8.txt Executable file

File diff suppressed because one or more lines are too long

1
inputs/8_test.txt Normal file
View File

@ -0,0 +1 @@
2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2

1
inputs/9.txt Normal file
View File

@ -0,0 +1 @@
471 players; last marble is worth 72026 points

1
inputs/9_test.txt Normal file
View File

@ -0,0 +1 @@
9 players; last marble is worth 25 points

256
src/day10.rs Normal file
View File

@ -0,0 +1,256 @@
extern crate regex;
use std::collections::HashSet;
use std::error::Error;
use std::fmt;
use std::fs;
use std::result;
use std::str::FromStr;
use regex::Regex;
type Result<T> = result::Result<T, Box<Error>>;
const INPUT: &str = "inputs/10.txt";
#[derive(Debug, PartialEq, Clone)]
struct Vector {
x: i32,
y: i32,
}
#[derive(Debug, PartialEq)]
struct Point {
position: Vector,
velocity: Vector,
}
impl FromStr for Point {
type Err = Box<Error>;
fn from_str(s: &str) -> Result<Point> {
lazy_static! {
static ref RE: Regex = Regex::new(concat!(
r"position=<(?P<position_x>(\s|-)?\d+), (?P<position_y>(\s|-)?\d+)> ",
r"velocity=<(?P<velocity_x>(\s|-)?\d+), (?P<velocity_y>(\s|-)?\d+)>"
))
.unwrap();
}
let captures = match RE.captures(s) {
None => {
return Err(From::from("Malformed points, no fields could be found"));
}
Some(captures) => captures,
};
Ok(Point {
position: Vector {
x: captures["position_x"].trim_start().parse()?,
y: captures["position_y"].trim_start().parse()?,
},
velocity: Vector {
x: captures["velocity_x"].trim_start().parse()?,
y: captures["velocity_y"].trim_start().parse()?,
},
})
}
}
#[derive(Debug, PartialEq)]
struct Sky {
points: Vec<Point>,
}
impl FromStr for Sky {
type Err = Box<Error>;
fn from_str(s: &str) -> Result<Sky> {
Ok(Sky {
points: s
.trim_end()
.split('\n')
.map(|line| line.parse().unwrap())
.collect(),
})
}
}
impl Sky {
fn point_spread(&self) -> (Vector, Vector) {
let mut min = self.points[0].position.clone();
let mut max = self.points[0].position.clone();
for point in self.points.iter() {
if point.position.x < min.x {
min.x = point.position.x;
}
if point.position.y < min.y {
min.y = point.position.y;
}
if point.position.x > max.x {
max.x = point.position.x;
}
if point.position.y > max.y {
max.y = point.position.y;
}
}
(min, max)
}
fn move_points(&mut self, seconds: i32) {
for point in self.points.iter_mut() {
point.position.x += point.velocity.x * seconds;
point.position.y += point.velocity.y * seconds;
}
}
}
impl fmt::Display for Sky {
#[allow(clippy::write_with_newline)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let (min, max) = self.point_spread();
let points_set: HashSet<(i32, i32)> = self
.points
.iter()
.map(|point| (point.position.x, point.position.y))
.collect();
for y in min.y..=max.y {
for x in min.x..=max.x {
if points_set.contains(&(x, y)) {
write!(f, "#")?;
} else {
write!(f, ".")?;
}
}
write!(f, "\n")?;
}
Ok(())
}
}
pub fn solve_parts() -> Result<(String, u32)> {
let mut sky = read_points_file(INPUT)?;
let (min, max) = sky.point_spread();
let mut min_spread = Vector {
x: (max.x - min.x).abs(),
y: (max.y - min.y).abs(),
};
let mut seconds = 0;
loop {
sky.move_points(1);
let (min, max) = sky.point_spread();
let spread_x = (max.x - min.x).abs();
let spread_y = (max.y - min.y).abs();
if spread_x > min_spread.x && spread_y > min_spread.y {
sky.move_points(-1);
return Ok((format!("{}", &sky), seconds));
}
if spread_x < min_spread.x {
min_spread.x = spread_x
}
if spread_y < min_spread.y {
min_spread.y = spread_y
}
seconds += 1;
}
}
fn read_points_file(filename: &str) -> Result<Sky> {
let points = fs::read_to_string(filename)?;
Ok(points.parse()?)
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT_ONE: &str = "inputs/10_test_one.txt";
const TEST_INPUT: &str = "inputs/10_test.txt";
const TEST_POINT_1: Point = Point {
position: Vector { x: 0, y: 1 },
velocity: Vector { x: 0, y: 0 },
};
const TEST_POINT_2: Point = Point {
position: Vector { x: 0, y: 0 },
velocity: Vector { x: 0, y: 0 },
};
fn test_sky() -> Sky {
Sky {
points: vec![TEST_POINT_1, TEST_POINT_2],
}
}
#[test]
fn parses_string_to_point() {
let point = "position=< 0, 1> velocity=< 0, 0>";
assert_eq!(point.parse::<Point>().unwrap(), TEST_POINT_1);
}
#[test]
fn reads_points_file() {
assert_eq!(
read_points_file(TEST_INPUT_ONE).unwrap(),
Sky {
points: vec![TEST_POINT_1]
}
);
}
#[test]
fn displays_sky_with_one_point() {
assert_eq!(format!("{}", test_sky()), "#\n#\n");
}
#[test]
fn displays_sky() {
let sky = read_points_file(TEST_INPUT).unwrap();
print!("{}", &sky);
assert_eq!(
format!("{}", sky),
concat!(
"........#.............\n",
"................#.....\n",
".........#.#..#.......\n",
"......................\n",
"#..........#.#.......#\n",
"...............#......\n",
"....#.................\n",
"..#.#....#............\n",
".......#..............\n",
"......#...............\n",
"...#...#.#...#........\n",
"....#..#..#.........#.\n",
".......#..............\n",
"...........#..#.......\n",
"#...........#.........\n",
"...#.......#..........\n",
)
);
}
#[test]
fn displays_message_in_sky() {
let mut sky = read_points_file(TEST_INPUT).unwrap();
sky.move_points(3);
print!("{}", &sky);
assert_eq!(
format!("{}", sky),
concat!(
"#...#..###\n",
"#...#...#.\n",
"#...#...#.\n",
"#####...#.\n",
"#...#...#.\n",
"#...#...#.\n",
"#...#...#.\n",
"#...#..###\n",
)
);
}
}

200
src/day11.rs Normal file
View File

@ -0,0 +1,200 @@
use std::error::Error;
use std::fmt;
use std::fs;
use std::result;
type Result<T> = result::Result<T, Box<Error>>;
const INPUT: &str = "inputs/11.txt";
const GRID_SIZE: usize = 300;
#[derive(Clone)]
struct Cells([[i32; GRID_SIZE + 1]; GRID_SIZE + 1]);
impl fmt::Display for Cells {
#[allow(clippy::write_with_newline)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for x in 1..=GRID_SIZE {
for y in 1..=GRID_SIZE {
write!(f, "{}", self.0[x][y])?;
}
write!(f, "\n")?;
}
Ok(())
}
}
impl fmt::Debug for Cells {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Cells {{\n{}\n}}", self)?;
Ok(())
}
}
#[derive(Debug, Clone)]
struct Grid {
serial_number: usize,
sums: Cells,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Coordinate {
pub x: usize,
pub y: usize,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Subsection {
pub coord: Coordinate,
pub size: usize,
}
impl Subsection {
fn top_left(&self) -> Subsection {
Subsection {
coord: Coordinate {
x: self.coord.x - self.size + 1,
y: self.coord.y - self.size + 1,
},
size: self.size,
}
}
}
impl Grid {
fn new(serial_number: usize) -> Grid {
Grid {
serial_number,
sums: Cells([[0; GRID_SIZE + 1]; GRID_SIZE + 1]),
}
}
fn power_at_cell(&self, coord: &Coordinate) -> i32 {
let rack_id = coord.x + 10;
let mut power_level = rack_id * coord.y;
power_level += self.serial_number;
power_level *= rack_id;
power_level = power_level / 100 % 10;
power_level as i32 - 5
}
fn fill_sums(&mut self) {
for x in 1..=GRID_SIZE {
for y in 1..=GRID_SIZE {
let power = self.power_at_cell(&Coordinate { x, y });
self.sums.0[x][y] = power + self.sums.0[x - 1][y] + self.sums.0[x][y - 1]
- self.sums.0[x - 1][y - 1];
}
}
}
fn power_of_subsection(&mut self, subsection: &Subsection) -> i32 {
let Subsection { coord, size } = subsection;
let &Coordinate { x, y } = coord;
self.sums.0[x][y] - self.sums.0[x - size][y] - self.sums.0[x][y - size]
+ self.sums.0[x - size][y - size]
}
fn highest_power_subsection(&mut self, size: usize) -> (Subsection, i32) {
let mut highest_power_subsection = Subsection {
coord: Coordinate { x: size, y: size },
size,
};
let mut highest_power_level = self.power_of_subsection(&highest_power_subsection);
for x in size..GRID_SIZE {
for y in size..GRID_SIZE {
let subsection = Subsection {
coord: Coordinate { x, y },
size,
};
if subsection == highest_power_subsection {
continue;
};
let power = self.power_of_subsection(&subsection);
if power > highest_power_level {
highest_power_subsection = subsection;
highest_power_level = power;
}
}
}
(highest_power_subsection.top_left(), highest_power_level)
}
}
fn read_serial_number_file(filename: &str) -> Result<usize> {
let serial_number = fs::read_to_string(filename)?;
Ok(serial_number.trim().parse()?)
}
pub fn solve_part1() -> Result<Subsection> {
let serial_number = read_serial_number_file(INPUT)?;
let mut grid = Grid::new(serial_number);
grid.fill_sums();
Ok(grid.highest_power_subsection(3).0)
}
pub fn solve_part2() -> Result<Subsection> {
let serial_number = read_serial_number_file(INPUT)?;
let mut grid = Grid::new(serial_number);
grid.fill_sums();
let (mut highest_power_subsection, mut highest_power_level) = grid.highest_power_subsection(1);
for size in 2..=GRID_SIZE {
let (subsection, power) = grid.highest_power_subsection(size);
if power > highest_power_level {
highest_power_subsection = subsection;
highest_power_level = power;
}
}
Ok(highest_power_subsection)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn creates_new_empty_grid() {
let grid = Grid::new(18);
assert_eq!(grid.serial_number, 18);
}
#[test]
fn returns_power_at_cell() {
let grid = Grid::new(8);
assert_eq!(grid.power_at_cell(&Coordinate { x: 3, y: 5 }), 4);
let grid = Grid::new(57);
assert_eq!(grid.power_at_cell(&Coordinate { x: 122, y: 79 }), -5);
let grid = Grid::new(39);
assert_eq!(grid.power_at_cell(&Coordinate { x: 217, y: 196 }), 0);
}
#[test]
fn returns_power_of_subsection() {
let mut grid = Grid::new(18);
grid.fill_sums();
assert_eq!(
grid.power_of_subsection(&Subsection {
coord: Coordinate { x: 35, y: 47 },
size: 3
}),
29
);
}
#[test]
fn returns_highest_power_subsection() {
let mut grid = Grid::new(18);
grid.fill_sums();
assert_eq!(
grid.highest_power_subsection(3),
(
Subsection {
coord: Coordinate { x: 33, y: 45 },
size: 3
},
29
)
);
}
}

265
src/day12.rs Normal file
View File

@ -0,0 +1,265 @@
extern crate regex;
use std::collections::{HashMap, VecDeque};
use std::error::Error;
use std::fmt;
use std::fs;
use std::result;
use std::str::FromStr;
use regex::Regex;
type Result<T> = result::Result<T, Box<Error>>;
const INPUT: &str = "inputs/12.txt";
#[derive(Debug, PartialEq)]
struct Pots(VecDeque<bool>);
#[derive(Debug, PartialEq)]
struct SpreadRules(HashMap<[bool; 5], bool>);
#[derive(Debug, PartialEq)]
struct GrowthSimulation {
pots: Pots,
spread_rules: SpreadRules,
generations: usize,
}
impl fmt::Display for Pots {
#[allow(clippy::write_with_newline)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for pot in self.0.iter() {
if *pot {
write!(f, "#")?;
} else {
write!(f, ".")?;
}
}
write!(f, "\n")?;
Ok(())
}
}
impl fmt::Display for SpreadRules {
#[allow(clippy::write_with_newline)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (pattern, result) in self.0.iter() {
for pot in pattern {
if *pot {
write!(f, "#")?;
} else {
write!(f, ".")?;
}
}
write!(f, " => ")?;
if *result {
write!(f, "#")?;
} else {
write!(f, ".")?;
}
write!(f, "\n")?;
}
write!(f, "\n")?;
Ok(())
}
}
impl fmt::Display for GrowthSimulation {
#[allow(clippy::write_with_newline)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.pots)?;
write!(f, "\n")?;
write!(f, "{}", self.spread_rules)?;
Ok(())
}
}
impl FromStr for GrowthSimulation {
type Err = Box<Error>;
fn from_str(s: &str) -> Result<GrowthSimulation> {
let sections: Vec<&str> = s.split("\n\n").collect();
let (initial_state_str, spread_rules_str) = (sections[0], sections[1]);
let mut pots = Pots(VecDeque::new());
let mut spread_rules = SpreadRules(HashMap::new());
lazy_static! {
static ref initial_state_regex: Regex =
Regex::new(r"initial state: (?P<initial_state>[#.]+)").unwrap();
static ref spread_rules_regex: Regex =
Regex::new(r"(?P<pattern>[#.]{5}) => (?P<result>[#.])").unwrap();
}
let initial_state_captures = match initial_state_regex.captures(initial_state_str) {
None => {
return Err(From::from(
"Malformed initial state, no fields could be found",
));
}
Some(captures) => captures,
};
for pot in initial_state_captures["initial_state"].chars() {
pots.0.push_back(pot == '#');
}
for rule in spread_rules_str.lines() {
let spread_rules_captures = match spread_rules_regex.captures(rule) {
None => {
return Err(From::from(
"Malformed spread rules, no fields could be found",
));
}
Some(captures) => captures,
};
let mut pattern = [false; 5];
let pattern_vec: Vec<bool> = spread_rules_captures["pattern"]
.chars()
.map(|c| c == '#')
.collect();
pattern.copy_from_slice(&pattern_vec);
let result = &spread_rules_captures["result"] == "#";
spread_rules.0.insert(pattern, result);
}
Ok(GrowthSimulation { pots, spread_rules, generations: 0 })
}
}
impl GrowthSimulation {
fn advance_generation(&mut self) {
let mut next_generation = VecDeque::new();
let padding = &[false; 4];
let pots_slice = self.pots.0.as_slices();
let pots_slice = [padding, pots_slice.0, pots_slice.1, padding].concat();
for (index, pot_window) in pots_slice.windows(5).enumerate() {
match self.spread_rules.0.get(pot_window) {
Some(result) => {
next_generation.push_back(*result);
},
None => {
next_generation.push_back(pots_slice[2]);
},
}
}
self.pots = Pots(next_generation);
self.generations += 1;
}
fn sum_plant_indices(&self) -> i32 {
let mut sum: i32 = 0;
for (index, pot) in self.pots.0.iter().enumerate() {
if *pot {
let shifted_index = index as i32 - self.generations as i32 * 2;
sum += shifted_index;
}
}
sum
}
}
fn read_initial_state_and_rules(filename: &str) -> Result<GrowthSimulation> {
let input = fs::read_to_string(filename)?;
Ok(input.parse()?)
}
pub fn solve_part1() -> Result<i32> {
let mut growth_sim = read_initial_state_and_rules(INPUT)?;
for _ in 0..20 {
growth_sim.advance_generation();
}
Ok(growth_sim.sum_plant_indices())
}
pub fn solve_part2() -> Result<i32> {
let mut growth_sim = read_initial_state_and_rules(INPUT)?;
for _ in 0..50_000_000_000_i64 {
growth_sim.advance_generation();
}
Ok(growth_sim.sum_plant_indices())
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/12_test.txt";
fn test_growth_sim() -> GrowthSimulation {
GrowthSimulation {
pots: Pots(VecDeque::from(vec![
true, false, false, true, false, true, false, false, true, true, false, false,
false, false, false, false, true, true, true, false, false, false, true, true,
true,
])),
spread_rules: SpreadRules([
([true, true, true, true, false], true),
([true, true, false, true, true], true),
([false, false, true, false, false], true),
([false, true, false, false, false], true),
([true, true, false, true, false], true),
([false, true, true, true, true], true),
([true, false, true, true, true], true),
([true, true, true, false, true], true),
([false, true, false, true, true], true),
([true, false, true, false, true], true),
([false, true, false, true, false], true),
([false, true, true, false, false], true),
([true, true, true, false, false], true),
([false, false, false, true, true], true),
]
.iter()
.cloned()
.collect()),
generations: 0,
}
}
#[test]
fn reads_initial_state_and_rules_file() {
let growth_sim = read_initial_state_and_rules(TEST_INPUT).unwrap();
assert_eq!(growth_sim, test_growth_sim());
}
#[test]
fn displays_growth_simulation() {
assert_eq!(
format!("{}", test_growth_sim()).lines().collect::<Vec<&str>>().sort(),
vec![
"#..#.#..##......###...###",
"",
"####. => #",
"##.## => #",
"..#.. => #",
".#... => #",
"##.#. => #",
".#### => #",
"#.### => #",
"###.# => #",
".#.## => #",
"#.#.# => #",
".#.#. => #",
".##.. => #",
"###.. => #",
"...## => #",
].sort()
);
}
#[test]
fn advances_simulation_by_one_generation() {
let mut growth_sim = test_growth_sim();
growth_sim.advance_generation();
assert_eq!(format!("{}", growth_sim.pots), "..#...#....#.....#..#..#..#..\n");
}
#[test]
fn returns_correct_sum_after_20_generations() {
let mut growth_sim = test_growth_sim();
for _ in 0..20 {
growth_sim.advance_generation();
}
assert_eq!(growth_sim.sum_plant_indices(), 325);
}
}

374
src/day13.rs Normal file
View File

@ -0,0 +1,374 @@
use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::fs;
use std::result;
use std::str::FromStr;
type Result<T> = result::Result<T, Box<Error>>;
const INPUT: &str = "inputs/13.txt";
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
pub struct Vector {
pub y: usize,
pub x: usize,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
enum Turn {
Left,
Straight,
Right,
Reverse,
}
const INTER_SEQ: [Turn; 3] = [Turn::Left, Turn::Straight, Turn::Right];
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
enum Direction {
North,
South,
East,
West,
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
struct Cart {
position: Vector,
direction: Direction,
next_turn: u8,
}
#[derive(Debug, PartialEq)]
struct Track {
carts: Vec<Cart>,
turns: HashMap<Vector, (Direction, Direction)>,
intersections: HashSet<Vector>,
}
#[derive(Debug, PartialEq)]
struct Collision {
position: Vector,
cart_indices: (usize, usize),
}
impl FromStr for Track {
type Err = Box<Error>;
fn from_str(s: &str) -> Result<Track> {
let mut carts = vec![];
let mut turns = HashMap::new();
let mut intersections = HashSet::new();
let mut incomplete_circuits: HashMap<(usize, usize), usize> = HashMap::new();
for (row_index, row) in s.lines().enumerate() {
let mut top_start: Option<usize> = None;
let mut bottom_start: Option<usize> = None;
for c in row.char_indices() {
match c {
(col_index, '\\') => match top_start {
Some(start) => {
incomplete_circuits.insert((start, col_index), row_index);
turns.insert(
Vector {
x: col_index,
y: row_index,
},
(Direction::South, Direction::West),
);
top_start = None;
}
None => {
bottom_start = Some(col_index);
turns.insert(
Vector {
x: col_index,
y: row_index,
},
(Direction::North, Direction::East),
);
}
},
(col_index, '/') => match bottom_start {
Some(start) => match incomplete_circuits.remove(&(start, col_index)) {
Some(_) => {
turns.insert(
Vector {
x: col_index,
y: row_index,
},
(Direction::West, Direction::North),
);
bottom_start = None;
}
None => {
return Err(From::from(
"Malformed track, circuit bottom without top",
))
}
},
None => {
top_start = Some(col_index);
turns.insert(
Vector {
x: col_index,
y: row_index,
},
(Direction::East, Direction::South),
);
}
},
(col_index, '+') => {
intersections.insert(Vector {
x: col_index,
y: row_index,
});
}
(col_index, '^') => carts.push(Cart {
position: Vector {
x: col_index,
y: row_index,
},
direction: Direction::North,
next_turn: 0,
}),
(col_index, 'v') => carts.push(Cart {
position: Vector {
x: col_index,
y: row_index,
},
direction: Direction::South,
next_turn: 0,
}),
(col_index, '>') => carts.push(Cart {
position: Vector {
x: col_index,
y: row_index,
},
direction: Direction::East,
next_turn: 0,
}),
(col_index, '<') => carts.push(Cart {
position: Vector {
x: col_index,
y: row_index,
},
direction: Direction::West,
next_turn: 0,
}),
_ => {}
}
}
}
Ok(Track {
carts,
turns,
intersections,
})
}
}
impl Direction {
fn turn(self, turn: Turn) -> Direction {
match turn {
Turn::Left => match self {
Direction::North => Direction::West,
Direction::South => Direction::East,
Direction::East => Direction::North,
Direction::West => Direction::South,
},
Turn::Right => match self {
Direction::North => Direction::East,
Direction::South => Direction::West,
Direction::East => Direction::South,
Direction::West => Direction::North,
},
Turn::Reverse => match self {
Direction::North => Direction::South,
Direction::South => Direction::North,
Direction::East => Direction::West,
Direction::West => Direction::East,
},
Turn::Straight => self,
}
}
}
impl Cart {
fn turn(&mut self, turn: Turn) {
self.direction = self.direction.turn(turn);
}
fn follow_turn(&mut self, turn_arms: (Direction, Direction)) {
let entering_from = self.direction.turn(Turn::Reverse);
if entering_from == turn_arms.0 {
self.direction = turn_arms.1;
} else if entering_from == turn_arms.1 {
self.direction = turn_arms.0;
} else {
panic!("Cart entered turn from an invalid direction");
}
}
}
impl Track {
fn run_tick(&mut self, find_final_cart: bool) -> Option<Vector> {
let mut collided_cart_indices = HashSet::new();
let mut cart_positions: HashMap<Vector, usize> = HashMap::new();
for (index, cart) in self.carts.iter().enumerate() {
cart_positions.insert(cart.position, index);
}
for (index, cart) in self.carts.iter_mut().enumerate() {
if collided_cart_indices.contains(&index) {
continue;
}
let Vector { x, y } = cart.position;
cart_positions.remove(&cart.position);
cart.position = match cart.direction {
Direction::North => Vector { x, y: y - 1 },
Direction::South => Vector { x, y: y + 1 },
Direction::East => Vector { x: x + 1, y },
Direction::West => Vector { x: x - 1, y },
};
if let Some(turn_arms) = self.turns.get(&cart.position) {
cart.follow_turn(*turn_arms);
}
if self.intersections.contains(&cart.position) {
cart.turn(INTER_SEQ[cart.next_turn as usize]);
cart.next_turn = (cart.next_turn + 1) % INTER_SEQ.len() as u8;
}
if let Some(colliding_cart) = cart_positions.get(&cart.position) {
if find_final_cart {
collided_cart_indices.insert(index);
collided_cart_indices.insert(*colliding_cart);
cart_positions.remove(&cart.position);
continue;
} else {
return Some(cart.position);
}
}
cart_positions.insert(cart.position, index);
}
self.carts = self
.carts
.drain(..)
.enumerate()
.filter(|(i, _)| !collided_cart_indices.contains(i))
.map(|(_, cart)| cart)
.collect();
self.carts.sort_unstable();
None
}
fn find_first_collision(&mut self) -> Vector {
let mut collision: Option<Vector> = None;
while collision.is_none() {
collision = self.run_tick(false);
}
collision.unwrap()
}
fn find_last_cart(&mut self) -> &Cart {
while self.carts.len() != 1 {
self.run_tick(true);
}
&self.carts[0]
}
}
fn read_track(filename: &str) -> Result<Track> {
let input = fs::read_to_string(filename)?;
Ok(input.parse()?)
}
pub fn solve_part1() -> Result<Vector> {
let mut track = read_track(INPUT)?;
Ok(track.find_first_collision())
}
pub fn solve_part2() -> Result<Vector> {
let mut track = read_track(INPUT)?;
Ok(track.find_last_cart().position)
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/13_test.txt";
fn test_track() -> Track {
Track {
carts: vec![
Cart {
position: Vector { x: 2, y: 0 },
direction: Direction::East,
next_turn: 0,
},
Cart {
position: Vector { x: 9, y: 3 },
direction: Direction::South,
next_turn: 0,
},
],
turns: vec![
(Vector { x: 0, y: 0 }, (Direction::East, Direction::South)),
(Vector { x: 4, y: 0 }, (Direction::South, Direction::West)),
(Vector { x: 4, y: 4 }, (Direction::West, Direction::North)),
(Vector { x: 0, y: 4 }, (Direction::North, Direction::East)),
(Vector { x: 7, y: 1 }, (Direction::East, Direction::South)),
(Vector { x: 12, y: 1 }, (Direction::South, Direction::West)),
(Vector { x: 12, y: 4 }, (Direction::West, Direction::North)),
(Vector { x: 7, y: 4 }, (Direction::North, Direction::East)),
(Vector { x: 2, y: 2 }, (Direction::East, Direction::South)),
(Vector { x: 9, y: 2 }, (Direction::South, Direction::West)),
(Vector { x: 9, y: 5 }, (Direction::West, Direction::North)),
(Vector { x: 2, y: 5 }, (Direction::North, Direction::East)),
]
.iter()
.cloned()
.collect(),
intersections: vec![
Vector { x: 4, y: 2 },
Vector { x: 7, y: 2 },
Vector { x: 2, y: 4 },
Vector { x: 9, y: 4 },
]
.iter()
.cloned()
.collect(),
}
}
#[test]
fn reads_track_file() {
let track = read_track(TEST_INPUT).unwrap();
assert_eq!(track, test_track());
}
#[test]
fn runs_one_tick() {
let mut track_after = test_track();
track_after.carts[0].position.x = 3;
track_after.carts[1].position.y = 4;
track_after.carts[1].direction = Direction::East;
track_after.carts[1].next_turn = 1;
let mut track = test_track();
track.run_tick(false);
assert_eq!(track, track_after);
}
#[test]
fn finds_first_collision() {
let mut track = test_track();
assert_eq!(track.find_first_collision(), Vector { x: 7, y: 3 });
}
}

249
src/day14.rs Normal file
View File

@ -0,0 +1,249 @@
use std::error::Error;
use std::fmt;
use std::fs;
use std::result;
type Result<T> = result::Result<T, Box<Error>>;
const INPUT: &str = "inputs/14.txt";
#[derive(Debug, PartialEq)]
struct Recipes {
scores: Vec<u8>,
elf1_index: usize,
elf2_index: usize,
}
impl fmt::Display for Recipes {
#[allow(clippy::write_with_newline)]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for (index, score) in self.scores.iter().enumerate() {
if index == self.elf1_index {
write!(f, "({})", score)?;
} else if index == self.elf2_index {
write!(f, "[{}]", score)?;
} else {
write!(f, " {} ", score)?;
}
}
write!(f, "\n")?;
Ok(())
}
}
impl Recipes {
fn new() -> Recipes {
Recipes {
scores: vec![3, 7],
elf1_index: 0,
elf2_index: 1,
}
}
fn new_recipes(&mut self) {
let elf1_score = self.scores[self.elf1_index];
let elf2_score = self.scores[self.elf2_index];
let sum = elf1_score + elf2_score;
fn push_digits(n: u8, digits: &mut Vec<u8>) {
if n >= 10 {
push_digits(n / 10, digits);
}
digits.push(n % 10);
}
push_digits(sum, &mut self.scores);
}
fn pick_recipes(&mut self) {
let elf1_score = self.scores[self.elf1_index];
let elf2_score = self.scores[self.elf2_index];
self.elf1_index = (self.elf1_index + (1 + elf1_score as usize)) % self.scores.len();
self.elf2_index = (self.elf2_index + (1 + elf2_score as usize)) % self.scores.len();
}
fn scores_after_n_recipes(&mut self, n: usize, num_scores: usize) -> String {
while self.scores.len() < n + num_scores {
self.new_recipes();
self.pick_recipes();
}
self.scores[n..n + num_scores].iter().map(|score| format!("{}", score)).collect()
}
fn find_index_of_sequence(&mut self, seq: &[u8]) -> usize {
let seq_len = seq.len();
loop {
let scores_len = self.scores.len();
self.new_recipes();
self.pick_recipes();
let new_scores_len = self.scores.len();
let diff = new_scores_len - scores_len;
if scores_len >= seq_len {
for i in 0..diff {
let seq_index = scores_len + i - seq_len;
if &self.scores[seq_index..(seq_index + seq_len)] == seq {
return seq_index;
}
}
}
}
}
}
fn digit_seq(n: &str) -> Vec<u8> {
let mut digits: Vec<u8> = vec![];
for digit in n.chars() {
digits.push(digit.to_digit(10).unwrap() as u8);
}
digits
}
fn read_input_file(filename: &str) -> Result<usize> {
let input = fs::read_to_string(filename)?;
Ok(input.trim().parse()?)
}
pub fn solve_part1() -> Result<String> {
let input = read_input_file(INPUT)?;
let mut recipes = Recipes::new();
Ok(recipes.scores_after_n_recipes(input, 10))
}
pub fn solve_part2() -> Result<usize> {
let input = fs::read_to_string(INPUT)?;
let mut recipes = Recipes::new();
let seq = digit_seq(&input.trim());
Ok(recipes.find_index_of_sequence(&seq[..]))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn creates_new_recipes_struct() {
let recipes = Recipes::new();
assert_eq!(recipes.scores, vec![3, 7]);
assert_eq!(recipes.elf1_index, 0);
assert_eq!(recipes.elf2_index, 1);
}
#[test]
fn adds_new_recipes() {
let mut recipes = Recipes::new();
recipes.new_recipes();
assert_eq!(recipes.scores, vec![3, 7, 1, 0]);
}
#[test]
fn picks_new_recipes() {
let mut recipes = Recipes::new();
recipes.new_recipes();
recipes.pick_recipes();
assert_eq!(recipes.elf1_index, 0);
assert_eq!(recipes.elf2_index, 1);
}
#[test]
fn iterates_15_times() {
let mut recipes = Recipes::new();
for _ in 0..15 {
recipes.new_recipes();
recipes.pick_recipes();
}
assert_eq!(
format!("{}", recipes),
" 3 7 1 0 [1] 0 1 2 (4) 5 1 5 8 9 1 6 7 7 9 2 \n",
);
}
#[test]
fn scores_after_5_recipes() {
let mut recipes = Recipes::new();
assert_eq!(
recipes.scores_after_n_recipes(5, 10),
"0124515891",
);
}
#[test]
fn scores_after_9_recipes() {
let mut recipes = Recipes::new();
assert_eq!(
recipes.scores_after_n_recipes(9, 10),
"5158916779",
);
}
#[test]
fn scores_after_18_recipes() {
let mut recipes = Recipes::new();
assert_eq!(
recipes.scores_after_n_recipes(18, 10),
"9251071085",
);
}
#[test]
fn scores_after_2018_recipes() {
let mut recipes = Recipes::new();
assert_eq!(
recipes.scores_after_n_recipes(2018, 10),
"5941429882",
);
}
#[test]
fn finds_index_of_sequence_1() {
let mut recipes = Recipes::new();
let seq = vec![5, 1, 5, 8, 9];
assert_eq!(
recipes.find_index_of_sequence(&seq[..]),
9,
);
}
#[test]
fn finds_index_of_sequence_2() {
let mut recipes = Recipes::new();
let seq = vec![0, 1, 2, 4, 5];
assert_eq!(
recipes.find_index_of_sequence(&seq[..]),
5,
);
}
#[test]
fn finds_index_of_sequence_3() {
let mut recipes = Recipes::new();
let seq = vec![9, 2, 5, 1, 0];
assert_eq!(
recipes.find_index_of_sequence(&seq[..]),
18,
);
}
#[test]
fn finds_index_of_sequence_4() {
let mut recipes = Recipes::new();
let seq = vec![5, 9, 4, 1, 4];
assert_eq!(
recipes.find_index_of_sequence(&seq[..]),
2018,
);
}
#[test]
fn gets_digit_seq_1() {
assert_eq!(
digit_seq("51589"),
vec![5, 1, 5, 8, 9],
);
}
#[test]
fn gets_digit_seq_2() {
assert_eq!(
digit_seq("01245"),
vec![0, 1, 2, 4, 5],
);
}
}

92
src/day5.rs Normal file
View File

@ -0,0 +1,92 @@
extern crate regex;
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::collections::HashMap;
use regex::Regex;
const INPUT: &str = "inputs/5.txt";
const UNITS: &str = "abcdefghijklmnopqrstuvwxyz";
pub fn solve_part1() -> Result<usize, Box<Error>> {
let polymer = read_polymer(INPUT)?;
Ok(reduce_polymer_completely(polymer).len())
}
pub fn solve_part2() -> Result<usize, Box<Error>> {
let polymer = read_polymer(INPUT)?;
Ok(find_shortest_unit_eliminated_polymer(polymer))
}
fn read_polymer(filename: &str) -> Result<String, Box<Error>> {
let file = File::open(filename)?;
let polymer = BufReader::new(file).lines().next().unwrap_or(Ok("".to_string()));
Ok(polymer?)
}
fn reduce_polymer(polymer: &String) -> String {
lazy_static! {
static ref REACTING_UNITS: Regex = Regex::new(concat!(
r"aA|bB|cC|dD|eE|fF|gG|hH|iI|jJ|kK|lL|mM|nN|",
r"oO|pP|qQ|rR|sS|tT|uU|vV|wW|xX|yY|zZ|",
r"Aa|Bb|Cc|Dd|Ee|Ff|Gg|Hh|Ii|Jj|Kk|Ll|Mm|Nn|",
r"Oo|Pp|Qq|Rr|Ss|Tt|Uu|Vv|Ww|Xx|Yy|Zz")).unwrap();
}
REACTING_UNITS.replace_all(&polymer, "").to_string()
}
fn reduce_polymer_completely(polymer: String) -> String {
let reduced = reduce_polymer(&polymer);
if reduced == polymer {
reduced
} else {
reduce_polymer_completely(reduced)
}
}
fn find_shortest_unit_eliminated_polymer(polymer: String) -> usize {
let mut eliminated_unit_polymers = HashMap::new();
for unit in UNITS.chars() {
let test_polymer = polymer
.replace(unit, "")
.replace(unit.to_ascii_uppercase(), "");
eliminated_unit_polymers.insert(unit, reduce_polymer_completely(test_polymer).len());
}
*eliminated_unit_polymers.iter().min_by_key(|&(_, len)| len).unwrap().1
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/5_test.txt";
#[test]
fn reduces_polymer() {
assert_eq!(reduce_polymer(&"aA".to_string()), "");
assert_eq!(reduce_polymer(&"aAbB".to_string()), "");
assert_eq!(reduce_polymer(&"aAfgbB".to_string()), "fg");
assert_eq!(reduce_polymer(&"abAB".to_string()), "abAB");
assert_eq!(reduce_polymer(&"aabAAB".to_string()), "aabAAB");
assert_eq!(reduce_polymer(&"dabAcCaCBAcCcaDA".to_string()), "dabAaCBAcaDA");
assert_eq!(reduce_polymer(&"dabAaCBAcCcaDA".to_string()), "dabCBAcaDA");
assert_eq!(reduce_polymer(&"dabCBAcCcaDA".to_string()), "dabCBAcaDA");
}
#[test]
fn reduces_polymer_completely() {
assert_eq!(reduce_polymer_completely("dabAcCaCBAcCcaDA".to_string()), "dabCBAcaDA");
}
#[test]
fn reads_polymer() {
assert_eq!(read_polymer(TEST_INPUT).unwrap(), "dabAcCaCBAcCcaDA");
}
#[test]
fn finds_shortest_unit_eliminated_polymer() {
assert_eq!(find_shortest_unit_eliminated_polymer("dabAcCaCBAcCcaDA".to_string()), 4);
}
}

490
src/day6.rs Normal file
View File

@ -0,0 +1,490 @@
extern crate regex;
use std::error::Error;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::fmt;
use std::collections::{HashMap, HashSet};
use regex::{Regex, Captures};
static ALPHABET: [char; 52] = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z',
];
const INPUT: &str = "inputs/6.txt";
#[derive(Debug, PartialEq, Copy, Clone, Eq, Hash)]
struct Coordinate {
x: u32,
y: u32,
letter: char,
}
#[derive(Debug, PartialEq)]
enum GridPoint {
Unfilled {
x: u32,
y: u32,
},
Tied {
x: u32,
y: u32,
closest_dist: u32,
},
Filled {
x: u32,
y: u32,
closest_coord: Coordinate,
closest_dist: u32,
},
}
#[derive(Debug, PartialEq)]
struct Grid {
points: Vec<GridPoint>,
boundary_coord: Coordinate,
}
impl fmt::Display for Coordinate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.letter)
}
}
impl fmt::Display for Grid {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "\n-----")?;
for (index, point) in self.points.iter().enumerate() {
if index as u32 % (self.boundary_coord.x + 1) == 0 {
write!(f, "\n")?;
}
match point {
GridPoint::Unfilled { x: _, y: _ } => { write!(f, "-")?; },
GridPoint::Tied { x: _, y: _, closest_dist: _} => {
write!(f, ".")?;
},
GridPoint::Filled { x, y, closest_coord, closest_dist: _ } => {
if *x == closest_coord.x && *y == closest_coord.y {
write!(f, "#")?;
} else {
write!(f, "{}", closest_coord)?;
}
},
}
}
write!(f, "\n-----")?;
Ok(())
}
}
#[derive(Debug, Clone, PartialEq)]
struct MalformedCoordinate {
details: String
}
impl MalformedCoordinate {
fn new(msg: &str) -> MalformedCoordinate {
MalformedCoordinate{ details: msg.to_string() }
}
}
impl fmt::Display for MalformedCoordinate {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.details)
}
}
impl Error for MalformedCoordinate {
fn description(&self) -> &str {
&self.details
}
}
pub fn solve_part1() -> Result<u32, Box<Error>> {
let coords = read_coordinates(INPUT)?;
let boundary_coord = get_boundary_coordinate(&coords);
let mut grid = create_grid(boundary_coord);
fill_grid(&mut grid, &coords).unwrap();
println!("{}", grid);
Ok(find_largest_coord_area(grid))
}
pub fn solve_part2() -> Result<u32, Box<Error>> {
let coords = read_coordinates(INPUT)?;
let boundary_coord = get_boundary_coordinate(&coords);
let grid = create_grid(boundary_coord);
Ok(region_closest_to_coordinates_size(grid, coords))
}
fn read_coordinates(filename: &str) -> Result<Vec<Coordinate>, Box<Error>> {
let mut records: Vec<Coordinate> = Vec::new();
lazy_static! {
static ref COORDINATE_REGEX: Regex = Regex::new(
r"(?P<x>\d+), (?P<y>\d+)").unwrap();
}
let file = File::open(filename)?;
for (index, line) in BufReader::new(file).lines().enumerate() {
match COORDINATE_REGEX.captures(&line?) {
Some(captures) => {
records.push(Coordinate {
x: get_captured_field(&captures, "x")?.parse()?,
y: get_captured_field(&captures, "y")?.parse()?,
letter: ALPHABET[index],
});
},
None => return Err(Box::new(MalformedCoordinate {
details: "Malformed coordinate line, no fields could be found".to_string()
})),
};
}
Ok(records)
}
fn get_captured_field(captures: &Captures, field: &str) -> Result<String, Box<Error>> {
match captures.name(field) {
Some(capture) => Ok(String::from(capture.as_str())),
None => return Err(Box::new(MalformedCoordinate {
details: format!("Malformed coordinate line, field {} could not be found", field)
}))
}
}
fn get_boundary_coordinate(coords: &Vec<Coordinate>) -> Coordinate {
let mut boundary_coord = Coordinate { x: 0, y: 0, letter: '+' };
for coord in coords {
if coord.x > boundary_coord.x {
boundary_coord.x = coord.x;
}
if coord.y > boundary_coord.y {
boundary_coord.y = coord.y;
}
}
boundary_coord
}
fn create_grid(boundary_coord: Coordinate) -> Grid {
let mut points = Vec::new();
for y in 0..boundary_coord.y + 1 {
for x in 0..boundary_coord.x + 1 {
points.push(GridPoint::Unfilled { x, y });
}
}
Grid { points, boundary_coord }
}
fn fill_grid<'a>(
grid: &'a mut Grid,
coords: &'a Vec<Coordinate>,
) -> Result<&'a mut Grid, Box<Error>> {
for coord in coords {
let start_index = (coord.x * (grid.boundary_coord.y + 1)) + coord.y;
fill_grid_with_coordinate(
grid,
start_index,
*coord,
)?;
}
Ok(grid)
}
fn fill_grid_with_coordinate(
grid: &mut Grid,
index: u32,
coord: Coordinate,
) -> Result<&mut Grid, Box<Error>> {
let mut visited_indices = HashSet::new();
for point in &mut grid.points {
visited_indices.insert(index);
match *point {
GridPoint::Unfilled { x, y } => {
*point = GridPoint::Filled {
x: x,
y: y,
closest_coord: coord,
closest_dist: manhattan_dist(coord.x, coord.y, x, y),
};
},
GridPoint::Tied { x, y, closest_dist } => {
let dist = manhattan_dist(coord.x, coord.y, x, y);
if dist < closest_dist {
*point = GridPoint::Filled {
x: x,
y: y,
closest_coord: coord,
closest_dist: dist,
};
}
},
GridPoint::Filled { x, y, closest_coord, closest_dist } => {
let dist = manhattan_dist(coord.x, coord.y, x, y);
if dist < closest_dist {
*point = GridPoint::Filled {
x: x,
y: y,
closest_coord: coord,
closest_dist: dist,
};
} else if dist == closest_dist && closest_coord != coord {
*point = GridPoint::Tied {
x: x,
y: y,
closest_dist: dist,
};
}
},
}
}
Ok(grid)
}
fn manhattan_dist(x1: u32, y1: u32, x2: u32, y2: u32) -> u32 {
((x2 as i32 - x1 as i32).abs() + (y2 as i32 - y1 as i32).abs()) as u32
}
fn find_largest_coord_area(
grid: Grid,
) -> u32 {
let mut point_count = HashMap::new();
let mut infinite_coords = HashSet::new();
for point in grid.points.iter() {
match point {
GridPoint::Filled { x, y, closest_coord: coord, closest_dist: _ } => {
if *x == 0 || *x == grid.boundary_coord.x ||
*y == 0 || *y == grid.boundary_coord.y {
point_count.remove(coord);
infinite_coords.insert(coord);
continue;
}
if !infinite_coords.contains(coord) {
let count = point_count.entry(coord).or_insert(0);
*count += 1;
}
},
_ => ()
}
}
*point_count.values().max().unwrap_or(&0)
}
fn region_closest_to_coordinates_size(grid: Grid, coords: Vec<Coordinate>) -> u32 {
let mut points_in_region = 0;
for point in grid.points.iter() {
match point {
GridPoint::Filled { x, y, closest_coord: _, closest_dist: _ } |
GridPoint::Tied { x, y, closest_dist: _ } |
GridPoint::Unfilled { x, y } => {
let mut sum = 0;
for coord in coords.iter() {
sum += manhattan_dist(coord.x, coord.y, *x, *y);
}
if sum < 10000 {
points_in_region += 1;
}
}
}
}
points_in_region
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/6_test.txt";
#[test]
fn read_coordinates_file() {
assert_eq!(read_coordinates(TEST_INPUT).unwrap(), vec![
Coordinate {
x: 1,
y: 1,
letter: 'a',
},
Coordinate {
x: 1,
y: 6,
letter: 'b',
},
Coordinate {
x: 8,
y: 3,
letter: 'c',
},
Coordinate {
x: 3,
y: 4,
letter: 'd',
},
Coordinate {
x: 5,
y: 5,
letter: 'e',
},
Coordinate {
x: 8,
y: 9,
letter: 'f',
},
]);
}
#[test]
fn gets_boundary_coordinate() {
assert_eq!(get_boundary_coordinate(&vec![
Coordinate {
x: 1,
y: 1,
letter: 'a',
},
Coordinate {
x: 5,
y: 5,
letter: 'b',
},
Coordinate {
x: 2,
y: 7,
letter: 'c',
}
]),
Coordinate {
x: 5,
y: 7,
letter: '+',
}
)
}
#[test]
fn creates_grid() {
let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
assert_eq!(
create_grid(boundary_coord),
Grid {
points: vec![
GridPoint::Unfilled {
x: 0,
y: 0,
},
GridPoint::Unfilled {
x: 1,
y: 0,
},
GridPoint::Unfilled {
x: 0,
y: 1,
},
GridPoint::Unfilled {
x: 1,
y: 1,
},
],
boundary_coord,
})
}
#[test]
fn calculates_manhattan_dist() {
assert_eq!(manhattan_dist(0, 0, 2, 1), 3);
assert_eq!(manhattan_dist(0, 0, 0, 0), 0);
assert_eq!(manhattan_dist(2, 1, 0, 0), 3);
}
#[test]
fn fills_grid_with_one_coord() {
let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
let mut grid = create_grid(boundary_coord);
let coord = Coordinate { x: 0, y: 0, letter: 'a' };
assert_eq!(
fill_grid(&mut grid, &vec![coord]).unwrap(),
&mut Grid {
points: vec![
GridPoint::Filled {
x: 0,
y: 0,
closest_coord: coord,
closest_dist: 0,
},
GridPoint::Filled {
x: 1,
y: 0,
closest_coord: coord,
closest_dist: 1,
},
GridPoint::Filled {
x: 0,
y: 1,
closest_coord: coord,
closest_dist: 1,
},
GridPoint::Filled {
x: 1,
y: 1,
closest_coord: coord,
closest_dist: 2,
},
],
boundary_coord
}
);
}
#[test]
fn fills_grid_with_two_coords() {
let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
let mut grid = create_grid(boundary_coord);
let coord_a = Coordinate { x: 0, y: 0, letter: 'a' };
let coord_b = Coordinate { x: 1, y: 1, letter: 'b' };
assert_eq!(
fill_grid(&mut grid, &vec![coord_a, coord_b]).unwrap(),
&mut Grid {
points: vec![
GridPoint::Filled {
x: 0,
y: 0,
closest_coord: coord_a,
closest_dist: 0,
},
GridPoint::Tied {
x: 1,
y: 0,
closest_dist: 1,
},
GridPoint::Tied {
x: 0,
y: 1,
closest_dist: 1,
},
GridPoint::Filled {
x: 1,
y: 1,
closest_coord: coord_b,
closest_dist: 0,
},
],
boundary_coord
}
);
}
#[test]
fn finds_largest_coord_area() {
let boundary_coord = Coordinate { x: 2, y: 2, letter: '+' };
let mut grid = create_grid(boundary_coord);
let coords = vec![
Coordinate { x: 0, y: 0, letter: 'a' },
Coordinate { x: 2, y: 2, letter: 'b' },
Coordinate { x: 1, y: 1, letter: 'c' },
];
fill_grid(&mut grid, &coords).unwrap();
assert_eq!(
find_largest_coord_area(grid),
1
);
}
}

487
src/day7.rs Normal file
View File

@ -0,0 +1,487 @@
extern crate regex;
use std::collections::HashMap;
use std::error::Error;
use std::fmt;
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::result;
use regex::{Captures, Regex};
type Result<T> = result::Result<T, Box<Error>>;
type Instructions = HashMap<char, Vec<char>>;
const INPUT: &str = "inputs/7.txt";
static ALPHABET: [char; 26] = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
];
pub fn solve_part1() -> Result<String> {
let mut instructions = read_instructions(INPUT)?;
Ok(get_step_sequence(&mut instructions))
}
pub fn solve_part2() -> Result<u32> {
let mut pool = WorkerPool::new(5);
let mut instructions = read_instructions(INPUT)?;
Ok(get_parallel_step_sequence_seconds(&mut instructions, &mut pool))
}
fn read_instructions(filename: &str) -> Result<Instructions> {
let mut instructions: Instructions = HashMap::new();
lazy_static! {
static ref INSTRUCTION_REGEX: Regex = Regex::new(
r"Step (?P<dependency>\w) must be finished before step (?P<step>\w) can begin."
)
.unwrap();
}
let file = File::open(filename)?;
for line in BufReader::new(file).lines() {
match INSTRUCTION_REGEX.captures(&line?) {
Some(captures) => {
let step = get_captured_field(&captures, "step")?;
let dependency: char = get_captured_field(&captures, "dependency")?;
instructions.entry(dependency).or_insert_with(Vec::new);
let dependencies = instructions.entry(step).or_insert_with(Vec::new);
dependencies.push(dependency);
}
None => {
return Err(From::from(
"Malformed instruction line, no fields could be found",
))
}
};
}
Ok(instructions)
}
fn get_captured_field(captures: &Captures, field: &str) -> Result<char> {
match captures.name(field) {
Some(capture) => match capture.as_str().chars().next() {
Some(letter) => Ok(letter),
None => Err(From::from(format!(
"Malformed instruction line, field {} not a char",
field
))),
},
None => Err(From::from(format!(
"Malformed instruction line, field {} could not be found",
field
))),
}
}
fn get_step_sequence(instructions: &mut Instructions) -> String {
let mut sequence = String::new();
loop {
let mut available: Vec<char> = instructions
.iter()
.filter(|(_, dependencies)| dependencies.is_empty())
.map(|(step, _)| *step)
.collect();
if available.is_empty() {
break;
}
available.sort();
available.reverse();
let next = available.pop().unwrap();
instructions.remove(&next);
for dependencies in instructions.values_mut() {
if let Some(index) = dependencies.iter().position(|d| *d == next) {
dependencies.remove(index);
}
}
sequence.push(next);
}
sequence
}
fn get_parallel_step_sequence_seconds(
mut instructions: &mut Instructions,
worker_pool: &mut WorkerPool,
) -> u32 {
let mut sequence = String::new();
let mut seconds = 0;
loop {
worker_pool.run_one_second(&mut instructions, &mut sequence);
let mut available: Vec<char> = instructions
.iter()
.filter(|(_, dependencies)| dependencies.is_empty())
.map(|(step, _)| *step)
.collect();
if available.is_empty() && worker_pool.all_idle() {
break;
}
available.sort();
available.reverse();
for mut worker in worker_pool.available() {
let next = match available.pop() {
None => break,
Some(next) => next,
};
instructions.remove(&next);
worker_pool.assign_worker(worker.id, next);
}
seconds += 1;
}
println!("{}", sequence);
seconds
}
fn get_seconds_for_step(step_letter: char) -> u8 {
ALPHABET.iter().position(|&c| c == step_letter).unwrap_or(0) as u8 + 61 as u8
}
#[derive(Clone, Copy, Debug, PartialEq)]
struct Worker {
id: u8,
status: Status,
}
#[derive(Clone, Copy, Debug, PartialEq)]
enum Status {
Idle,
Working { step: char, remaining: u8 },
}
#[derive(Debug, PartialEq)]
struct WorkerPool {
workers: Vec<Worker>,
}
impl WorkerPool {
fn new(count: u8) -> WorkerPool {
let mut workers = Vec::new();
for i in 0..count {
workers.push(Worker {
id: i,
status: Status::Idle,
})
}
WorkerPool { workers }
}
fn available(&self) -> Vec<Worker> {
self.workers
.iter()
.filter(|worker| match worker.status {
Status::Idle => true,
Status::Working { .. } => false,
})
.cloned()
.collect()
}
fn all_idle(&self) -> bool {
self.workers
.iter()
.all(|worker| worker.status == Status::Idle)
}
fn run_one_second(&mut self, instructions: &mut Instructions, sequence: &mut String) {
let new_workers = self
.workers
.iter()
.map(|worker| Worker {
id: worker.id,
status: match worker.status {
Status::Idle => Status::Idle,
Status::Working { step, remaining } => {
if remaining == 1 {
for dependencies in instructions.values_mut() {
if let Some(index) = dependencies.iter().position(|d| *d == step) {
dependencies.remove(index);
}
}
sequence.push(step);
Status::Idle
} else {
Status::Working {
step,
remaining: remaining - 1,
}
}
}
},
})
.collect();
self.workers = new_workers;
}
fn assign_worker(&mut self, id: u8, step: char) {
let new_workers = self
.workers
.iter()
.map(|worker| {
if worker.id == id {
Worker {
id: worker.id,
status: Status::Working {
step,
remaining: get_seconds_for_step(step),
},
}
} else {
*worker
}
})
.collect();
self.workers = new_workers;
}
}
impl fmt::Display for WorkerPool {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for worker in &self.workers {
writeln!(f, "{}", worker)?;
}
Ok(())
}
}
impl fmt::Display for Worker {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.status {
Status::Idle => write!(f, "{}: idle", self.id),
Status::Working { step, remaining } => {
write!(f, "{}: {} - {}", self.id, step, remaining)
}
}
}
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/7_test.txt";
fn test_instructions() -> Instructions {
[
('A', vec!['C']),
('F', vec!['C']),
('C', vec![]),
('B', vec!['A']),
('D', vec!['A']),
('E', vec!['B', 'D', 'F']),
]
.iter()
.cloned()
.collect()
}
#[test]
fn reads_instructions_file() {
assert_eq!(read_instructions(TEST_INPUT).unwrap(), test_instructions());
}
#[test]
fn gets_step_sequence() {
assert_eq!(get_step_sequence(&mut test_instructions()), "CABDFE");
}
#[test]
fn new_worker_pool() {
assert_eq!(
WorkerPool::new(3),
WorkerPool {
workers: vec![
Worker {
id: 0,
status: Status::Idle
},
Worker {
id: 1,
status: Status::Idle
},
Worker {
id: 2,
status: Status::Idle
},
]
}
)
}
#[test]
fn available_workers_in_pool() {
let pool = WorkerPool {
workers: vec![
Worker {
id: 0,
status: Status::Idle,
},
Worker {
id: 1,
status: Status::Working {
step: 'A',
remaining: 1,
},
},
Worker {
id: 2,
status: Status::Idle,
},
],
};
assert_eq!(
pool.available(),
vec![
Worker {
id: 0,
status: Status::Idle
},
Worker {
id: 2,
status: Status::Idle
},
]
)
}
#[test]
fn run_workers_one_second() {
let mut pool = WorkerPool {
workers: vec![
Worker {
id: 0,
status: Status::Idle,
},
Worker {
id: 1,
status: Status::Working {
step: 'A',
remaining: 2,
},
},
Worker {
id: 2,
status: Status::Idle,
},
],
};
pool.run_one_second(&mut test_instructions(), &mut String::new());
assert_eq!(
pool,
WorkerPool {
workers: vec![
Worker {
id: 0,
status: Status::Idle
},
Worker {
id: 1,
status: Status::Working {
step: 'A',
remaining: 1
}
},
Worker {
id: 2,
status: Status::Idle
},
]
}
)
}
#[test]
fn run_workers_one_second_and_complete_step() {
let mut pool = WorkerPool {
workers: vec![Worker {
id: 0,
status: Status::Working {
step: 'A',
remaining: 1,
},
}],
};
let mut instructions = [('A', vec![])].iter().cloned().collect();
let mut sequence = "Z".to_string();
pool.run_one_second(&mut instructions, &mut sequence);
assert_eq!(
pool,
WorkerPool {
workers: vec![Worker {
id: 0,
status: Status::Idle
},]
}
);
assert_eq!(instructions, [('A', vec![])].iter().cloned().collect());
assert_eq!(sequence, "ZA".to_string());
}
#[test]
fn worker_pool_all_idle() {
assert_eq!(WorkerPool::new(3).all_idle(), true);
}
#[test]
fn worker_pool_not_all_idle() {
assert_eq!(
WorkerPool {
workers: vec![
Worker {
id: 0,
status: Status::Idle
},
Worker {
id: 1,
status: Status::Working {
step: 'A',
remaining: 1
}
},
],
}
.all_idle(),
false
);
}
#[test]
fn assign_step_to_worker_in_pool() {
let mut pool = WorkerPool::new(2);
pool.assign_worker(0, 'A');
assert_eq!(
pool,
WorkerPool {
workers: vec![
Worker {
id: 0,
status: Status::Working {
step: 'A',
remaining: 61,
}
},
Worker {
id: 1,
status: Status::Idle,
}
],
}
)
}
#[test]
fn gets_seconds_for_step() {
assert_eq!(get_seconds_for_step('A'), 61);
assert_eq!(get_seconds_for_step('B'), 62);
assert_eq!(get_seconds_for_step('Z'), 86);
}
#[test]
fn gets_sequence_with_workers() {
let mut pool = WorkerPool::new(2);
let mut instructions = test_instructions();
assert_eq!(get_parallel_step_sequence_seconds(&mut instructions, &mut pool), 258);
}
}

94
src/day8.rs Normal file
View File

@ -0,0 +1,94 @@
use std::error::Error;
use std::fs;
use std::result;
type Result<T> = result::Result<T, Box<Error>>;
const INPUT: &str = "inputs/8.txt";
pub fn solve_part1() -> Result<u32> {
let license = read_license(INPUT)?;
Ok(sum_metadata(&license, 0, 0).0)
}
pub fn solve_part2() -> Result<u32> {
let license = read_license(INPUT)?;
Ok(sum_metadata_with_indices(&license, 0).0)
}
fn read_license(filename: &str) -> Result<Vec<u32>> {
let license = fs::read_to_string(filename)?;
let license = license.trim();
Ok(license.split(' ').map(|num| num.parse().unwrap()).collect())
}
fn sum_metadata(license: &[u32], mut index: usize, mut sum_acc: u32) -> (u32, usize) {
let num_children = license[index];
let num_metadata = license[index + 1];
index += 2;
if num_children != 0 {
for _ in 0..num_children {
let (child_sum_acc, child_index) = sum_metadata(license, index, sum_acc);
sum_acc = child_sum_acc;
index = child_index;
}
}
if num_metadata != 0 {
let sum: u32 = license[index..index + num_metadata as usize].iter().sum();
index += num_metadata as usize;
sum_acc += sum;
}
(sum_acc, index)
}
fn sum_metadata_with_indices(license: &[u32], mut index: usize) -> (u32, usize) {
let mut sum: u32 = 0;
let num_children = license[index];
let num_metadata = license[index + 1];
index += 2;
if num_children != 0 {
let mut child_sums: Vec<u32> = Vec::new();
for _ in 0..num_children {
let (child_sum, child_index) = sum_metadata_with_indices(license, index);
index = child_index;
child_sums.push(child_sum)
}
if num_metadata != 0 {
sum = license[index..index + num_metadata as usize]
.iter()
.map(|num| *child_sums.get(*num as usize - 1).unwrap_or(&0))
.sum();
index += num_metadata as usize;
}
} else if num_metadata != 0 {
sum = license[index..index + num_metadata as usize].iter().sum();
index += num_metadata as usize;
}
(sum, index)
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/8_test.txt";
fn test_license() -> Vec<u32> {
vec![2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2]
}
#[test]
fn reads_license_file() {
assert_eq!(read_license(TEST_INPUT).unwrap(), test_license());
}
#[test]
fn sums_license_metadata() {
assert_eq!(sum_metadata(&test_license(), 0, 0).0, 138);
}
#[test]
fn sums_license_metadata_with_indices() {
assert_eq!(sum_metadata_with_indices(&test_license(), 0).0, 66);
}
}

232
src/day9.rs Normal file
View File

@ -0,0 +1,232 @@
extern crate regex;
use std::error::Error;
use std::fmt;
use std::fs;
use std::result;
use std::str::FromStr;
use std::collections::VecDeque;
use regex::Regex;
type Result<T> = result::Result<T, Box<Error>>;
const INPUT: &str = "inputs/9.txt";
#[derive(Clone, Copy, Debug, PartialEq)]
struct GameParameters {
players: usize,
last_marble: usize,
}
impl FromStr for GameParameters {
type Err = Box<Error>;
fn from_str(s: &str) -> Result<GameParameters> {
lazy_static! {
static ref RE: Regex = Regex::new(
r"(?P<players>\d+) players; last marble is worth (?P<last_marble>\d+) points"
)
.unwrap();
}
let captures = match RE.captures(s) {
None => {
return Err(From::from(
"Malformed game parameters, no fields could be found",
));
}
Some(captures) => captures,
};
Ok(GameParameters {
players: captures["players"].parse()?,
last_marble: captures["last_marble"].parse()?,
})
}
}
#[derive(Debug, PartialEq)]
struct GameState {
turn: Option<usize>,
circle: VecDeque<usize>,
current_marble: usize,
player_scores: Vec<usize>,
}
impl GameState {
fn new(parameters: GameParameters) -> GameState {
GameState {
turn: None,
circle: VecDeque::from(vec![0]),
current_marble: 0,
player_scores: vec![0; parameters.players as usize],
}
}
fn rotate_clockwise(&mut self, steps: usize) {
for _ in 0..steps {
if let Some(marble) = self.circle.pop_back() {
self.circle.push_front(marble);
}
}
}
fn rotate_counter_clockwise(&mut self, steps: usize) {
for _ in 0..steps {
if let Some(marble) = self.circle.pop_front() {
self.circle.push_back(marble);
}
}
}
fn play_until_marble(&mut self, last_marble: usize) {
for _ in 0..last_marble {
self.turn = match self.turn {
None => Some(0),
Some(turn) => Some((turn + 1) % self.player_scores.len()),
};
if (self.current_marble + 1) % 23 == 0 {
self.place_23rd_marble();
} else {
self.place_next_marble();
}
}
}
fn place_next_marble(&mut self) {
self.current_marble += 1;
self.rotate_counter_clockwise(1);
self.circle.push_back(self.current_marble);
}
fn place_23rd_marble(&mut self) {
self.current_marble += 1;
self.player_scores[self.turn.unwrap()] += self.current_marble;
self.rotate_clockwise(7);
if let Some(marble) = self.circle.pop_back() {
self.player_scores[self.turn.unwrap()] += marble;
}
self.rotate_counter_clockwise(1);
}
fn highest_score(&mut self) -> usize {
*self.player_scores.iter().max().unwrap_or(&0)
}
}
impl fmt::Display for GameState {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.turn {
None => write!(f, "[-] ")?,
Some(turn) => write!(f, "[{}] ", turn + 1)?,
}
for (index, marble) in self.circle.iter().enumerate() {
if index == self.circle.len() - 1 {
write!(f, "({}) ", marble)?;
} else {
write!(f, "{} ", marble)?;
}
}
Ok(())
}
}
pub fn solve_part1() -> Result<usize> {
let game_params = read_game_parameters(INPUT)?;
Ok(get_highest_score_for_game(game_params))
}
pub fn solve_part2() -> Result<usize> {
let mut game_params = read_game_parameters(INPUT)?;
game_params.last_marble *= 100;
Ok(get_highest_score_for_game(game_params))
}
fn read_game_parameters(filename: &str) -> Result<GameParameters> {
let game_params = fs::read_to_string(filename)?;
Ok(game_params.parse()?)
}
fn get_highest_score_for_game(game_params: GameParameters) -> usize {
let mut game_state = GameState::new(game_params);
game_state.play_until_marble(game_params.last_marble);
game_state.highest_score()
}
#[cfg(test)]
mod tests {
use super::*;
const TEST_INPUT: &str = "inputs/9_test.txt";
const TEST_GAME_PARAMS: GameParameters = GameParameters {
players: 9,
last_marble: 25,
};
#[test]
fn reads_game_parameters_file() {
assert_eq!(read_game_parameters(TEST_INPUT).unwrap(), TEST_GAME_PARAMS);
}
#[test]
fn gets_highest_score_for_game1() {
assert_eq!(get_highest_score_for_game(TEST_GAME_PARAMS), 32);
}
#[test]
fn gets_highest_score_for_game2() {
assert_eq!(
get_highest_score_for_game(GameParameters {
players: 10,
last_marble: 1618,
}),
8317
);
}
#[test]
fn gets_highest_score_for_game3() {
assert_eq!(
get_highest_score_for_game(GameParameters {
players: 13,
last_marble: 7999,
}),
146_373
);
}
#[test]
fn gets_highest_score_for_game4() {
assert_eq!(
get_highest_score_for_game(GameParameters {
players: 17,
last_marble: 1104,
}),
2764
);
}
#[test]
fn gets_highest_score_for_game5() {
assert_eq!(
get_highest_score_for_game(GameParameters {
players: 21,
last_marble: 6111,
}),
54718
);
}
#[test]
fn gets_highest_score_for_game6() {
assert_eq!(
get_highest_score_for_game(GameParameters {
players: 30,
last_marble: 5807,
}),
37305
);
}
}

View File

@ -1,19 +1,69 @@
#![warn(clippy)]
#[macro_use]
extern crate lazy_static;
mod day1;
mod day2;
mod day3;
mod day4;
mod day5;
mod day6;
mod day7;
mod day8;
mod day9;
mod day10;
mod day11;
mod day12;
mod day13;
mod day14;
fn main() {
println!("Day 1:");
println!("{}", day1::solve_part1().unwrap());
println!("{}", day1::solve_part2().unwrap().unwrap());
println!("Day 2:");
println!("{}", day2::solve_part1().unwrap());
println!("{}", day2::solve_part2().unwrap().unwrap());
println!("Day 3:");
println!("{}", day3::solve_part1().unwrap());
println!("{}", day3::solve_part2().unwrap().unwrap());
println!("Day 4:");
println!("{}", day4::solve_part1().unwrap());
println!("{}", day4::solve_part2().unwrap());
// println!("Day 1:");
// println!("{}", day1::solve_part1().unwrap());
// println!("{}", day1::solve_part2().unwrap().unwrap());
// println!("Day 2:");
// println!("{}", day2::solve_part1().unwrap());
// println!("{}", day2::solve_part2().unwrap().unwrap());
// println!("Day 3:");
// println!("{}", day3::solve_part1().unwrap());
// println!("{}", day3::solve_part2().unwrap().unwrap());
// println!("Day 4:");
// println!("{}", day4::solve_part1().unwrap());
// println!("{}", day4::solve_part2().unwrap());
// println!("Day 5:");
// println!("{}", day5::solve_part1().unwrap());
// println!("{}", day5::solve_part2().unwrap());
// println!("Day 6:");
// println!("{}", day6::solve_part1().unwrap());
// println!("{}", day6::solve_part2().unwrap());
// println!("Day 7:");
// println!("{}", day7::solve_part1().unwrap());
// println!("{}", day7::solve_part2().unwrap());
// println!("Day 8:");
// println!("{}", day8::solve_part1().unwrap());
// println!("{}", day8::solve_part2().unwrap());
// println!("Day 9:");
// println!("{}", day9::solve_part1().unwrap());
// println!("{}", day9::solve_part2().unwrap());
// println!("Day 10:");
// let parts = day10::solve_parts().unwrap();
// println!("{}", parts.0);
// println!("{}", parts.1);
// println!("Day 11:");
// let part1 = day11::solve_part1().unwrap();
// println!("{},{}", part1.coord.x, part1.coord.y);
// let part2 = day11::solve_part2().unwrap();
// println!("{},{},{}", part2.coord.x, part2.coord.y, part2.size);
// println!("Day 12:");
// println!("{}", day12::solve_part1().unwrap());
// println!("{}", day12::solve_part2().unwrap());
// println!("Day 13");
// let part1 = day13::solve_part1().unwrap();
// println!("{},{}", part1.x, part1.y);
// println!("{},{}", part2.x, part2.y);
// let part2 = day13::solve_part2().unwrap();
println!("Day 14");
println!("{}", day14::solve_part1().unwrap());
println!("{}", day14::solve_part2().unwrap());
}