Compare commits
28 Commits
day4-hours
...
master
Author | SHA1 | Date | |
---|---|---|---|
e85f9131be | |||
3872264523 | |||
4b2a232f11 | |||
e5f615cf48 | |||
0d84ff39b8 | |||
fa882266a6 | |||
55c949f796 | |||
6190b9742c | |||
f615a47bb6 | |||
f5aa9aad9b | |||
21a0815fd7 | |||
d0fe734212 | |||
dc5e1c6427 | |||
af6709d2a8 | |||
f155273a5b | |||
e82f8b3820 | |||
33c926887d | |||
595605daaf | |||
f00091cbf0 | |||
0f2e4bdf47 | |||
f4392d62c0 | |||
e3ab089ce3 | |||
bd6c348581 | |||
41eaeb8192 | |||
35af0175f0 | |||
7307f6a76e | |||
57d8189964 | |||
20ab475034 |
461
Cargo.lock
generated
461
Cargo.lock
generated
@ -1,8 +1,12 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "advent-of-code-2018"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
@ -14,6 +18,49 @@ dependencies = [
|
||||
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.6"
|
||||
@ -29,6 +76,142 @@ dependencies = [
|
||||
"time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-queue"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.2.0"
|
||||
@ -49,6 +232,19 @@ dependencies = [
|
||||
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.39"
|
||||
@ -62,6 +258,95 @@ name = "num-traits"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "0.4.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "0.6.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "rand_os"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_xoshiro"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.1.44"
|
||||
@ -79,6 +364,14 @@ dependencies = [
|
||||
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.4"
|
||||
@ -87,6 +380,88 @@ dependencies = [
|
||||
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "0.3.6"
|
||||
@ -105,11 +480,30 @@ dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-util"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "utf8-ranges"
|
||||
version = "1.0.2"
|
||||
@ -120,6 +514,16 @@ name = "version_check"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.6"
|
||||
@ -134,6 +538,14 @@ name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
@ -141,21 +553,70 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[metadata]
|
||||
"checksum aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1e9a933f4e58658d7b12defcf96dc5c720f20832deebe3e0a19efd3b6aaeeb9e"
|
||||
"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
|
||||
"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90"
|
||||
"checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd"
|
||||
"checksum bstr 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e0a692f1c740e7e821ca71a22cf99b9b2322dfa94d10f71443befb1797b3946a"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
|
||||
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||
"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
|
||||
"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
||||
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
|
||||
"checksum criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "0363053954f3e679645fc443321ca128b7b950a6fe288cf5f9335cc22ee58394"
|
||||
"checksum criterion-plot 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76f9212ddf2f4a9eb2d401635190600656a1f88a932ef53d06e7fa4c7e02fb8e"
|
||||
"checksum crossbeam-deque 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "05e44b8cf3e1a625844d1750e1f7820da46044ff6d28f4d43e455ba3e5bb2c13"
|
||||
"checksum crossbeam-epoch 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fedcd6772e37f3da2a9af9bf12ebe046c0dfe657992377b4df982a2b54cd37a9"
|
||||
"checksum crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7c979cd6cfe72335896575c6b5688da489e420d36a27a0b9eb0c73db574b4a4b"
|
||||
"checksum crossbeam-utils 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "04973fa96e96579258a5091af6003abde64af786b860f18622b82e026cca60e6"
|
||||
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
|
||||
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
|
||||
"checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358"
|
||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||
"checksum libc 0.2.45 (registry+https://github.com/rust-lang/crates.io-index)" = "2d2857ec59fadc0773853c664d2d18e7198e83883e7060b63c924cb077bd5c74"
|
||||
"checksum memchr 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "db4c41318937f6e76648f42826b1d9ade5c09cafb5aef7e351240a70f39206e9"
|
||||
"checksum memoffset 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ce6075db033bbbb7ee5a0bbd3a3186bbae616f57fb001c485c7ff77955f8177f"
|
||||
"checksum nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2f9667ddcc6cc8a43afc9b7917599d7216aa09c463919ea32c59ed6cac8bc945"
|
||||
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
|
||||
"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
|
||||
"checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
|
||||
"checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
"checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0"
|
||||
"checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071"
|
||||
"checksum rand_xoshiro 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "03b418169fb9c46533f326efd6eed2576699c44ca92d3052a066214a8d828929"
|
||||
"checksum rayon 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a4b0186e22767d5b9738a05eab7c6ac90b15db17e5b5f9bd87976dd7d89a10a4"
|
||||
"checksum rayon-core 1.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbe0df8435ac0c397d467b6cad6d25543d06e8a019ef3f6af3c384597515bd2"
|
||||
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
"checksum redox_syscall 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "a84bcd297b87a545980a2d25a0beb72a1f490c31f0a9fde52fca35bfbb1ceb70"
|
||||
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
||||
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
|
||||
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
|
||||
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
|
||||
"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997"
|
||||
"checksum same-file 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "585e8ddcedc187886a30fa705c47985c3fa88d06624095856b36ca0b82ff4421"
|
||||
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
|
||||
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
"checksum serde 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "7fe5626ac617da2f2d9c48af5515a21d5a480dbd151e01bb1c355e26a3e68113"
|
||||
"checksum serde_derive 1.0.98 (registry+https://github.com/rust-lang/crates.io-index)" = "01e69e1b8a631f245467ee275b8c757b818653c6d704cdbcaeb56b56767b529c"
|
||||
"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704"
|
||||
"checksum syn 0.15.42 (registry+https://github.com/rust-lang/crates.io-index)" = "eadc09306ca51a40555dd6fc2b415538e9e18bc9f870e47b1a524a79fe2dcf5e"
|
||||
"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||
"checksum time 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)" = "847da467bf0db05882a9e2375934a8a55cffdc9db0d128af1518200260ba1f6c"
|
||||
"checksum tinytemplate 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4574b75faccaacddb9b284faecdf0b544b80b6b294f3d062d325c5726a209c20"
|
||||
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||
"checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "796f7e48bef87609f7ade7e06495a87d5cd06c7866e6a5cbfceffc558a243737"
|
||||
"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
|
||||
"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-util 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7168bab6e1daee33b4557efd0e95d5ca70a03706d39fa5f3fe7a236f584b03c9"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
@ -6,4 +6,12 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
chrono = "0.4"
|
||||
lazy_static = "1.2.0"
|
||||
regex = "1"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.2"
|
||||
|
||||
[[bench]]
|
||||
name = "day_11"
|
||||
harness = false
|
||||
|
14
benches/day_11.rs
Normal file
14
benches/day_11.rs
Normal file
@ -0,0 +1,14 @@
|
||||
#[macro_use]
|
||||
extern crate criterion;
|
||||
|
||||
use criterion::Criterion;
|
||||
|
||||
#[path = "../src/day11.rs"]
|
||||
mod day11;
|
||||
|
||||
fn criterion_benchmark(c: &mut Criterion) {
|
||||
c.bench_function("day 11", |b| b.iter(|| day11::solve_part2()));
|
||||
}
|
||||
|
||||
criterion_group!(benches, criterion_benchmark);
|
||||
criterion_main!(benches);
|
313
inputs/10.txt
Normal file
313
inputs/10.txt
Normal file
@ -0,0 +1,313 @@
|
||||
position=<-52775, 31912> velocity=< 5, -3>
|
||||
position=<-52816, 10731> velocity=< 5, -1>
|
||||
position=< 42573, -31652> velocity=<-4, 3>
|
||||
position=<-31611, 31918> velocity=< 3, -3>
|
||||
position=< 42585, -31656> velocity=<-4, 3>
|
||||
position=<-10428, 53102> velocity=< 1, -5>
|
||||
position=< 31958, -10460> velocity=<-3, 1>
|
||||
position=<-21020, 10723> velocity=< 2, -1>
|
||||
position=<-52770, 10731> velocity=< 5, -1>
|
||||
position=< 21400, 10728> velocity=<-2, -1>
|
||||
position=<-10427, -42253> velocity=< 1, 4>
|
||||
position=< 21343, 42515> velocity=<-2, -4>
|
||||
position=<-10417, -52846> velocity=< 1, 5>
|
||||
position=< 42558, -42251> velocity=<-4, 4>
|
||||
position=<-21008, 53106> velocity=< 2, -5>
|
||||
position=<-10443, 31912> velocity=< 1, -3>
|
||||
position=<-31584, 31919> velocity=< 3, -3>
|
||||
position=<-31604, 10726> velocity=< 3, -1>
|
||||
position=<-52786, -21055> velocity=< 5, 2>
|
||||
position=<-10394, 31918> velocity=< 1, -3>
|
||||
position=<-52786, 53109> velocity=< 5, -5>
|
||||
position=<-52770, 10722> velocity=< 5, -1>
|
||||
position=<-21007, -10464> velocity=< 2, 1>
|
||||
position=< 21392, -31657> velocity=<-2, 3>
|
||||
position=< 53180, 31913> velocity=<-5, -3>
|
||||
position=<-10393, 21319> velocity=< 1, -2>
|
||||
position=<-10430, 10724> velocity=< 1, -1>
|
||||
position=<-20985, -42245> velocity=< 2, 4>
|
||||
position=<-31610, -10468> velocity=< 3, 1>
|
||||
position=<-20989, -42247> velocity=< 2, 4>
|
||||
position=<-21006, 21317> velocity=< 2, -2>
|
||||
position=< 10752, -31651> velocity=<-1, 3>
|
||||
position=< 42577, 31912> velocity=<-4, -3>
|
||||
position=<-42196, -21059> velocity=< 4, 2>
|
||||
position=< 10744, -10460> velocity=<-1, 1>
|
||||
position=<-10443, -31658> velocity=< 1, 3>
|
||||
position=< 53185, 31912> velocity=<-5, -3>
|
||||
position=<-52790, -21063> velocity=< 5, 2>
|
||||
position=< 31990, -21060> velocity=<-3, 2>
|
||||
position=< 10776, -52845> velocity=<-1, 5>
|
||||
position=<-31636, 21324> velocity=< 3, -2>
|
||||
position=<-10395, -42249> velocity=< 1, 4>
|
||||
position=<-31591, 31912> velocity=< 3, -3>
|
||||
position=<-10430, -21063> velocity=< 1, 2>
|
||||
position=<-10422, 31912> velocity=< 1, -3>
|
||||
position=< 10800, -42250> velocity=<-1, 4>
|
||||
position=<-42199, -42248> velocity=< 4, 4>
|
||||
position=< 31950, 42515> velocity=<-3, -4>
|
||||
position=< 31982, 53104> velocity=<-3, -5>
|
||||
position=< 31982, -52845> velocity=<-3, 5>
|
||||
position=< 10752, 42510> velocity=<-1, -4>
|
||||
position=< 31958, -21054> velocity=<-3, 2>
|
||||
position=< 10752, -10467> velocity=<-1, 1>
|
||||
position=< 31977, -31649> velocity=<-3, 3>
|
||||
position=<-10438, -10460> velocity=< 1, 1>
|
||||
position=<-20983, 10726> velocity=< 2, -1>
|
||||
position=<-10385, 53109> velocity=< 1, -5>
|
||||
position=< 42590, -52839> velocity=<-4, 5>
|
||||
position=<-42180, 21317> velocity=< 4, -2>
|
||||
position=<-31592, -21063> velocity=< 3, 2>
|
||||
position=<-52782, -10466> velocity=< 5, 1>
|
||||
position=<-31604, -42251> velocity=< 3, 4>
|
||||
position=<-42198, -52848> velocity=< 4, 5>
|
||||
position=<-31632, 42513> velocity=< 3, -4>
|
||||
position=<-31601, -10468> velocity=< 3, 1>
|
||||
position=<-31632, 21320> velocity=< 3, -2>
|
||||
position=<-52773, 10725> velocity=< 5, -1>
|
||||
position=<-42205, -10459> velocity=< 4, 1>
|
||||
position=< 42533, 21322> velocity=<-4, -2>
|
||||
position=< 53181, 53106> velocity=<-5, -5>
|
||||
position=< 42533, 53102> velocity=<-4, -5>
|
||||
position=< 53185, -42248> velocity=<-5, 4>
|
||||
position=< 10797, 10730> velocity=<-1, -1>
|
||||
position=< 53137, 21326> velocity=<-5, -2>
|
||||
position=< 10776, 42508> velocity=<-1, -4>
|
||||
position=< 21387, -42249> velocity=<-2, 4>
|
||||
position=< 10805, -42250> velocity=<-1, 4>
|
||||
position=<-20990, 42512> velocity=< 2, -4>
|
||||
position=<-52801, 53102> velocity=< 5, -5>
|
||||
position=< 42554, 53111> velocity=<-4, -5>
|
||||
position=<-52809, 53106> velocity=< 5, -5>
|
||||
position=<-31588, -42249> velocity=< 3, 4>
|
||||
position=<-31595, 31921> velocity=< 3, -3>
|
||||
position=< 42553, -10468> velocity=<-4, 1>
|
||||
position=<-52818, -42249> velocity=< 5, 4>
|
||||
position=<-20999, -42244> velocity=< 2, 4>
|
||||
position=< 53127, 10731> velocity=<-5, -1>
|
||||
position=< 21347, -52842> velocity=<-2, 5>
|
||||
position=<-52794, 21323> velocity=< 5, -2>
|
||||
position=<-42214, 31912> velocity=< 4, -3>
|
||||
position=< 42558, -52847> velocity=<-4, 5>
|
||||
position=<-10414, -42244> velocity=< 1, 4>
|
||||
position=<-21025, 10728> velocity=< 2, -1>
|
||||
position=<-10398, 10727> velocity=< 1, -1>
|
||||
position=<-52794, -21056> velocity=< 5, 2>
|
||||
position=< 10800, 53103> velocity=<-1, -5>
|
||||
position=< 42556, -21059> velocity=<-4, 2>
|
||||
position=<-31610, 42516> velocity=< 3, -4>
|
||||
position=< 10780, 42507> velocity=<-1, -4>
|
||||
position=< 31987, -52840> velocity=<-3, 5>
|
||||
position=< 31952, 53102> velocity=<-3, -5>
|
||||
position=<-21033, -42250> velocity=< 2, 4>
|
||||
position=<-52773, -10466> velocity=< 5, 1>
|
||||
position=<-42199, 42511> velocity=< 4, -4>
|
||||
position=< 21355, -10467> velocity=<-2, 1>
|
||||
position=<-21029, -10459> velocity=< 2, 1>
|
||||
position=<-52775, 10727> velocity=< 5, -1>
|
||||
position=<-21009, 31915> velocity=< 2, -3>
|
||||
position=<-10389, -10464> velocity=< 1, 1>
|
||||
position=< 53156, 31921> velocity=<-5, -3>
|
||||
position=< 31995, 31920> velocity=<-3, -3>
|
||||
position=<-31620, -52839> velocity=< 3, 5>
|
||||
position=< 53158, -31654> velocity=<-5, 3>
|
||||
position=<-42205, 42512> velocity=< 4, -4>
|
||||
position=< 31950, 10725> velocity=<-3, -1>
|
||||
position=<-10430, -42250> velocity=< 1, 4>
|
||||
position=<-42206, 53102> velocity=< 4, -5>
|
||||
position=< 42573, 10730> velocity=<-4, -1>
|
||||
position=<-42178, 53111> velocity=< 4, -5>
|
||||
position=<-10385, 53106> velocity=< 1, -5>
|
||||
position=< 31955, 21320> velocity=<-3, -2>
|
||||
position=< 42558, 10731> velocity=<-4, -1>
|
||||
position=< 42585, -31656> velocity=<-4, 3>
|
||||
position=< 42558, -21063> velocity=<-4, 2>
|
||||
position=<-31612, -10461> velocity=< 3, 1>
|
||||
position=<-10398, 31921> velocity=< 1, -3>
|
||||
position=<-52765, 10724> velocity=< 5, -1>
|
||||
position=< 42553, 53109> velocity=<-4, -5>
|
||||
position=<-52810, -21061> velocity=< 5, 2>
|
||||
position=<-42181, -31654> velocity=< 4, 3>
|
||||
position=<-42175, -21058> velocity=< 4, 2>
|
||||
position=<-10427, -10468> velocity=< 1, 1>
|
||||
position=< 42529, -21055> velocity=<-4, 2>
|
||||
position=< 10752, 53109> velocity=<-1, -5>
|
||||
position=< 42561, 53107> velocity=<-4, -5>
|
||||
position=< 31958, -31649> velocity=<-3, 3>
|
||||
position=< 31968, -21063> velocity=<-3, 2>
|
||||
position=<-10402, -52840> velocity=< 1, 5>
|
||||
position=< 42565, -52848> velocity=<-4, 5>
|
||||
position=< 53184, 31916> velocity=<-5, -3>
|
||||
position=<-52797, 53111> velocity=< 5, -5>
|
||||
position=< 42558, -52847> velocity=<-4, 5>
|
||||
position=<-10394, 53106> velocity=< 1, -5>
|
||||
position=<-42199, -42252> velocity=< 4, 4>
|
||||
position=<-31592, -42250> velocity=< 3, 4>
|
||||
position=< 10765, 53104> velocity=<-1, -5>
|
||||
position=<-52794, 42509> velocity=< 5, -4>
|
||||
position=< 21371, 53107> velocity=<-2, -5>
|
||||
position=<-31616, -21063> velocity=< 3, 2>
|
||||
position=<-42170, 31913> velocity=< 4, -3>
|
||||
position=<-42199, 42513> velocity=< 4, -4>
|
||||
position=< 10797, 53104> velocity=<-1, -5>
|
||||
position=<-42175, 42511> velocity=< 4, -4>
|
||||
position=<-20993, 21326> velocity=< 2, -2>
|
||||
position=<-31588, 42513> velocity=< 3, -4>
|
||||
position=<-20989, 31919> velocity=< 2, -3>
|
||||
position=< 53140, 42509> velocity=<-5, -4>
|
||||
position=< 53172, -10464> velocity=<-5, 1>
|
||||
position=< 53128, 10724> velocity=<-5, -1>
|
||||
position=<-31592, 42512> velocity=< 3, -4>
|
||||
position=< 21347, 10724> velocity=<-2, -1>
|
||||
position=<-52818, -21058> velocity=< 5, 2>
|
||||
position=< 10794, 31912> velocity=<-1, -3>
|
||||
position=<-10414, -52845> velocity=< 1, 5>
|
||||
position=<-42219, 21326> velocity=< 4, -2>
|
||||
position=< 31952, 31912> velocity=<-3, -3>
|
||||
position=<-10413, 42507> velocity=< 1, -4>
|
||||
position=< 21387, -31657> velocity=<-2, 3>
|
||||
position=< 42557, -21054> velocity=<-4, 2>
|
||||
position=<-20997, 53104> velocity=< 2, -5>
|
||||
position=<-21014, -10468> velocity=< 2, 1>
|
||||
position=<-10442, 10723> velocity=< 1, -1>
|
||||
position=< 42572, -21054> velocity=<-4, 2>
|
||||
position=<-20991, -42249> velocity=< 2, 4>
|
||||
position=<-10435, -31649> velocity=< 1, 3>
|
||||
position=< 10770, -10463> velocity=<-1, 1>
|
||||
position=< 31958, 10730> velocity=<-3, -1>
|
||||
position=<-21015, -42244> velocity=< 2, 4>
|
||||
position=<-21039, 53111> velocity=< 2, -5>
|
||||
position=<-31592, 31919> velocity=< 3, -3>
|
||||
position=<-21022, -42249> velocity=< 2, 4>
|
||||
position=< 31966, 10729> velocity=<-3, -1>
|
||||
position=< 53167, -10468> velocity=<-5, 1>
|
||||
position=<-42183, 21324> velocity=< 4, -2>
|
||||
position=< 31955, 31915> velocity=<-3, -3>
|
||||
position=< 42572, 53111> velocity=<-4, -5>
|
||||
position=<-42170, 53102> velocity=< 4, -5>
|
||||
position=< 42590, -10466> velocity=<-4, 1>
|
||||
position=<-31609, 53106> velocity=< 3, -5>
|
||||
position=< 42533, -10467> velocity=<-4, 1>
|
||||
position=<-42215, 10731> velocity=< 4, -1>
|
||||
position=<-42170, 10722> velocity=< 4, -1>
|
||||
position=<-21004, 53102> velocity=< 2, -5>
|
||||
position=< 53167, 10722> velocity=<-5, -1>
|
||||
position=< 53132, -52844> velocity=<-5, 5>
|
||||
position=< 42529, -21055> velocity=<-4, 2>
|
||||
position=< 31960, 21322> velocity=<-3, -2>
|
||||
position=<-42175, 42507> velocity=< 4, -4>
|
||||
position=< 21342, 21326> velocity=<-2, -2>
|
||||
position=<-52774, 31916> velocity=< 5, -3>
|
||||
position=< 21355, -42248> velocity=<-2, 4>
|
||||
position=< 53140, 10727> velocity=<-5, -1>
|
||||
position=< 21368, 21317> velocity=<-2, -2>
|
||||
position=< 42585, -42246> velocity=<-4, 4>
|
||||
position=< 10805, -10459> velocity=<-1, 1>
|
||||
position=< 21383, -52845> velocity=<-2, 5>
|
||||
position=< 53133, -31649> velocity=<-5, 3>
|
||||
position=<-31580, -31658> velocity=< 3, 3>
|
||||
position=< 10792, -10463> velocity=<-1, 1>
|
||||
position=< 10768, -52840> velocity=<-1, 5>
|
||||
position=<-10420, -52848> velocity=< 1, 5>
|
||||
position=<-42203, 31912> velocity=< 4, -3>
|
||||
position=< 31974, -42245> velocity=<-3, 4>
|
||||
position=<-52778, 42515> velocity=< 5, -4>
|
||||
position=<-42170, 53106> velocity=< 4, -5>
|
||||
position=<-10398, -10462> velocity=< 1, 1>
|
||||
position=<-52799, -52848> velocity=< 5, 5>
|
||||
position=<-42175, 42515> velocity=< 4, -4>
|
||||
position=< 53142, -21059> velocity=<-5, 2>
|
||||
position=< 10772, 42510> velocity=<-1, -4>
|
||||
position=< 53137, 42516> velocity=<-5, -4>
|
||||
position=<-42187, -21062> velocity=< 4, 2>
|
||||
position=< 10805, 31914> velocity=<-1, -3>
|
||||
position=< 21348, 10731> velocity=<-2, -1>
|
||||
position=<-21023, 10726> velocity=< 2, -1>
|
||||
position=< 31950, -31655> velocity=<-3, 3>
|
||||
position=<-10386, -31654> velocity=< 1, 3>
|
||||
position=<-21025, -21062> velocity=< 2, 2>
|
||||
position=< 31966, 21318> velocity=<-3, -2>
|
||||
position=<-52776, 31912> velocity=< 5, -3>
|
||||
position=< 42569, -52841> velocity=<-4, 5>
|
||||
position=<-31592, 10724> velocity=< 3, -1>
|
||||
position=<-10429, 21317> velocity=< 1, -2>
|
||||
position=<-31584, 10729> velocity=< 3, -1>
|
||||
position=<-52818, 21320> velocity=< 5, -2>
|
||||
position=<-21016, -10468> velocity=< 2, 1>
|
||||
position=<-52791, 42507> velocity=< 5, -4>
|
||||
position=<-42199, 42515> velocity=< 4, -4>
|
||||
position=< 31982, -10467> velocity=<-3, 1>
|
||||
position=<-10442, -52848> velocity=< 1, 5>
|
||||
position=< 42565, 10726> velocity=<-4, -1>
|
||||
position=<-42187, -10468> velocity=< 4, 1>
|
||||
position=< 42561, -52841> velocity=<-4, 5>
|
||||
position=< 42549, 31916> velocity=<-4, -3>
|
||||
position=< 53180, -52842> velocity=<-5, 5>
|
||||
position=< 21347, 21326> velocity=<-2, -2>
|
||||
position=< 53151, 31921> velocity=<-5, -3>
|
||||
position=< 31938, 10726> velocity=<-3, -1>
|
||||
position=< 31942, -52848> velocity=<-3, 5>
|
||||
position=< 10788, -10464> velocity=<-1, 1>
|
||||
position=< 42590, 53103> velocity=<-4, -5>
|
||||
position=< 53180, -21055> velocity=<-5, 2>
|
||||
position=< 31935, 10731> velocity=<-3, -1>
|
||||
position=<-52802, -31651> velocity=< 5, 3>
|
||||
position=<-52776, -42249> velocity=< 5, 4>
|
||||
position=< 53185, -21062> velocity=<-5, 2>
|
||||
position=< 53159, 42511> velocity=<-5, -4>
|
||||
position=< 10772, 10722> velocity=<-1, -1>
|
||||
position=<-31593, 31912> velocity=< 3, -3>
|
||||
position=< 10795, 21322> velocity=<-1, -2>
|
||||
position=<-10436, -10459> velocity=< 1, 1>
|
||||
position=< 21388, -42249> velocity=<-2, 4>
|
||||
position=<-10405, 31921> velocity=< 1, -3>
|
||||
position=<-52801, 42513> velocity=< 5, -4>
|
||||
position=< 42573, 31915> velocity=<-4, -3>
|
||||
position=< 21355, 53109> velocity=<-2, -5>
|
||||
position=<-21025, 21323> velocity=< 2, -2>
|
||||
position=< 53140, -10467> velocity=<-5, 1>
|
||||
position=<-52767, 10726> velocity=< 5, -1>
|
||||
position=< 21347, 31912> velocity=<-2, -3>
|
||||
position=<-42183, 53107> velocity=< 4, -5>
|
||||
position=< 31942, -10460> velocity=<-3, 1>
|
||||
position=<-10401, 53102> velocity=< 1, -5>
|
||||
position=< 21400, -10459> velocity=<-2, 1>
|
||||
position=< 42579, 10722> velocity=<-4, -1>
|
||||
position=< 31936, 42516> velocity=<-3, -4>
|
||||
position=< 53128, -21056> velocity=<-5, 2>
|
||||
position=<-20997, -42253> velocity=< 2, 4>
|
||||
position=<-52777, -31658> velocity=< 5, 3>
|
||||
position=<-10430, 21325> velocity=< 1, -2>
|
||||
position=< 42545, -10464> velocity=<-4, 1>
|
||||
position=<-21017, -52839> velocity=< 2, 5>
|
||||
position=<-31584, 31912> velocity=< 3, -3>
|
||||
position=< 53168, -21056> velocity=<-5, 2>
|
||||
position=<-42199, -10459> velocity=< 4, 1>
|
||||
position=< 10803, 53106> velocity=<-1, -5>
|
||||
position=< 21371, 21317> velocity=<-2, -2>
|
||||
position=<-21040, -42244> velocity=< 2, 4>
|
||||
position=<-31577, 42511> velocity=< 3, -4>
|
||||
position=< 42573, 21322> velocity=<-4, -2>
|
||||
position=< 31990, 10728> velocity=<-3, -1>
|
||||
position=< 53175, -52844> velocity=<-5, 5>
|
||||
position=< 42561, 21323> velocity=<-4, -2>
|
||||
position=<-42223, -52840> velocity=< 4, 5>
|
||||
position=< 53152, -10468> velocity=<-5, 1>
|
||||
position=<-52785, 53111> velocity=< 5, -5>
|
||||
position=<-31632, -31656> velocity=< 3, 3>
|
||||
position=<-21009, -10466> velocity=< 2, 1>
|
||||
position=<-21025, -31651> velocity=< 2, 3>
|
||||
position=< 10795, 53106> velocity=<-1, -5>
|
||||
position=< 31978, -52844> velocity=<-3, 5>
|
||||
position=<-52774, -21059> velocity=< 5, 2>
|
||||
position=<-42211, -42253> velocity=< 4, 4>
|
||||
position=<-31580, 53107> velocity=< 3, -5>
|
||||
position=< 53172, 53102> velocity=<-5, -5>
|
||||
position=<-52773, 42508> velocity=< 5, -4>
|
||||
position=<-10398, -21054> velocity=< 1, 2>
|
||||
position=<-31607, -10466> velocity=< 3, 1>
|
||||
position=<-52801, 53108> velocity=< 5, -5>
|
||||
position=<-52813, -21054> velocity=< 5, 2>
|
||||
position=<-31600, 42511> velocity=< 3, -4>
|
||||
position=<-31631, 21317> velocity=< 3, -2>
|
||||
position=< 42532, -31649> velocity=<-4, 3>
|
31
inputs/10_test.txt
Normal file
31
inputs/10_test.txt
Normal file
@ -0,0 +1,31 @@
|
||||
position=< 9, 1> velocity=< 0, 2>
|
||||
position=< 7, 0> velocity=<-1, 0>
|
||||
position=< 3, -2> velocity=<-1, 1>
|
||||
position=< 6, 10> velocity=<-2, -1>
|
||||
position=< 2, -4> velocity=< 2, 2>
|
||||
position=<-6, 10> velocity=< 2, -2>
|
||||
position=< 1, 8> velocity=< 1, -1>
|
||||
position=< 1, 7> velocity=< 1, 0>
|
||||
position=<-3, 11> velocity=< 1, -2>
|
||||
position=< 7, 6> velocity=<-1, -1>
|
||||
position=<-2, 3> velocity=< 1, 0>
|
||||
position=<-4, 3> velocity=< 2, 0>
|
||||
position=<10, -3> velocity=<-1, 1>
|
||||
position=< 5, 11> velocity=< 1, -2>
|
||||
position=< 4, 7> velocity=< 0, -1>
|
||||
position=< 8, -2> velocity=< 0, 1>
|
||||
position=<15, 0> velocity=<-2, 0>
|
||||
position=< 1, 6> velocity=< 1, 0>
|
||||
position=< 8, 9> velocity=< 0, -1>
|
||||
position=< 3, 3> velocity=<-1, 1>
|
||||
position=< 0, 5> velocity=< 0, -1>
|
||||
position=<-2, 2> velocity=< 2, 0>
|
||||
position=< 5, -2> velocity=< 1, 2>
|
||||
position=< 1, 4> velocity=< 2, 1>
|
||||
position=<-2, 7> velocity=< 2, -2>
|
||||
position=< 3, 6> velocity=<-1, -1>
|
||||
position=< 5, 0> velocity=< 1, 0>
|
||||
position=<-6, 0> velocity=< 2, 0>
|
||||
position=< 5, 9> velocity=< 1, -2>
|
||||
position=<14, 7> velocity=<-2, 0>
|
||||
position=<-3, 6> velocity=< 2, -1>
|
1
inputs/10_test_one.txt
Normal file
1
inputs/10_test_one.txt
Normal file
@ -0,0 +1 @@
|
||||
position=< 0, 1> velocity=< 0, 0>
|
1
inputs/11.txt
Normal file
1
inputs/11.txt
Normal file
@ -0,0 +1 @@
|
||||
8979
|
34
inputs/12.txt
Normal file
34
inputs/12.txt
Normal file
@ -0,0 +1,34 @@
|
||||
initial state: ##.##.##..#..#.#.#.#...#...#####.###...#####.##..#####.#..#.##..#..#.#...#...##.##...#.##......####.
|
||||
|
||||
##.#. => #
|
||||
#.#.. => #
|
||||
##... => .
|
||||
...## => #
|
||||
###.# => #
|
||||
#.##. => #
|
||||
#.### => #
|
||||
####. => #
|
||||
.#..# => #
|
||||
...#. => .
|
||||
#..#. => .
|
||||
#.#.# => .
|
||||
.##.# => .
|
||||
..#.. => .
|
||||
.#.## => #
|
||||
..##. => .
|
||||
.#.#. => #
|
||||
#..## => #
|
||||
..#.# => #
|
||||
#.... => .
|
||||
..### => .
|
||||
#...# => .
|
||||
##### => #
|
||||
###.. => #
|
||||
....# => .
|
||||
##.## => #
|
||||
.#### => .
|
||||
..... => .
|
||||
##..# => #
|
||||
.##.. => .
|
||||
.###. => .
|
||||
.#... => #
|
16
inputs/12_test.txt
Normal file
16
inputs/12_test.txt
Normal file
@ -0,0 +1,16 @@
|
||||
initial state: #..#.#..##......###...###
|
||||
|
||||
...## => #
|
||||
..#.. => #
|
||||
.#... => #
|
||||
.#.#. => #
|
||||
.#.## => #
|
||||
.##.. => #
|
||||
.#### => #
|
||||
#.#.# => #
|
||||
#.### => #
|
||||
##.#. => #
|
||||
##.## => #
|
||||
###.. => #
|
||||
###.# => #
|
||||
####. => #
|
150
inputs/13.txt
Normal file
150
inputs/13.txt
Normal file
@ -0,0 +1,150 @@
|
||||
/-----------------------------\ /-------------------------------\
|
||||
/---------+-----------------------------+---------------------------------------------+--------------------\ |
|
||||
| | /----------------+------------------------------------------\ | | |
|
||||
| | | | /---------------+--+--------------\ | |
|
||||
| | | /-------------+-------------\ | | | | | |
|
||||
| | | | | /->-+------------+---------------+--+------------\ | | |
|
||||
/---+---------+----------\ | | | | | /--------+---------------+--+----------\ | | | /+-------------------\
|
||||
| | | | | | /+---------+---+---+------<-+---------------+--+---------\| | | /--+---------++---------------\ |
|
||||
| | /----+--------<-+-+--+------------++---------+---+---+--------+---------------+--+---------++-+-+--+--+-\ || | |
|
||||
| | | | /--------+-+--+---------\ || | | | | /---------+--+-\ /++-+-+--+-\| | || | |
|
||||
/--+---+----+----+-+--------+-+--+---------+--++---------+---+---+--------+-----+---------+--+-+-----\||| | | | || | || | |
|
||||
| | | | | | /---+-+--+---------+-\|| /--+---+---+--------+-----+---------+--+-+-----++++-+\| | || | || | |
|
||||
| | | /+----+-+----+--\|/+--+---------+-+++------+\ | | | | | | | | |||| ||| | || | || | |
|
||||
| | | || | | | |||| | | ||| || | | | | | /--+--+-+-----++++-+++--+-++-+------\|| | |
|
||||
| | | || | | | |||| | /----+-+++------++-+---+---+--------+-----+------+--+--+-+-----++++-+++--+-++-+------+++-----------\ | |
|
||||
| | | || | | /+--++++--+----+----+-+++-\ || | | | | | | | | | |||| ||| | || | ||| | | |
|
||||
| | | || \-+---++--++++--+----+----+-++/ | || | | | | | | | | | |||| ||| | || | ||| | | |
|
||||
| | | || | || |||| | | | || | /--++-+---+---+--------+-----+------+\ | | | |||| ||| | || | ||| | | |
|
||||
| | | || | || |||| | | | || | | || | | | \-----+------++-+--+-+-----++++-++/ | || | ||| | | |
|
||||
| | | || | || |||| | | | || | |/-++-+---+---+--------------+------++-+--+-+-----++++-++---+\|| | ||| | | |
|
||||
| | | || | |\--++++--+----+----+-/| | || || | | | | || |/-+-+-----++++-++---++++-+------+++-----------+---+---+---\
|
||||
| | | || | | ||||/-+----+----+--+--+-++-++-+---+---+--------------+------++-++-+-+-----++++-++---++++-+---\ ||| | | | |
|
||||
| | | || | | ||||| | | | | | || || | | | | || || \-+-----++++-++---++++-+---+--++/ | | | |
|
||||
| \---+---++------+---+---+/||| | /--+----+--+--+-++-++\| | | /----+------++-++---+-----++++-++---++++-+---+--++------------+---+\ | |
|
||||
| /+---++------+---+---+-+++-+-+--+--\ | | | || |||| | | /------+----+-\ || || | |||| || |||| | | || /---------+---++--+-\ |
|
||||
| || || | | | \++-+-+--+--+-+--+--+-++-+/||/--+---+--+------+----+-+----++-++---+-----++++-++---++++-+---+--++--+---------+\ || | | |
|
||||
| || || | | | || | | | | | | | || | ||| | | |/-----+----+-+----++-++---+-----++++-++---++++-+---+\ || | || || | | |
|
||||
| || || | \---+--++-+-+--+--+-+--+--/ || | ||| | | || | | | || || | |||| || |||| | || || | || || | | |
|
||||
\-----++---++------+-------+--++-+-+--+--+-+--+----++-+-+++--+---+--++-----+----+-+----++-++---+-----/||| || |||| | || || | || || | | |
|
||||
|| || | | || |/+--+--+-+--+----++-+-+++--+---+--++\ | | |/---++-++---+------+++-++\ |||| | || || | || || | | |
|
||||
|| || | | || ||| | | | | || | ||| | | ||| | | || || || | ||| ||| |||| | || || | || || | | |
|
||||
|| || | | || ||| | | | |/---++-+-+++--+---+--+++----+\ | || || || | ||| ||| |||| | || || | || || | | |
|
||||
|| || | | || ||| | | | || || | ||| | | ||| || | || /-++-++---+------+++-+++--++++-+---++-++--+--------\|| || | | |
|
||||
|| \+------+-------/ || ||| | | | || || | ||| | /+--+++----++---+-++-+-++-++---+------+++\||| |||| | || |\--+--------+++--++--/ | |
|
||||
/----++----+------+---\ \+-+++--+--+-+--++---++-+-+++--+--++--+++----++---+-++-+-++-/| | ||||||| |||| | || | | ||| || | |
|
||||
| || /--+------+---+----\ | ||| | | |/-++---++-+-+++--+--++--+++\ || /-+-++-+-++--+---+------+++++++--++++-+---++-+---+--------+++\ || | |
|
||||
| || | | /---+---+----+--+-+++--+--+-++-++--\|| | ||| | || ||||/--++-+-+-++-+-++--+---+------+++++++--++++-+---++-+---+--------++++-++---\| |
|
||||
| || | | | | | | | ||| | | |v || ||| | ||| | || ||||| \+-+-+-++-+-++--+---+------+++++++--++++-+---++-+---+--------++++-+/ || |
|
||||
| || | | | | | | | ||| | | || || /+++-+-+++--+--++--+++++---+-+-+-++-+-++--+---+------+++++++--++++-+---++-+---+---\ |||| | || |
|
||||
| || | | | \---+----+--+-+++--+--+-/| || |||| | |\+--+--++--+++++---+-+-+-++-+-++--+---+------++++/|| |||| | || | | | |||| | || |
|
||||
| || | | |/------+-\ | | ||| | /+--+-++-++++-+-+-+--+--++--+++++---+-+-+-++-+-++--+---+------++++-++-\|||| | || | | | |||| | || |
|
||||
| /--++-+--+--++------+\| | | ||| |/++--+-++-++++-+-+\| | || ||||| | | | |\-+-++--+---+------++++-+/ ||||| | || | /+---+----++++-+----++\|
|
||||
/+-+--++-+--+\ || ||| | \-+++--++++--+-++-++++-+-+++--+--++--+++++---+-+-+-+--+-++--+---+------++++-+--+++++-+---/| | || | /--++++-+--\ ||||
|
||||
|| | ||/+--++-++------+++--+---\||| |||| | || |||| | ||| | || ||||| | | \-+--+-++--+---/ |||| | ||||| | | | || | | |||| | | ||||
|
||||
|| | |||| || || ||| | |||| |||| | || |||| \-+++--+--++--+++++---+-+---+--+-++--+----------++++-/ ||||| | | | || | | |||| | | ||||
|
||||
|| | v||| || || /---+++--+---++++--++++--+-++-++++---+++--+--++--+++++---+-+---+--+-++--+-------\ |||| ||||| | | | || | | |||| | | ||||
|
||||
|| | |||| || || | ||| | |||| |||| | || |||| ||| |/-++--+++++---+-+---+--+-++--+\ | |||| |\+++-+----+-+--++---+-+--++++-/ | ||||
|
||||
|| | |||| || || | ||| | /++++--++++--+-++-++++---+++--++-++--+++++---+-+---+--+-++--++----\ | |||| | ||| | | | || | | |||| | ||||
|
||||
|| | |||| || || | ||| | ||||| /++++--+-++-++++---+++--++-++--+++++---+-+---+--+-++--++----+-+--++++----+-+++-+----+-+--++---+-+--++++----+\||||
|
||||
|| | |||| || || | ||| | ||||| ||||| | || |||\---+++--++-++--+++++---+-+---+--+-++--++----+-+--++++----+-/|| | | | || | | |||| ||||||
|
||||
|| | |||| || || | ||| | ||||| ||||| | ||/+++----+++--++-++--+++++---+-+---+--+-++--++----+-+--++++----+--++-+----+-+--++---+-+--++++\ ||||||
|
||||
|| | |||| || || | ||| | ||||| ||||| | |||||| ||| || || ||||| | | | | || || | | |||| | || | | | || | | ||||| ||||||
|
||||
|| | |||| || || | ||| | |||||/+++++--+-++++++----+++--++-++--+++++---+-+---+--+-++--++----+-+--++++----+\ || | | | || | | ||||| ||||||
|
||||
|| | |\++--++-++--+---+++--+--+++++++++++--+-++++++----+++--++-++--+++++---+-+---+--+-++--++----+-+--++++----++-+/ | | | || | | ||||| ||||||
|
||||
|| | | || || || | ||| | ||||||||||| |/++++++----+++--++-++-\||||| | | | | || || | | |||| || | | | | || | | ||||| ||||||
|
||||
|| | | || || || | ||| | ||||\++++++--++++++++----/|| || || |||||| | | | | || || | | |||| || | | | | || | | ||||| ||||||
|
||||
|| | | || || || | ||| /+--++++-++++++--++++++++-----++--++-++-++++++---+-+---+--+-++--++----+-+--++++----++-+--+----+-+--++---+-+\ ||||| ||||||
|
||||
|| | | || || || | ||| || |||| |||||| |||\++++-----++--++-++-++++++---/ | | | || || | | |||| || | | | | || | || ||||| ||||||
|
||||
|\-+--+-++--++-++--+---/|| || |||| |||||| ||| |||| || || || |||||| | | | || || | | |||| || | | | | || | || ||||| ||||||
|
||||
| | | || || || | || || |||| |||||| ||| |^|| || /++-++-++++++-----+---+\ | || || /+-+--++++----++-+--+----+-+--++---+-++-+++++--\||||||
|
||||
| | | || || || | || || |||| |||||| ||| |||| || ||| || |\++++-----+---/| | || || || | |||| || | | | | || | || ||||| |||||||
|
||||
| /+--+-++--++-++--+----++-++--++++-++++++--+++-++++-----++-+++-++-+-++++\ | | | || || || | |||| /-++-+--+\ ^ | || | || ||||| |||||||
|
||||
| || | || ||/++--+----++-++--++++-++++++--+++-++++-----++-+++-++-+-+++++----+----+-+-++--++---++-+\ |||| | || | || | | || | || ||||| |||||||
|
||||
| || | || ||||| | /--++-++--++++-++++++--+++-++++-----++-+++-++-+-+++++----+----+-+-++--++---++-++-++++--+-++-+--++---+-+--++-\ | || ||||| |||||||
|
||||
| || | || ||||| /+-+--++-++--++++-++++++--+++-++++-----++-+++-++-+-+++++---\| | | || || || ||/++++--+-++\| || | | || | | || ||||| |||||||
|
||||
| || | || ||||| || | || || |||| |||||| ||| |||| /---++-+++-++-+-+++++---++----+-+-++--++---++-+++++++--+-++++--++---+-+-\|| | | || ||||| |||||||
|
||||
| || | || ||||| || | || || |||| \+++++--+++-++++-+---++-+++-++-+-+++++---++----+-+-++--++---++-+++++++--+-+/|| || | | ||| | | || ||||| |||||||
|
||||
| || | || |||||/++-+--++-++--++++--+++++--+++-++++-+---++-+++-++-+-+++++---++----+-+-++--++---++-+++++++--+-+-++\ || | | ||| | | || ||||| |||||||
|
||||
| || | || |||||||| | || || |||\--+++++--+++-++++-+---++-+++-++-+-+/||| || | | ||/-++---++-+++++++--+-+-+++-++---+-+-+++-+\| || ||||| |||||||
|
||||
| || | || |||||||| | || || ||| ||||| ||| |||| | || ||| || | | ||| || | | ||| || || ||||||| | | ||| || | | ||| ||| || ||||| |||||||
|
||||
| || | ||/-++++++++-+--++-++--+++---+++++--+++-++++-+---++-+++-++-+-+-+++---++----+-+-+++-++-\ || ||||||| | | |v| || | | ||| ||| || ||||| |||||||
|
||||
| || | ||| |||||||| | || || ||| ||||| ||| |||| | || ||| || | | ||| || | | ||| || | || ||||||| | | ||| || | | ||| ||| || ||||| |||||||
|
||||
| || | ||| ||||\+++-+--+/ || /+++---+++++--+++-++++-+---++-+++-++-+-+-+++---++----+-+-+++-++-+-++-+++++++--+-+-+++-++\ | | ||| ||| || ||||| |||||||
|
||||
| || | ||| |||| ||| | | || |||| ||||| ||| |||| | || ||| || | | ||| || | | ||| || | || ||||||| | | ||| ||| | | ||| ||| || ||||| |||||||
|
||||
| || | ||| |||| ||| | | || |||| ||||| ||| |||| |/--++-+++-++-+-+\||| || | | ||| || | || ||||||| | | ||| ||| | | ||| ||| || ||||| |||||||
|
||||
| || | ||| |||| ||| | | || |||| ||||| ||| |||| || || \++-++-+-+++++---++----/ | ||| || | || ||||||| | | ||| ||| | | ||| ||| || ||||| |||||||
|
||||
| || |/+++-++++-+++\| | || |||| ||||| ||| |||| || || || || | ||||| || | ||| || | || ||||||| | | ||| ||| | | ||| ||| || ||||| |||||||
|
||||
| || ||||| |||\-+++++--+--++-++++---+++++--+++-++/| || || || || | ||||| || | ||| || | || ||||||| | | ||| ||| | | ||| ||| || ||||| |||||||
|
||||
| || ||||| ||| ||||| | || |||| ||||| ||| || | || || || || | ||||| || | ||| || | || ||||||| | | ||| ||| | | ||| ||| || ||||| |||||||
|
||||
| || ||||| ||| ||||| | || |||| ||||| ||| || | || || || || | ||||| || | ||| \+-+-++-+++++++--+-+-+++-+++--+-+-+++-+++-++-+++++--++++++/
|
||||
| || ||||| ||| ||||| | \+-++++---+++++--+++-++-+-++--++--++-++-+-+++++---++------+-+++--+-+-++-+++++++--+-+-+++-+++--+-+-+++-+++-+/ ||||| ||||||
|
||||
| || ||||| ||| ||||| | | |\++---+++++--+++-++-+-++--++--++-++-+-+++++---++------+-+++--+-+-+/ ||||||| | | ||| ||| | | ||| ||| | ||||| ||||||
|
||||
| || ||||| ||| ||||| | | | |\---+++++--+++-++-+-++--++--/| || | ||||| || | ||| | | | ||||||| | | ||| ||| | | ||| ||| | ||||| ||||||
|
||||
| || ||||| ||| ||||| |/--+-+-+----+++++--+++-++-+-++--++\ | || | \++++---++------+-+++--+-+-+--+++++++--+-+-+++-+++--/ | ||| ||| | ||||| ||||||
|
||||
| || ||||| ||| ||||| || | | | ||||| ||| || | || ||| | || | |||| || | ||| | | | ||||||| | | ||| ||| | ||| ||| | ||||| ||||||
|
||||
| || ||||| ||| ||||| || | | | ||||| ||| || | || ||| | || | |||| || | ||| | | | ||||||| \-+-+++-+/| | ||| ||| | ||||| ||||||
|
||||
| || ||||| ||| ||||| || | | | ||\++--+++-++-+-++--/|| | || | |||| || | ||| | | \--+++++++----+-+++-+-+----+-+++-+++-+--+++++--/|||||
|
||||
| || ||||| ||| ||||| || | | | || || ||| || | || || | || | |||| || | ||| | | ||||||| | ||| | | | ||| ||| | ||||| |||||
|
||||
| || ||||| ||| ||||| || |/+-+----++-++--+++-++-+-++---++--+-++-+--++++---++------+-+++--+-+----+++++++--\ | ||| | | | ||| ||| | ||||| |||||
|
||||
| || ||||| ||| ||||| || /+++-+----++-++--+++-++-+-++---++--+-++-+--++++---++------+-+++--+-+\ ||||||| | | ||| | | | ||| ||| | ||||| |||||
|
||||
| || ||||| ||| ||||| || |||| | || || ||| || | || || | || | |||| || /----+-+++--+-++---+++++++--+-+-+++-+-+----+-+++-+++-+--+++++---+++++\
|
||||
| || ||||| ||| ||||| || |||| | || || ||| || | ||/--++--+-++-+--++++---++-+----+-+++--+-++---+++++++\ | | ||| | | | ||| ||| | ||||| ||||||
|
||||
| || ||||| ||| ||||| || |||| |/---++-++--+++-++-+\||| || | |\-+--++++---++-+----+-+++--+-++---+++++/|| | | ||| | | | ||| ||| | ||||| ||||||
|
||||
| ||/-+++++-+++--+++++--++-++++-++\ || || ||| || ||||| || | | | |||| || | | ||| | || ||\++-++-+-+-/|| | | | ||| ||| | ||||| ||||||
|
||||
| ||| ||||| ||| ||||| || |||| ||| || || ||\-++-+++++--++--+-+--+--++++---++-+----+-+++--+-++---++-+/ || | | /++-+-+--\ | ||| ||| | ||||| ||||||
|
||||
| ||| ||||| ||| ||||| || |||| ||| || || || || ||||| || | | | |||| || | \-+++--+-++---++-+--++-+-+-+++-+-+--+-+-+++-+++-+--/|||| ||||||
|
||||
| ||| ||||| ||| ||||| || |||| ||| || || || /++-+++++--++--+-+--+--++++---++-+------+++\ | || || | || | | ||| | | | | ||| ||| | |||| ||||||
|
||||
| |\+-+++++-+++--+++++--/| |||| ||| || || || ||| ||||| || | | | |||| || | |||| | || || \--++-+-+-+/| | | | | ||| ||| \---++++---/|||||
|
||||
| | | ||||| ||| ||||| | |||| ||| || || || ||| ||||| || | | | |||| || | |||| | || || || | | | | | | | | ||^ |v| |||| |||||
|
||||
| | | ||||| ||| ||\++---+-++++-+++--++-++--++-+++-+++++--++--+-+--+--++++---++-+------++++-+-++---/| || | | | | | | | | ||| ||| |||| |||||
|
||||
| | | ||||| ||| || || | |||| ||| || || || ||| ||||| || | | | |||| || | |||| | || | || | | | | | | | | ||| ||| |||| |||||
|
||||
| | | ||||| ||| || || | |||| ||| |\-++--++-+++-+++++--++--+-+--+--++++---++-+------++++-+-++----+----++-+-+-+-+-+-+--+-+-+++-+++-----/||| |||||
|
||||
| | | ||||| ||| || || | |||| ||| | || || ||| ||||\--++--+-+--+--++++---++-+------++++-+-++----+----+/ | | | | | | | | ||| ||| ||| |||||
|
||||
| | | ||||| ||| || || | |||| ||| | || || ||| |||| \+--+-+--+--++++---++-+------++++-+-++----+----+--+-+-+-+-+-+--+-+-+++-+++------/|| |||||
|
||||
| | | ||||| ||| || || | |||| ||| | || /++-+++-++++----+--+-+\ | |||| || | ||||/+-++----+----+--+-+-+-+-+-+--+-+-+++-+++---\ || |||||
|
||||
| | | ||||| |||/-++-++---+-++++-+++--+--++-+++-+++-++++----+--+-++-+--++++---++-+\ |||||| || | | | | | |/+-+--+-+-+++\||| | || |||||
|
||||
| | | ||||| |||| || || | |||| ||| | || ||| ||| \+++----+--+-++-+--++++---++-++-----+/|||| || | | | | | ||| | | | ||||||| | || |||||
|
||||
| | | |||\+-++++-++-++---+-+/|| ||| | || ||| ||| ||| | | || | |||| || || \-++++-++----+----+--+-+-+-+++-+--+-/ ||||||| | || |||||
|
||||
| | | ||| \-++++-++-++---+-+-++-+++--+--++-+++-+++--+++----+--+-++-+--++++---++-++-------++++-/| | | | | | ||| | | ||||||| | || |||||
|
||||
| | | \++---++++-++-++---+-+-++-+++--+--+/ ||| ||| ||| | | || | |||| ||/++-------++++--+----+----+--+-+-+-+++-+--+---+++++++-\ | || |||||
|
||||
| | | || |||| || || | | || ||| | \--+++-+++--+++----+--+-++-+--++++---+++++-------++++--+----+----+--+-/ | ||| | | ||||||| | | || |||||
|
||||
| | | || |||| || || | | || ||| \-----+++-+++--+++----+--+-++-+--++++---+++++-------++++--+----+----+--+---+-+++-+--+---+++++++-+-+---++----/||||
|
||||
| | | || ^||| || || | | || ||| ||| ||| ||| | | || | |||| ||||| |||| | | | | | ||| | | ||||||| | | || ||||
|
||||
| | | || \+++-++-++---+-+-++-+++--------+++-+++--+++----+--+-++-+--++++---+++++-------++++--+----+----+--+---+-++/ | | ||||||| | | || ||||
|
||||
| | | || ||| || || | | || ||| /-+++-+++--+++----+--+-++-+--++++---+++++-------++++--+----+----+--+---+\|| | | ||\++++-+-+---++-----+/||
|
||||
| | | || ||| || || | | || |||/-----+-+++-+++\ ||| /-+--+-++-+--++++---+++++-------++++--+----+----+--+---++++-\| | || |||| | | || | ||
|
||||
| | | \+----+++-++-/| | | || |||| | ||\-++++-+++--+-+--+-++-/ |||| ||||| |||| | | | | ||||/++--+---++\|||| | | || | ||
|
||||
| | | | ||| || \---+-+-++-++++-----+-++--++++-+++--+-+--+-++----++++---+++++-------++++--+----+----+--+---+++++++--+---++++/|| | | || | ||
|
||||
| | | | ||| || | | || |||| | || |||| ||| | | |/++----++++\ ||||| |||| | | | | ||||||| | |||| || | | || | ||
|
||||
| | | | ||| || | | || |||| | || |||| ||| | | |||| /--+++++--+++++-------++++--+----+----+--+<--+++++++--+---++++-++-+-+---++--\ | ||
|
||||
| | | | ||| || | | || |||| | || \+++-+++--+-+--++++-+--+++++--+++++-------+/|| | | | | |||\+++--+---+++/ || | | || | | ||
|
||||
| | | \----+++-++->----+-+-++-/\++-----+-++---+++-/|| | | |||| | ||||| ||||| | || | | | | ||| ||| | ||| || | | || | | ||
|
||||
| | | ||| || | | || || | || ||| \+--+-+--++++-+--+++++--+++++-->----+-++--+----+----+--+---+++-+++--+---/|| || | | || | | ||
|
||||
| | | ||| || | | \+---++-----+-++---+++---+--+-+--++++-+--+++++--+++++-------+-++--+----+----+--/ ||| ||| | || || | | || | | ||
|
||||
| | | ||| || | | | |\-----+-++---++//--+--+-+-\|||| | ||||| ||||| \-++--+----+----+------+++-+++--+----++--/| | | || | | ||
|
||||
| | | ||| || | | | | | || || | | | | ||||| | ||||| ||||| || | | | ||| ||| | ||/--+-+-+---++-\| | ||
|
||||
\-+-+--------/|| || | | | | | || || | | | | ||||| | ||||| ||\++---------++--+----+----+------+++<+++--+----+++--+-/ | || || | ||
|
||||
| | || |\------+-+--+---+------+-++---++-+--+--+-+-+++++-+--+++++--/| || \+--+----+----+------+++-+++--+----+++--+---/ || || | ||
|
||||
| | || | /-----+-+--+---+------+-++\ || | | | | |||\+-+--+++++---+-++----------+--+----+----/ ||| ||| | ||| | || || | ||
|
||||
| | || | | | | | | | ||| || | | | | ||| | | ||||| | \+----------+--+----+-----------+++-+++--+----+++--+-------++-++--+-+/
|
||||
| | || | | | | | | | ||| || | \--+-+-+++-+-+--/|\++---+--+----------+--+----+------>----+++-+++--+----+++--+-------++-++--/ |
|
||||
| \---------++-+-+-----+-+--+---/ | ||| || | | | |\+-+-+---+-++---+--+----------/ | | ||| ||| | ||| | || || |
|
||||
| || | | | \--+----------+-+++--++-+-----+-+-+-+-+-+---+-++---+--+-------------/ | \++-+++--/ ||| | || || |
|
||||
\-----------++-+-+-----+----+----------+-+++--++-+-----+-+-+-+-+-+---+-/| | | | || ||| ||| | || || |
|
||||
|| | | | | | \++--++-+-----+-+-+-+-/ \---+--+---+--+------------------+------------++-+++-------+++--+-------++-+/ |
|
||||
|| | | | | \--++--++-+-----+-+-+-+-------+--+---+--+------------------+------------/| ||| ||| | || | |
|
||||
|| | | | | \+--++-+-----+-+-+-+-------/ | | | | | ||| ||| | || | |
|
||||
|| | | | | | || \-----+-+-/ | | \--+------------------+-------------+-+++-------+++--+-------/| | |
|
||||
|| | \-----+----+--------------/ |\-------+-+---+----------+------+------------------+-------------+-+++-------+++--/ | | |
|
||||
|| | \----+-----------------+--------+-/ | | | | | ||| ||| | | |
|
||||
|| | | | | | | | | | ||| ||| | | |
|
||||
|| | | | | | | | | | ||| ||| | | |
|
||||
|| \------------+-----------------+--------+-----+----------+------+------------------+-------------/ ||| ||| | | |
|
||||
|| | | \-----+----------+------+------------------+---------------+/| \++-----------+-+-----/
|
||||
|| | | | | | | | | || | |
|
||||
|| | \--------------+----------+------+------------------+---------------+-+--------++-----------/ |
|
||||
|\---<----------+--------------------------------+----------+------/ | | | || |
|
||||
| | \----------/ | \-+--------/\-------------/
|
||||
| \---------------------------------------------------------------------+-----------------/
|
||||
\-------------------------------------------------------------------------------------/
|
6
inputs/13_test.txt
Normal file
6
inputs/13_test.txt
Normal file
@ -0,0 +1,6 @@
|
||||
/->-\
|
||||
| | /----\
|
||||
| /-+--+-\ |
|
||||
| | | | v |
|
||||
\-+-/ \-+--/
|
||||
\------/
|
1
inputs/14.txt
Normal file
1
inputs/14.txt
Normal file
@ -0,0 +1 @@
|
||||
236021
|
1
inputs/5.txt
Normal file
1
inputs/5.txt
Normal file
File diff suppressed because one or more lines are too long
1
inputs/5_test.txt
Normal file
1
inputs/5_test.txt
Normal file
@ -0,0 +1 @@
|
||||
dabAcCaCBAcCcaDA
|
50
inputs/6.txt
Normal file
50
inputs/6.txt
Normal file
@ -0,0 +1,50 @@
|
||||
84, 212
|
||||
168, 116
|
||||
195, 339
|
||||
110, 86
|
||||
303, 244
|
||||
228, 338
|
||||
151, 295
|
||||
115, 49
|
||||
161, 98
|
||||
60, 197
|
||||
40, 55
|
||||
55, 322
|
||||
148, 82
|
||||
86, 349
|
||||
145, 295
|
||||
243, 281
|
||||
91, 343
|
||||
280, 50
|
||||
149, 129
|
||||
174, 119
|
||||
170, 44
|
||||
296, 148
|
||||
152, 160
|
||||
115, 251
|
||||
266, 281
|
||||
269, 285
|
||||
109, 242
|
||||
136, 241
|
||||
236, 249
|
||||
338, 245
|
||||
71, 101
|
||||
254, 327
|
||||
208, 231
|
||||
289, 184
|
||||
282, 158
|
||||
352, 51
|
||||
326, 230
|
||||
88, 240
|
||||
292, 342
|
||||
352, 189
|
||||
231, 141
|
||||
280, 350
|
||||
296, 185
|
||||
226, 252
|
||||
172, 235
|
||||
137, 161
|
||||
207, 90
|
||||
101, 133
|
||||
156, 234
|
||||
241, 185
|
6
inputs/6_test.txt
Normal file
6
inputs/6_test.txt
Normal file
@ -0,0 +1,6 @@
|
||||
1, 1
|
||||
1, 6
|
||||
8, 3
|
||||
3, 4
|
||||
5, 5
|
||||
8, 9
|
101
inputs/7.txt
Executable file
101
inputs/7.txt
Executable file
@ -0,0 +1,101 @@
|
||||
Step I must be finished before step Q can begin.
|
||||
Step B must be finished before step O can begin.
|
||||
Step J must be finished before step M can begin.
|
||||
Step W must be finished before step Y can begin.
|
||||
Step U must be finished before step X can begin.
|
||||
Step T must be finished before step Q can begin.
|
||||
Step G must be finished before step M can begin.
|
||||
Step K must be finished before step C can begin.
|
||||
Step F must be finished before step Z can begin.
|
||||
Step D must be finished before step A can begin.
|
||||
Step N must be finished before step Y can begin.
|
||||
Step Y must be finished before step Q can begin.
|
||||
Step Q must be finished before step Z can begin.
|
||||
Step V must be finished before step E can begin.
|
||||
Step A must be finished before step X can begin.
|
||||
Step E must be finished before step C can begin.
|
||||
Step O must be finished before step R can begin.
|
||||
Step P must be finished before step L can begin.
|
||||
Step H must be finished before step R can begin.
|
||||
Step M must be finished before step R can begin.
|
||||
Step C must be finished before step Z can begin.
|
||||
Step R must be finished before step L can begin.
|
||||
Step L must be finished before step S can begin.
|
||||
Step S must be finished before step X can begin.
|
||||
Step Z must be finished before step X can begin.
|
||||
Step T must be finished before step O can begin.
|
||||
Step D must be finished before step Z can begin.
|
||||
Step P must be finished before step R can begin.
|
||||
Step M must be finished before step Z can begin.
|
||||
Step L must be finished before step Z can begin.
|
||||
Step W must be finished before step N can begin.
|
||||
Step Q must be finished before step R can begin.
|
||||
Step P must be finished before step C can begin.
|
||||
Step U must be finished before step O can begin.
|
||||
Step F must be finished before step O can begin.
|
||||
Step K must be finished before step X can begin.
|
||||
Step G must be finished before step K can begin.
|
||||
Step M must be finished before step C can begin.
|
||||
Step Y must be finished before step Z can begin.
|
||||
Step A must be finished before step O can begin.
|
||||
Step D must be finished before step P can begin.
|
||||
Step K must be finished before step S can begin.
|
||||
Step I must be finished before step E can begin.
|
||||
Step G must be finished before step F can begin.
|
||||
Step S must be finished before step Z can begin.
|
||||
Step N must be finished before step V can begin.
|
||||
Step F must be finished before step D can begin.
|
||||
Step A must be finished before step Z can begin.
|
||||
Step F must be finished before step X can begin.
|
||||
Step T must be finished before step Y can begin.
|
||||
Step W must be finished before step H can begin.
|
||||
Step D must be finished before step H can begin.
|
||||
Step W must be finished before step G can begin.
|
||||
Step J must be finished before step X can begin.
|
||||
Step T must be finished before step X can begin.
|
||||
Step U must be finished before step R can begin.
|
||||
Step O must be finished before step P can begin.
|
||||
Step L must be finished before step X can begin.
|
||||
Step I must be finished before step B can begin.
|
||||
Step M must be finished before step L can begin.
|
||||
Step C must be finished before step R can begin.
|
||||
Step R must be finished before step X can begin.
|
||||
Step F must be finished before step N can begin.
|
||||
Step V must be finished before step H can begin.
|
||||
Step K must be finished before step A can begin.
|
||||
Step W must be finished before step O can begin.
|
||||
Step U must be finished before step Q can begin.
|
||||
Step O must be finished before step C can begin.
|
||||
Step K must be finished before step V can begin.
|
||||
Step R must be finished before step S can begin.
|
||||
Step E must be finished before step S can begin.
|
||||
Step J must be finished before step A can begin.
|
||||
Step E must be finished before step X can begin.
|
||||
Step K must be finished before step Y can begin.
|
||||
Step Y must be finished before step X can begin.
|
||||
Step P must be finished before step Z can begin.
|
||||
Step W must be finished before step X can begin.
|
||||
Step Y must be finished before step A can begin.
|
||||
Step V must be finished before step X can begin.
|
||||
Step O must be finished before step M can begin.
|
||||
Step I must be finished before step J can begin.
|
||||
Step W must be finished before step L can begin.
|
||||
Step I must be finished before step G can begin.
|
||||
Step D must be finished before step O can begin.
|
||||
Step D must be finished before step N can begin.
|
||||
Step M must be finished before step X can begin.
|
||||
Step I must be finished before step R can begin.
|
||||
Step Y must be finished before step M can begin.
|
||||
Step F must be finished before step M can begin.
|
||||
Step U must be finished before step M can begin.
|
||||
Step Y must be finished before step H can begin.
|
||||
Step K must be finished before step D can begin.
|
||||
Step N must be finished before step O can begin.
|
||||
Step H must be finished before step S can begin.
|
||||
Step G must be finished before step L can begin.
|
||||
Step T must be finished before step D can begin.
|
||||
Step J must be finished before step N can begin.
|
||||
Step K must be finished before step M can begin.
|
||||
Step K must be finished before step P can begin.
|
||||
Step E must be finished before step R can begin.
|
||||
Step N must be finished before step H can begin.
|
7
inputs/7_test.txt
Normal file
7
inputs/7_test.txt
Normal file
@ -0,0 +1,7 @@
|
||||
Step C must be finished before step A can begin.
|
||||
Step C must be finished before step F can begin.
|
||||
Step A must be finished before step B can begin.
|
||||
Step A must be finished before step D can begin.
|
||||
Step B must be finished before step E can begin.
|
||||
Step D must be finished before step E can begin.
|
||||
Step F must be finished before step E can begin.
|
1
inputs/8.txt
Executable file
1
inputs/8.txt
Executable file
File diff suppressed because one or more lines are too long
1
inputs/8_test.txt
Normal file
1
inputs/8_test.txt
Normal file
@ -0,0 +1 @@
|
||||
2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2
|
1
inputs/9.txt
Normal file
1
inputs/9.txt
Normal file
@ -0,0 +1 @@
|
||||
471 players; last marble is worth 72026 points
|
1
inputs/9_test.txt
Normal file
1
inputs/9_test.txt
Normal file
@ -0,0 +1 @@
|
||||
9 players; last marble is worth 25 points
|
256
src/day10.rs
Normal file
256
src/day10.rs
Normal file
@ -0,0 +1,256 @@
|
||||
extern crate regex;
|
||||
|
||||
use std::collections::HashSet;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
use std::str::FromStr;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/10.txt";
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
struct Vector {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Point {
|
||||
position: Vector,
|
||||
velocity: Vector,
|
||||
}
|
||||
|
||||
impl FromStr for Point {
|
||||
type Err = Box<Error>;
|
||||
|
||||
fn from_str(s: &str) -> Result<Point> {
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(concat!(
|
||||
r"position=<(?P<position_x>(\s|-)?\d+), (?P<position_y>(\s|-)?\d+)> ",
|
||||
r"velocity=<(?P<velocity_x>(\s|-)?\d+), (?P<velocity_y>(\s|-)?\d+)>"
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let captures = match RE.captures(s) {
|
||||
None => {
|
||||
return Err(From::from("Malformed points, no fields could be found"));
|
||||
}
|
||||
Some(captures) => captures,
|
||||
};
|
||||
|
||||
Ok(Point {
|
||||
position: Vector {
|
||||
x: captures["position_x"].trim_start().parse()?,
|
||||
y: captures["position_y"].trim_start().parse()?,
|
||||
},
|
||||
velocity: Vector {
|
||||
x: captures["velocity_x"].trim_start().parse()?,
|
||||
y: captures["velocity_y"].trim_start().parse()?,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Sky {
|
||||
points: Vec<Point>,
|
||||
}
|
||||
|
||||
impl FromStr for Sky {
|
||||
type Err = Box<Error>;
|
||||
|
||||
fn from_str(s: &str) -> Result<Sky> {
|
||||
Ok(Sky {
|
||||
points: s
|
||||
.trim_end()
|
||||
.split('\n')
|
||||
.map(|line| line.parse().unwrap())
|
||||
.collect(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Sky {
|
||||
fn point_spread(&self) -> (Vector, Vector) {
|
||||
let mut min = self.points[0].position.clone();
|
||||
let mut max = self.points[0].position.clone();
|
||||
|
||||
for point in self.points.iter() {
|
||||
if point.position.x < min.x {
|
||||
min.x = point.position.x;
|
||||
}
|
||||
if point.position.y < min.y {
|
||||
min.y = point.position.y;
|
||||
}
|
||||
if point.position.x > max.x {
|
||||
max.x = point.position.x;
|
||||
}
|
||||
if point.position.y > max.y {
|
||||
max.y = point.position.y;
|
||||
}
|
||||
}
|
||||
|
||||
(min, max)
|
||||
}
|
||||
|
||||
fn move_points(&mut self, seconds: i32) {
|
||||
for point in self.points.iter_mut() {
|
||||
point.position.x += point.velocity.x * seconds;
|
||||
point.position.y += point.velocity.y * seconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Sky {
|
||||
#[allow(clippy::write_with_newline)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let (min, max) = self.point_spread();
|
||||
let points_set: HashSet<(i32, i32)> = self
|
||||
.points
|
||||
.iter()
|
||||
.map(|point| (point.position.x, point.position.y))
|
||||
.collect();
|
||||
|
||||
for y in min.y..=max.y {
|
||||
for x in min.x..=max.x {
|
||||
if points_set.contains(&(x, y)) {
|
||||
write!(f, "#")?;
|
||||
} else {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
write!(f, "\n")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve_parts() -> Result<(String, u32)> {
|
||||
let mut sky = read_points_file(INPUT)?;
|
||||
let (min, max) = sky.point_spread();
|
||||
let mut min_spread = Vector {
|
||||
x: (max.x - min.x).abs(),
|
||||
y: (max.y - min.y).abs(),
|
||||
};
|
||||
let mut seconds = 0;
|
||||
|
||||
loop {
|
||||
sky.move_points(1);
|
||||
let (min, max) = sky.point_spread();
|
||||
let spread_x = (max.x - min.x).abs();
|
||||
let spread_y = (max.y - min.y).abs();
|
||||
|
||||
if spread_x > min_spread.x && spread_y > min_spread.y {
|
||||
sky.move_points(-1);
|
||||
return Ok((format!("{}", &sky), seconds));
|
||||
}
|
||||
|
||||
if spread_x < min_spread.x {
|
||||
min_spread.x = spread_x
|
||||
}
|
||||
if spread_y < min_spread.y {
|
||||
min_spread.y = spread_y
|
||||
}
|
||||
seconds += 1;
|
||||
}
|
||||
}
|
||||
|
||||
fn read_points_file(filename: &str) -> Result<Sky> {
|
||||
let points = fs::read_to_string(filename)?;
|
||||
Ok(points.parse()?)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT_ONE: &str = "inputs/10_test_one.txt";
|
||||
const TEST_INPUT: &str = "inputs/10_test.txt";
|
||||
const TEST_POINT_1: Point = Point {
|
||||
position: Vector { x: 0, y: 1 },
|
||||
velocity: Vector { x: 0, y: 0 },
|
||||
};
|
||||
const TEST_POINT_2: Point = Point {
|
||||
position: Vector { x: 0, y: 0 },
|
||||
velocity: Vector { x: 0, y: 0 },
|
||||
};
|
||||
fn test_sky() -> Sky {
|
||||
Sky {
|
||||
points: vec![TEST_POINT_1, TEST_POINT_2],
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_string_to_point() {
|
||||
let point = "position=< 0, 1> velocity=< 0, 0>";
|
||||
assert_eq!(point.parse::<Point>().unwrap(), TEST_POINT_1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_points_file() {
|
||||
assert_eq!(
|
||||
read_points_file(TEST_INPUT_ONE).unwrap(),
|
||||
Sky {
|
||||
points: vec![TEST_POINT_1]
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn displays_sky_with_one_point() {
|
||||
assert_eq!(format!("{}", test_sky()), "#\n#\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn displays_sky() {
|
||||
let sky = read_points_file(TEST_INPUT).unwrap();
|
||||
print!("{}", &sky);
|
||||
assert_eq!(
|
||||
format!("{}", sky),
|
||||
concat!(
|
||||
"........#.............\n",
|
||||
"................#.....\n",
|
||||
".........#.#..#.......\n",
|
||||
"......................\n",
|
||||
"#..........#.#.......#\n",
|
||||
"...............#......\n",
|
||||
"....#.................\n",
|
||||
"..#.#....#............\n",
|
||||
".......#..............\n",
|
||||
"......#...............\n",
|
||||
"...#...#.#...#........\n",
|
||||
"....#..#..#.........#.\n",
|
||||
".......#..............\n",
|
||||
"...........#..#.......\n",
|
||||
"#...........#.........\n",
|
||||
"...#.......#..........\n",
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn displays_message_in_sky() {
|
||||
let mut sky = read_points_file(TEST_INPUT).unwrap();
|
||||
sky.move_points(3);
|
||||
print!("{}", &sky);
|
||||
assert_eq!(
|
||||
format!("{}", sky),
|
||||
concat!(
|
||||
"#...#..###\n",
|
||||
"#...#...#.\n",
|
||||
"#...#...#.\n",
|
||||
"#####...#.\n",
|
||||
"#...#...#.\n",
|
||||
"#...#...#.\n",
|
||||
"#...#...#.\n",
|
||||
"#...#..###\n",
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
200
src/day11.rs
Normal file
200
src/day11.rs
Normal file
@ -0,0 +1,200 @@
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/11.txt";
|
||||
const GRID_SIZE: usize = 300;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Cells([[i32; GRID_SIZE + 1]; GRID_SIZE + 1]);
|
||||
|
||||
impl fmt::Display for Cells {
|
||||
#[allow(clippy::write_with_newline)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for x in 1..=GRID_SIZE {
|
||||
for y in 1..=GRID_SIZE {
|
||||
write!(f, "{}", self.0[x][y])?;
|
||||
}
|
||||
write!(f, "\n")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Cells {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
writeln!(f, "Cells {{\n{}\n}}", self)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Grid {
|
||||
serial_number: usize,
|
||||
sums: Cells,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Coordinate {
|
||||
pub x: usize,
|
||||
pub y: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub struct Subsection {
|
||||
pub coord: Coordinate,
|
||||
pub size: usize,
|
||||
}
|
||||
|
||||
impl Subsection {
|
||||
fn top_left(&self) -> Subsection {
|
||||
Subsection {
|
||||
coord: Coordinate {
|
||||
x: self.coord.x - self.size + 1,
|
||||
y: self.coord.y - self.size + 1,
|
||||
},
|
||||
size: self.size,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Grid {
|
||||
fn new(serial_number: usize) -> Grid {
|
||||
Grid {
|
||||
serial_number,
|
||||
sums: Cells([[0; GRID_SIZE + 1]; GRID_SIZE + 1]),
|
||||
}
|
||||
}
|
||||
|
||||
fn power_at_cell(&self, coord: &Coordinate) -> i32 {
|
||||
let rack_id = coord.x + 10;
|
||||
let mut power_level = rack_id * coord.y;
|
||||
power_level += self.serial_number;
|
||||
power_level *= rack_id;
|
||||
power_level = power_level / 100 % 10;
|
||||
power_level as i32 - 5
|
||||
}
|
||||
|
||||
fn fill_sums(&mut self) {
|
||||
for x in 1..=GRID_SIZE {
|
||||
for y in 1..=GRID_SIZE {
|
||||
let power = self.power_at_cell(&Coordinate { x, y });
|
||||
self.sums.0[x][y] = power + self.sums.0[x - 1][y] + self.sums.0[x][y - 1]
|
||||
- self.sums.0[x - 1][y - 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn power_of_subsection(&mut self, subsection: &Subsection) -> i32 {
|
||||
let Subsection { coord, size } = subsection;
|
||||
let &Coordinate { x, y } = coord;
|
||||
self.sums.0[x][y] - self.sums.0[x - size][y] - self.sums.0[x][y - size]
|
||||
+ self.sums.0[x - size][y - size]
|
||||
}
|
||||
|
||||
fn highest_power_subsection(&mut self, size: usize) -> (Subsection, i32) {
|
||||
let mut highest_power_subsection = Subsection {
|
||||
coord: Coordinate { x: size, y: size },
|
||||
size,
|
||||
};
|
||||
let mut highest_power_level = self.power_of_subsection(&highest_power_subsection);
|
||||
for x in size..GRID_SIZE {
|
||||
for y in size..GRID_SIZE {
|
||||
let subsection = Subsection {
|
||||
coord: Coordinate { x, y },
|
||||
size,
|
||||
};
|
||||
if subsection == highest_power_subsection {
|
||||
continue;
|
||||
};
|
||||
let power = self.power_of_subsection(&subsection);
|
||||
if power > highest_power_level {
|
||||
highest_power_subsection = subsection;
|
||||
highest_power_level = power;
|
||||
}
|
||||
}
|
||||
}
|
||||
(highest_power_subsection.top_left(), highest_power_level)
|
||||
}
|
||||
}
|
||||
|
||||
fn read_serial_number_file(filename: &str) -> Result<usize> {
|
||||
let serial_number = fs::read_to_string(filename)?;
|
||||
Ok(serial_number.trim().parse()?)
|
||||
}
|
||||
|
||||
pub fn solve_part1() -> Result<Subsection> {
|
||||
let serial_number = read_serial_number_file(INPUT)?;
|
||||
let mut grid = Grid::new(serial_number);
|
||||
grid.fill_sums();
|
||||
Ok(grid.highest_power_subsection(3).0)
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<Subsection> {
|
||||
let serial_number = read_serial_number_file(INPUT)?;
|
||||
let mut grid = Grid::new(serial_number);
|
||||
grid.fill_sums();
|
||||
let (mut highest_power_subsection, mut highest_power_level) = grid.highest_power_subsection(1);
|
||||
|
||||
for size in 2..=GRID_SIZE {
|
||||
let (subsection, power) = grid.highest_power_subsection(size);
|
||||
if power > highest_power_level {
|
||||
highest_power_subsection = subsection;
|
||||
highest_power_level = power;
|
||||
}
|
||||
}
|
||||
Ok(highest_power_subsection)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn creates_new_empty_grid() {
|
||||
let grid = Grid::new(18);
|
||||
assert_eq!(grid.serial_number, 18);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_power_at_cell() {
|
||||
let grid = Grid::new(8);
|
||||
assert_eq!(grid.power_at_cell(&Coordinate { x: 3, y: 5 }), 4);
|
||||
let grid = Grid::new(57);
|
||||
assert_eq!(grid.power_at_cell(&Coordinate { x: 122, y: 79 }), -5);
|
||||
let grid = Grid::new(39);
|
||||
assert_eq!(grid.power_at_cell(&Coordinate { x: 217, y: 196 }), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_power_of_subsection() {
|
||||
let mut grid = Grid::new(18);
|
||||
grid.fill_sums();
|
||||
assert_eq!(
|
||||
grid.power_of_subsection(&Subsection {
|
||||
coord: Coordinate { x: 35, y: 47 },
|
||||
size: 3
|
||||
}),
|
||||
29
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_highest_power_subsection() {
|
||||
let mut grid = Grid::new(18);
|
||||
grid.fill_sums();
|
||||
assert_eq!(
|
||||
grid.highest_power_subsection(3),
|
||||
(
|
||||
Subsection {
|
||||
coord: Coordinate { x: 33, y: 45 },
|
||||
size: 3
|
||||
},
|
||||
29
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
265
src/day12.rs
Normal file
265
src/day12.rs
Normal file
@ -0,0 +1,265 @@
|
||||
extern crate regex;
|
||||
|
||||
use std::collections::{HashMap, VecDeque};
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
use std::str::FromStr;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/12.txt";
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Pots(VecDeque<bool>);
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct SpreadRules(HashMap<[bool; 5], bool>);
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct GrowthSimulation {
|
||||
pots: Pots,
|
||||
spread_rules: SpreadRules,
|
||||
generations: usize,
|
||||
}
|
||||
|
||||
impl fmt::Display for Pots {
|
||||
#[allow(clippy::write_with_newline)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for pot in self.0.iter() {
|
||||
if *pot {
|
||||
write!(f, "#")?;
|
||||
} else {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
write!(f, "\n")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for SpreadRules {
|
||||
#[allow(clippy::write_with_newline)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (pattern, result) in self.0.iter() {
|
||||
for pot in pattern {
|
||||
if *pot {
|
||||
write!(f, "#")?;
|
||||
} else {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
}
|
||||
write!(f, " => ")?;
|
||||
if *result {
|
||||
write!(f, "#")?;
|
||||
} else {
|
||||
write!(f, ".")?;
|
||||
}
|
||||
write!(f, "\n")?;
|
||||
}
|
||||
write!(f, "\n")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GrowthSimulation {
|
||||
#[allow(clippy::write_with_newline)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.pots)?;
|
||||
write!(f, "\n")?;
|
||||
write!(f, "{}", self.spread_rules)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for GrowthSimulation {
|
||||
type Err = Box<Error>;
|
||||
|
||||
fn from_str(s: &str) -> Result<GrowthSimulation> {
|
||||
let sections: Vec<&str> = s.split("\n\n").collect();
|
||||
let (initial_state_str, spread_rules_str) = (sections[0], sections[1]);
|
||||
let mut pots = Pots(VecDeque::new());
|
||||
let mut spread_rules = SpreadRules(HashMap::new());
|
||||
|
||||
lazy_static! {
|
||||
static ref initial_state_regex: Regex =
|
||||
Regex::new(r"initial state: (?P<initial_state>[#.]+)").unwrap();
|
||||
static ref spread_rules_regex: Regex =
|
||||
Regex::new(r"(?P<pattern>[#.]{5}) => (?P<result>[#.])").unwrap();
|
||||
}
|
||||
|
||||
let initial_state_captures = match initial_state_regex.captures(initial_state_str) {
|
||||
None => {
|
||||
return Err(From::from(
|
||||
"Malformed initial state, no fields could be found",
|
||||
));
|
||||
}
|
||||
Some(captures) => captures,
|
||||
};
|
||||
|
||||
for pot in initial_state_captures["initial_state"].chars() {
|
||||
pots.0.push_back(pot == '#');
|
||||
}
|
||||
|
||||
for rule in spread_rules_str.lines() {
|
||||
let spread_rules_captures = match spread_rules_regex.captures(rule) {
|
||||
None => {
|
||||
return Err(From::from(
|
||||
"Malformed spread rules, no fields could be found",
|
||||
));
|
||||
}
|
||||
Some(captures) => captures,
|
||||
};
|
||||
|
||||
let mut pattern = [false; 5];
|
||||
let pattern_vec: Vec<bool> = spread_rules_captures["pattern"]
|
||||
.chars()
|
||||
.map(|c| c == '#')
|
||||
.collect();
|
||||
pattern.copy_from_slice(&pattern_vec);
|
||||
let result = &spread_rules_captures["result"] == "#";
|
||||
spread_rules.0.insert(pattern, result);
|
||||
}
|
||||
|
||||
Ok(GrowthSimulation { pots, spread_rules, generations: 0 })
|
||||
}
|
||||
}
|
||||
|
||||
impl GrowthSimulation {
|
||||
fn advance_generation(&mut self) {
|
||||
let mut next_generation = VecDeque::new();
|
||||
let padding = &[false; 4];
|
||||
let pots_slice = self.pots.0.as_slices();
|
||||
let pots_slice = [padding, pots_slice.0, pots_slice.1, padding].concat();
|
||||
for (index, pot_window) in pots_slice.windows(5).enumerate() {
|
||||
match self.spread_rules.0.get(pot_window) {
|
||||
Some(result) => {
|
||||
next_generation.push_back(*result);
|
||||
},
|
||||
None => {
|
||||
next_generation.push_back(pots_slice[2]);
|
||||
},
|
||||
}
|
||||
}
|
||||
self.pots = Pots(next_generation);
|
||||
self.generations += 1;
|
||||
}
|
||||
|
||||
fn sum_plant_indices(&self) -> i32 {
|
||||
let mut sum: i32 = 0;
|
||||
for (index, pot) in self.pots.0.iter().enumerate() {
|
||||
if *pot {
|
||||
let shifted_index = index as i32 - self.generations as i32 * 2;
|
||||
sum += shifted_index;
|
||||
}
|
||||
}
|
||||
sum
|
||||
}
|
||||
}
|
||||
|
||||
fn read_initial_state_and_rules(filename: &str) -> Result<GrowthSimulation> {
|
||||
let input = fs::read_to_string(filename)?;
|
||||
Ok(input.parse()?)
|
||||
}
|
||||
|
||||
pub fn solve_part1() -> Result<i32> {
|
||||
let mut growth_sim = read_initial_state_and_rules(INPUT)?;
|
||||
for _ in 0..20 {
|
||||
growth_sim.advance_generation();
|
||||
}
|
||||
Ok(growth_sim.sum_plant_indices())
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<i32> {
|
||||
let mut growth_sim = read_initial_state_and_rules(INPUT)?;
|
||||
for _ in 0..50_000_000_000_i64 {
|
||||
growth_sim.advance_generation();
|
||||
}
|
||||
Ok(growth_sim.sum_plant_indices())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/12_test.txt";
|
||||
fn test_growth_sim() -> GrowthSimulation {
|
||||
GrowthSimulation {
|
||||
pots: Pots(VecDeque::from(vec![
|
||||
true, false, false, true, false, true, false, false, true, true, false, false,
|
||||
false, false, false, false, true, true, true, false, false, false, true, true,
|
||||
true,
|
||||
])),
|
||||
spread_rules: SpreadRules([
|
||||
([true, true, true, true, false], true),
|
||||
([true, true, false, true, true], true),
|
||||
([false, false, true, false, false], true),
|
||||
([false, true, false, false, false], true),
|
||||
([true, true, false, true, false], true),
|
||||
([false, true, true, true, true], true),
|
||||
([true, false, true, true, true], true),
|
||||
([true, true, true, false, true], true),
|
||||
([false, true, false, true, true], true),
|
||||
([true, false, true, false, true], true),
|
||||
([false, true, false, true, false], true),
|
||||
([false, true, true, false, false], true),
|
||||
([true, true, true, false, false], true),
|
||||
([false, false, false, true, true], true),
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect()),
|
||||
generations: 0,
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_initial_state_and_rules_file() {
|
||||
let growth_sim = read_initial_state_and_rules(TEST_INPUT).unwrap();
|
||||
assert_eq!(growth_sim, test_growth_sim());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn displays_growth_simulation() {
|
||||
assert_eq!(
|
||||
format!("{}", test_growth_sim()).lines().collect::<Vec<&str>>().sort(),
|
||||
vec![
|
||||
"#..#.#..##......###...###",
|
||||
"",
|
||||
"####. => #",
|
||||
"##.## => #",
|
||||
"..#.. => #",
|
||||
".#... => #",
|
||||
"##.#. => #",
|
||||
".#### => #",
|
||||
"#.### => #",
|
||||
"###.# => #",
|
||||
".#.## => #",
|
||||
"#.#.# => #",
|
||||
".#.#. => #",
|
||||
".##.. => #",
|
||||
"###.. => #",
|
||||
"...## => #",
|
||||
].sort()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advances_simulation_by_one_generation() {
|
||||
let mut growth_sim = test_growth_sim();
|
||||
growth_sim.advance_generation();
|
||||
assert_eq!(format!("{}", growth_sim.pots), "..#...#....#.....#..#..#..#..\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn returns_correct_sum_after_20_generations() {
|
||||
let mut growth_sim = test_growth_sim();
|
||||
for _ in 0..20 {
|
||||
growth_sim.advance_generation();
|
||||
}
|
||||
assert_eq!(growth_sim.sum_plant_indices(), 325);
|
||||
}
|
||||
}
|
374
src/day13.rs
Normal file
374
src/day13.rs
Normal file
@ -0,0 +1,374 @@
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
use std::str::FromStr;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/13.txt";
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
pub struct Vector {
|
||||
pub y: usize,
|
||||
pub x: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||
enum Turn {
|
||||
Left,
|
||||
Straight,
|
||||
Right,
|
||||
Reverse,
|
||||
}
|
||||
|
||||
const INTER_SEQ: [Turn; 3] = [Turn::Left, Turn::Straight, Turn::Right];
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
|
||||
enum Direction {
|
||||
North,
|
||||
South,
|
||||
East,
|
||||
West,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
struct Cart {
|
||||
position: Vector,
|
||||
direction: Direction,
|
||||
next_turn: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Track {
|
||||
carts: Vec<Cart>,
|
||||
turns: HashMap<Vector, (Direction, Direction)>,
|
||||
intersections: HashSet<Vector>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Collision {
|
||||
position: Vector,
|
||||
cart_indices: (usize, usize),
|
||||
}
|
||||
|
||||
impl FromStr for Track {
|
||||
type Err = Box<Error>;
|
||||
|
||||
fn from_str(s: &str) -> Result<Track> {
|
||||
let mut carts = vec![];
|
||||
let mut turns = HashMap::new();
|
||||
let mut intersections = HashSet::new();
|
||||
let mut incomplete_circuits: HashMap<(usize, usize), usize> = HashMap::new();
|
||||
|
||||
for (row_index, row) in s.lines().enumerate() {
|
||||
let mut top_start: Option<usize> = None;
|
||||
let mut bottom_start: Option<usize> = None;
|
||||
for c in row.char_indices() {
|
||||
match c {
|
||||
(col_index, '\\') => match top_start {
|
||||
Some(start) => {
|
||||
incomplete_circuits.insert((start, col_index), row_index);
|
||||
turns.insert(
|
||||
Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
(Direction::South, Direction::West),
|
||||
);
|
||||
top_start = None;
|
||||
}
|
||||
None => {
|
||||
bottom_start = Some(col_index);
|
||||
turns.insert(
|
||||
Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
(Direction::North, Direction::East),
|
||||
);
|
||||
}
|
||||
},
|
||||
(col_index, '/') => match bottom_start {
|
||||
Some(start) => match incomplete_circuits.remove(&(start, col_index)) {
|
||||
Some(_) => {
|
||||
turns.insert(
|
||||
Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
(Direction::West, Direction::North),
|
||||
);
|
||||
bottom_start = None;
|
||||
}
|
||||
None => {
|
||||
return Err(From::from(
|
||||
"Malformed track, circuit bottom without top",
|
||||
))
|
||||
}
|
||||
},
|
||||
None => {
|
||||
top_start = Some(col_index);
|
||||
turns.insert(
|
||||
Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
(Direction::East, Direction::South),
|
||||
);
|
||||
}
|
||||
},
|
||||
(col_index, '+') => {
|
||||
intersections.insert(Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
});
|
||||
}
|
||||
(col_index, '^') => carts.push(Cart {
|
||||
position: Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
direction: Direction::North,
|
||||
next_turn: 0,
|
||||
}),
|
||||
(col_index, 'v') => carts.push(Cart {
|
||||
position: Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
direction: Direction::South,
|
||||
next_turn: 0,
|
||||
}),
|
||||
(col_index, '>') => carts.push(Cart {
|
||||
position: Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
direction: Direction::East,
|
||||
next_turn: 0,
|
||||
}),
|
||||
(col_index, '<') => carts.push(Cart {
|
||||
position: Vector {
|
||||
x: col_index,
|
||||
y: row_index,
|
||||
},
|
||||
direction: Direction::West,
|
||||
next_turn: 0,
|
||||
}),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Track {
|
||||
carts,
|
||||
turns,
|
||||
intersections,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl Direction {
|
||||
fn turn(self, turn: Turn) -> Direction {
|
||||
match turn {
|
||||
Turn::Left => match self {
|
||||
Direction::North => Direction::West,
|
||||
Direction::South => Direction::East,
|
||||
Direction::East => Direction::North,
|
||||
Direction::West => Direction::South,
|
||||
},
|
||||
Turn::Right => match self {
|
||||
Direction::North => Direction::East,
|
||||
Direction::South => Direction::West,
|
||||
Direction::East => Direction::South,
|
||||
Direction::West => Direction::North,
|
||||
},
|
||||
Turn::Reverse => match self {
|
||||
Direction::North => Direction::South,
|
||||
Direction::South => Direction::North,
|
||||
Direction::East => Direction::West,
|
||||
Direction::West => Direction::East,
|
||||
},
|
||||
Turn::Straight => self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cart {
|
||||
fn turn(&mut self, turn: Turn) {
|
||||
self.direction = self.direction.turn(turn);
|
||||
}
|
||||
|
||||
fn follow_turn(&mut self, turn_arms: (Direction, Direction)) {
|
||||
let entering_from = self.direction.turn(Turn::Reverse);
|
||||
|
||||
if entering_from == turn_arms.0 {
|
||||
self.direction = turn_arms.1;
|
||||
} else if entering_from == turn_arms.1 {
|
||||
self.direction = turn_arms.0;
|
||||
} else {
|
||||
panic!("Cart entered turn from an invalid direction");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Track {
|
||||
fn run_tick(&mut self, find_final_cart: bool) -> Option<Vector> {
|
||||
let mut collided_cart_indices = HashSet::new();
|
||||
let mut cart_positions: HashMap<Vector, usize> = HashMap::new();
|
||||
for (index, cart) in self.carts.iter().enumerate() {
|
||||
cart_positions.insert(cart.position, index);
|
||||
}
|
||||
|
||||
for (index, cart) in self.carts.iter_mut().enumerate() {
|
||||
if collided_cart_indices.contains(&index) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let Vector { x, y } = cart.position;
|
||||
cart_positions.remove(&cart.position);
|
||||
cart.position = match cart.direction {
|
||||
Direction::North => Vector { x, y: y - 1 },
|
||||
Direction::South => Vector { x, y: y + 1 },
|
||||
Direction::East => Vector { x: x + 1, y },
|
||||
Direction::West => Vector { x: x - 1, y },
|
||||
};
|
||||
|
||||
if let Some(turn_arms) = self.turns.get(&cart.position) {
|
||||
cart.follow_turn(*turn_arms);
|
||||
}
|
||||
|
||||
if self.intersections.contains(&cart.position) {
|
||||
cart.turn(INTER_SEQ[cart.next_turn as usize]);
|
||||
cart.next_turn = (cart.next_turn + 1) % INTER_SEQ.len() as u8;
|
||||
}
|
||||
|
||||
if let Some(colliding_cart) = cart_positions.get(&cart.position) {
|
||||
if find_final_cart {
|
||||
collided_cart_indices.insert(index);
|
||||
collided_cart_indices.insert(*colliding_cart);
|
||||
cart_positions.remove(&cart.position);
|
||||
continue;
|
||||
} else {
|
||||
return Some(cart.position);
|
||||
}
|
||||
}
|
||||
|
||||
cart_positions.insert(cart.position, index);
|
||||
}
|
||||
|
||||
self.carts = self
|
||||
.carts
|
||||
.drain(..)
|
||||
.enumerate()
|
||||
.filter(|(i, _)| !collided_cart_indices.contains(i))
|
||||
.map(|(_, cart)| cart)
|
||||
.collect();
|
||||
self.carts.sort_unstable();
|
||||
None
|
||||
}
|
||||
|
||||
fn find_first_collision(&mut self) -> Vector {
|
||||
let mut collision: Option<Vector> = None;
|
||||
while collision.is_none() {
|
||||
collision = self.run_tick(false);
|
||||
}
|
||||
collision.unwrap()
|
||||
}
|
||||
|
||||
fn find_last_cart(&mut self) -> &Cart {
|
||||
while self.carts.len() != 1 {
|
||||
self.run_tick(true);
|
||||
}
|
||||
&self.carts[0]
|
||||
}
|
||||
}
|
||||
|
||||
fn read_track(filename: &str) -> Result<Track> {
|
||||
let input = fs::read_to_string(filename)?;
|
||||
Ok(input.parse()?)
|
||||
}
|
||||
|
||||
pub fn solve_part1() -> Result<Vector> {
|
||||
let mut track = read_track(INPUT)?;
|
||||
Ok(track.find_first_collision())
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<Vector> {
|
||||
let mut track = read_track(INPUT)?;
|
||||
Ok(track.find_last_cart().position)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/13_test.txt";
|
||||
fn test_track() -> Track {
|
||||
Track {
|
||||
carts: vec![
|
||||
Cart {
|
||||
position: Vector { x: 2, y: 0 },
|
||||
direction: Direction::East,
|
||||
next_turn: 0,
|
||||
},
|
||||
Cart {
|
||||
position: Vector { x: 9, y: 3 },
|
||||
direction: Direction::South,
|
||||
next_turn: 0,
|
||||
},
|
||||
],
|
||||
turns: vec![
|
||||
(Vector { x: 0, y: 0 }, (Direction::East, Direction::South)),
|
||||
(Vector { x: 4, y: 0 }, (Direction::South, Direction::West)),
|
||||
(Vector { x: 4, y: 4 }, (Direction::West, Direction::North)),
|
||||
(Vector { x: 0, y: 4 }, (Direction::North, Direction::East)),
|
||||
(Vector { x: 7, y: 1 }, (Direction::East, Direction::South)),
|
||||
(Vector { x: 12, y: 1 }, (Direction::South, Direction::West)),
|
||||
(Vector { x: 12, y: 4 }, (Direction::West, Direction::North)),
|
||||
(Vector { x: 7, y: 4 }, (Direction::North, Direction::East)),
|
||||
(Vector { x: 2, y: 2 }, (Direction::East, Direction::South)),
|
||||
(Vector { x: 9, y: 2 }, (Direction::South, Direction::West)),
|
||||
(Vector { x: 9, y: 5 }, (Direction::West, Direction::North)),
|
||||
(Vector { x: 2, y: 5 }, (Direction::North, Direction::East)),
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
intersections: vec![
|
||||
Vector { x: 4, y: 2 },
|
||||
Vector { x: 7, y: 2 },
|
||||
Vector { x: 2, y: 4 },
|
||||
Vector { x: 9, y: 4 },
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_track_file() {
|
||||
let track = read_track(TEST_INPUT).unwrap();
|
||||
assert_eq!(track, test_track());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn runs_one_tick() {
|
||||
let mut track_after = test_track();
|
||||
track_after.carts[0].position.x = 3;
|
||||
track_after.carts[1].position.y = 4;
|
||||
track_after.carts[1].direction = Direction::East;
|
||||
track_after.carts[1].next_turn = 1;
|
||||
let mut track = test_track();
|
||||
track.run_tick(false);
|
||||
assert_eq!(track, track_after);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_first_collision() {
|
||||
let mut track = test_track();
|
||||
assert_eq!(track.find_first_collision(), Vector { x: 7, y: 3 });
|
||||
}
|
||||
}
|
249
src/day14.rs
Normal file
249
src/day14.rs
Normal file
@ -0,0 +1,249 @@
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/14.txt";
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Recipes {
|
||||
scores: Vec<u8>,
|
||||
elf1_index: usize,
|
||||
elf2_index: usize,
|
||||
}
|
||||
|
||||
impl fmt::Display for Recipes {
|
||||
#[allow(clippy::write_with_newline)]
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for (index, score) in self.scores.iter().enumerate() {
|
||||
if index == self.elf1_index {
|
||||
write!(f, "({})", score)?;
|
||||
} else if index == self.elf2_index {
|
||||
write!(f, "[{}]", score)?;
|
||||
} else {
|
||||
write!(f, " {} ", score)?;
|
||||
}
|
||||
}
|
||||
write!(f, "\n")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Recipes {
|
||||
fn new() -> Recipes {
|
||||
Recipes {
|
||||
scores: vec![3, 7],
|
||||
elf1_index: 0,
|
||||
elf2_index: 1,
|
||||
}
|
||||
}
|
||||
|
||||
fn new_recipes(&mut self) {
|
||||
let elf1_score = self.scores[self.elf1_index];
|
||||
let elf2_score = self.scores[self.elf2_index];
|
||||
let sum = elf1_score + elf2_score;
|
||||
fn push_digits(n: u8, digits: &mut Vec<u8>) {
|
||||
if n >= 10 {
|
||||
push_digits(n / 10, digits);
|
||||
}
|
||||
digits.push(n % 10);
|
||||
}
|
||||
push_digits(sum, &mut self.scores);
|
||||
}
|
||||
|
||||
fn pick_recipes(&mut self) {
|
||||
let elf1_score = self.scores[self.elf1_index];
|
||||
let elf2_score = self.scores[self.elf2_index];
|
||||
self.elf1_index = (self.elf1_index + (1 + elf1_score as usize)) % self.scores.len();
|
||||
self.elf2_index = (self.elf2_index + (1 + elf2_score as usize)) % self.scores.len();
|
||||
}
|
||||
|
||||
fn scores_after_n_recipes(&mut self, n: usize, num_scores: usize) -> String {
|
||||
while self.scores.len() < n + num_scores {
|
||||
self.new_recipes();
|
||||
self.pick_recipes();
|
||||
}
|
||||
self.scores[n..n + num_scores].iter().map(|score| format!("{}", score)).collect()
|
||||
}
|
||||
|
||||
fn find_index_of_sequence(&mut self, seq: &[u8]) -> usize {
|
||||
let seq_len = seq.len();
|
||||
loop {
|
||||
let scores_len = self.scores.len();
|
||||
self.new_recipes();
|
||||
self.pick_recipes();
|
||||
let new_scores_len = self.scores.len();
|
||||
let diff = new_scores_len - scores_len;
|
||||
if scores_len >= seq_len {
|
||||
for i in 0..diff {
|
||||
let seq_index = scores_len + i - seq_len;
|
||||
if &self.scores[seq_index..(seq_index + seq_len)] == seq {
|
||||
return seq_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn digit_seq(n: &str) -> Vec<u8> {
|
||||
let mut digits: Vec<u8> = vec![];
|
||||
for digit in n.chars() {
|
||||
digits.push(digit.to_digit(10).unwrap() as u8);
|
||||
}
|
||||
digits
|
||||
}
|
||||
|
||||
fn read_input_file(filename: &str) -> Result<usize> {
|
||||
let input = fs::read_to_string(filename)?;
|
||||
Ok(input.trim().parse()?)
|
||||
}
|
||||
|
||||
pub fn solve_part1() -> Result<String> {
|
||||
let input = read_input_file(INPUT)?;
|
||||
let mut recipes = Recipes::new();
|
||||
Ok(recipes.scores_after_n_recipes(input, 10))
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<usize> {
|
||||
let input = fs::read_to_string(INPUT)?;
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = digit_seq(&input.trim());
|
||||
Ok(recipes.find_index_of_sequence(&seq[..]))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn creates_new_recipes_struct() {
|
||||
let recipes = Recipes::new();
|
||||
assert_eq!(recipes.scores, vec![3, 7]);
|
||||
assert_eq!(recipes.elf1_index, 0);
|
||||
assert_eq!(recipes.elf2_index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn adds_new_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
recipes.new_recipes();
|
||||
assert_eq!(recipes.scores, vec![3, 7, 1, 0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn picks_new_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
recipes.new_recipes();
|
||||
recipes.pick_recipes();
|
||||
assert_eq!(recipes.elf1_index, 0);
|
||||
assert_eq!(recipes.elf2_index, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn iterates_15_times() {
|
||||
let mut recipes = Recipes::new();
|
||||
for _ in 0..15 {
|
||||
recipes.new_recipes();
|
||||
recipes.pick_recipes();
|
||||
}
|
||||
assert_eq!(
|
||||
format!("{}", recipes),
|
||||
" 3 7 1 0 [1] 0 1 2 (4) 5 1 5 8 9 1 6 7 7 9 2 \n",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_5_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(5, 10),
|
||||
"0124515891",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_9_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(9, 10),
|
||||
"5158916779",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_18_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(18, 10),
|
||||
"9251071085",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn scores_after_2018_recipes() {
|
||||
let mut recipes = Recipes::new();
|
||||
assert_eq!(
|
||||
recipes.scores_after_n_recipes(2018, 10),
|
||||
"5941429882",
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_1() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![5, 1, 5, 8, 9];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
9,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_2() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![0, 1, 2, 4, 5];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
5,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_3() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![9, 2, 5, 1, 0];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
18,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_index_of_sequence_4() {
|
||||
let mut recipes = Recipes::new();
|
||||
let seq = vec![5, 9, 4, 1, 4];
|
||||
assert_eq!(
|
||||
recipes.find_index_of_sequence(&seq[..]),
|
||||
2018,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_digit_seq_1() {
|
||||
assert_eq!(
|
||||
digit_seq("51589"),
|
||||
vec![5, 1, 5, 8, 9],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_digit_seq_2() {
|
||||
assert_eq!(
|
||||
digit_seq("01245"),
|
||||
vec![0, 1, 2, 4, 5],
|
||||
);
|
||||
}
|
||||
}
|
92
src/day5.rs
Normal file
92
src/day5.rs
Normal file
@ -0,0 +1,92 @@
|
||||
extern crate regex;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
const INPUT: &str = "inputs/5.txt";
|
||||
const UNITS: &str = "abcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
pub fn solve_part1() -> Result<usize, Box<Error>> {
|
||||
let polymer = read_polymer(INPUT)?;
|
||||
Ok(reduce_polymer_completely(polymer).len())
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<usize, Box<Error>> {
|
||||
let polymer = read_polymer(INPUT)?;
|
||||
Ok(find_shortest_unit_eliminated_polymer(polymer))
|
||||
}
|
||||
|
||||
fn read_polymer(filename: &str) -> Result<String, Box<Error>> {
|
||||
let file = File::open(filename)?;
|
||||
let polymer = BufReader::new(file).lines().next().unwrap_or(Ok("".to_string()));
|
||||
Ok(polymer?)
|
||||
}
|
||||
|
||||
fn reduce_polymer(polymer: &String) -> String {
|
||||
lazy_static! {
|
||||
static ref REACTING_UNITS: Regex = Regex::new(concat!(
|
||||
r"aA|bB|cC|dD|eE|fF|gG|hH|iI|jJ|kK|lL|mM|nN|",
|
||||
r"oO|pP|qQ|rR|sS|tT|uU|vV|wW|xX|yY|zZ|",
|
||||
r"Aa|Bb|Cc|Dd|Ee|Ff|Gg|Hh|Ii|Jj|Kk|Ll|Mm|Nn|",
|
||||
r"Oo|Pp|Qq|Rr|Ss|Tt|Uu|Vv|Ww|Xx|Yy|Zz")).unwrap();
|
||||
}
|
||||
REACTING_UNITS.replace_all(&polymer, "").to_string()
|
||||
}
|
||||
|
||||
fn reduce_polymer_completely(polymer: String) -> String {
|
||||
let reduced = reduce_polymer(&polymer);
|
||||
if reduced == polymer {
|
||||
reduced
|
||||
} else {
|
||||
reduce_polymer_completely(reduced)
|
||||
}
|
||||
}
|
||||
|
||||
fn find_shortest_unit_eliminated_polymer(polymer: String) -> usize {
|
||||
let mut eliminated_unit_polymers = HashMap::new();
|
||||
for unit in UNITS.chars() {
|
||||
let test_polymer = polymer
|
||||
.replace(unit, "")
|
||||
.replace(unit.to_ascii_uppercase(), "");
|
||||
eliminated_unit_polymers.insert(unit, reduce_polymer_completely(test_polymer).len());
|
||||
}
|
||||
*eliminated_unit_polymers.iter().min_by_key(|&(_, len)| len).unwrap().1
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/5_test.txt";
|
||||
|
||||
#[test]
|
||||
fn reduces_polymer() {
|
||||
assert_eq!(reduce_polymer(&"aA".to_string()), "");
|
||||
assert_eq!(reduce_polymer(&"aAbB".to_string()), "");
|
||||
assert_eq!(reduce_polymer(&"aAfgbB".to_string()), "fg");
|
||||
assert_eq!(reduce_polymer(&"abAB".to_string()), "abAB");
|
||||
assert_eq!(reduce_polymer(&"aabAAB".to_string()), "aabAAB");
|
||||
assert_eq!(reduce_polymer(&"dabAcCaCBAcCcaDA".to_string()), "dabAaCBAcaDA");
|
||||
assert_eq!(reduce_polymer(&"dabAaCBAcCcaDA".to_string()), "dabCBAcaDA");
|
||||
assert_eq!(reduce_polymer(&"dabCBAcCcaDA".to_string()), "dabCBAcaDA");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reduces_polymer_completely() {
|
||||
assert_eq!(reduce_polymer_completely("dabAcCaCBAcCcaDA".to_string()), "dabCBAcaDA");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_polymer() {
|
||||
assert_eq!(read_polymer(TEST_INPUT).unwrap(), "dabAcCaCBAcCcaDA");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_shortest_unit_eliminated_polymer() {
|
||||
assert_eq!(find_shortest_unit_eliminated_polymer("dabAcCaCBAcCcaDA".to_string()), 4);
|
||||
}
|
||||
}
|
490
src/day6.rs
Normal file
490
src/day6.rs
Normal file
@ -0,0 +1,490 @@
|
||||
extern crate regex;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::fmt;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use regex::{Regex, Captures};
|
||||
|
||||
static ALPHABET: [char; 52] = [
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
||||
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
];
|
||||
const INPUT: &str = "inputs/6.txt";
|
||||
|
||||
#[derive(Debug, PartialEq, Copy, Clone, Eq, Hash)]
|
||||
struct Coordinate {
|
||||
x: u32,
|
||||
y: u32,
|
||||
letter: char,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
enum GridPoint {
|
||||
Unfilled {
|
||||
x: u32,
|
||||
y: u32,
|
||||
},
|
||||
Tied {
|
||||
x: u32,
|
||||
y: u32,
|
||||
closest_dist: u32,
|
||||
},
|
||||
Filled {
|
||||
x: u32,
|
||||
y: u32,
|
||||
closest_coord: Coordinate,
|
||||
closest_dist: u32,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct Grid {
|
||||
points: Vec<GridPoint>,
|
||||
boundary_coord: Coordinate,
|
||||
}
|
||||
|
||||
impl fmt::Display for Coordinate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.letter)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Grid {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "\n-----")?;
|
||||
for (index, point) in self.points.iter().enumerate() {
|
||||
if index as u32 % (self.boundary_coord.x + 1) == 0 {
|
||||
write!(f, "\n")?;
|
||||
}
|
||||
match point {
|
||||
GridPoint::Unfilled { x: _, y: _ } => { write!(f, "-")?; },
|
||||
GridPoint::Tied { x: _, y: _, closest_dist: _} => {
|
||||
write!(f, ".")?;
|
||||
},
|
||||
GridPoint::Filled { x, y, closest_coord, closest_dist: _ } => {
|
||||
if *x == closest_coord.x && *y == closest_coord.y {
|
||||
write!(f, "#")?;
|
||||
} else {
|
||||
write!(f, "{}", closest_coord)?;
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
write!(f, "\n-----")?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct MalformedCoordinate {
|
||||
details: String
|
||||
}
|
||||
|
||||
impl MalformedCoordinate {
|
||||
fn new(msg: &str) -> MalformedCoordinate {
|
||||
MalformedCoordinate{ details: msg.to_string() }
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for MalformedCoordinate {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{}", self.details)
|
||||
}
|
||||
}
|
||||
|
||||
impl Error for MalformedCoordinate {
|
||||
fn description(&self) -> &str {
|
||||
&self.details
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve_part1() -> Result<u32, Box<Error>> {
|
||||
let coords = read_coordinates(INPUT)?;
|
||||
let boundary_coord = get_boundary_coordinate(&coords);
|
||||
let mut grid = create_grid(boundary_coord);
|
||||
fill_grid(&mut grid, &coords).unwrap();
|
||||
println!("{}", grid);
|
||||
Ok(find_largest_coord_area(grid))
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<u32, Box<Error>> {
|
||||
let coords = read_coordinates(INPUT)?;
|
||||
let boundary_coord = get_boundary_coordinate(&coords);
|
||||
let grid = create_grid(boundary_coord);
|
||||
Ok(region_closest_to_coordinates_size(grid, coords))
|
||||
}
|
||||
|
||||
fn read_coordinates(filename: &str) -> Result<Vec<Coordinate>, Box<Error>> {
|
||||
let mut records: Vec<Coordinate> = Vec::new();
|
||||
lazy_static! {
|
||||
static ref COORDINATE_REGEX: Regex = Regex::new(
|
||||
r"(?P<x>\d+), (?P<y>\d+)").unwrap();
|
||||
}
|
||||
let file = File::open(filename)?;
|
||||
for (index, line) in BufReader::new(file).lines().enumerate() {
|
||||
match COORDINATE_REGEX.captures(&line?) {
|
||||
Some(captures) => {
|
||||
records.push(Coordinate {
|
||||
x: get_captured_field(&captures, "x")?.parse()?,
|
||||
y: get_captured_field(&captures, "y")?.parse()?,
|
||||
letter: ALPHABET[index],
|
||||
});
|
||||
},
|
||||
None => return Err(Box::new(MalformedCoordinate {
|
||||
details: "Malformed coordinate line, no fields could be found".to_string()
|
||||
})),
|
||||
};
|
||||
}
|
||||
Ok(records)
|
||||
}
|
||||
|
||||
fn get_captured_field(captures: &Captures, field: &str) -> Result<String, Box<Error>> {
|
||||
match captures.name(field) {
|
||||
Some(capture) => Ok(String::from(capture.as_str())),
|
||||
None => return Err(Box::new(MalformedCoordinate {
|
||||
details: format!("Malformed coordinate line, field {} could not be found", field)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
fn get_boundary_coordinate(coords: &Vec<Coordinate>) -> Coordinate {
|
||||
let mut boundary_coord = Coordinate { x: 0, y: 0, letter: '+' };
|
||||
for coord in coords {
|
||||
if coord.x > boundary_coord.x {
|
||||
boundary_coord.x = coord.x;
|
||||
}
|
||||
if coord.y > boundary_coord.y {
|
||||
boundary_coord.y = coord.y;
|
||||
}
|
||||
}
|
||||
boundary_coord
|
||||
}
|
||||
|
||||
fn create_grid(boundary_coord: Coordinate) -> Grid {
|
||||
let mut points = Vec::new();
|
||||
for y in 0..boundary_coord.y + 1 {
|
||||
for x in 0..boundary_coord.x + 1 {
|
||||
points.push(GridPoint::Unfilled { x, y });
|
||||
}
|
||||
}
|
||||
Grid { points, boundary_coord }
|
||||
}
|
||||
|
||||
fn fill_grid<'a>(
|
||||
grid: &'a mut Grid,
|
||||
coords: &'a Vec<Coordinate>,
|
||||
) -> Result<&'a mut Grid, Box<Error>> {
|
||||
for coord in coords {
|
||||
let start_index = (coord.x * (grid.boundary_coord.y + 1)) + coord.y;
|
||||
fill_grid_with_coordinate(
|
||||
grid,
|
||||
start_index,
|
||||
*coord,
|
||||
)?;
|
||||
}
|
||||
Ok(grid)
|
||||
}
|
||||
|
||||
fn fill_grid_with_coordinate(
|
||||
grid: &mut Grid,
|
||||
index: u32,
|
||||
coord: Coordinate,
|
||||
) -> Result<&mut Grid, Box<Error>> {
|
||||
let mut visited_indices = HashSet::new();
|
||||
for point in &mut grid.points {
|
||||
visited_indices.insert(index);
|
||||
match *point {
|
||||
GridPoint::Unfilled { x, y } => {
|
||||
*point = GridPoint::Filled {
|
||||
x: x,
|
||||
y: y,
|
||||
closest_coord: coord,
|
||||
closest_dist: manhattan_dist(coord.x, coord.y, x, y),
|
||||
};
|
||||
},
|
||||
GridPoint::Tied { x, y, closest_dist } => {
|
||||
let dist = manhattan_dist(coord.x, coord.y, x, y);
|
||||
if dist < closest_dist {
|
||||
*point = GridPoint::Filled {
|
||||
x: x,
|
||||
y: y,
|
||||
closest_coord: coord,
|
||||
closest_dist: dist,
|
||||
};
|
||||
}
|
||||
},
|
||||
GridPoint::Filled { x, y, closest_coord, closest_dist } => {
|
||||
let dist = manhattan_dist(coord.x, coord.y, x, y);
|
||||
if dist < closest_dist {
|
||||
*point = GridPoint::Filled {
|
||||
x: x,
|
||||
y: y,
|
||||
closest_coord: coord,
|
||||
closest_dist: dist,
|
||||
};
|
||||
} else if dist == closest_dist && closest_coord != coord {
|
||||
*point = GridPoint::Tied {
|
||||
x: x,
|
||||
y: y,
|
||||
closest_dist: dist,
|
||||
};
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(grid)
|
||||
}
|
||||
|
||||
fn manhattan_dist(x1: u32, y1: u32, x2: u32, y2: u32) -> u32 {
|
||||
((x2 as i32 - x1 as i32).abs() + (y2 as i32 - y1 as i32).abs()) as u32
|
||||
}
|
||||
|
||||
fn find_largest_coord_area(
|
||||
grid: Grid,
|
||||
) -> u32 {
|
||||
let mut point_count = HashMap::new();
|
||||
let mut infinite_coords = HashSet::new();
|
||||
for point in grid.points.iter() {
|
||||
match point {
|
||||
GridPoint::Filled { x, y, closest_coord: coord, closest_dist: _ } => {
|
||||
if *x == 0 || *x == grid.boundary_coord.x ||
|
||||
*y == 0 || *y == grid.boundary_coord.y {
|
||||
point_count.remove(coord);
|
||||
infinite_coords.insert(coord);
|
||||
continue;
|
||||
}
|
||||
if !infinite_coords.contains(coord) {
|
||||
let count = point_count.entry(coord).or_insert(0);
|
||||
*count += 1;
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
*point_count.values().max().unwrap_or(&0)
|
||||
}
|
||||
|
||||
fn region_closest_to_coordinates_size(grid: Grid, coords: Vec<Coordinate>) -> u32 {
|
||||
let mut points_in_region = 0;
|
||||
for point in grid.points.iter() {
|
||||
match point {
|
||||
GridPoint::Filled { x, y, closest_coord: _, closest_dist: _ } |
|
||||
GridPoint::Tied { x, y, closest_dist: _ } |
|
||||
GridPoint::Unfilled { x, y } => {
|
||||
let mut sum = 0;
|
||||
for coord in coords.iter() {
|
||||
sum += manhattan_dist(coord.x, coord.y, *x, *y);
|
||||
}
|
||||
if sum < 10000 {
|
||||
points_in_region += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
points_in_region
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/6_test.txt";
|
||||
|
||||
#[test]
|
||||
fn read_coordinates_file() {
|
||||
assert_eq!(read_coordinates(TEST_INPUT).unwrap(), vec![
|
||||
Coordinate {
|
||||
x: 1,
|
||||
y: 1,
|
||||
letter: 'a',
|
||||
},
|
||||
Coordinate {
|
||||
x: 1,
|
||||
y: 6,
|
||||
letter: 'b',
|
||||
},
|
||||
Coordinate {
|
||||
x: 8,
|
||||
y: 3,
|
||||
letter: 'c',
|
||||
},
|
||||
Coordinate {
|
||||
x: 3,
|
||||
y: 4,
|
||||
letter: 'd',
|
||||
},
|
||||
Coordinate {
|
||||
x: 5,
|
||||
y: 5,
|
||||
letter: 'e',
|
||||
},
|
||||
Coordinate {
|
||||
x: 8,
|
||||
y: 9,
|
||||
letter: 'f',
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_boundary_coordinate() {
|
||||
assert_eq!(get_boundary_coordinate(&vec![
|
||||
Coordinate {
|
||||
x: 1,
|
||||
y: 1,
|
||||
letter: 'a',
|
||||
},
|
||||
Coordinate {
|
||||
x: 5,
|
||||
y: 5,
|
||||
letter: 'b',
|
||||
},
|
||||
Coordinate {
|
||||
x: 2,
|
||||
y: 7,
|
||||
letter: 'c',
|
||||
}
|
||||
]),
|
||||
Coordinate {
|
||||
x: 5,
|
||||
y: 7,
|
||||
letter: '+',
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn creates_grid() {
|
||||
let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
|
||||
assert_eq!(
|
||||
create_grid(boundary_coord),
|
||||
Grid {
|
||||
points: vec![
|
||||
GridPoint::Unfilled {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
GridPoint::Unfilled {
|
||||
x: 1,
|
||||
y: 0,
|
||||
},
|
||||
GridPoint::Unfilled {
|
||||
x: 0,
|
||||
y: 1,
|
||||
},
|
||||
GridPoint::Unfilled {
|
||||
x: 1,
|
||||
y: 1,
|
||||
},
|
||||
],
|
||||
boundary_coord,
|
||||
})
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn calculates_manhattan_dist() {
|
||||
assert_eq!(manhattan_dist(0, 0, 2, 1), 3);
|
||||
assert_eq!(manhattan_dist(0, 0, 0, 0), 0);
|
||||
assert_eq!(manhattan_dist(2, 1, 0, 0), 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fills_grid_with_one_coord() {
|
||||
let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
|
||||
let mut grid = create_grid(boundary_coord);
|
||||
let coord = Coordinate { x: 0, y: 0, letter: 'a' };
|
||||
assert_eq!(
|
||||
fill_grid(&mut grid, &vec![coord]).unwrap(),
|
||||
&mut Grid {
|
||||
points: vec![
|
||||
GridPoint::Filled {
|
||||
x: 0,
|
||||
y: 0,
|
||||
closest_coord: coord,
|
||||
closest_dist: 0,
|
||||
},
|
||||
GridPoint::Filled {
|
||||
x: 1,
|
||||
y: 0,
|
||||
closest_coord: coord,
|
||||
closest_dist: 1,
|
||||
},
|
||||
GridPoint::Filled {
|
||||
x: 0,
|
||||
y: 1,
|
||||
closest_coord: coord,
|
||||
closest_dist: 1,
|
||||
},
|
||||
GridPoint::Filled {
|
||||
x: 1,
|
||||
y: 1,
|
||||
closest_coord: coord,
|
||||
closest_dist: 2,
|
||||
},
|
||||
],
|
||||
boundary_coord
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fills_grid_with_two_coords() {
|
||||
let boundary_coord = Coordinate { x: 1, y: 1, letter: '+' };
|
||||
let mut grid = create_grid(boundary_coord);
|
||||
let coord_a = Coordinate { x: 0, y: 0, letter: 'a' };
|
||||
let coord_b = Coordinate { x: 1, y: 1, letter: 'b' };
|
||||
assert_eq!(
|
||||
fill_grid(&mut grid, &vec![coord_a, coord_b]).unwrap(),
|
||||
&mut Grid {
|
||||
points: vec![
|
||||
GridPoint::Filled {
|
||||
x: 0,
|
||||
y: 0,
|
||||
closest_coord: coord_a,
|
||||
closest_dist: 0,
|
||||
},
|
||||
GridPoint::Tied {
|
||||
x: 1,
|
||||
y: 0,
|
||||
closest_dist: 1,
|
||||
},
|
||||
GridPoint::Tied {
|
||||
x: 0,
|
||||
y: 1,
|
||||
closest_dist: 1,
|
||||
},
|
||||
GridPoint::Filled {
|
||||
x: 1,
|
||||
y: 1,
|
||||
closest_coord: coord_b,
|
||||
closest_dist: 0,
|
||||
},
|
||||
],
|
||||
boundary_coord
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn finds_largest_coord_area() {
|
||||
let boundary_coord = Coordinate { x: 2, y: 2, letter: '+' };
|
||||
let mut grid = create_grid(boundary_coord);
|
||||
let coords = vec![
|
||||
Coordinate { x: 0, y: 0, letter: 'a' },
|
||||
Coordinate { x: 2, y: 2, letter: 'b' },
|
||||
Coordinate { x: 1, y: 1, letter: 'c' },
|
||||
];
|
||||
fill_grid(&mut grid, &coords).unwrap();
|
||||
assert_eq!(
|
||||
find_largest_coord_area(grid),
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
487
src/day7.rs
Normal file
487
src/day7.rs
Normal file
@ -0,0 +1,487 @@
|
||||
extern crate regex;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::result;
|
||||
|
||||
use regex::{Captures, Regex};
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
type Instructions = HashMap<char, Vec<char>>;
|
||||
|
||||
const INPUT: &str = "inputs/7.txt";
|
||||
static ALPHABET: [char; 26] = [
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
|
||||
'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
];
|
||||
|
||||
pub fn solve_part1() -> Result<String> {
|
||||
let mut instructions = read_instructions(INPUT)?;
|
||||
Ok(get_step_sequence(&mut instructions))
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<u32> {
|
||||
let mut pool = WorkerPool::new(5);
|
||||
let mut instructions = read_instructions(INPUT)?;
|
||||
Ok(get_parallel_step_sequence_seconds(&mut instructions, &mut pool))
|
||||
}
|
||||
|
||||
fn read_instructions(filename: &str) -> Result<Instructions> {
|
||||
let mut instructions: Instructions = HashMap::new();
|
||||
lazy_static! {
|
||||
static ref INSTRUCTION_REGEX: Regex = Regex::new(
|
||||
r"Step (?P<dependency>\w) must be finished before step (?P<step>\w) can begin."
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
let file = File::open(filename)?;
|
||||
for line in BufReader::new(file).lines() {
|
||||
match INSTRUCTION_REGEX.captures(&line?) {
|
||||
Some(captures) => {
|
||||
let step = get_captured_field(&captures, "step")?;
|
||||
let dependency: char = get_captured_field(&captures, "dependency")?;
|
||||
instructions.entry(dependency).or_insert_with(Vec::new);
|
||||
let dependencies = instructions.entry(step).or_insert_with(Vec::new);
|
||||
dependencies.push(dependency);
|
||||
}
|
||||
None => {
|
||||
return Err(From::from(
|
||||
"Malformed instruction line, no fields could be found",
|
||||
))
|
||||
}
|
||||
};
|
||||
}
|
||||
Ok(instructions)
|
||||
}
|
||||
|
||||
fn get_captured_field(captures: &Captures, field: &str) -> Result<char> {
|
||||
match captures.name(field) {
|
||||
Some(capture) => match capture.as_str().chars().next() {
|
||||
Some(letter) => Ok(letter),
|
||||
None => Err(From::from(format!(
|
||||
"Malformed instruction line, field {} not a char",
|
||||
field
|
||||
))),
|
||||
},
|
||||
None => Err(From::from(format!(
|
||||
"Malformed instruction line, field {} could not be found",
|
||||
field
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_step_sequence(instructions: &mut Instructions) -> String {
|
||||
let mut sequence = String::new();
|
||||
loop {
|
||||
let mut available: Vec<char> = instructions
|
||||
.iter()
|
||||
.filter(|(_, dependencies)| dependencies.is_empty())
|
||||
.map(|(step, _)| *step)
|
||||
.collect();
|
||||
if available.is_empty() {
|
||||
break;
|
||||
}
|
||||
available.sort();
|
||||
available.reverse();
|
||||
let next = available.pop().unwrap();
|
||||
instructions.remove(&next);
|
||||
for dependencies in instructions.values_mut() {
|
||||
if let Some(index) = dependencies.iter().position(|d| *d == next) {
|
||||
dependencies.remove(index);
|
||||
}
|
||||
}
|
||||
sequence.push(next);
|
||||
}
|
||||
sequence
|
||||
}
|
||||
|
||||
fn get_parallel_step_sequence_seconds(
|
||||
mut instructions: &mut Instructions,
|
||||
worker_pool: &mut WorkerPool,
|
||||
) -> u32 {
|
||||
let mut sequence = String::new();
|
||||
let mut seconds = 0;
|
||||
loop {
|
||||
worker_pool.run_one_second(&mut instructions, &mut sequence);
|
||||
|
||||
let mut available: Vec<char> = instructions
|
||||
.iter()
|
||||
.filter(|(_, dependencies)| dependencies.is_empty())
|
||||
.map(|(step, _)| *step)
|
||||
.collect();
|
||||
|
||||
if available.is_empty() && worker_pool.all_idle() {
|
||||
break;
|
||||
}
|
||||
|
||||
available.sort();
|
||||
available.reverse();
|
||||
|
||||
for mut worker in worker_pool.available() {
|
||||
let next = match available.pop() {
|
||||
None => break,
|
||||
Some(next) => next,
|
||||
};
|
||||
instructions.remove(&next);
|
||||
worker_pool.assign_worker(worker.id, next);
|
||||
}
|
||||
seconds += 1;
|
||||
}
|
||||
println!("{}", sequence);
|
||||
seconds
|
||||
}
|
||||
|
||||
fn get_seconds_for_step(step_letter: char) -> u8 {
|
||||
ALPHABET.iter().position(|&c| c == step_letter).unwrap_or(0) as u8 + 61 as u8
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
struct Worker {
|
||||
id: u8,
|
||||
status: Status,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
enum Status {
|
||||
Idle,
|
||||
Working { step: char, remaining: u8 },
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct WorkerPool {
|
||||
workers: Vec<Worker>,
|
||||
}
|
||||
|
||||
impl WorkerPool {
|
||||
fn new(count: u8) -> WorkerPool {
|
||||
let mut workers = Vec::new();
|
||||
for i in 0..count {
|
||||
workers.push(Worker {
|
||||
id: i,
|
||||
status: Status::Idle,
|
||||
})
|
||||
}
|
||||
WorkerPool { workers }
|
||||
}
|
||||
|
||||
fn available(&self) -> Vec<Worker> {
|
||||
self.workers
|
||||
.iter()
|
||||
.filter(|worker| match worker.status {
|
||||
Status::Idle => true,
|
||||
Status::Working { .. } => false,
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn all_idle(&self) -> bool {
|
||||
self.workers
|
||||
.iter()
|
||||
.all(|worker| worker.status == Status::Idle)
|
||||
}
|
||||
|
||||
fn run_one_second(&mut self, instructions: &mut Instructions, sequence: &mut String) {
|
||||
let new_workers = self
|
||||
.workers
|
||||
.iter()
|
||||
.map(|worker| Worker {
|
||||
id: worker.id,
|
||||
status: match worker.status {
|
||||
Status::Idle => Status::Idle,
|
||||
Status::Working { step, remaining } => {
|
||||
if remaining == 1 {
|
||||
for dependencies in instructions.values_mut() {
|
||||
if let Some(index) = dependencies.iter().position(|d| *d == step) {
|
||||
dependencies.remove(index);
|
||||
}
|
||||
}
|
||||
sequence.push(step);
|
||||
Status::Idle
|
||||
} else {
|
||||
Status::Working {
|
||||
step,
|
||||
remaining: remaining - 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
.collect();
|
||||
self.workers = new_workers;
|
||||
}
|
||||
|
||||
fn assign_worker(&mut self, id: u8, step: char) {
|
||||
let new_workers = self
|
||||
.workers
|
||||
.iter()
|
||||
.map(|worker| {
|
||||
if worker.id == id {
|
||||
Worker {
|
||||
id: worker.id,
|
||||
status: Status::Working {
|
||||
step,
|
||||
remaining: get_seconds_for_step(step),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
*worker
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
self.workers = new_workers;
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for WorkerPool {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
for worker in &self.workers {
|
||||
writeln!(f, "{}", worker)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Worker {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.status {
|
||||
Status::Idle => write!(f, "{}: idle", self.id),
|
||||
Status::Working { step, remaining } => {
|
||||
write!(f, "{}: {} - {}", self.id, step, remaining)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/7_test.txt";
|
||||
|
||||
fn test_instructions() -> Instructions {
|
||||
[
|
||||
('A', vec!['C']),
|
||||
('F', vec!['C']),
|
||||
('C', vec![]),
|
||||
('B', vec!['A']),
|
||||
('D', vec!['A']),
|
||||
('E', vec!['B', 'D', 'F']),
|
||||
]
|
||||
.iter()
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_instructions_file() {
|
||||
assert_eq!(read_instructions(TEST_INPUT).unwrap(), test_instructions());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_step_sequence() {
|
||||
assert_eq!(get_step_sequence(&mut test_instructions()), "CABDFE");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn new_worker_pool() {
|
||||
assert_eq!(
|
||||
WorkerPool::new(3),
|
||||
WorkerPool {
|
||||
workers: vec![
|
||||
Worker {
|
||||
id: 0,
|
||||
status: Status::Idle
|
||||
},
|
||||
Worker {
|
||||
id: 1,
|
||||
status: Status::Idle
|
||||
},
|
||||
Worker {
|
||||
id: 2,
|
||||
status: Status::Idle
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn available_workers_in_pool() {
|
||||
let pool = WorkerPool {
|
||||
workers: vec![
|
||||
Worker {
|
||||
id: 0,
|
||||
status: Status::Idle,
|
||||
},
|
||||
Worker {
|
||||
id: 1,
|
||||
status: Status::Working {
|
||||
step: 'A',
|
||||
remaining: 1,
|
||||
},
|
||||
},
|
||||
Worker {
|
||||
id: 2,
|
||||
status: Status::Idle,
|
||||
},
|
||||
],
|
||||
};
|
||||
assert_eq!(
|
||||
pool.available(),
|
||||
vec![
|
||||
Worker {
|
||||
id: 0,
|
||||
status: Status::Idle
|
||||
},
|
||||
Worker {
|
||||
id: 2,
|
||||
status: Status::Idle
|
||||
},
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_workers_one_second() {
|
||||
let mut pool = WorkerPool {
|
||||
workers: vec![
|
||||
Worker {
|
||||
id: 0,
|
||||
status: Status::Idle,
|
||||
},
|
||||
Worker {
|
||||
id: 1,
|
||||
status: Status::Working {
|
||||
step: 'A',
|
||||
remaining: 2,
|
||||
},
|
||||
},
|
||||
Worker {
|
||||
id: 2,
|
||||
status: Status::Idle,
|
||||
},
|
||||
],
|
||||
};
|
||||
pool.run_one_second(&mut test_instructions(), &mut String::new());
|
||||
assert_eq!(
|
||||
pool,
|
||||
WorkerPool {
|
||||
workers: vec![
|
||||
Worker {
|
||||
id: 0,
|
||||
status: Status::Idle
|
||||
},
|
||||
Worker {
|
||||
id: 1,
|
||||
status: Status::Working {
|
||||
step: 'A',
|
||||
remaining: 1
|
||||
}
|
||||
},
|
||||
Worker {
|
||||
id: 2,
|
||||
status: Status::Idle
|
||||
},
|
||||
]
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn run_workers_one_second_and_complete_step() {
|
||||
let mut pool = WorkerPool {
|
||||
workers: vec![Worker {
|
||||
id: 0,
|
||||
status: Status::Working {
|
||||
step: 'A',
|
||||
remaining: 1,
|
||||
},
|
||||
}],
|
||||
};
|
||||
let mut instructions = [('A', vec![])].iter().cloned().collect();
|
||||
let mut sequence = "Z".to_string();
|
||||
pool.run_one_second(&mut instructions, &mut sequence);
|
||||
assert_eq!(
|
||||
pool,
|
||||
WorkerPool {
|
||||
workers: vec![Worker {
|
||||
id: 0,
|
||||
status: Status::Idle
|
||||
},]
|
||||
}
|
||||
);
|
||||
assert_eq!(instructions, [('A', vec![])].iter().cloned().collect());
|
||||
assert_eq!(sequence, "ZA".to_string());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_pool_all_idle() {
|
||||
assert_eq!(WorkerPool::new(3).all_idle(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn worker_pool_not_all_idle() {
|
||||
assert_eq!(
|
||||
WorkerPool {
|
||||
workers: vec![
|
||||
Worker {
|
||||
id: 0,
|
||||
status: Status::Idle
|
||||
},
|
||||
Worker {
|
||||
id: 1,
|
||||
status: Status::Working {
|
||||
step: 'A',
|
||||
remaining: 1
|
||||
}
|
||||
},
|
||||
],
|
||||
}
|
||||
.all_idle(),
|
||||
false
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn assign_step_to_worker_in_pool() {
|
||||
let mut pool = WorkerPool::new(2);
|
||||
pool.assign_worker(0, 'A');
|
||||
assert_eq!(
|
||||
pool,
|
||||
WorkerPool {
|
||||
workers: vec![
|
||||
Worker {
|
||||
id: 0,
|
||||
status: Status::Working {
|
||||
step: 'A',
|
||||
remaining: 61,
|
||||
}
|
||||
},
|
||||
Worker {
|
||||
id: 1,
|
||||
status: Status::Idle,
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_seconds_for_step() {
|
||||
assert_eq!(get_seconds_for_step('A'), 61);
|
||||
assert_eq!(get_seconds_for_step('B'), 62);
|
||||
assert_eq!(get_seconds_for_step('Z'), 86);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_sequence_with_workers() {
|
||||
let mut pool = WorkerPool::new(2);
|
||||
let mut instructions = test_instructions();
|
||||
assert_eq!(get_parallel_step_sequence_seconds(&mut instructions, &mut pool), 258);
|
||||
}
|
||||
}
|
94
src/day8.rs
Normal file
94
src/day8.rs
Normal file
@ -0,0 +1,94 @@
|
||||
use std::error::Error;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/8.txt";
|
||||
|
||||
pub fn solve_part1() -> Result<u32> {
|
||||
let license = read_license(INPUT)?;
|
||||
Ok(sum_metadata(&license, 0, 0).0)
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<u32> {
|
||||
let license = read_license(INPUT)?;
|
||||
Ok(sum_metadata_with_indices(&license, 0).0)
|
||||
}
|
||||
|
||||
fn read_license(filename: &str) -> Result<Vec<u32>> {
|
||||
let license = fs::read_to_string(filename)?;
|
||||
let license = license.trim();
|
||||
Ok(license.split(' ').map(|num| num.parse().unwrap()).collect())
|
||||
}
|
||||
|
||||
fn sum_metadata(license: &[u32], mut index: usize, mut sum_acc: u32) -> (u32, usize) {
|
||||
let num_children = license[index];
|
||||
let num_metadata = license[index + 1];
|
||||
index += 2;
|
||||
if num_children != 0 {
|
||||
for _ in 0..num_children {
|
||||
let (child_sum_acc, child_index) = sum_metadata(license, index, sum_acc);
|
||||
sum_acc = child_sum_acc;
|
||||
index = child_index;
|
||||
}
|
||||
}
|
||||
if num_metadata != 0 {
|
||||
let sum: u32 = license[index..index + num_metadata as usize].iter().sum();
|
||||
index += num_metadata as usize;
|
||||
sum_acc += sum;
|
||||
}
|
||||
(sum_acc, index)
|
||||
}
|
||||
|
||||
fn sum_metadata_with_indices(license: &[u32], mut index: usize) -> (u32, usize) {
|
||||
let mut sum: u32 = 0;
|
||||
let num_children = license[index];
|
||||
let num_metadata = license[index + 1];
|
||||
index += 2;
|
||||
if num_children != 0 {
|
||||
let mut child_sums: Vec<u32> = Vec::new();
|
||||
for _ in 0..num_children {
|
||||
let (child_sum, child_index) = sum_metadata_with_indices(license, index);
|
||||
index = child_index;
|
||||
child_sums.push(child_sum)
|
||||
}
|
||||
|
||||
if num_metadata != 0 {
|
||||
sum = license[index..index + num_metadata as usize]
|
||||
.iter()
|
||||
.map(|num| *child_sums.get(*num as usize - 1).unwrap_or(&0))
|
||||
.sum();
|
||||
index += num_metadata as usize;
|
||||
}
|
||||
} else if num_metadata != 0 {
|
||||
sum = license[index..index + num_metadata as usize].iter().sum();
|
||||
index += num_metadata as usize;
|
||||
}
|
||||
(sum, index)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/8_test.txt";
|
||||
fn test_license() -> Vec<u32> {
|
||||
vec![2, 3, 0, 3, 10, 11, 12, 1, 1, 0, 1, 99, 2, 1, 1, 2]
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reads_license_file() {
|
||||
assert_eq!(read_license(TEST_INPUT).unwrap(), test_license());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sums_license_metadata() {
|
||||
assert_eq!(sum_metadata(&test_license(), 0, 0).0, 138);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sums_license_metadata_with_indices() {
|
||||
assert_eq!(sum_metadata_with_indices(&test_license(), 0).0, 66);
|
||||
}
|
||||
}
|
232
src/day9.rs
Normal file
232
src/day9.rs
Normal file
@ -0,0 +1,232 @@
|
||||
extern crate regex;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
use std::fs;
|
||||
use std::result;
|
||||
use std::str::FromStr;
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use regex::Regex;
|
||||
|
||||
type Result<T> = result::Result<T, Box<Error>>;
|
||||
|
||||
const INPUT: &str = "inputs/9.txt";
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
struct GameParameters {
|
||||
players: usize,
|
||||
last_marble: usize,
|
||||
}
|
||||
|
||||
impl FromStr for GameParameters {
|
||||
type Err = Box<Error>;
|
||||
|
||||
fn from_str(s: &str) -> Result<GameParameters> {
|
||||
lazy_static! {
|
||||
static ref RE: Regex = Regex::new(
|
||||
r"(?P<players>\d+) players; last marble is worth (?P<last_marble>\d+) points"
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
let captures = match RE.captures(s) {
|
||||
None => {
|
||||
return Err(From::from(
|
||||
"Malformed game parameters, no fields could be found",
|
||||
));
|
||||
}
|
||||
Some(captures) => captures,
|
||||
};
|
||||
Ok(GameParameters {
|
||||
players: captures["players"].parse()?,
|
||||
last_marble: captures["last_marble"].parse()?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
struct GameState {
|
||||
turn: Option<usize>,
|
||||
circle: VecDeque<usize>,
|
||||
current_marble: usize,
|
||||
player_scores: Vec<usize>,
|
||||
}
|
||||
|
||||
impl GameState {
|
||||
fn new(parameters: GameParameters) -> GameState {
|
||||
GameState {
|
||||
turn: None,
|
||||
circle: VecDeque::from(vec![0]),
|
||||
current_marble: 0,
|
||||
player_scores: vec![0; parameters.players as usize],
|
||||
}
|
||||
}
|
||||
|
||||
fn rotate_clockwise(&mut self, steps: usize) {
|
||||
for _ in 0..steps {
|
||||
if let Some(marble) = self.circle.pop_back() {
|
||||
self.circle.push_front(marble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rotate_counter_clockwise(&mut self, steps: usize) {
|
||||
for _ in 0..steps {
|
||||
if let Some(marble) = self.circle.pop_front() {
|
||||
self.circle.push_back(marble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn play_until_marble(&mut self, last_marble: usize) {
|
||||
for _ in 0..last_marble {
|
||||
self.turn = match self.turn {
|
||||
None => Some(0),
|
||||
Some(turn) => Some((turn + 1) % self.player_scores.len()),
|
||||
};
|
||||
|
||||
if (self.current_marble + 1) % 23 == 0 {
|
||||
self.place_23rd_marble();
|
||||
} else {
|
||||
self.place_next_marble();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn place_next_marble(&mut self) {
|
||||
self.current_marble += 1;
|
||||
self.rotate_counter_clockwise(1);
|
||||
self.circle.push_back(self.current_marble);
|
||||
}
|
||||
|
||||
fn place_23rd_marble(&mut self) {
|
||||
self.current_marble += 1;
|
||||
|
||||
self.player_scores[self.turn.unwrap()] += self.current_marble;
|
||||
self.rotate_clockwise(7);
|
||||
if let Some(marble) = self.circle.pop_back() {
|
||||
self.player_scores[self.turn.unwrap()] += marble;
|
||||
}
|
||||
self.rotate_counter_clockwise(1);
|
||||
}
|
||||
|
||||
fn highest_score(&mut self) -> usize {
|
||||
*self.player_scores.iter().max().unwrap_or(&0)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GameState {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self.turn {
|
||||
None => write!(f, "[-] ")?,
|
||||
Some(turn) => write!(f, "[{}] ", turn + 1)?,
|
||||
}
|
||||
for (index, marble) in self.circle.iter().enumerate() {
|
||||
if index == self.circle.len() - 1 {
|
||||
write!(f, "({}) ", marble)?;
|
||||
} else {
|
||||
write!(f, "{} ", marble)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn solve_part1() -> Result<usize> {
|
||||
let game_params = read_game_parameters(INPUT)?;
|
||||
Ok(get_highest_score_for_game(game_params))
|
||||
}
|
||||
|
||||
pub fn solve_part2() -> Result<usize> {
|
||||
let mut game_params = read_game_parameters(INPUT)?;
|
||||
game_params.last_marble *= 100;
|
||||
Ok(get_highest_score_for_game(game_params))
|
||||
}
|
||||
|
||||
fn read_game_parameters(filename: &str) -> Result<GameParameters> {
|
||||
let game_params = fs::read_to_string(filename)?;
|
||||
Ok(game_params.parse()?)
|
||||
}
|
||||
|
||||
fn get_highest_score_for_game(game_params: GameParameters) -> usize {
|
||||
let mut game_state = GameState::new(game_params);
|
||||
game_state.play_until_marble(game_params.last_marble);
|
||||
game_state.highest_score()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const TEST_INPUT: &str = "inputs/9_test.txt";
|
||||
const TEST_GAME_PARAMS: GameParameters = GameParameters {
|
||||
players: 9,
|
||||
last_marble: 25,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn reads_game_parameters_file() {
|
||||
assert_eq!(read_game_parameters(TEST_INPUT).unwrap(), TEST_GAME_PARAMS);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_highest_score_for_game1() {
|
||||
assert_eq!(get_highest_score_for_game(TEST_GAME_PARAMS), 32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_highest_score_for_game2() {
|
||||
assert_eq!(
|
||||
get_highest_score_for_game(GameParameters {
|
||||
players: 10,
|
||||
last_marble: 1618,
|
||||
}),
|
||||
8317
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_highest_score_for_game3() {
|
||||
assert_eq!(
|
||||
get_highest_score_for_game(GameParameters {
|
||||
players: 13,
|
||||
last_marble: 7999,
|
||||
}),
|
||||
146_373
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_highest_score_for_game4() {
|
||||
assert_eq!(
|
||||
get_highest_score_for_game(GameParameters {
|
||||
players: 17,
|
||||
last_marble: 1104,
|
||||
}),
|
||||
2764
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_highest_score_for_game5() {
|
||||
assert_eq!(
|
||||
get_highest_score_for_game(GameParameters {
|
||||
players: 21,
|
||||
last_marble: 6111,
|
||||
}),
|
||||
54718
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gets_highest_score_for_game6() {
|
||||
assert_eq!(
|
||||
get_highest_score_for_game(GameParameters {
|
||||
players: 30,
|
||||
last_marble: 5807,
|
||||
}),
|
||||
37305
|
||||
);
|
||||
}
|
||||
}
|
74
src/main.rs
74
src/main.rs
@ -1,19 +1,69 @@
|
||||
#![warn(clippy)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
mod day1;
|
||||
mod day2;
|
||||
mod day3;
|
||||
mod day4;
|
||||
mod day5;
|
||||
mod day6;
|
||||
mod day7;
|
||||
mod day8;
|
||||
mod day9;
|
||||
mod day10;
|
||||
mod day11;
|
||||
mod day12;
|
||||
mod day13;
|
||||
mod day14;
|
||||
|
||||
fn main() {
|
||||
println!("Day 1:");
|
||||
println!("{}", day1::solve_part1().unwrap());
|
||||
println!("{}", day1::solve_part2().unwrap().unwrap());
|
||||
println!("Day 2:");
|
||||
println!("{}", day2::solve_part1().unwrap());
|
||||
println!("{}", day2::solve_part2().unwrap().unwrap());
|
||||
println!("Day 3:");
|
||||
println!("{}", day3::solve_part1().unwrap());
|
||||
println!("{}", day3::solve_part2().unwrap().unwrap());
|
||||
println!("Day 4:");
|
||||
println!("{}", day4::solve_part1().unwrap());
|
||||
println!("{}", day4::solve_part2().unwrap());
|
||||
// println!("Day 1:");
|
||||
// println!("{}", day1::solve_part1().unwrap());
|
||||
// println!("{}", day1::solve_part2().unwrap().unwrap());
|
||||
// println!("Day 2:");
|
||||
// println!("{}", day2::solve_part1().unwrap());
|
||||
// println!("{}", day2::solve_part2().unwrap().unwrap());
|
||||
// println!("Day 3:");
|
||||
// println!("{}", day3::solve_part1().unwrap());
|
||||
// println!("{}", day3::solve_part2().unwrap().unwrap());
|
||||
// println!("Day 4:");
|
||||
// println!("{}", day4::solve_part1().unwrap());
|
||||
// println!("{}", day4::solve_part2().unwrap());
|
||||
// println!("Day 5:");
|
||||
// println!("{}", day5::solve_part1().unwrap());
|
||||
// println!("{}", day5::solve_part2().unwrap());
|
||||
// println!("Day 6:");
|
||||
// println!("{}", day6::solve_part1().unwrap());
|
||||
// println!("{}", day6::solve_part2().unwrap());
|
||||
// println!("Day 7:");
|
||||
// println!("{}", day7::solve_part1().unwrap());
|
||||
// println!("{}", day7::solve_part2().unwrap());
|
||||
// println!("Day 8:");
|
||||
// println!("{}", day8::solve_part1().unwrap());
|
||||
// println!("{}", day8::solve_part2().unwrap());
|
||||
// println!("Day 9:");
|
||||
// println!("{}", day9::solve_part1().unwrap());
|
||||
// println!("{}", day9::solve_part2().unwrap());
|
||||
// println!("Day 10:");
|
||||
// let parts = day10::solve_parts().unwrap();
|
||||
// println!("{}", parts.0);
|
||||
// println!("{}", parts.1);
|
||||
// println!("Day 11:");
|
||||
// let part1 = day11::solve_part1().unwrap();
|
||||
// println!("{},{}", part1.coord.x, part1.coord.y);
|
||||
// let part2 = day11::solve_part2().unwrap();
|
||||
// println!("{},{},{}", part2.coord.x, part2.coord.y, part2.size);
|
||||
// println!("Day 12:");
|
||||
// println!("{}", day12::solve_part1().unwrap());
|
||||
// println!("{}", day12::solve_part2().unwrap());
|
||||
// println!("Day 13");
|
||||
// let part1 = day13::solve_part1().unwrap();
|
||||
// println!("{},{}", part1.x, part1.y);
|
||||
// println!("{},{}", part2.x, part2.y);
|
||||
// let part2 = day13::solve_part2().unwrap();
|
||||
println!("Day 14");
|
||||
println!("{}", day14::solve_part1().unwrap());
|
||||
println!("{}", day14::solve_part2().unwrap());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user