Compare commits

..

1 Commits

Author SHA1 Message Date
34eaed357d Try really sloppily adding hour * 60 to mins
Tests still pass but real result is STILL the same. Think I give up on this one.
2018-12-18 00:05:45 -05:00
34 changed files with 30 additions and 4015 deletions

461
Cargo.lock generated
View File

@ -1,12 +1,8 @@
# 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)",
]
@ -18,49 +14,6 @@ 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"
@ -76,142 +29,6 @@ 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"
@ -232,19 +49,6 @@ 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"
@ -258,95 +62,6 @@ 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"
@ -364,14 +79,6 @@ 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"
@ -380,88 +87,6 @@ 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"
@ -480,30 +105,11 @@ 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"
@ -514,16 +120,6 @@ 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"
@ -538,14 +134,6 @@ 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"
@ -553,70 +141,21 @@ 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,12 +6,4 @@ edition = "2018"
[dependencies]
chrono = "0.4"
lazy_static = "1.2.0"
regex = "1"
[dev-dependencies]
criterion = "0.2"
[[bench]]
name = "day_11"
harness = false

View File

@ -1,14 +0,0 @@
#[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);

View File

@ -1,313 +0,0 @@
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>

View File

@ -1,31 +0,0 @@
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>

View File

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

View File

@ -1 +0,0 @@
8979

View File

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

View File

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

View File

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

View File

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

View File

@ -1 +0,0 @@
236021

File diff suppressed because one or more lines are too long

View File

@ -1 +0,0 @@
dabAcCaCBAcCcaDA

View File

@ -1,50 +0,0 @@
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

View File

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

View File

@ -1,101 +0,0 @@
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.

View File

@ -1,7 +0,0 @@
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.

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

@ -1,256 +0,0 @@
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",
)
);
}
}

View File

@ -1,200 +0,0 @@
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
)
);
}
}

View File

@ -1,265 +0,0 @@
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);
}
}

View File

@ -1,374 +0,0 @@
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 });
}
}

View File

@ -1,249 +0,0 @@
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],
);
}
}

View File

@ -74,7 +74,7 @@ fn get_part1(filename: &str) -> Result<u32, Box<Error>> {
let minutes_asleep = minutes_asleep_per_guard(records);
let sleepiest_guard = minutes_asleep.iter().max_by_key(|&(_, mins)| mins.len()).unwrap();
let sleepiest_minute = mode(sleepiest_guard.1);
Ok(sleepiest_guard.0 * sleepiest_minute)
Ok(sleepiest_guard.0 * (sleepiest_minute % 60))
}
fn get_part2(filename: &str) -> Result<u32, Box<Error>> {
@ -90,7 +90,7 @@ fn get_part2(filename: &str) -> Result<u32, Box<Error>> {
.iter()
.max_by_key(|(_, mins)| mins.into_iter().filter(|min| **min == sleepiest_minute).count())
.unwrap();
Ok(sleepiest_guard.0 * sleepiest_minute)
Ok(sleepiest_guard.0 * (sleepiest_minute % 60))
}
fn mode(numbers: &[u32]) -> u32 {
@ -113,9 +113,19 @@ fn minutes_asleep_per_guard(mut records: Vec<Record>) -> HashMap<u32, Vec<u32>>
for record in records {
match record {
Record::Start { time: _, guard_id } => current_guard = guard_id,
Record::Sleep { time } => fell_asleep = time.minute(),
Record::Sleep { time } => {
let mut hour = 0;
if time.hour() == 0 {
hour = 60
}
fell_asleep = time.minute() + hour;
}
Record::Wake { time } => {
let mut slept_minutes = (fell_asleep..time.minute()).collect();
let mut hour = 0;
if time.hour() == 0 {
hour = 60
}
let mut slept_minutes = (fell_asleep..(time.minute() + hour)).collect();
match minutes_asleep.entry(current_guard) {
Entry::Vacant(e) => { e.insert(slept_minutes); },
Entry::Occupied(mut e) => { e.get_mut().append(&mut slept_minutes); },
@ -281,20 +291,20 @@ mod tests {
#[test]
fn gets_minutes_asleep_per_guard() {
let mut expected: HashMap<u32, Vec<u32>> = HashMap::new();
expected.insert(10, vec![5, 6, 7, 8, 9]);
expected.insert(10, vec![59, 60, 61, 62, 63, 64]);
assert_eq!(minutes_asleep_per_guard(vec![
Record::Sleep {
time: NaiveDateTime::parse_from_str(
"1518-11-01 00:05", "%Y-%m-%d %H:%M").unwrap(),
"1518-11-01 23:59", "%Y-%m-%d %H:%M").unwrap(),
},
Record::Start {
time: NaiveDateTime::parse_from_str(
"1518-11-01 00:00", "%Y-%m-%d %H:%M").unwrap(),
"1518-11-01 23:00", "%Y-%m-%d %H:%M").unwrap(),
guard_id: 10,
},
Record::Wake {
time: NaiveDateTime::parse_from_str(
"1518-11-01 00:10", "%Y-%m-%d %H:%M").unwrap(),
"1518-11-02 00:05", "%Y-%m-%d %H:%M").unwrap(),
},
]), expected);
}

View File

@ -1,92 +0,0 @@
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);
}
}

View File

@ -1,490 +0,0 @@
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
);
}
}

View File

@ -1,487 +0,0 @@
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);
}
}

View File

@ -1,94 +0,0 @@
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);
}
}

View File

@ -1,232 +0,0 @@
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,69 +1,19 @@
#![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 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());
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());
}