Compare commits
No commits in common. 'main' and 'sorbet' have entirely different histories.
@ -1,3 +0,0 @@
|
|||||||
[submodule "2022/bqn/lib"]
|
|
||||||
path = 2022/bqn/lib
|
|
||||||
url = https://github.com/mlochbaum/bqn-libs.git
|
|
@ -1,145 +1,146 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
[root]
|
||||||
# It is not intended for manual editing.
|
name = "advent_of_code"
|
||||||
version = 3
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"permutohedron 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "advapi32-sys"
|
name = "advapi32-sys"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "307c92332867e586720c0222ee9d890bbe8431711efed8a1b06bc5b40fc66bd7"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi-build",
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "advent_of_code"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"permutohedron",
|
|
||||||
"regex",
|
|
||||||
"rust-crypto",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.18"
|
version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca10e3e1f1c8278047da19b94dc17c4397861150d5fbcea052eedb1d9847d356"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"advapi32-sys",
|
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi",
|
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "kernel32-sys"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5b5e7edf375e6d26243bde172f1d5ed1446f4a766fc9b7006e1fd27258243f1"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi-build",
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.4"
|
version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "10569e57695cc2c91ca4214357907649c9e242dc822c9ae623d0e0b0d68aa4d9"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
dependencies = [
|
||||||
|
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "permutohedron"
|
name = "permutohedron"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "abf78a1e8b52782de92fc4f361362a62bcf5fd5718b5432b48cb381485740b83"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.3.12"
|
version = "0.3.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5eee40bdf3d293e1648490ab47e5471d9ab3e455e6b0bd48e558c454be4a015e"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"advapi32-sys",
|
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.4",
|
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi",
|
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.5"
|
version = "0.1.44"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr",
|
"memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex-syntax",
|
"regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.26"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-crypto"
|
name = "rust-crypto"
|
||||||
version = "0.2.34"
|
version = "0.2.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8672a8eb8db93d0938972e391159ba66912b415285ee5cf0ebe732df9e53b70"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc",
|
"gcc 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.1.12",
|
"libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand",
|
"rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize",
|
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time",
|
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "rustc-serialize"
|
||||||
version = "0.3.16"
|
version = "0.3.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a48546a64cae47d06885e9bccadb99d0547d877a94c5167fa451ea33a484456"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.34"
|
version = "0.1.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8c4aeaa1c95974f5763c3a5ac0db95a19793589bcea5d22e161b5587e3aad029"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys",
|
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.4",
|
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi",
|
"winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc3583688b861fcd83c2823d37cf2cd2446c233dd7ba3f97884d1a7302817537"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-build"
|
name = "winapi-build"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
|
||||||
|
[metadata]
|
||||||
|
"checksum advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "307c92332867e586720c0222ee9d890bbe8431711efed8a1b06bc5b40fc66bd7"
|
||||||
|
"checksum aho-corasick 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f36f237c490deb976b38aca6369182dceb5a7af249aabf41c0ba5a964bac5ed"
|
||||||
|
"checksum gcc 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "ca10e3e1f1c8278047da19b94dc17c4397861150d5fbcea052eedb1d9847d356"
|
||||||
|
"checksum kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b5b5e7edf375e6d26243bde172f1d5ed1446f4a766fc9b7006e1fd27258243f1"
|
||||||
|
"checksum libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e32a70cf75e5846d53a673923498228bbec6a8624708a9ea5645f075d6276122"
|
||||||
|
"checksum libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "10569e57695cc2c91ca4214357907649c9e242dc822c9ae623d0e0b0d68aa4d9"
|
||||||
|
"checksum memchr 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "dc66b0957bf6ae6590681ceac49b0df16823d43037d49aaf2ee658d483af30ab"
|
||||||
|
"checksum permutohedron 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "abf78a1e8b52782de92fc4f361362a62bcf5fd5718b5432b48cb381485740b83"
|
||||||
|
"checksum rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "5eee40bdf3d293e1648490ab47e5471d9ab3e455e6b0bd48e558c454be4a015e"
|
||||||
|
"checksum regex 0.1.44 (registry+https://github.com/rust-lang/crates.io-index)" = "e0940ad6bf8abf79e3210809a6a49e199fc8e00b7deafc0d9394157f56f5401e"
|
||||||
|
"checksum regex-syntax 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fcf1e805b0a23c845be2a303136d840a1511284727bc1f1fc32d079552ef901f"
|
||||||
|
"checksum rust-crypto 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)" = "b8672a8eb8db93d0938972e391159ba66912b415285ee5cf0ebe732df9e53b70"
|
||||||
|
"checksum rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)" = "1a48546a64cae47d06885e9bccadb99d0547d877a94c5167fa451ea33a484456"
|
||||||
|
"checksum time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)" = "8c4aeaa1c95974f5763c3a5ac0db95a19793589bcea5d22e161b5587e3aad029"
|
||||||
|
"checksum winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "dc3583688b861fcd83c2823d37cf2cd2446c233dd7ba3f97884d1a7302817537"
|
||||||
|
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||||
|
@ -1,173 +1,201 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
[root]
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "advent_of_code_2016"
|
name = "advent_of_code_2016"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"error-chain",
|
"error-chain 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex",
|
"regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rust-crypto",
|
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.18"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace-sys",
|
"backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"cfg-if",
|
"cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"dbghelp-sys",
|
"dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"kernel32-sys",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc",
|
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-demangle",
|
"rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace-sys"
|
name = "backtrace-sys"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3602e8d8c43336088a8505fa55cae2b3884a9be29440863a11528a42f46f6bb7"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc",
|
"gcc 0.3.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc",
|
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dbghelp-sys"
|
name = "dbghelp-sys"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi-build",
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "error-chain"
|
name = "error-chain"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1cd681735364a04cd5d69f01a4f6768e70473941f8d86d8c224faf6955a75799"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gcc"
|
name = "gcc"
|
||||||
version = "0.3.39"
|
version = "0.3.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "771e4a97ff6f237cf0f7d5f5102f6e28bb9743814b6198d684da5c58b76c11e0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "kernel32-sys"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"winapi",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi-build",
|
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.18"
|
version = "0.2.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "0.1.11"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
dependencies = [
|
||||||
|
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.5"
|
version = "0.1.80"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr",
|
"memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex-syntax",
|
"regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.26"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-crypto"
|
name = "rust-crypto"
|
||||||
version = "0.2.36"
|
version = "0.2.36"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"gcc",
|
"gcc 0.3.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc",
|
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand",
|
"rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize",
|
"rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"time",
|
"time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1430d286cadb237c17c885e25447c982c97113926bb579f4379c0eca8d9586dc"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-serialize"
|
name = "rustc-serialize"
|
||||||
version = "0.3.21"
|
version = "0.3.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread-id"
|
||||||
|
version = "2.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "0.2.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
dependencies = [
|
||||||
|
"thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.35"
|
version = "0.1.35"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"kernel32-sys",
|
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc",
|
"libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"winapi",
|
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-ranges"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.2.8"
|
version = "0.2.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi-build"
|
name = "winapi-build"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
|
||||||
|
[metadata]
|
||||||
|
"checksum aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ca972c2ea5f742bfce5687b9aef75506a764f61d37f8f649047846a9686ddb66"
|
||||||
|
"checksum backtrace 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f551bc2ddd53aea015d453ef0b635af89444afa5ed2405dd0b2062ad5d600d80"
|
||||||
|
"checksum backtrace-sys 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3602e8d8c43336088a8505fa55cae2b3884a9be29440863a11528a42f46f6bb7"
|
||||||
|
"checksum cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de1e760d7b6535af4241fca8bd8adf68e2e7edacc6b29f5d399050c5e48cf88c"
|
||||||
|
"checksum dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "97590ba53bcb8ac28279161ca943a924d1fd4a8fb3fa63302591647c4fc5b850"
|
||||||
|
"checksum error-chain 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1cd681735364a04cd5d69f01a4f6768e70473941f8d86d8c224faf6955a75799"
|
||||||
|
"checksum gcc 0.3.39 (registry+https://github.com/rust-lang/crates.io-index)" = "771e4a97ff6f237cf0f7d5f5102f6e28bb9743814b6198d684da5c58b76c11e0"
|
||||||
|
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||||
|
"checksum libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "a51822fc847e7a8101514d1d44e354ba2ffa7d4c194dcab48870740e327cac70"
|
||||||
|
"checksum memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d8b629fb514376c675b98c1421e80b151d3817ac42d7c667717d282761418d20"
|
||||||
|
"checksum rand 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "022e0636ec2519ddae48154b028864bdce4eaf7d35226ab8e65c611be97b189d"
|
||||||
|
"checksum regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)" = "4fd4ace6a8cf7860714a2c2280d6c1f7e6a413486c13298bbc86fd3da019402f"
|
||||||
|
"checksum regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f9ec002c35e86791825ed294b50008eea9ddfc8def4420124fbc6b08db834957"
|
||||||
|
"checksum rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||||
|
"checksum rustc-demangle 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1430d286cadb237c17c885e25447c982c97113926bb579f4379c0eca8d9586dc"
|
||||||
|
"checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818"
|
||||||
|
"checksum thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a9539db560102d1cef46b8b78ce737ff0bb64e7e18d35b2a5688f7d097d0ff03"
|
||||||
|
"checksum thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8576dbbfcaef9641452d5cf0df9b0e7eeab7694956dd33bb61515fb8f18cfdd5"
|
||||||
|
"checksum time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "3c7ec6d62a20df54e07ab3b78b9a3932972f4b7981de295563686849eb3989af"
|
||||||
|
"checksum utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1ca13c08c41c9c3e04224ed9ff80461d97e121589ff27c753a16cb10830ae0f"
|
||||||
|
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||||
|
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||||
|
@ -1,205 +1,252 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
|
||||||
# It is not intended for manual editing.
|
|
||||||
version = 3
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "advent_of_code"
|
name = "advent_of_code"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pest",
|
"pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pest_derive",
|
"pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex",
|
"regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aho-corasick"
|
name = "aho-corasick"
|
||||||
version = "0.7.18"
|
version = "0.6.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "block-buffer"
|
name = "block-buffer"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byte-tools",
|
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byte-tools"
|
name = "byte-tools"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"generic-array",
|
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fake-simd"
|
name = "fake-simd"
|
||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "generic-array"
|
name = "generic-array"
|
||||||
version = "0.9.1"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6d00328cedcac5e81c683e5620ca6a30756fc23027ebf9bff405c0e8da1fbb7e"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"typenum",
|
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "maplit"
|
name = "maplit"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
dependencies = [
|
||||||
|
"cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest"
|
name = "pest"
|
||||||
version = "2.0.2"
|
version = "2.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a677051ad923732bb5c70f2d45f8985a96e3eee2e2bff86697e3b11b0c3fcfde"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ucd-trie",
|
"ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_derive"
|
name = "pest_derive"
|
||||||
version = "2.0.1"
|
version = "2.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b76f477146419bc539a63f4ef40e902166cb43b3e51cecc71d9136fd12c567e7"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pest_generator",
|
"pest_generator 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_generator"
|
name = "pest_generator"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3ebee4e9680be4fd162e6f3394ae4192a6b60b1e4d17d845e631f0c68d1a3386"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pest",
|
"pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pest_meta",
|
"pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"proc-macro2",
|
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote",
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"syn",
|
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pest_meta"
|
name = "pest_meta"
|
||||||
version = "2.0.3"
|
version = "2.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1f6d5f6f0e6082578c86af197d780dc38328e3f768cec06aac9bc46d714e8221"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"maplit",
|
"maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"pest",
|
"pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sha-1",
|
"sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "0.4.24"
|
version = "0.4.24"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "0.6.10"
|
version = "0.6.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.5.5"
|
version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"memchr",
|
"memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"regex-syntax",
|
"regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"utf8-ranges 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.26"
|
version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "49b3de9ec5dc0a3417da371aab17d729997c15010e7fd24ff707773a33bddb64"
|
dependencies = [
|
||||||
|
"ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha-1"
|
name = "sha-1"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer",
|
"block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"byte-tools",
|
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"digest",
|
"digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"fake-simd",
|
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "0.14.9"
|
version = "0.14.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
|
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"quote",
|
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"unicode-xid",
|
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "0.3.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)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ucd-trie"
|
name = "ucd-trie"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-util"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-xid"
|
name = "unicode-xid"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8-ranges"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.1.5"
|
||||||
|
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 arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
|
||||||
|
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
|
||||||
|
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
|
||||||
|
"checksum cfg-if 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "082bb9b28e00d3c9d39cc03e64ce4cea0f1bb9b3fde493f0cbc008472d22bdf4"
|
||||||
|
"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
|
||||||
|
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||||
|
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
|
||||||
|
"checksum lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a374c89b9db55895453a74c1e38861d9deec0b01b405a82516e9d5de4820dea1"
|
||||||
|
"checksum libc 0.2.44 (registry+https://github.com/rust-lang/crates.io-index)" = "10923947f84a519a45c8fefb7dd1b3e8c08747993381adee176d7a82b4195311"
|
||||||
|
"checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
|
||||||
|
"checksum memchr 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0a3eb002f0535929f1199681417029ebea04aadc0c7a4224b46be99c7f5d6a16"
|
||||||
|
"checksum pest 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a677051ad923732bb5c70f2d45f8985a96e3eee2e2bff86697e3b11b0c3fcfde"
|
||||||
|
"checksum pest_derive 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b76f477146419bc539a63f4ef40e902166cb43b3e51cecc71d9136fd12c567e7"
|
||||||
|
"checksum pest_generator 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ebee4e9680be4fd162e6f3394ae4192a6b60b1e4d17d845e631f0c68d1a3386"
|
||||||
|
"checksum pest_meta 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1f6d5f6f0e6082578c86af197d780dc38328e3f768cec06aac9bc46d714e8221"
|
||||||
|
"checksum proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)" = "77619697826f31a02ae974457af0b29b723e5619e113e9397b8b82c6bd253f09"
|
||||||
|
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
|
||||||
|
"checksum regex 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37e7cbbd370869ce2e8dff25c7018702d10b21a20ef7135316f8daecd6c25b7f"
|
||||||
|
"checksum regex-syntax 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4e47a2ed29da7a9e1960e1639e7a982e6edc6d49be308a3b02daf511504a16d1"
|
||||||
|
"checksum sha-1 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "51b9d1f3b5de8a167ab06834a7c883bd197f2191e1dda1a22d9ccfeedbf9aded"
|
||||||
|
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
|
||||||
|
"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
|
||||||
|
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
|
||||||
|
"checksum ucd-trie 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "71a9c5b1fe77426cf144cc30e49e955270f5086e31a6441dfa8b32efc09b9d77"
|
||||||
|
"checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86"
|
||||||
|
"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"
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
require "rake/testtask"
|
|
||||||
|
|
||||||
task default: [:test, :srb]
|
|
||||||
|
|
||||||
Rake::TestTask.new do |t|
|
|
||||||
t.libs << "test"
|
|
||||||
t.test_files = FileList["test_*.rb"]
|
|
||||||
t.verbose = true
|
|
||||||
end
|
|
||||||
|
|
||||||
task :srb do
|
|
||||||
sh "srb tc"
|
|
||||||
end
|
|
@ -1,27 +0,0 @@
|
|||||||
require_relative "computer"
|
|
||||||
|
|
||||||
program = ARGF.read
|
|
||||||
|
|
||||||
p (5..9).to_a.permutation.map {|phase_settings|
|
|
||||||
amplifiers = Array.new(5) { Computer.from(program) }
|
|
||||||
|
|
||||||
pipes = Array.new(5) { IO.pipe }
|
|
||||||
|
|
||||||
# input phase settings
|
|
||||||
pipes.zip(phase_settings).each do |(_, w), ps|
|
|
||||||
w.puts(ps)
|
|
||||||
end
|
|
||||||
|
|
||||||
# first 0 signal
|
|
||||||
pipes.first.last.puts(?0)
|
|
||||||
|
|
||||||
ios = pipes.cycle.each_cons(2).take(5).map {|(r, _), (_, w)| [r, w] }
|
|
||||||
|
|
||||||
ts = amplifiers.zip(ios).map {|(a, (i, o))|
|
|
||||||
Thread.new { a.run(i, o) }
|
|
||||||
}
|
|
||||||
ts.each(&:join)
|
|
||||||
|
|
||||||
thrusters_input = ios.first.first
|
|
||||||
thrusters_input.gets.to_i
|
|
||||||
}.max
|
|
@ -1,17 +0,0 @@
|
|||||||
image = ARGF.read.scan(/\d/).map(&:to_i)
|
|
||||||
|
|
||||||
w = 25
|
|
||||||
h = 6
|
|
||||||
|
|
||||||
# l = image.each_slice(w*h).min_by {|l| l.count(0) }
|
|
||||||
# p l.count(1) * l.count(2)
|
|
||||||
|
|
||||||
layers = image.each_slice(w*h)
|
|
||||||
puts layers
|
|
||||||
.inject {|n,l| n.zip(l) }
|
|
||||||
.map(&:flatten)
|
|
||||||
.map {|layers| layers.drop_while {|p| p == 2 }.first }
|
|
||||||
.map {|p| p.zero? ? "█" : " " }
|
|
||||||
.each_slice(w)
|
|
||||||
.map(&:join)
|
|
||||||
.join("\n")
|
|
@ -1,6 +0,0 @@
|
|||||||
require_relative "computer"
|
|
||||||
|
|
||||||
program = ARGF.read
|
|
||||||
c = Computer.from(program)
|
|
||||||
|
|
||||||
c.run(StringIO.new("2"))
|
|
@ -1,32 +0,0 @@
|
|||||||
require "pp"
|
|
||||||
|
|
||||||
asteroids = ARGF.read.strip.lines.map(&:strip).map {|l| l.chars }
|
|
||||||
|
|
||||||
max_y = asteroids.size
|
|
||||||
max_x = asteroids.first.size
|
|
||||||
|
|
||||||
asteroids = asteroids.flat_map.with_index {|row, y|
|
|
||||||
row.filter_map.with_index {|l, x| l == ?. ? nil : [x, y] }
|
|
||||||
}
|
|
||||||
|
|
||||||
asteroids = asteroids.each.with_object({}) {|(x, y), h|
|
|
||||||
visible = asteroids
|
|
||||||
.reject {|ax, ay| [x, y] == [ax, ay] }
|
|
||||||
.each.with_object(Hash.new {|h,k| h[k] = [] }) {|(ax, ay), ah|
|
|
||||||
rad = (Math.atan2(ax - x, y - ay) + 2*Math::PI) % (2*Math::PI)
|
|
||||||
ah[rad] << [ax, ay]
|
|
||||||
}
|
|
||||||
|
|
||||||
h[[x, y]] = visible
|
|
||||||
}
|
|
||||||
|
|
||||||
station = asteroids.max_by {|_,v| v.size }
|
|
||||||
# p station.last.size
|
|
||||||
|
|
||||||
asteroids = station.last.to_h.sort_by(&:first).map(&:last)
|
|
||||||
199.times do
|
|
||||||
a = asteroids.shift
|
|
||||||
asteroids.concat(a[1..-1]) if a.first.is_a?(Array)
|
|
||||||
end
|
|
||||||
x, y = asteroids.first.first
|
|
||||||
p 100*x + y
|
|
@ -1,47 +0,0 @@
|
|||||||
# typed: ignore
|
|
||||||
|
|
||||||
require "stringio"
|
|
||||||
|
|
||||||
require_relative "computer"
|
|
||||||
|
|
||||||
include Math
|
|
||||||
|
|
||||||
panels = Hash.new {|h,k| h[k] = [0]}
|
|
||||||
panels[[0, 0]] = [1]
|
|
||||||
|
|
||||||
i_r, i_w = IO.pipe
|
|
||||||
o_r, o_w = IO.pipe
|
|
||||||
|
|
||||||
Robot = Struct.new(:panel, :rad)
|
|
||||||
|
|
||||||
robot = Robot.new([0, 0], PI/2)
|
|
||||||
|
|
||||||
t = Thread.new {
|
|
||||||
loop do
|
|
||||||
i_w.puts(panels[robot.panel].last)
|
|
||||||
|
|
||||||
panels[robot.panel] << o_r.gets.to_i
|
|
||||||
dir = o_r.gets.to_i
|
|
||||||
raise "unexpected direction: #{dir}" unless [0, 1].include?(dir)
|
|
||||||
|
|
||||||
robot.rad += -(2*dir - 1) * (PI/2)
|
|
||||||
|
|
||||||
delta = [cos(robot.rad).to_i, sin(robot.rad).to_i]
|
|
||||||
robot.panel = robot.panel.zip(delta).map(&:sum)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread.new { Computer.from(ARGF.read).run(i_r, o_w) }.join
|
|
||||||
|
|
||||||
# p panels.values.count {|v| v.size > 1 }
|
|
||||||
|
|
||||||
min_x, max_x = panels.keys.map(&:first).minmax
|
|
||||||
min_y, max_y = panels.keys.map(&:last).minmax
|
|
||||||
|
|
||||||
letters = (min_y..max_y).map {|y|
|
|
||||||
(min_x..max_x).map {|x|
|
|
||||||
(panels[[x, y]].last == 1) ? ?█ : " "
|
|
||||||
}.join
|
|
||||||
}.reverse.join("\n")
|
|
||||||
|
|
||||||
puts letters
|
|
@ -1,126 +0,0 @@
|
|||||||
# typed: ignore
|
|
||||||
|
|
||||||
require "matrix"
|
|
||||||
require "prime"
|
|
||||||
require "set"
|
|
||||||
|
|
||||||
V = Vector
|
|
||||||
Moon = Struct.new(:id, :pos, :vel) do
|
|
||||||
def potential_energy
|
|
||||||
pos.map(&:abs).sum
|
|
||||||
end
|
|
||||||
|
|
||||||
def kinetic_energy
|
|
||||||
vel.map(&:abs).sum
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Moons < SimpleDelegator
|
|
||||||
def self.from(input)
|
|
||||||
moons = input
|
|
||||||
.scan(/x=(-?\d+), y=(-?\d+), z=(-?\d+)/)
|
|
||||||
.map.with_index {|x,i| Moon.new(i, V[*x.map(&:to_i)], V.zero(3)) }
|
|
||||||
new(moons)
|
|
||||||
end
|
|
||||||
|
|
||||||
def step
|
|
||||||
# apply gravity
|
|
||||||
deltas = Hash.new {|h,k| h[k] = V.zero(3) }
|
|
||||||
combination(2).each do |a, b|
|
|
||||||
delta = V[*a.pos.zip(b.pos).map {|a,b| a <=> b }]
|
|
||||||
deltas[a] -= delta
|
|
||||||
deltas[b] += delta
|
|
||||||
end
|
|
||||||
|
|
||||||
# apply velocity
|
|
||||||
Moons.new(map {|m|
|
|
||||||
v = m.vel + deltas.fetch(m)
|
|
||||||
Moon.new(m.id, m.pos + v, v)
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
def energy
|
|
||||||
map {|m| m.potential_energy * m.kinetic_energy }.sum
|
|
||||||
end
|
|
||||||
|
|
||||||
def fingerprint(axis)
|
|
||||||
map {|m| [m.pos[axis], m.vel[axis]] }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
require "minitest"
|
|
||||||
|
|
||||||
class TestMoons < Minitest::Test
|
|
||||||
def setup
|
|
||||||
@moons = Moons.from(<<~MOONS)
|
|
||||||
<x=-1, y=0, z=2>
|
|
||||||
<x=2, y=-10, z=-7>
|
|
||||||
<x=4, y=-8, z=8>
|
|
||||||
<x=3, y=5, z=-1>
|
|
||||||
MOONS
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_from
|
|
||||||
assert_equal Moon.new(0, V[-1, 0, 2], V[0, 0, 0]), @moons.fetch(0)
|
|
||||||
assert_equal Moon.new(3, V[3, 5, -1], V[0, 0, 0]), @moons.fetch(3)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_step
|
|
||||||
moons = @moons.step
|
|
||||||
|
|
||||||
assert_equal Moon.new(0, V[2, -1, 1], V[3, -1, -1]), moons.fetch(0)
|
|
||||||
assert_equal Moon.new(3, V[2, 2, 0], V[-1, -3, 1]), moons.fetch(3)
|
|
||||||
|
|
||||||
9.times do
|
|
||||||
moons = moons.step
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal Moon.new(0, V[2, 1, -3], V[-3, -2, 1]), moons.fetch(0)
|
|
||||||
assert_equal Moon.new(3, V[2, 0, 4], V[1, -1, -1]), moons.fetch(3)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_energy
|
|
||||||
10.times do
|
|
||||||
@moons = @moons.step
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_equal 179, @moons.energy
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def gcd(*n)
|
|
||||||
n.map {|c| Prime.prime_division(c).to_h }
|
|
||||||
.inject {|h,p| h.merge(p) {|_, a, b| [a, b].max }}
|
|
||||||
.map {|n,e| n**e }
|
|
||||||
.inject(&:*)
|
|
||||||
end
|
|
||||||
|
|
||||||
if ARGF.to_io.tty?
|
|
||||||
require "minitest/autorun"
|
|
||||||
else
|
|
||||||
moons = Moons.from(ARGF.read)
|
|
||||||
|
|
||||||
# 1000.times do
|
|
||||||
# moons = moons.step
|
|
||||||
# end
|
|
||||||
# puts moons.energy
|
|
||||||
|
|
||||||
seen = [{}, {}, {}]
|
|
||||||
cycles = [nil, nil, nil]
|
|
||||||
(0..).each do |step|
|
|
||||||
if cycles.none?(&:nil?)
|
|
||||||
puts gcd(*cycles.map(&:size))
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
(0..2).each do |i|
|
|
||||||
seen[i][moons.fingerprint(i)] ||= step
|
|
||||||
end
|
|
||||||
|
|
||||||
moons = moons.step
|
|
||||||
|
|
||||||
(0..2).each do |i|
|
|
||||||
cycles[i] ||= (seen[i][moons.fingerprint(i)]..step) if seen[i].include?(moons.fingerprint(i))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,103 +0,0 @@
|
|||||||
# typed: ignore
|
|
||||||
|
|
||||||
require "stringio"
|
|
||||||
|
|
||||||
require_relative "computer"
|
|
||||||
|
|
||||||
class Game
|
|
||||||
def initialize
|
|
||||||
@output = Hash.new(0)
|
|
||||||
@min_x, @max_x, @min_y, @max_y = 0, 0, 0, 0
|
|
||||||
end
|
|
||||||
|
|
||||||
def []=(x, y, value)
|
|
||||||
@output[[x, y]] = value
|
|
||||||
|
|
||||||
@min_x = [@min_x, x].min
|
|
||||||
@max_x = [@max_x, x].max
|
|
||||||
@min_y = [@min_y, y].min
|
|
||||||
@max_y = [@max_y, y].max
|
|
||||||
end
|
|
||||||
|
|
||||||
def ball_pos
|
|
||||||
@output.key(4)
|
|
||||||
end
|
|
||||||
|
|
||||||
def paddle_pos
|
|
||||||
@output.key(3)
|
|
||||||
end
|
|
||||||
|
|
||||||
def score
|
|
||||||
@output[[-1, 0]]
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
min_x = [0, @min_x].max
|
|
||||||
|
|
||||||
screen = (@min_y..@max_y).map {|y|
|
|
||||||
(min_x..@max_x).map {|x|
|
|
||||||
tile(@output[[x, y]])
|
|
||||||
}.join
|
|
||||||
}.join("\n")
|
|
||||||
|
|
||||||
score = @output[[-1, 0]] || 0
|
|
||||||
|
|
||||||
"#{screen}\n#{score}"
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def tile(id)
|
|
||||||
case id
|
|
||||||
when 0 then " "
|
|
||||||
when 1 then ?█
|
|
||||||
when 2 then ?▒
|
|
||||||
when 3 then ?▄
|
|
||||||
when 4 then ?@
|
|
||||||
else fail "unexpected tile id: #{id}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class FollowBall
|
|
||||||
def initialize(game)
|
|
||||||
@game = game
|
|
||||||
@last_ball = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def gets
|
|
||||||
ball, paddle = nil, nil
|
|
||||||
until [ball, paddle].none?(&:nil?) && ball != @last_ball
|
|
||||||
ball = @game.ball_pos
|
|
||||||
paddle = @game.paddle_pos
|
|
||||||
end
|
|
||||||
@last_ball = ball
|
|
||||||
|
|
||||||
# puts @game
|
|
||||||
|
|
||||||
# STDIN.gets
|
|
||||||
ball[0] <=> paddle[0]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
game = Game.new
|
|
||||||
follow_ball = FollowBall.new(game)
|
|
||||||
output, output_writer = IO.pipe
|
|
||||||
|
|
||||||
Thread.new do
|
|
||||||
loop do
|
|
||||||
x, y, tile_id = 3.times.map { output.gets.to_i }
|
|
||||||
game[x, y] = tile_id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Thread.new do
|
|
||||||
program = File.read("day_13.txt").split(?,).map(&:to_i)
|
|
||||||
program[0] = 2
|
|
||||||
|
|
||||||
Computer.new(program).run(follow_ball, output_writer)
|
|
||||||
|
|
||||||
sleep 1
|
|
||||||
|
|
||||||
puts game.score
|
|
||||||
end.join
|
|
File diff suppressed because one or more lines are too long
@ -1,37 +0,0 @@
|
|||||||
reactions = ARGF.read.strip.lines.each.with_object({}) {|line, h|
|
|
||||||
reactands = line.scan(/(\d+) (\w+)/).map {|q,c| [c,q.to_i] }
|
|
||||||
c, q = reactands.pop
|
|
||||||
h[c] = { quantity: q, inputs: reactands }
|
|
||||||
}.to_h
|
|
||||||
|
|
||||||
Factory = Struct.new(:reactions, :supply, :ores_used) do
|
|
||||||
def produce(chemical)
|
|
||||||
self.ores_used ||= 0
|
|
||||||
|
|
||||||
case reaction = reactions[chemical]
|
|
||||||
in { quantity: quantity, inputs: inputs }
|
|
||||||
until inputs.all? {|c,q| supply[c] >= q }
|
|
||||||
inputs
|
|
||||||
.select {|c,q| supply[c] < q }
|
|
||||||
.each do |c,_|
|
|
||||||
produce(c)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
inputs.each do |c,q|
|
|
||||||
self.ores_used += q if c == "ORE"
|
|
||||||
supply[c] -= q
|
|
||||||
end
|
|
||||||
|
|
||||||
supply[chemical] += quantity
|
|
||||||
else
|
|
||||||
fail "unexpected reaction: #{reaction}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
supply = Hash.new(0)
|
|
||||||
supply["ORE"] = Float::INFINITY
|
|
||||||
|
|
||||||
factory = Factory.new(reactions, supply)
|
|
||||||
factory.produce("FUEL")
|
|
@ -1,200 +0,0 @@
|
|||||||
1567
|
|
||||||
1223
|
|
||||||
1758
|
|
||||||
1842
|
|
||||||
1933
|
|
||||||
1898
|
|
||||||
1409
|
|
||||||
1058
|
|
||||||
1533
|
|
||||||
1417
|
|
||||||
1032
|
|
||||||
1634
|
|
||||||
1477
|
|
||||||
1394
|
|
||||||
1888
|
|
||||||
1972
|
|
||||||
1237
|
|
||||||
1390
|
|
||||||
1677
|
|
||||||
1546
|
|
||||||
1302
|
|
||||||
1070
|
|
||||||
1369
|
|
||||||
1455
|
|
||||||
1065
|
|
||||||
1924
|
|
||||||
1593
|
|
||||||
1131
|
|
||||||
1064
|
|
||||||
1346
|
|
||||||
1914
|
|
||||||
1129
|
|
||||||
1830
|
|
||||||
1450
|
|
||||||
1278
|
|
||||||
1740
|
|
||||||
1809
|
|
||||||
1176
|
|
||||||
1734
|
|
||||||
1102
|
|
||||||
1807
|
|
||||||
1982
|
|
||||||
1603
|
|
||||||
1736
|
|
||||||
2008
|
|
||||||
1980
|
|
||||||
1905
|
|
||||||
1633
|
|
||||||
1732
|
|
||||||
1350
|
|
||||||
1865
|
|
||||||
1988
|
|
||||||
1805
|
|
||||||
1998
|
|
||||||
1152
|
|
||||||
1046
|
|
||||||
1870
|
|
||||||
1557
|
|
||||||
1789
|
|
||||||
1766
|
|
||||||
1945
|
|
||||||
1359
|
|
||||||
1002
|
|
||||||
1126
|
|
||||||
1719
|
|
||||||
1497
|
|
||||||
1296
|
|
||||||
1560
|
|
||||||
1936
|
|
||||||
1929
|
|
||||||
1464
|
|
||||||
2005
|
|
||||||
1281
|
|
||||||
618
|
|
||||||
1257
|
|
||||||
1107
|
|
||||||
1632
|
|
||||||
1688
|
|
||||||
1964
|
|
||||||
1803
|
|
||||||
1360
|
|
||||||
1384
|
|
||||||
1889
|
|
||||||
1411
|
|
||||||
1328
|
|
||||||
1452
|
|
||||||
1868
|
|
||||||
1515
|
|
||||||
1586
|
|
||||||
1631
|
|
||||||
1618
|
|
||||||
1087
|
|
||||||
1710
|
|
||||||
1094
|
|
||||||
1774
|
|
||||||
1295
|
|
||||||
1700
|
|
||||||
1636
|
|
||||||
1230
|
|
||||||
1421
|
|
||||||
1910
|
|
||||||
1522
|
|
||||||
1366
|
|
||||||
1144
|
|
||||||
1757
|
|
||||||
1493
|
|
||||||
1316
|
|
||||||
1103
|
|
||||||
687
|
|
||||||
1371
|
|
||||||
1720
|
|
||||||
1155
|
|
||||||
1559
|
|
||||||
1900
|
|
||||||
989
|
|
||||||
1367
|
|
||||||
1999
|
|
||||||
1066
|
|
||||||
1773
|
|
||||||
1787
|
|
||||||
1402
|
|
||||||
1047
|
|
||||||
1806
|
|
||||||
1956
|
|
||||||
1219
|
|
||||||
1555
|
|
||||||
1307
|
|
||||||
1419
|
|
||||||
1706
|
|
||||||
1884
|
|
||||||
1109
|
|
||||||
1181
|
|
||||||
2010
|
|
||||||
1298
|
|
||||||
1730
|
|
||||||
1078
|
|
||||||
1848
|
|
||||||
1398
|
|
||||||
1687
|
|
||||||
2007
|
|
||||||
1550
|
|
||||||
1664
|
|
||||||
1225
|
|
||||||
1079
|
|
||||||
1698
|
|
||||||
350
|
|
||||||
1222
|
|
||||||
1377
|
|
||||||
1977
|
|
||||||
1510
|
|
||||||
1571
|
|
||||||
1630
|
|
||||||
1029
|
|
||||||
1379
|
|
||||||
1942
|
|
||||||
1949
|
|
||||||
1249
|
|
||||||
1829
|
|
||||||
1297
|
|
||||||
1530
|
|
||||||
1607
|
|
||||||
1324
|
|
||||||
1069
|
|
||||||
1476
|
|
||||||
928
|
|
||||||
1039
|
|
||||||
1855
|
|
||||||
1644
|
|
||||||
1454
|
|
||||||
1310
|
|
||||||
1172
|
|
||||||
547
|
|
||||||
1034
|
|
||||||
1878
|
|
||||||
1479
|
|
||||||
1457
|
|
||||||
1319
|
|
||||||
1810
|
|
||||||
1759
|
|
||||||
1439
|
|
||||||
1851
|
|
||||||
545
|
|
||||||
1470
|
|
||||||
2003
|
|
||||||
1908
|
|
||||||
1564
|
|
||||||
1491
|
|
||||||
1174
|
|
||||||
1301
|
|
||||||
1689
|
|
||||||
1276
|
|
||||||
1781
|
|
||||||
1392
|
|
||||||
1499
|
|
||||||
1962
|
|
||||||
1653
|
|
||||||
1823
|
|
||||||
1381
|
|
||||||
1827
|
|
||||||
1974
|
|
File diff suppressed because it is too large
Load Diff
@ -1 +0,0 @@
|
|||||||
3
|
|
@ -1,3 +0,0 @@
|
|||||||
n = 3
|
|
||||||
x = ARGF.read.split.map(&:to_i).combination(n).find {|x| x.sum == 2020 }
|
|
||||||
p x.reduce(&:*)
|
|
@ -1,5 +0,0 @@
|
|||||||
day1 = proc {|min,max,char,pass| (min..max).cover?(pass.count(char)) }
|
|
||||||
day2 = proc {|p1,p2,char,pass| [pass[p1-1], pass[p2-1]].count(char) == 1 }
|
|
||||||
puts ARGF.read.scan(/^(\d+)-(\d+)\s*(\w):\s*(\w+)$/)
|
|
||||||
.map {|a,b,c,d| [a.to_i, b.to_i, c, d] }
|
|
||||||
.count(&day2)
|
|
@ -1,15 +0,0 @@
|
|||||||
map = ARGF.read.split("\n").map(&:chars)
|
|
||||||
rows = map.size
|
|
||||||
cols = map[0].size
|
|
||||||
slopes = [
|
|
||||||
[1, 1],
|
|
||||||
[3, 1],
|
|
||||||
[5, 1],
|
|
||||||
[7, 1],
|
|
||||||
[1, 2],
|
|
||||||
]
|
|
||||||
puts slopes.map {|dx,dy|
|
|
||||||
Array.new(rows / dy) {|i| [dx*i % cols, dy*i] }
|
|
||||||
.map {|x,y| map[y][x] }
|
|
||||||
.count(?#)
|
|
||||||
}.reduce(&:*)
|
|
@ -1,25 +0,0 @@
|
|||||||
FIELDS = {
|
|
||||||
byr: ->(s) { s =~ /^\d{4}$/ && (1920..2002).cover?(s.to_i) },
|
|
||||||
iyr: ->(s) { s =~ /^\d{4}$/ && (2010..2020).cover?(s.to_i) },
|
|
||||||
eyr: ->(s) { s =~ /^\d{4}$/ && (2020..2030).cover?(s.to_i) },
|
|
||||||
hgt: ->(s) {
|
|
||||||
s =~ /^(\d+)(cm|in)$/
|
|
||||||
case $2
|
|
||||||
when "cm"
|
|
||||||
(150..193).cover?($1.to_i)
|
|
||||||
when "in"
|
|
||||||
(59..76).cover?($1.to_i)
|
|
||||||
else
|
|
||||||
false
|
|
||||||
end
|
|
||||||
},
|
|
||||||
hcl: ->(s) { s =~ /^#[0-9a-f]{6}$/ },
|
|
||||||
ecl: ->(s) { s =~ /^(amb|blu|brn|gry|grn|hzl|oth)$/ },
|
|
||||||
pid: ->(s) { s =~ /^\d{9}$/ },
|
|
||||||
cid: ->(s) { true },
|
|
||||||
}
|
|
||||||
|
|
||||||
puts ARGF.read.split("\n\n").map {|line| line.scan(/(\w+):(\S+)/).to_h }
|
|
||||||
.count {|passport|
|
|
||||||
FIELDS.map {|k,v| v[passport.fetch(k.to_s, "")] }.all?
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
seats = ARGF.read.split("\n")
|
|
||||||
.map {|pass| pass.tr("FB", "01").tr("LR", "01") }
|
|
||||||
.map {|pass| pass.to_i(2) }
|
|
||||||
p seats.max # day 1
|
|
||||||
|
|
||||||
p (0b1000..).find {|id| !seats.include?(id) }
|
|
@ -1,6 +0,0 @@
|
|||||||
p ARGF.read.split("\n\n").map {|group|
|
|
||||||
group.split("\n").map(&:chars)
|
|
||||||
}.map {|group|
|
|
||||||
# group.inject(&:|)
|
|
||||||
group.inject(&:&)
|
|
||||||
}.map(&:size).sum
|
|
@ -1,16 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
rules = ARGF.read.split("\n")
|
|
||||||
.map {|line| line.split(" bags contain") }.to_h
|
|
||||||
.transform_values {|v| v.scan(/(\d+) ([\w ]+) bags?/).map(&:reverse).to_h }
|
|
||||||
|
|
||||||
# bags = rules.select {|_,v| v.has_key?("shiny gold") }.map(&:first).to_set
|
|
||||||
# while true
|
|
||||||
# bags.merge(bags.flat_map {|bag| rules.select {|_,v| v.has_key?(bag) }.map(&:first) })
|
|
||||||
# p bags.size
|
|
||||||
# end
|
|
||||||
|
|
||||||
bags = Hash.new {|h,k|
|
|
||||||
h[k] = rules.fetch(k).map {|k,v| v.to_i + h[k] * v.to_i }.sum
|
|
||||||
}
|
|
||||||
p bags["shiny gold"]
|
|
@ -1,55 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
execute = ->(r, op, arg) {
|
|
||||||
delta = case op
|
|
||||||
when :acc
|
|
||||||
{ acc: arg, pc: 1 }
|
|
||||||
when :jmp
|
|
||||||
{ pc: arg }
|
|
||||||
when :nop
|
|
||||||
{ pc: 1 }
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
|
|
||||||
r.merge(delta) {|_, old, new| old + new }
|
|
||||||
}
|
|
||||||
|
|
||||||
# part 1
|
|
||||||
seen = Set.new
|
|
||||||
detect_loop = ->(r, op, arg) {
|
|
||||||
throw :halt if seen.include?(r[:pc])
|
|
||||||
seen << r[:pc]
|
|
||||||
|
|
||||||
execute[r, op, arg]
|
|
||||||
}
|
|
||||||
|
|
||||||
instructions = ARGF.read.scan(/(\w+) ([-+]\d+)/).map {|op,arg| [op.to_sym, arg.to_i] }
|
|
||||||
registers = Hash.new(0)
|
|
||||||
|
|
||||||
swaps = { nop: :jmp, jmp: :nop }
|
|
||||||
candidates = instructions.filter_map.with_index {|(op, arg), i|
|
|
||||||
swap = swaps[op]
|
|
||||||
if swap.nil?
|
|
||||||
nil
|
|
||||||
else
|
|
||||||
[i, [swap, arg]]
|
|
||||||
end
|
|
||||||
}.map {|i, swap|
|
|
||||||
candidate = instructions.clone
|
|
||||||
candidate[i] = swap
|
|
||||||
candidate
|
|
||||||
}
|
|
||||||
|
|
||||||
candidates.each do |candidate|
|
|
||||||
seen = Set.new
|
|
||||||
registers = Hash.new(0)
|
|
||||||
catch(:halt) do
|
|
||||||
while instruction = candidate[registers[:pc]]
|
|
||||||
registers = detect_loop[registers, *instruction]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
break if registers[:pc] == candidate.size
|
|
||||||
end
|
|
||||||
|
|
||||||
p registers[:acc]
|
|
@ -1,18 +0,0 @@
|
|||||||
N = 25
|
|
||||||
|
|
||||||
data = ARGF.read.scan(/\d+/).map(&:to_i)
|
|
||||||
|
|
||||||
invalid = data.each_cons(N+1).filter_map {|range|
|
|
||||||
n = range.pop
|
|
||||||
range.combination(2).map(&:sum).include?(n) ? nil : n
|
|
||||||
}.first
|
|
||||||
|
|
||||||
weakness = (0..).lazy.flat_map {|start|
|
|
||||||
(2..data.size-start-1).map {|len|
|
|
||||||
data[start, len]
|
|
||||||
}
|
|
||||||
}.find {|range|
|
|
||||||
range.sum == invalid
|
|
||||||
}.minmax.sum
|
|
||||||
|
|
||||||
p weakness
|
|
@ -1,29 +0,0 @@
|
|||||||
adapters = ARGF.read.scan(/\d+/).map(&:to_i)
|
|
||||||
|
|
||||||
outlet = 0
|
|
||||||
device = adapters.max + 3
|
|
||||||
|
|
||||||
dist = (adapters + [outlet, device]).sort.each_cons(2).map {|a,b| b - a }
|
|
||||||
|
|
||||||
# part 1
|
|
||||||
# tally = dist.tally
|
|
||||||
# p dist[1] * dist[3]
|
|
||||||
|
|
||||||
# programmatically figuring out the arrangements
|
|
||||||
# arrangements = Hash.new {|h,k|
|
|
||||||
# h[k] = (0..k-1).flat_map {|n| (2..k).to_a.combination(n).to_a }
|
|
||||||
# .reject {|c| (c << 1 << k+1).sort.each_cons(2).any? {|a,b| b-a > 3 }}
|
|
||||||
# .count
|
|
||||||
# }
|
|
||||||
|
|
||||||
# tribonacci
|
|
||||||
arrangements = Hash.new {|h,k| h[k] = h[k-1] + h[k-2] + h[k-3] }
|
|
||||||
arrangements[0] = 1
|
|
||||||
arrangements[1] = 1
|
|
||||||
arrangements[2] = 2
|
|
||||||
|
|
||||||
p dist
|
|
||||||
.slice_when {|a,b| a != b }
|
|
||||||
.select {|run| run.first == 1 }
|
|
||||||
.map {|run| arrangements[run.size] }
|
|
||||||
.inject(&:*)
|
|
@ -1,90 +0,0 @@
|
|||||||
class Layout
|
|
||||||
def self.from(raw, &logic)
|
|
||||||
seats = Hash.new
|
|
||||||
raw.split("\n").each.with_index do |row,y|
|
|
||||||
row.chars.each.with_index do |pos,x|
|
|
||||||
seats[[y,x]] = false if pos == ?L
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.new(seats, &logic)
|
|
||||||
end
|
|
||||||
|
|
||||||
attr_reader :seats, :y_max, :x_max
|
|
||||||
|
|
||||||
def initialize(seats, &logic)
|
|
||||||
@seats, @logic = seats, logic
|
|
||||||
@y_max = @seats.keys.map(&:first).max
|
|
||||||
@x_max = @seats.keys.map(&:last).max
|
|
||||||
end
|
|
||||||
|
|
||||||
def [](yx)
|
|
||||||
@seats[yx]
|
|
||||||
end
|
|
||||||
|
|
||||||
def each
|
|
||||||
return enum_for(__method__) unless block_given?
|
|
||||||
|
|
||||||
loop do
|
|
||||||
yield self
|
|
||||||
seats = tick(&@logic)
|
|
||||||
break if seats == @seats
|
|
||||||
@seats = seats
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def tick
|
|
||||||
@seats.keys.map {|yx|
|
|
||||||
[yx, @logic[self, yx]]
|
|
||||||
}.to_h
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
(0..@y_max).map {|y|
|
|
||||||
(0..@x_max).map {|x|
|
|
||||||
case @seats[[y,x]]
|
|
||||||
when true then ?#
|
|
||||||
when false then ?L
|
|
||||||
when nil then ?.
|
|
||||||
else fail
|
|
||||||
end
|
|
||||||
}.join
|
|
||||||
}.join("\n")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
NEIGHBORS = (-1..1).flat_map {|y| (-1..1).map {|x| [y, x] }} - [[0, 0]]
|
|
||||||
day1 = ->(layout, yx) {
|
|
||||||
y, x = yx
|
|
||||||
occupied_neighbors = NEIGHBORS.filter_map {|dy,dx| layout[[y+dy, x+dx]] }
|
|
||||||
if !layout[yx] && occupied_neighbors.empty?
|
|
||||||
true
|
|
||||||
elsif layout[yx] && occupied_neighbors.size >= 4
|
|
||||||
false
|
|
||||||
else
|
|
||||||
layout[yx]
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
day2 = ->(layout, yx) {
|
|
||||||
y, x = yx
|
|
||||||
occupied_neighbors = NEIGHBORS.filter_map {|dy,dx|
|
|
||||||
(1..).lazy
|
|
||||||
.map {|i| [y+dy*i, x+dx*i] }
|
|
||||||
.find {|y,x|
|
|
||||||
!(0..layout.y_max).cover?(y) ||
|
|
||||||
!(0..layout.x_max).cover?(x) ||
|
|
||||||
layout.seats.has_key?([y, x])
|
|
||||||
}
|
|
||||||
}.filter_map {|yx| layout[yx] }
|
|
||||||
if !layout[yx] && occupied_neighbors.empty?
|
|
||||||
true
|
|
||||||
elsif layout[yx] && occupied_neighbors.size >= 5
|
|
||||||
false
|
|
||||||
else
|
|
||||||
layout[yx]
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
layout = Layout.from(ARGF.read, &day2)
|
|
||||||
layout.each.take_while(&:itself).last
|
|
||||||
puts layout.seats.count(&:last)
|
|
@ -1,54 +0,0 @@
|
|||||||
actions = ARGF.read.scan(/(\w)(\d+)/).map {|a,v| [a, v.to_i] }
|
|
||||||
|
|
||||||
dir = 0
|
|
||||||
pos = [0, 0]
|
|
||||||
way = [10, 1]
|
|
||||||
actions.each do |a,v|
|
|
||||||
# delta = case a
|
|
||||||
# when ?N
|
|
||||||
# [ 0, v]
|
|
||||||
# when ?S
|
|
||||||
# [ 0, -v]
|
|
||||||
# when ?E
|
|
||||||
# [ v, 0]
|
|
||||||
# when ?W
|
|
||||||
# [-v, 0]
|
|
||||||
# when ?L
|
|
||||||
# dir += v
|
|
||||||
# [0, 0]
|
|
||||||
# when ?R
|
|
||||||
# dir -= v
|
|
||||||
# [0, 0]
|
|
||||||
# when ?F
|
|
||||||
# rad = dir * Math::PI / 180.0
|
|
||||||
# [v * Math.cos(rad), v * Math.sin(rad)].map(&:round)
|
|
||||||
# else
|
|
||||||
# fail
|
|
||||||
# end
|
|
||||||
case a
|
|
||||||
when ?N
|
|
||||||
way[1] += v
|
|
||||||
when ?S
|
|
||||||
way[1] -= v
|
|
||||||
when ?E
|
|
||||||
way[0] += v
|
|
||||||
when ?W
|
|
||||||
way[0] -= v
|
|
||||||
when ?L
|
|
||||||
rad = Math.atan2(*way.reverse)
|
|
||||||
dis = Math.sqrt(way.map {|x| x**2 }.sum)
|
|
||||||
rad += v * Math::PI / 180
|
|
||||||
way = [dis * Math.cos(rad), dis * Math.sin(rad)].map(&:round)
|
|
||||||
when ?R
|
|
||||||
rad = Math.atan2(*way.reverse)
|
|
||||||
dis = Math.sqrt(way.map {|x| x**2 }.sum)
|
|
||||||
rad -= v * Math::PI / 180
|
|
||||||
way = [dis * Math.cos(rad), dis * Math.sin(rad)].map(&:round)
|
|
||||||
when ?F
|
|
||||||
delta = way.map {|i| v * i }
|
|
||||||
pos = pos.zip(delta).map {|a,b| a + b }
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
p pos.map(&:abs).sum
|
|
@ -1,42 +0,0 @@
|
|||||||
input = ARGF.read.split("\n")
|
|
||||||
depart_time = input.shift.to_i
|
|
||||||
buses = input.shift.split(?,).map {|b| b != ?x ? b.to_i : nil }
|
|
||||||
|
|
||||||
# p buses.compact.map {|bus|
|
|
||||||
# d = bus * ((depart_time / bus) + 1)
|
|
||||||
# [bus, d - depart_time]
|
|
||||||
# }.min_by(&:last).inject {|a,b| a * b }
|
|
||||||
|
|
||||||
# shamelessly copied from https://rosettacode.org/wiki/Chinese_remainder_theorem#Ruby
|
|
||||||
def extended_gcd(a, b)
|
|
||||||
last_remainder, remainder = a.abs, b.abs
|
|
||||||
x, last_x, y, last_y = 0, 1, 1, 0
|
|
||||||
while remainder != 0
|
|
||||||
last_remainder, (quotient, remainder) = remainder, last_remainder.divmod(remainder)
|
|
||||||
x, last_x = last_x - quotient*x, x
|
|
||||||
y, last_y = last_y - quotient*y, y
|
|
||||||
end
|
|
||||||
return last_remainder, last_x * (a < 0 ? -1 : 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
def invmod(e, et)
|
|
||||||
g, x = extended_gcd(e, et)
|
|
||||||
if g != 1
|
|
||||||
raise 'Multiplicative inverse modulo does not exist!'
|
|
||||||
end
|
|
||||||
x % et
|
|
||||||
end
|
|
||||||
|
|
||||||
def chinese_remainder(mods, remainders)
|
|
||||||
max = mods.inject( :* ) # product of all moduli
|
|
||||||
series = remainders.zip(mods).map{ |r,m| (r * max * invmod(max/m, m) / m) }
|
|
||||||
series.inject( :+ ) % max
|
|
||||||
end
|
|
||||||
|
|
||||||
buses = buses.map.with_index.select {|b,_| b }
|
|
||||||
# p 0.step(by: buses[0][0]).lazy.find {|depart_time|
|
|
||||||
# buses.all? {|b,i| (depart_time + i) % b == 0 }
|
|
||||||
# }
|
|
||||||
|
|
||||||
mods, remainders = buses.map {|b,i| [b, b-i] }.transpose
|
|
||||||
p chinese_remainder(mods, remainders)
|
|
@ -1,37 +0,0 @@
|
|||||||
require "strscan"
|
|
||||||
|
|
||||||
mem = Hash.new(0)
|
|
||||||
mask = nil
|
|
||||||
|
|
||||||
ss = StringScanner.new(ARGF.read)
|
|
||||||
until ss.eos?
|
|
||||||
case
|
|
||||||
when ss.scan(/mask = ([10X]+)\n/)
|
|
||||||
mask = ss.captures.fetch(0)
|
|
||||||
when ss.scan(/mem\[(\d+)\] = (\d+)\n/)
|
|
||||||
addr, value = ss.captures.map(&:to_i)
|
|
||||||
|
|
||||||
# part 1
|
|
||||||
# value &= mask.gsub(?X, ?1).to_i(2)
|
|
||||||
# value |= mask.gsub(?X, ?0).to_i(2)
|
|
||||||
# mem[addr] = value
|
|
||||||
|
|
||||||
masked = ("%036b" % addr).chars.zip(mask.chars).map {|a,m|
|
|
||||||
case m
|
|
||||||
when ?X then ?X
|
|
||||||
when ?1 then ?1
|
|
||||||
when ?0 then a
|
|
||||||
else fail
|
|
||||||
end
|
|
||||||
}.join
|
|
||||||
floating = masked.count(?X)
|
|
||||||
(0...2**floating).map {|i| i.to_s(2).chars }.each do |i|
|
|
||||||
floated = masked.gsub(?X) { i.pop || "0" }.to_i(2)
|
|
||||||
mem[floated] = value
|
|
||||||
end
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
p mem.values.sum
|
|
@ -1,31 +0,0 @@
|
|||||||
# turns = ARGF.read.scan(/\d+/).map(&:to_i)
|
|
||||||
# until turns.size == 2020
|
|
||||||
# turns << if turns.count(turns.last) == 1
|
|
||||||
# 0
|
|
||||||
# else
|
|
||||||
# a, b = turns.filter_map.with_index {|x,i|
|
|
||||||
# x == turns.last ? i : nil
|
|
||||||
# }[-2,2]
|
|
||||||
# b - a
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
start = ARGF.read.scan(/\d+/).map(&:to_i)
|
|
||||||
|
|
||||||
turns = Hash.new
|
|
||||||
last = start.pop
|
|
||||||
start.each.with_index do |x,i|
|
|
||||||
turns[x] = i+1
|
|
||||||
end
|
|
||||||
|
|
||||||
(start.size+1...30000000).each do |turn|
|
|
||||||
if n = turns[last]
|
|
||||||
turns[last] = turn
|
|
||||||
last = turn - n
|
|
||||||
else
|
|
||||||
turns[last] = turn
|
|
||||||
last = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
p last
|
|
@ -1,52 +0,0 @@
|
|||||||
require "strscan"
|
|
||||||
|
|
||||||
ss = StringScanner.new(ARGF.read)
|
|
||||||
|
|
||||||
rules = {}
|
|
||||||
mine = []
|
|
||||||
nearby = []
|
|
||||||
|
|
||||||
while ss.scan(/([\w\s]+): (\d+)-(\d+) or (\d+)-(\d+)\n/)
|
|
||||||
c = ss.captures
|
|
||||||
field = c.shift
|
|
||||||
rules[field] = c.map(&:to_i).each_slice(2).map {|a,b| a..b }
|
|
||||||
end
|
|
||||||
ss.scan(/\n/)
|
|
||||||
|
|
||||||
ss.scan(/your ticket:\n/)
|
|
||||||
mine = ss.scan(/(?~\n)\n/).scan(/\d+/).map(&:to_i)
|
|
||||||
|
|
||||||
ss.scan(/\nnearby tickets:\n/)
|
|
||||||
nearby = ss.rest.split("\n").map {|line| line.split(?,).map(&:to_i) }
|
|
||||||
|
|
||||||
# part one
|
|
||||||
# p nearby.flat_map {|fields|
|
|
||||||
# fields.reject {|field|
|
|
||||||
# rules.values.any? {|values| values.any? {|range| range.cover?(field) }}
|
|
||||||
# }
|
|
||||||
# }.sum
|
|
||||||
|
|
||||||
nearby.select! {|fields|
|
|
||||||
fields.all? {|field|
|
|
||||||
rules.values.any? {|values| values.any? {|range| range.cover?(field) }}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
valid = (0...mine.size).map {|i|
|
|
||||||
rules.select {|name, ranges|
|
|
||||||
nearby.map {|n| n[i] }.all? {|n| ranges.any? {|range| range.cover?(n) }}
|
|
||||||
}
|
|
||||||
}.map.with_index {|v,i| [i, v.keys] }.to_h
|
|
||||||
|
|
||||||
order = {}
|
|
||||||
until valid.values.all?(&:empty?)
|
|
||||||
k, f = valid.find {|_,v| v.size == 1 }
|
|
||||||
order[k] = f[0]
|
|
||||||
valid.transform_values! {|v| v - f }
|
|
||||||
end
|
|
||||||
|
|
||||||
p order
|
|
||||||
.select {|_,v| v.start_with?("departure") }
|
|
||||||
.map(&:first)
|
|
||||||
.map {|i| mine[i] }
|
|
||||||
.inject(&:*)
|
|
@ -1,33 +0,0 @@
|
|||||||
DIMENSIONS = 4
|
|
||||||
state = ARGF.read.strip.split("\n").flat_map.with_index {|line,y|
|
|
||||||
line.chars.map.with_index {|c,x|
|
|
||||||
[[x,y].fill(0, 2, DIMENSIONS-2), c == "#"]
|
|
||||||
}
|
|
||||||
}.to_h
|
|
||||||
|
|
||||||
NEIGHBORS = (0...3**DIMENSIONS)
|
|
||||||
.reject {|n| n == 3**DIMENSIONS / 2 }
|
|
||||||
.map {|n| n.digits(3) }
|
|
||||||
.map {|n| (0...DIMENSIONS).map {|x| n.fetch(x, 0) - 1 }}
|
|
||||||
|
|
||||||
def tick(state)
|
|
||||||
actives = state.select {|_,c| c }.keys
|
|
||||||
minmaxes = actives
|
|
||||||
.transpose.map(&:minmax)
|
|
||||||
.map {|min,max| (min-1..max+1).to_a }
|
|
||||||
coords = minmaxes.inject {|n,x|
|
|
||||||
n.flat_map {|nn| x.map {|xx| [nn, xx] }}
|
|
||||||
}.map(&:flatten)
|
|
||||||
coords.map {|coord|
|
|
||||||
active_neighbors = NEIGHBORS.count {|delta| state[coord.zip(delta).map {|a,b| a + b }] }
|
|
||||||
[ coord,
|
|
||||||
state[coord] ? (2..3).cover?(active_neighbors) : active_neighbors == 3
|
|
||||||
]
|
|
||||||
}.to_h
|
|
||||||
end
|
|
||||||
|
|
||||||
6.times do
|
|
||||||
state = tick(state)
|
|
||||||
end
|
|
||||||
|
|
||||||
p state.values.count(&:itself)
|
|
@ -1,58 +0,0 @@
|
|||||||
require "strscan"
|
|
||||||
|
|
||||||
# def evaluate(input)
|
|
||||||
# while input.include?(?()
|
|
||||||
# input = input.gsub(/\((?~[()])+\)/) {|m| evaluate(m[1..-2]) }
|
|
||||||
# end
|
|
||||||
|
|
||||||
# # part one
|
|
||||||
# # ss = StringScanner.new(input)
|
|
||||||
# # n = ss.scan(/\d+/).to_i
|
|
||||||
# # until ss.eos?
|
|
||||||
# # case
|
|
||||||
# # when ss.scan(/\s*\+\s*(\d+)/)
|
|
||||||
# # n += ss.captures[0].to_i
|
|
||||||
# # when ss.scan(/\s*\*\s*(\d+)/)
|
|
||||||
# # n *= ss.captures[0].to_i
|
|
||||||
# # else
|
|
||||||
# # fail
|
|
||||||
# # end
|
|
||||||
# # end
|
|
||||||
# # n
|
|
||||||
|
|
||||||
# while input.include?(?+)
|
|
||||||
# input = input.gsub(/\d+\s*\+\s*\d+/) {|m| eval(m) }
|
|
||||||
# end
|
|
||||||
# while input.include?(?*)
|
|
||||||
# input = input.gsub(/\d+\s*\*\s*\d+/) {|m| eval(m) }
|
|
||||||
# end
|
|
||||||
# input.to_i
|
|
||||||
# end
|
|
||||||
|
|
||||||
def evaluate(input)
|
|
||||||
stack = [->(x) { x }]
|
|
||||||
|
|
||||||
ss = StringScanner.new(input)
|
|
||||||
until ss.eos?
|
|
||||||
ss.scan(/\s*/)
|
|
||||||
stack << case
|
|
||||||
when n = ss.scan(/\d+/)
|
|
||||||
stack.pop[n.to_i]
|
|
||||||
when ss.scan(/\+/)
|
|
||||||
->(x) { stack.pop + x }
|
|
||||||
when ss.scan(/\*/)
|
|
||||||
->(x) { stack.pop * x }
|
|
||||||
when ss.scan(/\(/)
|
|
||||||
->(x) { x }
|
|
||||||
when ss.scan(/\)/)
|
|
||||||
n = stack.pop
|
|
||||||
stack.pop[n]
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
stack.pop
|
|
||||||
end
|
|
||||||
|
|
||||||
p ARGF.read.split("\n").map {|line| evaluate(line) }.sum
|
|
@ -1,67 +0,0 @@
|
|||||||
# require "bundler/inline"
|
|
||||||
|
|
||||||
# gemfile do
|
|
||||||
# source "https://rubygems.org"
|
|
||||||
# gem "parslet"
|
|
||||||
# end
|
|
||||||
|
|
||||||
rules, messages = ARGF.read.split("\n\n")
|
|
||||||
|
|
||||||
# class Day19 < Parslet::Parser
|
|
||||||
# root(:rule_0)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# rules = rules.split("\n").map {|rule| rule.split(": ") }.to_h
|
|
||||||
# rules["8"] = "42 | 42 8"
|
|
||||||
# rules["11"] = "42 31 | 42 11 31"
|
|
||||||
# rules.each do |rule, sub_rules|
|
|
||||||
# sub_rules = sub_rules.split(" | ").map {|sub_rule|
|
|
||||||
# sub_rule.split(/\s+/).map {|sub_sub_rule|
|
|
||||||
# sub_sub_rule =~ /^\d+$/ ? "rule_#{sub_sub_rule}" : "str(#{sub_sub_rule})"
|
|
||||||
# }.join(" >> ")
|
|
||||||
# }.join(" | ")
|
|
||||||
# rule = "rule(:rule_#{rule}) { #{sub_rules} }"
|
|
||||||
# p rule
|
|
||||||
|
|
||||||
# Day19.class_eval(rule)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# PARSER = Day19.new
|
|
||||||
# def parsable?(input)
|
|
||||||
# !!PARSER.parse(input)
|
|
||||||
# rescue
|
|
||||||
# false
|
|
||||||
# end
|
|
||||||
# puts messages.split("\n").select {|line| parsable?(line) }
|
|
||||||
|
|
||||||
# begin
|
|
||||||
# p PARSER.parse("bbbbbbbaaaabbbbaaabbabaaa")
|
|
||||||
# rescue Parslet::ParseFailed => failure
|
|
||||||
# puts failure.parse_failure_cause.ascii_tree
|
|
||||||
# end
|
|
||||||
|
|
||||||
rules = rules.split("\n").map {|line|
|
|
||||||
line.split(": ")
|
|
||||||
}.to_h
|
|
||||||
|
|
||||||
rule = rules["0"]
|
|
||||||
while rule =~ /\d/
|
|
||||||
rule.gsub!(/\d+/) {|r|
|
|
||||||
case r
|
|
||||||
when "8"
|
|
||||||
"(?:42)+"
|
|
||||||
when "11"
|
|
||||||
"(?:#{(1..5).map {|i| (Array.new(i, "42") + Array.new(i, "31")).join(" ") }.join(" | ")})"
|
|
||||||
else
|
|
||||||
value = rules.fetch(r)
|
|
||||||
value = value[1..-2] if value =~ /^"\w+"$/
|
|
||||||
"(?:#{value})"
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
rule.gsub!(" ", "")
|
|
||||||
while rule =~ /\(\?:\w+\)/
|
|
||||||
rule.gsub!(/\(\?:(\w+)\)/, '\1')
|
|
||||||
end
|
|
||||||
|
|
||||||
p messages.split("\n").count {|m| m =~ /^#{rule}$/ }
|
|
@ -1,107 +0,0 @@
|
|||||||
# all rotations are clockwise
|
|
||||||
# all flips are vertical
|
|
||||||
|
|
||||||
class Tile
|
|
||||||
attr_reader :id, :raw
|
|
||||||
|
|
||||||
def initialize(id, raw)
|
|
||||||
@id, @raw = id, raw
|
|
||||||
end
|
|
||||||
|
|
||||||
def [](y, x)
|
|
||||||
@raw.fetch(y).fetch(x)
|
|
||||||
end
|
|
||||||
|
|
||||||
def edge_keys
|
|
||||||
{
|
|
||||||
top: @raw.first,
|
|
||||||
down: @raw.last,
|
|
||||||
left: @raw.transpose.first,
|
|
||||||
right: @raw.transpose.last,
|
|
||||||
}.transform_values(&:join)
|
|
||||||
end
|
|
||||||
|
|
||||||
def permutations
|
|
||||||
(0..3).map {|i|
|
|
||||||
i.times.inject(self) {|x,_| x.rotated }
|
|
||||||
}.flat_map {|x| [x, x.flipped] }
|
|
||||||
end
|
|
||||||
|
|
||||||
def rotated
|
|
||||||
self.class.new(@id, @raw.reverse.transpose)
|
|
||||||
end
|
|
||||||
|
|
||||||
def flipped
|
|
||||||
self.class.new(@id, @raw.reverse)
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
@raw.map(&:join).join("\n")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
tiles = ARGF.read
|
|
||||||
.scan(/Tile (\d+):\n((?:[.#]+\n)+)/m)
|
|
||||||
.to_h
|
|
||||||
.transform_values {|v| v.split("\n").map {|row| row.chars } }
|
|
||||||
.map {|k,v| [k, Tile.new(k, v)] }
|
|
||||||
.to_h
|
|
||||||
|
|
||||||
keys_to_tiles = Hash.new {|h,k| h[k] = [] }
|
|
||||||
tiles.values.each do |tile|
|
|
||||||
tile.edge_keys.values.each do |key|
|
|
||||||
keys_to_tiles[key] << tile.id
|
|
||||||
keys_to_tiles[key.reverse] << tile.id
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
start_corner = tiles.values.find {|tile|
|
|
||||||
tile.edge_keys.values_at(:left, :top).all? {|key| keys_to_tiles.fetch(key).size == 1 }
|
|
||||||
}
|
|
||||||
|
|
||||||
image = [[start_corner]]
|
|
||||||
until image.map(&:size).sum == tiles.size
|
|
||||||
current = image.last.last
|
|
||||||
right_key = current.edge_keys.fetch(:right)
|
|
||||||
if right_id = keys_to_tiles.fetch(right_key, nil).find {|id| id != current.id }
|
|
||||||
right_tile = tiles.fetch(right_id).permutations.find {|p| p.edge_keys.fetch(:left) == right_key }
|
|
||||||
image.last << right_tile
|
|
||||||
else
|
|
||||||
current = image.last.first
|
|
||||||
down_key = current.edge_keys.fetch(:down)
|
|
||||||
break unless down_id = keys_to_tiles.fetch(down_key).find {|id| id != current.id }
|
|
||||||
|
|
||||||
down_tile = tiles.fetch(down_id).permutations.find {|p| p.edge_keys.fetch(:top) == down_key }
|
|
||||||
image << [down_tile]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
full_raw = image.map {|row| row.map {|tile|
|
|
||||||
tile.raw[1..-2].map {|row| row[1..-2] }
|
|
||||||
}}.flat_map {|row| row.inject(&:zip).map(&:flatten) }
|
|
||||||
full_tile = Tile.new(nil, full_raw)
|
|
||||||
|
|
||||||
sea_monster = <<~SEA_MONSTER.split("\n").map(&:chars)
|
|
||||||
#
|
|
||||||
# ## ## ###
|
|
||||||
# # # # # #
|
|
||||||
SEA_MONSTER
|
|
||||||
needle = sea_monster.flat_map.with_index {|row,y|
|
|
||||||
row.filter_map.with_index {|c,x|
|
|
||||||
c == ?# ? [y,x] : nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
num_monsters = full_tile.permutations.map {|tile|
|
|
||||||
needle_maxes = needle.transpose.map(&:max)
|
|
||||||
haystack = (0...tile.raw.size-needle_maxes.first).flat_map {|y|
|
|
||||||
(0...tile.raw.first.size-needle_maxes.last).map {|x|
|
|
||||||
[y, x]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
haystack.count {|y,x|
|
|
||||||
needle.all? {|dy,dx| tile[y+dy, x+dx] == ?# }
|
|
||||||
}
|
|
||||||
}.sum
|
|
||||||
|
|
||||||
puts full_tile.raw.map {|row| row.count(?#) }.sum - (num_monsters * needle.size)
|
|
@ -1,39 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
Food = Struct.new(:id, :ingredients, :allergens)
|
|
||||||
|
|
||||||
foods = ARGF.read
|
|
||||||
.scan(/(.+) \(contains (.+)\)/)
|
|
||||||
.map.with_index {|(ingredients, allergens), i|
|
|
||||||
ingredients, allergens = [ ingredients.split(" "), allergens.split(", ") ].map {|x| Set.new(x) }
|
|
||||||
Food.new(i, ingredients, allergens)
|
|
||||||
}
|
|
||||||
|
|
||||||
all_ingredients = foods.map(&:ingredients).inject(&:|)
|
|
||||||
all_allergens = foods.map(&:allergens).inject(&:|)
|
|
||||||
|
|
||||||
no_allergens = all_ingredients.select {|ingredient|
|
|
||||||
possible_allergens = foods
|
|
||||||
.select {|food| food.ingredients.include?(ingredient) }
|
|
||||||
.map(&:allergens)
|
|
||||||
.inject(&:|)
|
|
||||||
possible_allergens.none? {|allergen|
|
|
||||||
foods_with_allergen = foods.select {|f| f.allergens.include?(allergen) }
|
|
||||||
foods_with_allergen.all? {|f| f.ingredients.include?(ingredient) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# part one
|
|
||||||
# p foods.map {|f| f.ingredients.count {|i| no_allergens.include?(i) }}.sum
|
|
||||||
|
|
||||||
known, unknown = all_allergens.map {|a|
|
|
||||||
[a, foods.select {|f| f.allergens.include?(a) }.map(&:ingredients).inject(&:&) ]
|
|
||||||
}.to_h.partition {|_,v| v.size == 1 }.map(&:to_h)
|
|
||||||
|
|
||||||
until unknown.empty?
|
|
||||||
unknown.transform_values! {|v| v - known.values.inject(&:|) }
|
|
||||||
new_known, unknown = unknown.partition {|_,v| v.size == 1 }.map(&:to_h)
|
|
||||||
known.merge!(new_known)
|
|
||||||
end
|
|
||||||
|
|
||||||
p known.transform_values {|v| v.to_a.first }.sort_by(&:first).map(&:last).join(?,)
|
|
@ -1,46 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
decks = ARGF.read.split("\n\n").map {|players| players.split("\n")[1..].map(&:to_i) }
|
|
||||||
|
|
||||||
# part one
|
|
||||||
|
|
||||||
# until decks.any?(&:empty?)
|
|
||||||
# p decks
|
|
||||||
# top_cards = decks.map(&:shift)
|
|
||||||
# fail if top_cards.tally.size == 1
|
|
||||||
|
|
||||||
# if top_cards.first > top_cards.last
|
|
||||||
# decks.first.concat(top_cards)
|
|
||||||
# else
|
|
||||||
# decks.last.concat(top_cards.reverse)
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
SEEN = Set.new
|
|
||||||
def recursive_combat!(decks)
|
|
||||||
until decks.any?(&:empty?)
|
|
||||||
return 0 if SEEN.include?(decks)
|
|
||||||
SEEN << decks
|
|
||||||
|
|
||||||
top_cards = decks.map(&:shift)
|
|
||||||
winner = if decks.zip(top_cards).all? {|d,tc| d.size >= tc }
|
|
||||||
recursive_combat!(decks.zip(top_cards).map {|d,tc| d[0,tc] })
|
|
||||||
elsif top_cards.first > top_cards.last
|
|
||||||
0
|
|
||||||
else
|
|
||||||
1
|
|
||||||
end
|
|
||||||
|
|
||||||
if winner == 0
|
|
||||||
decks.first.concat(top_cards)
|
|
||||||
else
|
|
||||||
decks.last.concat(top_cards.reverse)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
decks.index {|d| !d.empty? }
|
|
||||||
end
|
|
||||||
|
|
||||||
recursive_combat!(decks)
|
|
||||||
|
|
||||||
p decks.flatten.reverse.map.with_index {|v,i| v * (i+1) }.sum
|
|
@ -1,32 +0,0 @@
|
|||||||
cups = Hash.new {|h,k|
|
|
||||||
fail if k > 1000000
|
|
||||||
h[k] = k + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
cup_values = ARGF.read.chars.map(&:to_i)
|
|
||||||
current = cup_values.first
|
|
||||||
|
|
||||||
cup_values = [1_000_000, *cup_values, cup_values.max + 1]
|
|
||||||
cup_values.each_cons(2) do |a,b|
|
|
||||||
cups[a] = b
|
|
||||||
end
|
|
||||||
cups_range = Range.new(*cups.keys.minmax)
|
|
||||||
|
|
||||||
10_000_000.times do |i|
|
|
||||||
pickup = 2.times.inject([cups[current]]) {|p,_| p << cups[p.last] }
|
|
||||||
cups[current] = cups[pickup.last]
|
|
||||||
|
|
||||||
dest_value = current - 1
|
|
||||||
loop do
|
|
||||||
dest_value = cups_range.max if dest_value == 0
|
|
||||||
break unless pickup.include?(dest_value)
|
|
||||||
dest_value -= 1
|
|
||||||
end
|
|
||||||
|
|
||||||
cups[pickup.last] = cups[dest_value]
|
|
||||||
cups[dest_value] = pickup.first
|
|
||||||
|
|
||||||
current = cups[current]
|
|
||||||
end
|
|
||||||
|
|
||||||
p 1.times.inject([cups[1]]) {|p,_| p << cups[p.last] }.inject(&:*)
|
|
@ -1,55 +0,0 @@
|
|||||||
require "set"
|
|
||||||
require "strscan"
|
|
||||||
|
|
||||||
def parse(line)
|
|
||||||
deltas = []
|
|
||||||
|
|
||||||
ss = StringScanner.new(line)
|
|
||||||
until ss.eos?
|
|
||||||
deltas << case
|
|
||||||
when ss.scan(/e/) then [ 1, 0]
|
|
||||||
when ss.scan(/se/) then [ 0, 1]
|
|
||||||
when ss.scan(/sw/) then [-1, 1]
|
|
||||||
when ss.scan(/w/) then [-1, 0]
|
|
||||||
when ss.scan(/nw/) then [ 0, -1]
|
|
||||||
when ss.scan(/ne/) then [ 1, -1]
|
|
||||||
else fail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
deltas.inject {|c,d| c.zip(d).map {|c,d| c+d }}
|
|
||||||
end
|
|
||||||
|
|
||||||
NEIGHBORS = %w[ e se sw w nw ne ].map {|dir| parse(dir) }
|
|
||||||
def tick(tiles)
|
|
||||||
coords = Set.new(tiles.flat_map {|coord|
|
|
||||||
[
|
|
||||||
coord,
|
|
||||||
*NEIGHBORS.map {|n| coord.zip(n).map {|c,d| c+d }},
|
|
||||||
]
|
|
||||||
})
|
|
||||||
Set.new(coords.select {|coord|
|
|
||||||
live_neighbors = NEIGHBORS.map {|n| coord.zip(n).map {|c,d| c+d }}.count {|c| tiles.include?(c) }
|
|
||||||
if tiles.include?(coord)
|
|
||||||
(1..2).cover?(live_neighbors)
|
|
||||||
else
|
|
||||||
live_neighbors == 2
|
|
||||||
end
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
tiles = Set.new
|
|
||||||
ARGF.read.split("\n").each do |line|
|
|
||||||
tile = parse(line)
|
|
||||||
if tiles.include?(tile)
|
|
||||||
tiles.delete(tile)
|
|
||||||
else
|
|
||||||
tiles << tile
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
100.times do |i|
|
|
||||||
tiles = tick(tiles)
|
|
||||||
end
|
|
||||||
|
|
||||||
p tiles.size
|
|
@ -1,17 +0,0 @@
|
|||||||
def transform(subject_number)
|
|
||||||
return enum_for(__method__, subject_number) unless block_given?
|
|
||||||
|
|
||||||
value = 1
|
|
||||||
(0..).each do |loop_size|
|
|
||||||
yield [loop_size, value]
|
|
||||||
value *= subject_number
|
|
||||||
value %= 20201227
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
public_keys = ARGF.read.scan(/\d+/).map(&:to_i)
|
|
||||||
|
|
||||||
loop_size, _ = transform(7).find {|_,v| v == public_keys.first }
|
|
||||||
_, encryption_key = transform(public_keys.last).find {|i,_| i == loop_size }
|
|
||||||
|
|
||||||
p encryption_key
|
|
@ -1,4 +0,0 @@
|
|||||||
#!/usr/bin/env jconsole
|
|
||||||
|
|
||||||
echo stdin
|
|
||||||
exit''
|
|
@ -1 +0,0 @@
|
|||||||
3
|
|
@ -1,2 +0,0 @@
|
|||||||
p ARGF.read.split("\n").map(&:to_i).each_cons(2).count {|x,y| x < y }
|
|
||||||
p ARGF.read.split("\n").map(&:to_i).each_cons(3).map(&:sum).each_cons(2).count {|x,y| x < y }
|
|
@ -1,35 +0,0 @@
|
|||||||
# h = 0
|
|
||||||
# d = 0
|
|
||||||
# ARGF.read.split("\n").map(&:split).each do |dir, n|
|
|
||||||
# n = n.to_i
|
|
||||||
# case dir
|
|
||||||
# when "forward"
|
|
||||||
# h += n
|
|
||||||
# when "down"
|
|
||||||
# d += n
|
|
||||||
# when "up"
|
|
||||||
# d -= n
|
|
||||||
# else
|
|
||||||
# fail dir
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# p h, d, h*d
|
|
||||||
|
|
||||||
h = 0
|
|
||||||
d = 0
|
|
||||||
aim = 0
|
|
||||||
ARGF.read.split("\n").map(&:split).each do |dir, n|
|
|
||||||
n = n.to_i
|
|
||||||
case dir
|
|
||||||
when "forward"
|
|
||||||
h += n
|
|
||||||
d += aim * n
|
|
||||||
when "down"
|
|
||||||
aim += n
|
|
||||||
when "up"
|
|
||||||
aim -= n
|
|
||||||
else
|
|
||||||
fail dir
|
|
||||||
end
|
|
||||||
end
|
|
||||||
p h, d, h*d
|
|
@ -1,23 +0,0 @@
|
|||||||
bits = ARGF.read.split("\n").map(&:chars)
|
|
||||||
|
|
||||||
gamma = bits.transpose.map {|a| a.tally.max_by(&:last).first }.join
|
|
||||||
epsilon = bits.transpose.map {|a| a.tally.min_by(&:last).first }.join
|
|
||||||
p gamma.to_i(2) * epsilon.to_i(2)
|
|
||||||
|
|
||||||
oxy = bits.clone
|
|
||||||
(0..oxy.first.length).each do |i|
|
|
||||||
b = oxy.transpose.map {|a| a.tally.sort.reverse.max_by(&:last).first }[i]
|
|
||||||
oxy.select! {|x| x[i] == b }
|
|
||||||
break if oxy.length == 1
|
|
||||||
end
|
|
||||||
oxy = oxy.join.to_i(2)
|
|
||||||
|
|
||||||
co2 = bits.clone
|
|
||||||
(0..co2.first.length).each do |i|
|
|
||||||
b = co2.transpose.map {|a| a.tally.sort.min_by(&:last).first }[i]
|
|
||||||
co2.select! {|x| x[i] == b }
|
|
||||||
break if co2.length == 1
|
|
||||||
end
|
|
||||||
co2 = co2.join.to_i(2)
|
|
||||||
|
|
||||||
p oxy * co2
|
|
@ -1,29 +0,0 @@
|
|||||||
input = ARGF.read
|
|
||||||
numbers, *cards = input.split("\n\n")
|
|
||||||
numbers = numbers.split(?,).map(&:to_i)
|
|
||||||
cards = cards.map {|c| c.split("\n").map {|r| r.split(/\s+/).reject(&:empty?).map(&:to_i) }}
|
|
||||||
|
|
||||||
def win?(card, drawn)
|
|
||||||
return true if card.any? {|row| row.all? {|c| drawn.include?(c) }}
|
|
||||||
return true if card.transpose.any? {|col| col.all? {|c| drawn.include?(c) }}
|
|
||||||
# return true if (0..4).all? {|x| drawn.include?(card.fetch(x).fetch(x)) }
|
|
||||||
# return true if (0..4).all? {|x| drawn.include?(card.fetch(x).fetch(4-x)) }
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
(0..numbers.length).each do |i|
|
|
||||||
drawn = numbers[0..i]
|
|
||||||
|
|
||||||
# winning_card = cards.find {|c| win?(c, drawn) }
|
|
||||||
# if winning_card
|
|
||||||
# p winning_card.flatten.reject {|x| drawn.include?(x) }.sum * drawn.last
|
|
||||||
# exit
|
|
||||||
# end
|
|
||||||
|
|
||||||
if cards.length == 1 && winning_card = cards.find {|c| win?(c, drawn) }
|
|
||||||
p winning_card.flatten.reject {|x| drawn.include?(x) }.sum * drawn.last
|
|
||||||
exit
|
|
||||||
else
|
|
||||||
cards = cards.reject {|c| win?(c, drawn) }
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,29 +0,0 @@
|
|||||||
vents = ARGF.read.split("\n").map {|l| l.split(" -> ").map {|x| x.split(?,).map(&:to_i) }}
|
|
||||||
|
|
||||||
straights = vents.select {|(x1,y1),(x2,y2)| x1 == x2 || y1 == y2 }
|
|
||||||
|
|
||||||
points = Hash.new(0)
|
|
||||||
straights.each do |(x1,y1),(x2,y2)|
|
|
||||||
x = [x1, x2].minmax
|
|
||||||
y = [y1, y2].minmax
|
|
||||||
(x[0]..x[1]).each do |x|
|
|
||||||
(y[0]..y[1]).each do |y|
|
|
||||||
points[[x,y]] += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
diagonals = vents - straights
|
|
||||||
diagonals.each do |(x1,y1),(x2,y2)|
|
|
||||||
if x1 > x2
|
|
||||||
x1,x2 = x2,x1
|
|
||||||
y1,y2 = y2,y1
|
|
||||||
end
|
|
||||||
sign = (y1 < y2) ? 1 : -1
|
|
||||||
(x1..x2).each.with_index do |x,i|
|
|
||||||
delta = i * sign
|
|
||||||
points[[x,y1+delta]] += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
p points.count {|_,v| v > 1 }
|
|
@ -1,22 +0,0 @@
|
|||||||
ages = ARGF.read.split(?,).map(&:to_i)
|
|
||||||
|
|
||||||
# 80.times do
|
|
||||||
# new_fish = 0
|
|
||||||
# ages.map! {|age|
|
|
||||||
# if age.zero?
|
|
||||||
# new_fish += 1
|
|
||||||
# 6
|
|
||||||
# else
|
|
||||||
# age - 1
|
|
||||||
# end
|
|
||||||
# }
|
|
||||||
# ages.concat(Array.new(new_fish) { 8 })
|
|
||||||
# end
|
|
||||||
# p ages.count
|
|
||||||
|
|
||||||
DURATION = 256
|
|
||||||
DESCENDANTS = Hash.new {|h,k|
|
|
||||||
children = (k...DURATION).step(7)
|
|
||||||
h[k] = children.count + children.map {|d| d + 9 }.select {|d| d < DURATION }.sum {|d| h[d] }
|
|
||||||
}
|
|
||||||
p ages.count + ages.sum {|age| DESCENDANTS[age] }
|
|
@ -1,9 +0,0 @@
|
|||||||
positions = ARGF.read.split(?,).map(&:to_i)
|
|
||||||
min, max = positions.minmax
|
|
||||||
pos = (min..max).min_by {|i|
|
|
||||||
# positions.sum {|p| (p - i).abs }
|
|
||||||
positions.sum {|p| n = (p - i).abs; (n * (n + 1)) / 2 }
|
|
||||||
}
|
|
||||||
|
|
||||||
# p positions.sum {|p| (p - pos).abs }
|
|
||||||
p positions.sum {|p| n = (p - pos).abs; (n * (n + 1)) / 2 }
|
|
@ -1,38 +0,0 @@
|
|||||||
include "globals.mzn";
|
|
||||||
|
|
||||||
enum Signals = { A, B, C, D, E, F, G };
|
|
||||||
|
|
||||||
set of Signals: Zero = { A, B, C, E, F, G };
|
|
||||||
set of Signals: One = { C, F };
|
|
||||||
set of Signals: Two = { A, C, D, E, G };
|
|
||||||
set of Signals: Three = { A, C, D, F, G };
|
|
||||||
set of Signals: Four = { B, C, D, F };
|
|
||||||
set of Signals: Five = { A, B, D, F, G };
|
|
||||||
set of Signals: Six = { A, B, D, E, F, G };
|
|
||||||
set of Signals: Seven = { A, C, F };
|
|
||||||
set of Signals: Eight = { A, B, C, D, E, F, G };
|
|
||||||
set of Signals: Nine = { A, B, C, D, F, G };
|
|
||||||
array[1..10] of set of Signals: AllSignals = [ Zero, One, Two, Three, Four, Five, Six, Seven, Eight, Nine ];
|
|
||||||
|
|
||||||
array[1..10] of set of Signals: Patterns;
|
|
||||||
% Patterns = [
|
|
||||||
% { A, C, E, D, G, F, B },
|
|
||||||
% { C, D, F, B, E },
|
|
||||||
% { G, C, D, F, A },
|
|
||||||
% { F, B, C, A, D },
|
|
||||||
% { D, A, B },
|
|
||||||
% { C, E, F, A, B, D },
|
|
||||||
% { C, D, F, G, E, B },
|
|
||||||
% { E, A, F, B },
|
|
||||||
% { C, A, G, E, D, B },
|
|
||||||
% { A, B },
|
|
||||||
% ];
|
|
||||||
|
|
||||||
array [Signals] of var Signals: Map;
|
|
||||||
|
|
||||||
constraint alldifferent(Map);
|
|
||||||
constraint forall(pattern in [ { Map[x] | x in pattern } | pattern in Patterns])(
|
|
||||||
exists(digit in AllSignals)(pattern = digit)
|
|
||||||
);
|
|
||||||
|
|
||||||
output [show(Map)];
|
|
@ -1,51 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
input = ARGF.read.split("\n").map {|x| x.split(/\s+\|\s+/).map {|x| x.split(/\s+/) } }
|
|
||||||
# output = input.map(&:last)
|
|
||||||
# p output.flatten.count {|x| [2, 4, 3, 7].include?(x.length) }
|
|
||||||
|
|
||||||
MAP = {
|
|
||||||
%w[ a b c e f g ] => 0,
|
|
||||||
%w[ c f ] => 1,
|
|
||||||
%w[ a c d e g ] => 2,
|
|
||||||
%w[ a c d f g ] => 3,
|
|
||||||
%w[ b c d f ] => 4,
|
|
||||||
%w[ a b d f g ] => 5,
|
|
||||||
%w[ a b d e f g ] => 6,
|
|
||||||
%w[ a c f ] => 7,
|
|
||||||
%w[ a b c d e f g ] => 8,
|
|
||||||
%w[ a b c d f g ] => 9,
|
|
||||||
# 8 6 8 7 4 9 7
|
|
||||||
}.transform_keys(&:to_set)
|
|
||||||
|
|
||||||
# # My original solution to part two
|
|
||||||
# def solve(signals, output)
|
|
||||||
# all = signals + output
|
|
||||||
# one = all.find {|x| x.length == 2 }
|
|
||||||
# four = all.find {|x| x.length == 4 }
|
|
||||||
# seven = all.find {|x| x.length == 3 }
|
|
||||||
# eight = all.find {|x| x.length == 7 }
|
|
||||||
|
|
||||||
# b = (?a..?g).find {|x| signals.count {|s| s.include?(x) } == 6 }
|
|
||||||
# e = (?a..?g).find {|x| signals.count {|s| s.include?(x) } == 4 }
|
|
||||||
# f = (?a..?g).find {|x| signals.count {|s| s.include?(x) } == 9 }
|
|
||||||
|
|
||||||
# a = (seven.chars - one.chars)[0]
|
|
||||||
# c = (one.chars - [f])[0]
|
|
||||||
# d = (four.chars - [b, c, f])[0]
|
|
||||||
# g = (eight.chars - [a, b, c, d, e, f])[0]
|
|
||||||
|
|
||||||
# map = { a: a, b: b, c: c, d: d, e: e, f: f, g: g }.invert
|
|
||||||
|
|
||||||
# output.map {|x| MAP.fetch(x.chars.map {|c| map.fetch(c).to_s }.to_set) }.join.to_i
|
|
||||||
# end
|
|
||||||
|
|
||||||
# Here it is with a solver, but much, much slower!
|
|
||||||
def solve(signals, output)
|
|
||||||
data = "Patterns = [ #{signals.map { "{ #{_1.upcase.chars.join(" ,")} }" }.join(", ")} ]"
|
|
||||||
solution = `minizinc --cmdline-data "#{data}" day_08.mzn`.scan(/[A-G]/)
|
|
||||||
map = (?a..?g).zip(solution.map(&:downcase)).to_h
|
|
||||||
output.map {|x| MAP.fetch(x.chars.map {|c| map.fetch(c).to_s }.to_set) }.join.to_i
|
|
||||||
end
|
|
||||||
|
|
||||||
p input.sum {|x| solve(*x) }
|
|
@ -1,31 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
INPUT = ARGF.read.split("\n").map {|l| l.chars.map(&:to_i) }
|
|
||||||
|
|
||||||
NEIGHBORS = [[0,-1], [-1, 0], [1, 0], [0, 1]]
|
|
||||||
def neighbors(y,x)
|
|
||||||
NEIGHBORS
|
|
||||||
.map {|dy,dx| [y+dy, x+dx] }
|
|
||||||
.select {|y,x| (0...INPUT.size).cover?(y) && (0...INPUT[0].size).cover?(x) }
|
|
||||||
end
|
|
||||||
|
|
||||||
all = (0...INPUT.size).flat_map {|y| (0...INPUT[0].size).map {|x| [y, x]}}
|
|
||||||
lows = all.select {|y,x| neighbors(y,x).all? {|yy,xx| INPUT[yy][xx] > INPUT[y][x] }}
|
|
||||||
# p lows.sum {|y,x| INPUT[y][x] + 1 }
|
|
||||||
|
|
||||||
def fill_basin(low)
|
|
||||||
basin = Set.new([low])
|
|
||||||
|
|
||||||
stack = [low]
|
|
||||||
until stack.empty?
|
|
||||||
y,x = stack.shift
|
|
||||||
new_neighbors = neighbors(y,x).reject {|y,x| basin.include?([y,x]) || INPUT[y][x] == 9 }
|
|
||||||
stack.concat(new_neighbors)
|
|
||||||
basin.merge(new_neighbors)
|
|
||||||
end
|
|
||||||
|
|
||||||
basin
|
|
||||||
end
|
|
||||||
|
|
||||||
p lows.map { fill_basin(_1) }.map(&:size).sort[-3, 3].inject(:*)
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
input = ARGF.read.split("\n")
|
|
||||||
|
|
||||||
COMPLEMENTS = %w[ () [] {} <> ].map(&:chars).to_h
|
|
||||||
OPENING_REGEXP = Regexp.new("[#{Regexp.escape(COMPLEMENTS.keys.join)}]")
|
|
||||||
CLOSING_REGEXP = Regexp.new("[#{Regexp.escape(COMPLEMENTS.values.join)}]")
|
|
||||||
def parse(line)
|
|
||||||
stack = []
|
|
||||||
|
|
||||||
s = line.chars
|
|
||||||
until s.empty?
|
|
||||||
case char = s.shift
|
|
||||||
when OPENING_REGEXP
|
|
||||||
stack << char
|
|
||||||
when CLOSING_REGEXP
|
|
||||||
return { err: char } unless stack.pop == COMPLEMENTS.invert.fetch(char)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
{ ok: stack }
|
|
||||||
end
|
|
||||||
|
|
||||||
# points = {
|
|
||||||
# ?) => 3,
|
|
||||||
# ?] => 57,
|
|
||||||
# ?} => 1197,
|
|
||||||
# ?> => 25137,
|
|
||||||
# }
|
|
||||||
|
|
||||||
# p input.sum {|line|
|
|
||||||
# case parse(line)
|
|
||||||
# in { ok: } then 0
|
|
||||||
# in { err: } then points.fetch(err)
|
|
||||||
# else fail
|
|
||||||
# end
|
|
||||||
# }
|
|
||||||
|
|
||||||
def score(closing) = closing
|
|
||||||
.map { COMPLEMENTS.values.index(_1) + 1 }
|
|
||||||
.inject(0) {|n,i| n*5 + i }
|
|
||||||
|
|
||||||
scores = input
|
|
||||||
.filter_map {|line|
|
|
||||||
case parse(line)
|
|
||||||
in { ok: } then ok
|
|
||||||
in { err: } then nil
|
|
||||||
else fail
|
|
||||||
end
|
|
||||||
}
|
|
||||||
.map {|remaining| remaining.reverse.map { COMPLEMENTS.fetch(_1) }}
|
|
||||||
.map { score(_1) }
|
|
||||||
p scores.sort.fetch(scores.length / 2)
|
|
@ -1,36 +0,0 @@
|
|||||||
input = ARGF.read.split("\n").map { _1.chars.map(&:to_i) }
|
|
||||||
ys = (0...input.size)
|
|
||||||
xs = (0...input.fetch(0).size)
|
|
||||||
coords = ys.flat_map {|y| xs.map {|x| [y,x] }}
|
|
||||||
octopuses = coords.to_h {|y,x| [[y,x], input.fetch(y).fetch(x)] }
|
|
||||||
|
|
||||||
deltas = (-1..1).flat_map {|dy| (-1..1).map {|dx| [dy, dx] }}.reject { _1 == [0, 0] }
|
|
||||||
neighbors = ->(y, x) {
|
|
||||||
deltas
|
|
||||||
.map {|dy,dx| [y+dy, x+dx] }
|
|
||||||
.select {|y,x| ys.cover?(y) && xs.cover?(x) }
|
|
||||||
}
|
|
||||||
|
|
||||||
# flashes = 0
|
|
||||||
# 100.times do
|
|
||||||
(1..).each do |i|
|
|
||||||
octopuses.transform_values! { _1 + 1 }
|
|
||||||
until (flashing = octopuses.select { _2 == 10 }).empty?
|
|
||||||
flashing.each do |(y,x),_|
|
|
||||||
octopuses[[y,x]] += 1
|
|
||||||
neighbors.(y,x)
|
|
||||||
.select {|y,x| octopuses.fetch([y,x]) < 10 }
|
|
||||||
.each do |y,x|
|
|
||||||
octopuses[[y,x]] += 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if octopuses.values.all? { _1 > 9 }
|
|
||||||
puts i
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
# flashes += octopuses.count { _2 > 9 }
|
|
||||||
octopuses.transform_values! { _1 > 10 ? 0 : _1 }
|
|
||||||
end
|
|
||||||
|
|
||||||
# p flashes
|
|
@ -1,25 +0,0 @@
|
|||||||
cave = Hash.new {|h,k| h[k] = [] }
|
|
||||||
ARGF.read.scan(/(\w+)-(\w+)/).each do
|
|
||||||
cave[_1] << _2
|
|
||||||
cave[_2] << _1
|
|
||||||
end
|
|
||||||
|
|
||||||
paths = [ %w[start] ]
|
|
||||||
|
|
||||||
loop do
|
|
||||||
closed, open = paths.partition { _1.last == "end" }
|
|
||||||
break if open.empty?
|
|
||||||
|
|
||||||
paths = closed + open.flat_map {|path|
|
|
||||||
cave.fetch(path.last)
|
|
||||||
# .reject { _1 =~ /^[a-z]+$/ && path.include?(_1) }
|
|
||||||
.reject { _1 == "start" }
|
|
||||||
.reject {|cave|
|
|
||||||
smalls = path.tally.select { _1 =~ /^[a-z]+$/ }
|
|
||||||
smalls.fetch(cave, 0) > (smalls.any? { _2 > 1 } ? 0 : 1)
|
|
||||||
}
|
|
||||||
.map { path + [_1] }
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
p paths.count
|
|
@ -1,18 +0,0 @@
|
|||||||
dots, folds = ARGF.read.split("\n\n")
|
|
||||||
|
|
||||||
dots = dots.scan(/(\d+),(\d+)/).map { _1.map(&:to_i) }
|
|
||||||
folds = folds.scan(/(x|y)=(\d+)/).map { [_1, _2.to_i] }
|
|
||||||
|
|
||||||
dirs = { ?x => 0, ?y => 1 }
|
|
||||||
folds.each do |dir, axis|
|
|
||||||
index = dirs.fetch(dir)
|
|
||||||
dots.select { _1[index] > axis }.each do |dot|
|
|
||||||
dot[index] = axis - (dot[index] - axis)
|
|
||||||
end
|
|
||||||
dots.uniq!
|
|
||||||
# p dots.size or exit
|
|
||||||
end
|
|
||||||
|
|
||||||
xx = Range.new(*dots.map(&:first).minmax)
|
|
||||||
yy = Range.new(*dots.map(&:last).minmax)
|
|
||||||
puts yy.map {|y| xx.map {|x| dots.include?([x,y]) ? "█" : " " }.join }.join("\n")
|
|
@ -1,41 +0,0 @@
|
|||||||
template, rules = ARGF.read.split("\n\n")
|
|
||||||
template = template.chars
|
|
||||||
rules = rules.scan(/(\w{2}) -> (\w)/).to_h
|
|
||||||
|
|
||||||
# polymer = template
|
|
||||||
# 10.times do
|
|
||||||
# polymer = polymer.each_cons(2).flat_map {|a,b|
|
|
||||||
# [a, rules.fetch("#{a}#{b}")]
|
|
||||||
# } << polymer.last
|
|
||||||
# end
|
|
||||||
|
|
||||||
# min, max = polymer.tally.values.minmax
|
|
||||||
# p max - min
|
|
||||||
|
|
||||||
tally = Hash.new {|h,k|
|
|
||||||
polymer, steps = k
|
|
||||||
new_elements = polymer.each_cons(2).map(&:join).map { rules.fetch(_1) }
|
|
||||||
h[k] = case steps
|
|
||||||
when 1
|
|
||||||
(polymer + new_elements).tally
|
|
||||||
when (2..)
|
|
||||||
initial = new_elements.tally.transform_values { -_1 }
|
|
||||||
polymer.zip(new_elements)
|
|
||||||
.flatten[0..-2]
|
|
||||||
.each_cons(2)
|
|
||||||
.map { h[[_1, steps-1]] }
|
|
||||||
.inject(initial) {|final,tally| final.merge(tally) { _2 + _3 } }
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
}
|
|
||||||
|
|
||||||
final = tally[[template, 40]]
|
|
||||||
|
|
||||||
# correct for internal elements being double-counted
|
|
||||||
template[1..-2].each do
|
|
||||||
final[_1] -= 1
|
|
||||||
end
|
|
||||||
|
|
||||||
min, max = final.values.minmax
|
|
||||||
p max - min
|
|
@ -1,38 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
cavern = ARGF.read.split("\n").map { _1.chars.map(&:to_i) }
|
|
||||||
cavern = (0..4).flat_map {|i| cavern.map {|row|
|
|
||||||
row.map { (_1 + i - 1) % 9 + 1 }
|
|
||||||
}}
|
|
||||||
cavern = cavern.map {|row| (0..4).flat_map {|i|
|
|
||||||
row.map { (_1 + i - 1) % 9 + 1 }
|
|
||||||
}}
|
|
||||||
|
|
||||||
cavern = cavern
|
|
||||||
.flat_map.with_index {|row,y| row.map.with_index {|risk,x| [[y,x], risk] }}
|
|
||||||
.to_h
|
|
||||||
bottom_right = cavern.keys.max
|
|
||||||
|
|
||||||
risks = Hash.new(0)
|
|
||||||
risks[[0,0]] = 0
|
|
||||||
edges = Set[[0,0]]
|
|
||||||
|
|
||||||
until risks.has_key?(bottom_right)
|
|
||||||
yx = edges.min_by { risks.fetch(_1) }
|
|
||||||
edges.delete(yx)
|
|
||||||
|
|
||||||
y,x = yx
|
|
||||||
neighbors = [[-1, 0], [1, 0], [0, 1], [0, -1]]
|
|
||||||
.map {|dy,dx| [y+dy, x+dx] }
|
|
||||||
.select { cavern.has_key?(_1) }
|
|
||||||
.reject { risks.has_key?(_1) }
|
|
||||||
|
|
||||||
risk = risks.fetch(yx)
|
|
||||||
neighbors.each do
|
|
||||||
risks[_1] = risk + cavern.fetch(_1)
|
|
||||||
end
|
|
||||||
|
|
||||||
edges.merge(neighbors)
|
|
||||||
end
|
|
||||||
|
|
||||||
p risks[bottom_right]
|
|
@ -1,79 +0,0 @@
|
|||||||
require "strscan"
|
|
||||||
|
|
||||||
Packet = Struct.new(:version, :type_id, :content) do
|
|
||||||
include Enumerable
|
|
||||||
|
|
||||||
def self.parse(ss)
|
|
||||||
version = ss.scan(/.{3}/).to_i(2)
|
|
||||||
type_id = ss.scan(/.{3}/).to_i(2)
|
|
||||||
|
|
||||||
case type_id
|
|
||||||
when 4 # literal value
|
|
||||||
value = ss.scan(/(1.{4})*(0.{4})/).chars
|
|
||||||
.each_slice(5).flat_map { _1[1..4] }.join
|
|
||||||
.to_i(2)
|
|
||||||
Literal.new(version, type_id, value)
|
|
||||||
else # operator
|
|
||||||
sub_packets = case
|
|
||||||
when ss.scan(/0(.{15})/)
|
|
||||||
length = ss.captures[0].to_i(2)
|
|
||||||
sub_packet = ss.scan(/.{#{length}}/)
|
|
||||||
|
|
||||||
sss = StringScanner.new(sub_packet)
|
|
||||||
sub_packets = []
|
|
||||||
until sss.eos?
|
|
||||||
sub_packets << parse(sss)
|
|
||||||
end
|
|
||||||
sub_packets
|
|
||||||
when ss.scan(/1(.{11})/)
|
|
||||||
n = ss.captures[0].to_i(2)
|
|
||||||
n.times.map { parse(ss) }
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
Operator.new(version, type_id, sub_packets)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def each
|
|
||||||
return enum_for(__method__) unless block_given?
|
|
||||||
|
|
||||||
yield self
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class Literal < Packet
|
|
||||||
def value = content
|
|
||||||
end
|
|
||||||
|
|
||||||
class Operator < Packet
|
|
||||||
def each(&block)
|
|
||||||
super
|
|
||||||
|
|
||||||
content.each do |sub_packet|
|
|
||||||
sub_packet.each(&block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def value
|
|
||||||
values = content.map(&:value)
|
|
||||||
case type_id
|
|
||||||
when 0 then values.sum
|
|
||||||
when 1 then values.inject(:*)
|
|
||||||
when 2 then values.min
|
|
||||||
when 3 then values.max
|
|
||||||
when 4 then fail
|
|
||||||
when 5 then values.inject(:>) ? 1 : 0
|
|
||||||
when 6 then values.inject(:<) ? 1 : 0
|
|
||||||
when 7 then values.inject(:==) ? 1 : 0
|
|
||||||
else fail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
message = ARGF.read.chomp.chars.map { _1.to_i(16).to_s(2).rjust(4, ?0) }.join
|
|
||||||
ss = StringScanner.new(message)
|
|
||||||
packet = Packet.parse(ss)
|
|
||||||
|
|
||||||
p packet.sum(&:version)
|
|
||||||
p packet.value
|
|
@ -1,29 +0,0 @@
|
|||||||
def fire(v, target)
|
|
||||||
return enum_for(__method__, v, target) unless block_given?
|
|
||||||
|
|
||||||
pos = [0,0]
|
|
||||||
v_x, v_y = v
|
|
||||||
|
|
||||||
loop do
|
|
||||||
yield pos
|
|
||||||
|
|
||||||
return if target.zip(pos).all? { _1.cover?(_2) }
|
|
||||||
|
|
||||||
pos = pos.zip([v_x, v_y]).map { _1.sum }
|
|
||||||
v_x -= 1 if v_x > 0
|
|
||||||
v_y -= 1
|
|
||||||
|
|
||||||
return if pos[0] > target[0].end
|
|
||||||
return if pos[1] < target[1].begin
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
input = ARGF.read.scan(/x=(.+), y=(.+)/)
|
|
||||||
target = input[0].map { eval(_1) }
|
|
||||||
|
|
||||||
xs = (0..target[0].end).select { (1.._1).sum > target[0].begin }
|
|
||||||
haystack = xs.flat_map {|x| (-256..256).map {|y| [x, y] }}
|
|
||||||
haystack.select! {|v| fire(v, target).each.any? {|pos| target.zip(pos).all? { _1.cover?(_2) }}}
|
|
||||||
|
|
||||||
# p haystack.map {|v| fire(v, target).each.map { _2 }.max }.max
|
|
||||||
p haystack.count
|
|
@ -1,75 +0,0 @@
|
|||||||
require "strscan"
|
|
||||||
|
|
||||||
def add(a, b)
|
|
||||||
reduced("[#{a},#{b}]")
|
|
||||||
end
|
|
||||||
|
|
||||||
def reduced(s)
|
|
||||||
last_s = ""
|
|
||||||
until s == last_s
|
|
||||||
last_s = s
|
|
||||||
|
|
||||||
to_explode = find_nested(s)
|
|
||||||
if to_explode
|
|
||||||
s = explode(s, to_explode)
|
|
||||||
next
|
|
||||||
end
|
|
||||||
|
|
||||||
s = s.sub(/[1-9]\d+/) {|n|
|
|
||||||
half = n.to_i / 2.0
|
|
||||||
pair = [half.floor, half.ceil]
|
|
||||||
"[#{pair.join(?,)}]"
|
|
||||||
}
|
|
||||||
end
|
|
||||||
s
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_nested(s)
|
|
||||||
ss = StringScanner.new(s)
|
|
||||||
|
|
||||||
depth = 0
|
|
||||||
until ss.eos?
|
|
||||||
case
|
|
||||||
when ss.scan(/\[/)
|
|
||||||
if depth == 4
|
|
||||||
a = ss.pos-1
|
|
||||||
ss.scan(/\d+,\d+\]/)
|
|
||||||
b = ss.pos-1
|
|
||||||
return [a, b]
|
|
||||||
end
|
|
||||||
depth += 1
|
|
||||||
when ss.scan(/\]/)
|
|
||||||
depth -= 1
|
|
||||||
when ss.scan(/\d+|,/)
|
|
||||||
# no-op
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def explode(s, pair_range)
|
|
||||||
a, b = pair_range
|
|
||||||
pair = s[a..b].scan(/\d+/).map(&:to_i)
|
|
||||||
|
|
||||||
[
|
|
||||||
s[0...a].reverse.sub(/\d+/) { (_1.reverse.to_i + pair[0]).to_s.reverse }.reverse,
|
|
||||||
0,
|
|
||||||
s[b+1..].sub(/(\d+)/) { _1.to_i + pair[1] },
|
|
||||||
].join
|
|
||||||
end
|
|
||||||
|
|
||||||
class Array
|
|
||||||
def magnitude = 3*self[0].magnitude + 2*self[1].magnitude
|
|
||||||
end
|
|
||||||
|
|
||||||
class Integer
|
|
||||||
def magnitude = self
|
|
||||||
end
|
|
||||||
|
|
||||||
# sum = ARGF.read.split("\n").reject(&:empty?).inject {|sum,num| add(sum, num) }
|
|
||||||
# p eval(sum).magnitude
|
|
||||||
|
|
||||||
p ARGF.read.split("\n").reject(&:empty?).permutation(2).map { eval(add(*_1)).magnitude }.max
|
|
@ -1,52 +0,0 @@
|
|||||||
require "matrix"
|
|
||||||
require "set"
|
|
||||||
|
|
||||||
scanners = ARGF.read.strip.split("\n\n").to_h {|scanner|
|
|
||||||
id, *rest = scanner.split("\n")
|
|
||||||
id = id.scan(/\d+/)[0].to_i
|
|
||||||
coords = rest.map { _1.split(?,).map(&:to_i) }
|
|
||||||
[id, coords.map { Matrix.column_vector(_1) }]
|
|
||||||
}
|
|
||||||
|
|
||||||
first_scanner = scanners.shift
|
|
||||||
origin_beacon = first_scanner[1].first
|
|
||||||
origin_beacon = Matrix.column_vector([-618,-824,-621])
|
|
||||||
|
|
||||||
known_scanners = {
|
|
||||||
first_scanner[0] => [ origin_beacon.map { -_1 }, Matrix.identity(3) ],
|
|
||||||
}
|
|
||||||
known_beacons = Set.new(first_scanner[1].map {|beacon| beacon - origin_beacon })
|
|
||||||
|
|
||||||
rot_x = Matrix[ [1, 0, 0], [0, 0, -1], [0, 1, 0] ]
|
|
||||||
rot_y = Matrix[ [0, 0, 1], [0, 1, 0], [-1, 0, 0] ]
|
|
||||||
rot_z = Matrix[ [0, -1, 0], [1, 0, 0], [0, 0, 1] ]
|
|
||||||
id = Matrix.identity(3)
|
|
||||||
|
|
||||||
ROTATIONS = Set.new(
|
|
||||||
Array.new(4) { rot_x ** _1 }.flat_map {|x|
|
|
||||||
Array.new(4) { rot_y ** _1 }.flat_map {|y|
|
|
||||||
Array.new(4) { rot_z ** _1 }.map {|z| x * y * z }}}
|
|
||||||
)
|
|
||||||
|
|
||||||
def find_overlapping_scanner(known_beacons, scanners)
|
|
||||||
scanners.filter_map {|id, beacons|
|
|
||||||
haystack = ROTATIONS.flat_map {|r| beacons.map {|b| [ r*b, r ] }}
|
|
||||||
# haystack.select { _2 == Matrix.identity(3) }.map(&:first).each { p _1 }
|
|
||||||
haystack.find {|position, rotation|
|
|
||||||
translated_beacons = beacons.map { (rotation * _1) - position }
|
|
||||||
(known_beacons & translated_beacons).size >= 12
|
|
||||||
}&.then {|p,o| [id, p, o] }
|
|
||||||
}.first
|
|
||||||
end
|
|
||||||
|
|
||||||
until scanners.empty?
|
|
||||||
id, position, orientation = find_overlapping_scanner(known_beacons, scanners)
|
|
||||||
|
|
||||||
p [id, position, orientation]
|
|
||||||
|
|
||||||
known_scanners[id] = [position, orientation]
|
|
||||||
translated_beacons = scanners[id].map {|b| b.zip(position).map { _2 - _1 }.zip(orientation).map { _1 * _2 }}
|
|
||||||
known_beacons.merge(translated_beacons)
|
|
||||||
scanners.delete(id)
|
|
||||||
end
|
|
||||||
|
|
@ -1,50 +0,0 @@
|
|||||||
algorithm, image = ARGF.read.strip.split("\n\n")
|
|
||||||
|
|
||||||
algorithm = algorithm.delete("\n") # for the example
|
|
||||||
algorithm = algorithm.chars.map.with_index { [_2, _1 == ?#] }.to_h
|
|
||||||
|
|
||||||
image = image.split("\n").flat_map.with_index {|row, y|
|
|
||||||
row.chars.map.with_index {|pixel, x| [[y, x], pixel == ?#] }
|
|
||||||
}.to_h
|
|
||||||
image.default = false
|
|
||||||
|
|
||||||
def each(image)
|
|
||||||
return enum_for(__method__, image) unless block_given?
|
|
||||||
|
|
||||||
ys = image.keys.map(&:first).minmax
|
|
||||||
xs = image.keys.map(&:last).minmax
|
|
||||||
|
|
||||||
(ys[0]-1..ys[1]+1).each do |y|
|
|
||||||
(xs[0]-1..xs[1]+1).each do |x|
|
|
||||||
yield [y, x]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def debug(image)
|
|
||||||
ys = image.keys.map(&:first).minmax
|
|
||||||
xs = image.keys.map(&:last).minmax
|
|
||||||
|
|
||||||
puts (ys[0]-1..ys[1]+1).map {|y|
|
|
||||||
(xs[0]-1..xs[1]+1).map {|x|
|
|
||||||
image[[y,x]] ? ?# : ?.
|
|
||||||
}.join
|
|
||||||
}.join("\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
50.times {
|
|
||||||
ys = image.keys.map(&:first).minmax
|
|
||||||
xs = image.keys.map(&:last).minmax
|
|
||||||
|
|
||||||
prev_default = image.default
|
|
||||||
image = each(image).to_h {|y,x|
|
|
||||||
area = (-1..1).flat_map {|dy| (-1..1).map {|dx| image[[y+dy, x+dx]] }}
|
|
||||||
index = area.map { _1 ? 1 : 0 }.join.to_i(2)
|
|
||||||
pixel = algorithm.fetch(index)
|
|
||||||
[[y,x], pixel]
|
|
||||||
}
|
|
||||||
|
|
||||||
image.default = prev_default ? algorithm.fetch(511) : algorithm.fetch(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
p image.count { _2 }
|
|
@ -1,76 +0,0 @@
|
|||||||
# Player = Struct.new(:space, :score)
|
|
||||||
# one = Player.new(7, 0)
|
|
||||||
# two = Player.new(3, 0)
|
|
||||||
|
|
||||||
# class Die
|
|
||||||
# def initialize
|
|
||||||
# @value = 0
|
|
||||||
# @rolls = 0
|
|
||||||
# end
|
|
||||||
|
|
||||||
# attr_reader :rolls
|
|
||||||
|
|
||||||
# def roll
|
|
||||||
# value = @value
|
|
||||||
|
|
||||||
# @value += 1
|
|
||||||
# @value %= 100
|
|
||||||
|
|
||||||
# @rolls += 1
|
|
||||||
|
|
||||||
# value
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# die = Die.new
|
|
||||||
|
|
||||||
# loop do
|
|
||||||
# one.space += 3.times.sum { die.roll + 1 }
|
|
||||||
# one.space %= 10
|
|
||||||
# one.score += one.space + 1
|
|
||||||
# break if one.score >= 1000
|
|
||||||
|
|
||||||
# two.space += 3.times.sum { die.roll + 1 }
|
|
||||||
# two.space %= 10
|
|
||||||
# two.score += two.space + 1
|
|
||||||
# break if two.score >= 1000
|
|
||||||
# end
|
|
||||||
|
|
||||||
# p [one, two].map(&:score).min * die.rolls
|
|
||||||
|
|
||||||
ROLLS = (1..3).flat_map {|a| (1..3).flat_map {|b| (1..3).map {|c|
|
|
||||||
[a, b, c].sum
|
|
||||||
}}}.tally
|
|
||||||
Player = Struct.new(:score, :space, keyword_init: true)
|
|
||||||
wins = Hash.new {|h,k|
|
|
||||||
one, two = k
|
|
||||||
|
|
||||||
multiverse = ROLLS.map {|delta,n|
|
|
||||||
space = (one.space + delta) % 10
|
|
||||||
[Player.new(score: one.score + space + 1, space: space), n]
|
|
||||||
}
|
|
||||||
one_wins, one_ongoing = multiverse.partition {|player,_| player.score >= 21 }
|
|
||||||
one_wins = one_wins.sum(&:last)
|
|
||||||
|
|
||||||
multiverse = ROLLS.map {|delta,n|
|
|
||||||
space = (two.space + delta) % 10
|
|
||||||
[Player.new(score: two.score + space + 1, space: space), n]
|
|
||||||
}
|
|
||||||
|
|
||||||
wins = one_ongoing.flat_map {|one, n_one| multiverse.map {|two, n_two|
|
|
||||||
n = n_one * n_two
|
|
||||||
if two.score >= 21
|
|
||||||
{ one: 0, two: n }
|
|
||||||
else
|
|
||||||
h[[one, two]].map { [_1, _2 * n] }.to_h
|
|
||||||
end
|
|
||||||
}}
|
|
||||||
wins = wins.inject({one: 0, two: 0}) {|acc,wins| acc.merge(wins) { _2 + _3 }}
|
|
||||||
|
|
||||||
h[k] = {
|
|
||||||
one: one_wins + wins.fetch(:one),
|
|
||||||
two: wins.fetch(:two),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# p wins[[Player.new(score: 0, space: 3), Player.new(score: 0, space: 7)]]
|
|
||||||
p wins[[Player.new(score: 0, space: 7), Player.new(score: 0, space: 3)]].values.max
|
|
@ -1,109 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
steps = ARGF.read.scan(/(on|off) x=(.+),y=(.+),z=(.+)/)
|
|
||||||
.map {|power, *ranges| [power == "on", *ranges.map { eval(_1) }] }
|
|
||||||
# .select {|_, *ranges| ranges.all? { _1.begin >= -50 && _1.end <= 50 }}
|
|
||||||
|
|
||||||
# reactor = Hash.new(false)
|
|
||||||
# steps.each do |power,x,y,z|
|
|
||||||
# x.each do |x|
|
|
||||||
# y.each do |y|
|
|
||||||
# z.each do |z|
|
|
||||||
# reactor[[x,y,z]] = power
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
# p reactor.count { _2 }
|
|
||||||
|
|
||||||
# xs = steps.flat_map { [_2.begin, _2.end] }.minmax
|
|
||||||
# ys = steps.flat_map { [_3.begin, _3.end] }.minmax
|
|
||||||
# zs = steps.flat_map { [_4.begin, _4.end] }.minmax
|
|
||||||
# ons = Range.new(*xs).sum {|x| Range.new(*ys).sum {|y| Range.new(*zs).count {|z|
|
|
||||||
# step = steps.find { _2.cover?(x) && _3.cover?(y) && _4.cover?(z) }
|
|
||||||
# step ? step[0] : false
|
|
||||||
# }}}
|
|
||||||
|
|
||||||
# p ons
|
|
||||||
|
|
||||||
class Range
|
|
||||||
def overlap(other)
|
|
||||||
if cover?(other.begin)
|
|
||||||
min = other.begin
|
|
||||||
max = [self.end, other.end].min
|
|
||||||
(min..max)
|
|
||||||
elsif cover?(other.end)
|
|
||||||
min = [self.begin, other.begin].max
|
|
||||||
max = other.end
|
|
||||||
(min..max)
|
|
||||||
elsif other.cover?(self.begin)
|
|
||||||
min = self.begin
|
|
||||||
max = [self.end, other.end].min
|
|
||||||
(min..max)
|
|
||||||
elsif other.cover?(self.end)
|
|
||||||
min = [self.begin, other.begin].max
|
|
||||||
max = self.end
|
|
||||||
(min..max)
|
|
||||||
else
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def split(other)
|
|
||||||
overlap = self.overlap(other)
|
|
||||||
return [] if overlap.nil?
|
|
||||||
|
|
||||||
splits = [ overlap ]
|
|
||||||
splits << (self.begin..overlap.begin-1) if overlap.begin > self.begin
|
|
||||||
splits << (overlap.end+1..self.end) if overlap.end < self.end
|
|
||||||
splits
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
Cube = Struct.new(:xs, :ys, :zs) do
|
|
||||||
def -(other)
|
|
||||||
return self unless o = overlap(other)
|
|
||||||
|
|
||||||
xxs = xs.split(other.xs)
|
|
||||||
yys = ys.split(other.ys)
|
|
||||||
zzs = zs.split(other.zs)
|
|
||||||
|
|
||||||
cuboids = xxs.flat_map {|x| yys.flat_map {|y| zzs.map {|z|
|
|
||||||
Cube.new(x, y, z)
|
|
||||||
}}}
|
|
||||||
cuboids.delete(o)
|
|
||||||
|
|
||||||
cuboids
|
|
||||||
end
|
|
||||||
|
|
||||||
def overlap(other)
|
|
||||||
overlaps = to_a.zip(other.to_a).map { _1.overlap(_2) }
|
|
||||||
return nil if overlaps.any?(&:nil?)
|
|
||||||
|
|
||||||
Cube.new(*overlaps)
|
|
||||||
end
|
|
||||||
|
|
||||||
def overlap?(other) = !overlap(other).nil?
|
|
||||||
|
|
||||||
def volume = (xs.end - xs.begin + 1) * (ys.end - ys.begin + 1) * (zs.end - zs.begin + 1)
|
|
||||||
|
|
||||||
def to_s = "[#{[xs, ys, zs].map(&:to_s).join(", ")}]"
|
|
||||||
alias_method :inspect, :to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
steps = steps.map {|power, *ranges| [power, Cube.new(*ranges)] }
|
|
||||||
|
|
||||||
reactor = Set.new
|
|
||||||
steps.each do |power, cube|
|
|
||||||
reactor
|
|
||||||
.select { _1.overlap?(cube) }
|
|
||||||
.each do |overlap|
|
|
||||||
reactor.delete(overlap)
|
|
||||||
reactor.merge(overlap - cube)
|
|
||||||
end
|
|
||||||
|
|
||||||
reactor << cube if power
|
|
||||||
end
|
|
||||||
|
|
||||||
p reactor.sum(&:volume)
|
|
@ -1,35 +0,0 @@
|
|||||||
#############
|
|
||||||
#...........#
|
|
||||||
###B#C#B#D###
|
|
||||||
#A#D#C#A#
|
|
||||||
#########
|
|
||||||
|
|
||||||
#############
|
|
||||||
#...........#
|
|
||||||
###D#D#A#A###
|
|
||||||
#C#C#B#B#
|
|
||||||
#########
|
|
||||||
|
|
||||||
State = Struct.new(:spaces, :energy) do
|
|
||||||
ENERGY = { A: 1, B: 10, C: 100, D: 1000 }.transform_keys(&:to_s)
|
|
||||||
ROOMS = [2, 4, 6, 8]
|
|
||||||
|
|
||||||
def rooms = ROOMS.to_h { [_1, spaces.fetch(_1)] }
|
|
||||||
|
|
||||||
def valid_moves
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
spaces = Array.new(11) { [] }
|
|
||||||
# input = "DC DC AB AB"
|
|
||||||
input = "BA CD BC DA"
|
|
||||||
input.split(" ").map(&:chars).each.with_index do |amphipods, i|
|
|
||||||
spaces[(i+1) * 2] = amphipods
|
|
||||||
end
|
|
||||||
|
|
||||||
start = State.new(spaces, 0)
|
|
||||||
|
|
||||||
p start
|
|
||||||
p start.rooms
|
|
||||||
p start.valid_moves
|
|
@ -1,58 +0,0 @@
|
|||||||
INSTRUCTIONS = ARGF.read.split("\n").map { _1.split(/\s+/) }
|
|
||||||
|
|
||||||
# INSTRUCTIONS.each do |instruction, *args|
|
|
||||||
# a, b = *args
|
|
||||||
# case instruction
|
|
||||||
# when "inp"
|
|
||||||
# puts "#{a} = input.shift"
|
|
||||||
# when "add"
|
|
||||||
# puts "#{a} += #{b}"
|
|
||||||
# when "mul"
|
|
||||||
# puts "#{a} *= #{b}"
|
|
||||||
# when "div"
|
|
||||||
# puts "#{a} = (#{a} / #{b}.to_f).floor"
|
|
||||||
# when "mod"
|
|
||||||
# puts "#{a} %= #{b}"
|
|
||||||
# when "eql"
|
|
||||||
# puts "#{a} = #{a} == #{b} ? 1 : 0"
|
|
||||||
# else
|
|
||||||
# fail
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
# exit
|
|
||||||
|
|
||||||
VARS = %w[ w x y z ]
|
|
||||||
def run(input)
|
|
||||||
vars = Hash.new(0)
|
|
||||||
|
|
||||||
INSTRUCTIONS.each do |instruction, *args|
|
|
||||||
a, b = *args
|
|
||||||
b = VARS.include?(b) ? vars[b] : b.to_i
|
|
||||||
case instruction
|
|
||||||
when "inp"
|
|
||||||
vars[a] = input.shift
|
|
||||||
when "add"
|
|
||||||
vars[a] += b
|
|
||||||
when "mul"
|
|
||||||
vars[a] *= b
|
|
||||||
when "div"
|
|
||||||
vars[a] = (vars[a] / b.to_f).floor
|
|
||||||
when "mod"
|
|
||||||
vars[a] %= b
|
|
||||||
when "eql"
|
|
||||||
vars[a] = vars[a] == b ? 1 : 0
|
|
||||||
else
|
|
||||||
fail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
vars
|
|
||||||
end
|
|
||||||
|
|
||||||
99999999999999.downto(11111111111111).lazy.map(&:to_s).reject { _1.include?(?0) }.each do |input|
|
|
||||||
vars = run(input.chars.map(&:to_i))
|
|
||||||
if vars[?z].zero?
|
|
||||||
puts input
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,262 +0,0 @@
|
|||||||
def run(input)
|
|
||||||
w, x, y, z = 0, 0, 0, 0
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x = z % 26
|
|
||||||
# z = (z / 1.to_f).floor
|
|
||||||
# x += 13
|
|
||||||
# x = x == w ? 0 : 1
|
|
||||||
# y = 25 * x + 1 # either y = 26 or y = 1
|
|
||||||
# z *= y # 0
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y = (w + 13) * x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
# # puts
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x = z % 26
|
|
||||||
# z = (z / 1.to_f).floor
|
|
||||||
# x += 11
|
|
||||||
# x = x == w ? 0 : 1
|
|
||||||
# y = 25 * x + 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y = (w + 10) * x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
# # puts
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x = z % 26
|
|
||||||
# z = (z / 1.to_f).floor
|
|
||||||
# x += 15
|
|
||||||
# x = x == w ? 0 : 1
|
|
||||||
# y = (25 * x) + 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y = (w + 5) * x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
# # puts
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x = z % 26
|
|
||||||
# z = (z / 26.to_f).floor
|
|
||||||
# x += -11
|
|
||||||
# x = x == w ? 0 : 1
|
|
||||||
# y = (25 * x) + 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y = (w + 14) * x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
# # puts
|
|
||||||
|
|
||||||
# return [w, x, y, z]
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x = z % 26
|
|
||||||
# z = (z / 1.to_f).floor
|
|
||||||
# x += 14
|
|
||||||
# x = x == w ? 0 : 1
|
|
||||||
# y = 25 * x + 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y = (w + 5) * x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
# # puts
|
|
||||||
# # puts
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x = z % 26
|
|
||||||
# z = (z / 26.to_f).floor
|
|
||||||
# x += 0
|
|
||||||
# x = x == w ? 0 : 1
|
|
||||||
# y = 25 * x + 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y = (w + 15) * x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
# # puts
|
|
||||||
|
|
||||||
# return [w, x, y, z]
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x = z % 26
|
|
||||||
# z = (z / 1.to_f).floor
|
|
||||||
# x += 12
|
|
||||||
# x = x == w ? 0 : 1
|
|
||||||
# y = 25 * x + 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y *= 0
|
|
||||||
# y += w
|
|
||||||
# y += 4
|
|
||||||
# y *= x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x *= 0
|
|
||||||
# x += z
|
|
||||||
# x %= 26
|
|
||||||
# z = (z / 1.to_f).floor
|
|
||||||
# x += 12
|
|
||||||
# x = x == w ? 1 : 0
|
|
||||||
# x = x == 0 ? 1 : 0
|
|
||||||
# y *= 0
|
|
||||||
# y += 25
|
|
||||||
# y *= x
|
|
||||||
# y += 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y *= 0
|
|
||||||
# y += w
|
|
||||||
# y += 11
|
|
||||||
# y *= x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x *= 0
|
|
||||||
# x += z
|
|
||||||
# x %= 26
|
|
||||||
# z = (z / 1.to_f).floor
|
|
||||||
# x += 14
|
|
||||||
# x = x == w ? 1 : 0
|
|
||||||
# x = x == 0 ? 1 : 0
|
|
||||||
# y *= 0
|
|
||||||
# y += 25
|
|
||||||
# y *= x
|
|
||||||
# y += 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y *= 0
|
|
||||||
# y += w
|
|
||||||
# y += 1
|
|
||||||
# y *= x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
# # puts
|
|
||||||
# # puts
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x *= 0
|
|
||||||
# x += z
|
|
||||||
# x %= 26
|
|
||||||
# z = (z / 26.to_f).floor
|
|
||||||
# x += -6
|
|
||||||
# x = x == w ? 1 : 0
|
|
||||||
# x = x == 0 ? 1 : 0
|
|
||||||
# y *= 0
|
|
||||||
# y += 25
|
|
||||||
# y *= x
|
|
||||||
# y += 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y *= 0
|
|
||||||
# y += w
|
|
||||||
# y += 15
|
|
||||||
# y *= x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# return [w, x, y, z]
|
|
||||||
|
|
||||||
# w = input.shift
|
|
||||||
# x *= 0
|
|
||||||
# x += z
|
|
||||||
# x %= 26
|
|
||||||
# z = (z / 26.to_f).floor
|
|
||||||
# x += -10
|
|
||||||
# x = x == w ? 1 : 0
|
|
||||||
# x = x == 0 ? 1 : 0
|
|
||||||
# y *= 0
|
|
||||||
# y += 25
|
|
||||||
# y *= x
|
|
||||||
# y += 1
|
|
||||||
# z *= y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# y *= 0
|
|
||||||
# y += w
|
|
||||||
# y += 12
|
|
||||||
# y *= x
|
|
||||||
# z += y
|
|
||||||
# # p [w, x, y, z]
|
|
||||||
|
|
||||||
# return [w, x, y, z]
|
|
||||||
|
|
||||||
w = input.shift
|
|
||||||
x *= 0
|
|
||||||
x += z
|
|
||||||
x %= 26
|
|
||||||
z = (z / 26.to_f).floor
|
|
||||||
x += -12
|
|
||||||
x = x == w ? 1 : 0
|
|
||||||
x = x == 0 ? 1 : 0
|
|
||||||
y *= 0
|
|
||||||
y += 25
|
|
||||||
y *= x
|
|
||||||
y += 1
|
|
||||||
z *= y
|
|
||||||
# p [w, x, y, z]
|
|
||||||
|
|
||||||
y *= 0
|
|
||||||
y += w
|
|
||||||
y += 8
|
|
||||||
y *= x
|
|
||||||
z += y
|
|
||||||
# p [w, x, y, z]
|
|
||||||
|
|
||||||
return [w, x, y, z]
|
|
||||||
|
|
||||||
w = input.shift
|
|
||||||
x = z % 26
|
|
||||||
z = (z / 26.to_f).floor
|
|
||||||
x += -3
|
|
||||||
x = x == w ? 0 : 1
|
|
||||||
y = 25 * x + 1
|
|
||||||
z *= y
|
|
||||||
# p [w, x, y, z]
|
|
||||||
|
|
||||||
y = (w + 14) * x
|
|
||||||
z += y
|
|
||||||
# p [w, x, y, z]
|
|
||||||
|
|
||||||
w = input.shift
|
|
||||||
x = z % 26 # z - 5 must be w
|
|
||||||
z = (z / 26.to_f).floor # z must be < 26
|
|
||||||
x += -5 # w must be x - 5
|
|
||||||
x = x == w ? 0 : 1 # x must be w
|
|
||||||
y = 25 * x + 1
|
|
||||||
z *= y # z must be 0
|
|
||||||
# p [w, x, y, z]
|
|
||||||
|
|
||||||
y = (w + 9) * x # x must be 0
|
|
||||||
z += y # y must be 0
|
|
||||||
|
|
||||||
[w, x, y, z]
|
|
||||||
end
|
|
||||||
|
|
||||||
# 99999999999999.downto(11111111111111).lazy.map(&:to_s).reject { _1.include?(?0) }.each do |input|
|
|
||||||
vars = run(input.chars.map(&:to_i))
|
|
||||||
p [input, vars[3]] if vars[3] < 400
|
|
||||||
if vars[3].zero?
|
|
||||||
puts input
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
end
|
|
@ -1 +0,0 @@
|
|||||||
day_*.txt
|
|
@ -1 +0,0 @@
|
|||||||
Subproject commit b90e26c29b1742bf164b6121275b5e1ee8a56365
|
|
@ -1,19 +0,0 @@
|
|||||||
(fn dbg [tbl]
|
|
||||||
(each [_ chunk (ipairs tbl)]
|
|
||||||
(print (accumulate [x "" _ i (ipairs chunk)]
|
|
||||||
(.. x ", " i)))))
|
|
||||||
|
|
||||||
(local input (accumulate [input [[]] line (io.lines :../day_01.txt)]
|
|
||||||
(do
|
|
||||||
(if (= (length line) 0)
|
|
||||||
(table.insert input [])
|
|
||||||
(table.insert (. input (length input)) (tonumber line)))
|
|
||||||
input)))
|
|
||||||
|
|
||||||
(fn sum [l]
|
|
||||||
(accumulate [sum 0 _ n (ipairs l)]
|
|
||||||
(+ sum n)))
|
|
||||||
|
|
||||||
(local l (icollect [_ l (ipairs input)] (sum l)))
|
|
||||||
(table.sort l)
|
|
||||||
(print (. l (length l)))
|
|
@ -1 +0,0 @@
|
|||||||
3.2
|
|
@ -1,8 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
source "https://rubygems.org"
|
|
||||||
|
|
||||||
gem "minitest"
|
|
||||||
gem "parslet"
|
|
||||||
gem "ruby-lsp"
|
|
||||||
gem "z3"
|
|
@ -1,29 +0,0 @@
|
|||||||
GEM
|
|
||||||
remote: https://rubygems.org/
|
|
||||||
specs:
|
|
||||||
ffi (1.15.5)
|
|
||||||
language_server-protocol (3.17.0.2)
|
|
||||||
minitest (5.16.3)
|
|
||||||
parslet (2.0.0)
|
|
||||||
prettier_print (1.2.0)
|
|
||||||
ruby-lsp (0.3.7)
|
|
||||||
language_server-protocol (~> 3.17.0)
|
|
||||||
sorbet-runtime
|
|
||||||
syntax_tree (>= 4.0.2, < 5.0.0)
|
|
||||||
sorbet-runtime (0.5.10597)
|
|
||||||
syntax_tree (4.3.0)
|
|
||||||
prettier_print (>= 1.0.2)
|
|
||||||
z3 (0.0.20221020)
|
|
||||||
ffi (~> 1.9)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
arm64-darwin-21
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
minitest
|
|
||||||
parslet
|
|
||||||
ruby-lsp
|
|
||||||
z3
|
|
||||||
|
|
||||||
BUNDLED WITH
|
|
||||||
2.3.18
|
|
@ -1,2 +0,0 @@
|
|||||||
# p ARGF.read.split("\n\n").map { _1.each_line.map(&:to_i).sum }.max
|
|
||||||
p ARGF.read.split("\n\n").map { _1.each_line.map(&:to_i).sum }.sort[-3..-1].sum
|
|
@ -1,14 +0,0 @@
|
|||||||
p ARGF.read.strip.lines(chomp: true).map(&:split).map {|a,b|
|
|
||||||
a = a.ord - ?A.ord
|
|
||||||
b = b.ord - ?X.ord
|
|
||||||
|
|
||||||
# part 2
|
|
||||||
b = (a + b - 1) % 3
|
|
||||||
|
|
||||||
outcome = case
|
|
||||||
when (a + 1) % 3 == b then 6
|
|
||||||
when a == b then 3
|
|
||||||
else 0
|
|
||||||
end
|
|
||||||
outcome + b + 1
|
|
||||||
}.sum
|
|
@ -1,8 +0,0 @@
|
|||||||
priorities = (?a..?z).chain(?A..?Z).each.with_index.to_h { [_1, _2+1] }
|
|
||||||
input = ARGF.read.lines(chomp: true).map(&:chars)
|
|
||||||
|
|
||||||
# part 1
|
|
||||||
p input.sum { priorities.fetch(_1.each_slice(_1.length/2).inject(&:&)[0]) }
|
|
||||||
|
|
||||||
# part 2
|
|
||||||
p input.each_slice(3).sum { priorities.fetch(_1.inject(&:&)[0]) }
|
|
@ -1,6 +0,0 @@
|
|||||||
p ARGF.read
|
|
||||||
.scan(/(\d+)-(\d+),(\d+)-(\d+)/)
|
|
||||||
.map { _1.map(&:to_i) }
|
|
||||||
.map {|a,b,c,d| [(a..b), (c..d)] }
|
|
||||||
# .count {|a,b| a.cover?(b) || b.cover?(a) } # part 1
|
|
||||||
.count {|a,b| a.minmax.any? { b.cover?(_1) } || b.minmax.any? { a.cover?(_1) }}
|
|
@ -1,18 +0,0 @@
|
|||||||
setup, moves = ARGF.read.split("\n\n")
|
|
||||||
|
|
||||||
setup = setup
|
|
||||||
.lines(chomp: true)
|
|
||||||
.map(&:chars)
|
|
||||||
.transpose
|
|
||||||
.map {|col| col.select { _1 =~ /[A-Z]/ }}
|
|
||||||
.reject(&:empty?)
|
|
||||||
|
|
||||||
moves = moves.scan(/move (\d+) from (\d+) to (\d+)/).map { _1.map(&:to_i) }
|
|
||||||
moves.each do |n,from,to|
|
|
||||||
# n.times {
|
|
||||||
# setup[to-1].unshift(setup[from-1].shift)
|
|
||||||
# }
|
|
||||||
setup[to-1].unshift(*setup[from-1].shift(n))
|
|
||||||
end
|
|
||||||
|
|
||||||
p setup.map(&:first).join
|
|
@ -1,2 +0,0 @@
|
|||||||
# p ARGF.read.chars.each_cons(4).with_index.find {|a,i| a.uniq.size == 4 }.last + 4
|
|
||||||
p ARGF.read.chars.each_cons(14).with_index.find {|a,i| a.uniq.size == 14 }.last + 14
|
|
@ -1,61 +0,0 @@
|
|||||||
input = ARGF.read.lines(chomp: true)
|
|
||||||
|
|
||||||
Dir = Struct.new(:parent, :name, :children) do
|
|
||||||
def size = children.sum(&:size)
|
|
||||||
|
|
||||||
def each
|
|
||||||
return enum_for(__method__) unless block_given?
|
|
||||||
|
|
||||||
yield self
|
|
||||||
|
|
||||||
children.each do |child|
|
|
||||||
case child
|
|
||||||
when Dir
|
|
||||||
child.each { yield _1 }
|
|
||||||
when File
|
|
||||||
yield child
|
|
||||||
else
|
|
||||||
fail child.inspect
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
File = Struct.new(:parent, :name, :size)
|
|
||||||
|
|
||||||
root = Dir.new(nil, ?/, [])
|
|
||||||
pwd = root
|
|
||||||
|
|
||||||
input.each do |line|
|
|
||||||
case line
|
|
||||||
when /\$ cd \//
|
|
||||||
# no-op
|
|
||||||
when /\$ cd \.\./
|
|
||||||
pwd = pwd.parent
|
|
||||||
when /\$ cd (.+)/
|
|
||||||
pwd = pwd.children.find { _1.name == $1 }
|
|
||||||
when /\$ ls/
|
|
||||||
# no-op
|
|
||||||
when /dir (.+)/
|
|
||||||
pwd.children << Dir.new(pwd, $1, [])
|
|
||||||
when /(\d+) (.+)/
|
|
||||||
pwd.children << File.new(pwd, $2, $1.to_i)
|
|
||||||
else
|
|
||||||
fail line
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# part 1
|
|
||||||
p root.each
|
|
||||||
.select { Dir === _1 }
|
|
||||||
.map(&:size)
|
|
||||||
.select { _1 < 100_000 }
|
|
||||||
.sum
|
|
||||||
|
|
||||||
# part 2
|
|
||||||
p root.each
|
|
||||||
.select { Dir === _1 }
|
|
||||||
.map(&:size)
|
|
||||||
.sort
|
|
||||||
.find { _1 >= 30_000_000 - (70_000_000 - root.size) }
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
|||||||
grid = ARGF.read.lines(chomp: true).map { _1.chars.map(&:to_i) }
|
|
||||||
|
|
||||||
def each(grid)
|
|
||||||
return enum_for(__method__, grid) unless block_given?
|
|
||||||
|
|
||||||
transposed = grid.transpose
|
|
||||||
|
|
||||||
grid.each.with_index do |row, y|
|
|
||||||
row.each.with_index do |tree, x|
|
|
||||||
col = transposed[x]
|
|
||||||
|
|
||||||
sight_lines = [
|
|
||||||
(0...x).map { row[_1] }.reverse,
|
|
||||||
(x+1...row.size).map { row[_1] },
|
|
||||||
(0...y).map { col[_1] }.reverse,
|
|
||||||
(y+1...row.size).map { col[_1] },
|
|
||||||
]
|
|
||||||
|
|
||||||
yield tree, sight_lines
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
p each(grid).count {|tree, sight_lines|
|
|
||||||
sight_lines.any? { _1.empty? || tree > _1.max }
|
|
||||||
}
|
|
||||||
|
|
||||||
p each(grid).map {|tree, sight_lines|
|
|
||||||
sight_lines
|
|
||||||
.map {|sl| sl.slice_after { _1 >= tree }.first }
|
|
||||||
.compact
|
|
||||||
.map(&:size)
|
|
||||||
.inject(:*)
|
|
||||||
}.max
|
|
@ -1,44 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
motions = ARGF.read.scan(/([RLUD])\s+(\d+)/).map { [_1, _2.to_i] }
|
|
||||||
|
|
||||||
class Snake
|
|
||||||
def initialize
|
|
||||||
@knots = Array.new(10) { [0, 0] }
|
|
||||||
end
|
|
||||||
|
|
||||||
def tail = @knots.last
|
|
||||||
|
|
||||||
def move!(dir)
|
|
||||||
delta = case dir
|
|
||||||
when ?L then [ 0, -1]
|
|
||||||
when ?U then [ 1, 0]
|
|
||||||
when ?R then [ 0, 1]
|
|
||||||
when ?D then [-1, 0]
|
|
||||||
else fail dir.inspect
|
|
||||||
end
|
|
||||||
@knots[0] = @knots[0].zip(delta).map { _1 + _2 }
|
|
||||||
|
|
||||||
@knots = @knots[1..].inject([@knots[0]]) {|knots, tail|
|
|
||||||
head = knots.last
|
|
||||||
delta = head.zip(tail).map { _1 - _2 }
|
|
||||||
knots << if delta.any? { _1.abs > 1 }
|
|
||||||
tail.zip(delta.map { _1.clamp(-1, 1) }).map { _1 + _2 }
|
|
||||||
else
|
|
||||||
tail
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
snake = Snake.new
|
|
||||||
seen = Set.new
|
|
||||||
|
|
||||||
motions.each do |dir, distance|
|
|
||||||
distance.times do
|
|
||||||
snake.move!(dir)
|
|
||||||
seen << snake.tail
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
p seen.size
|
|
@ -1,42 +0,0 @@
|
|||||||
instructions = ARGF.read.lines(chomp: true)
|
|
||||||
|
|
||||||
def exec(instructions)
|
|
||||||
return enum_for(__method__, instructions) unless block_given?
|
|
||||||
|
|
||||||
x = 1
|
|
||||||
instructions.each do |instruction|
|
|
||||||
case instruction
|
|
||||||
when /noop/
|
|
||||||
yield x
|
|
||||||
when /addx (-?\d+)/
|
|
||||||
yield x
|
|
||||||
yield x
|
|
||||||
x += $1.to_i
|
|
||||||
else
|
|
||||||
fail "invalid instruction: #{instruction}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
yield x
|
|
||||||
end
|
|
||||||
|
|
||||||
x_hist = exec(instructions).to_a
|
|
||||||
|
|
||||||
# part one
|
|
||||||
p 20.step(by: 40, to: 220).sum { x_hist[_1-1] * _1 }
|
|
||||||
|
|
||||||
# part two
|
|
||||||
puts x_hist.each_slice(40).map {|row|
|
|
||||||
row.each.with_index.map {|x, cycle|
|
|
||||||
(-1..1).cover?(cycle - x) ? ?# : ?.
|
|
||||||
}.join
|
|
||||||
}.join("\n")
|
|
||||||
|
|
||||||
# a functional version of part two, but I think
|
|
||||||
# the imperative version feels closer to the domain
|
|
||||||
#
|
|
||||||
# x_hist.each_slice(40) do |row|
|
|
||||||
# row.each.with_index do |x, cycle|
|
|
||||||
# putc (-1..1).cover?(cycle - x) ? ?# : ?.
|
|
||||||
# end
|
|
||||||
# puts
|
|
||||||
# end
|
|
@ -1,48 +0,0 @@
|
|||||||
Monkey = Struct.new(:id, :items, :operation, :test, :t, :f) do
|
|
||||||
def throw_to(item)
|
|
||||||
(item % test).zero? ? t : f
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
MONKEY_RE = /Monkey (?<id>\d+):
|
|
||||||
Starting items: (?<items>(?~\n))
|
|
||||||
Operation: new = (?<op>(?~\n))
|
|
||||||
Test: divisible by (?<test>\d+)
|
|
||||||
If true: throw to monkey (?<t>\d+)
|
|
||||||
If false: throw to monkey (?<f>\d+)/m
|
|
||||||
|
|
||||||
monkeys = ARGF.read.split("\n\n").map {|monkey|
|
|
||||||
md = MONKEY_RE.match(monkey)
|
|
||||||
fail if md.nil?
|
|
||||||
|
|
||||||
Monkey.new(
|
|
||||||
md[:id].to_i,
|
|
||||||
md[:items].split(", ").map(&:to_i),
|
|
||||||
md[:op],
|
|
||||||
md[:test].to_i,
|
|
||||||
md[:t].to_i,
|
|
||||||
md[:f].to_i,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
max_worry = monkeys.map(&:test).inject(:*)
|
|
||||||
|
|
||||||
inspections = Hash.new(0)
|
|
||||||
# 20.times do
|
|
||||||
10_000.times do
|
|
||||||
monkeys.each do |monkey|
|
|
||||||
until monkey.items.empty?
|
|
||||||
inspections[monkey.id] += 1
|
|
||||||
|
|
||||||
item = monkey.items.shift
|
|
||||||
old = item
|
|
||||||
item = eval(monkey.operation)
|
|
||||||
# item /= 3
|
|
||||||
item %= max_worry
|
|
||||||
to = monkey.throw_to(item)
|
|
||||||
monkeys[to].items << item
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
p inspections.values.max(2).inject(:*)
|
|
@ -1,49 +0,0 @@
|
|||||||
class HeightMap
|
|
||||||
NEIGHBORS = [[0, -1], [-1, 0], [0, 1], [1, 0]]
|
|
||||||
|
|
||||||
def initialize(heights)
|
|
||||||
@heights = heights
|
|
||||||
end
|
|
||||||
|
|
||||||
def shortest(from:, to:, &cond)
|
|
||||||
frontier = [from]
|
|
||||||
visited = { from => 0 }
|
|
||||||
|
|
||||||
until frontier.empty? || to.any? { visited.has_key?(_1) }
|
|
||||||
current = frontier.shift
|
|
||||||
|
|
||||||
NEIGHBORS.each do |delta|
|
|
||||||
candidate = current.zip(delta).map { _1 + _2 }
|
|
||||||
|
|
||||||
next if visited.has_key?(candidate)
|
|
||||||
next unless cand_height = @heights[candidate]
|
|
||||||
next unless cond.(@heights.fetch(current), cand_height)
|
|
||||||
|
|
||||||
visited[candidate] = visited.fetch(current) + 1
|
|
||||||
frontier << candidate
|
|
||||||
end
|
|
||||||
|
|
||||||
frontier.sort_by { visited.fetch(_1) }
|
|
||||||
end
|
|
||||||
|
|
||||||
visited.find {|k,v| to.include?(k) }.last
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
heights = ARGF.read.lines(chomp: true).map(&:chars)
|
|
||||||
.flat_map.with_index {|row,y|
|
|
||||||
row.map.with_index {|height,x| [[y, x], height] }
|
|
||||||
}.to_h
|
|
||||||
|
|
||||||
s, e = heights.invert.values_at(?S, ?E)
|
|
||||||
heights[s] = ?a
|
|
||||||
heights[e] = ?z
|
|
||||||
|
|
||||||
hm = HeightMap.new(heights)
|
|
||||||
|
|
||||||
# part one
|
|
||||||
p hm.shortest(from: s, to: [e]) { _1.ord + 1 >= _2.ord }
|
|
||||||
|
|
||||||
# part two
|
|
||||||
as = heights.select { _2 == ?a }.map(&:first)
|
|
||||||
p hm.shortest(from: e, to: as) { _1.ord - 1 <= _2.ord }
|
|
@ -1,37 +0,0 @@
|
|||||||
def compare(left, right)
|
|
||||||
case [left, right]
|
|
||||||
in [left, nil]
|
|
||||||
1
|
|
||||||
in [Integer, Integer]
|
|
||||||
left <=> right
|
|
||||||
in [Array, Array]
|
|
||||||
left.zip(right).each do |left, right|
|
|
||||||
case compare(left, right)
|
|
||||||
when -1 then return -1
|
|
||||||
when 0 # keep going
|
|
||||||
when 1 then return 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
(left.size == right.size) ? 0 : -1
|
|
||||||
else
|
|
||||||
compare(Array(left), Array(right))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# part one
|
|
||||||
pairs = ARGF.read.split("\n\n")
|
|
||||||
pairs = pairs.map {|pair| pair.lines(chomp: true).map { eval(_1) }}
|
|
||||||
|
|
||||||
p pairs.map.with_index
|
|
||||||
.select {|(l,r),_| compare(l, r) == -1 }
|
|
||||||
.sum { _1.last + 1 }
|
|
||||||
|
|
||||||
# part two
|
|
||||||
pairs = pairs.flatten(1)
|
|
||||||
|
|
||||||
dividers = [[[2]], [[6]]]
|
|
||||||
pairs.concat(dividers)
|
|
||||||
pairs = pairs.sort { compare(_1, _2) }
|
|
||||||
p dividers
|
|
||||||
.map { pairs.index(_1) + 1 }
|
|
||||||
.inject(:*)
|
|
@ -1,52 +0,0 @@
|
|||||||
scan = ARGF.read.lines(chomp: true)
|
|
||||||
|
|
||||||
cave = scan.each.with_object({}) {|line, cave|
|
|
||||||
line.split(" -> ")
|
|
||||||
.map { _1.split(?,).map(&:to_i) }
|
|
||||||
.each_cons(2) {|(ax,ay),(bx,by)|
|
|
||||||
Range.new(*[ax, bx].sort).each do |x|
|
|
||||||
Range.new(*[ay, by].sort).each do |y|
|
|
||||||
cave[[x, y]] = ?#
|
|
||||||
end
|
|
||||||
end
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
def cave.to_s
|
|
||||||
x_min, x_max = keys.map(&:first).minmax
|
|
||||||
y_min, y_max = keys.map(&:last).minmax
|
|
||||||
|
|
||||||
(0..y_max+1).map {|y|
|
|
||||||
(x_min-1..x_max+1).map {|x|
|
|
||||||
self.fetch([x, y], ?.)
|
|
||||||
}.join
|
|
||||||
}.join("\n")
|
|
||||||
end
|
|
||||||
|
|
||||||
def pour_sand(cave, stop:)
|
|
||||||
return enum_for(__method__, cave, stop:) unless block_given?
|
|
||||||
|
|
||||||
loop do
|
|
||||||
# puts cave
|
|
||||||
pos = [500, 0]
|
|
||||||
|
|
||||||
while next_pos = [0, -1, 1].map {|dx| pos.zip([dx, 1]).map { _1 + _2 }}.find { cave[_1].nil? }
|
|
||||||
pos = next_pos
|
|
||||||
break if stop.(*pos)
|
|
||||||
end
|
|
||||||
break if stop.(*pos)
|
|
||||||
|
|
||||||
cave[pos] = ?o
|
|
||||||
yield pos
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
y_max = cave.keys.map(&:last).max
|
|
||||||
|
|
||||||
# part one
|
|
||||||
p pour_sand(cave, stop: ->(_, y) { y >= y_max }).count
|
|
||||||
|
|
||||||
# part two
|
|
||||||
cave.delete_if { _2 == ?o } # reset cave
|
|
||||||
cave.default_proc = ->(_,(_,y)) { y == y_max + 2 ? ?# : nil }
|
|
||||||
p pour_sand(cave, stop: ->(x, y) { [x, y] == [500, 0] }).count + 1
|
|
@ -1,87 +0,0 @@
|
|||||||
require "set"
|
|
||||||
|
|
||||||
sensors_and_beacons = ARGF.read
|
|
||||||
.scan(/Sensor at x=(-?\d+), y=(-?\d+): closest beacon is at x=(-?\d+), y=(-?\d+)/)
|
|
||||||
.map { _1.map(&:to_i) }
|
|
||||||
.flatten
|
|
||||||
.each_slice(2)
|
|
||||||
|
|
||||||
# part one
|
|
||||||
row = 2_000_000
|
|
||||||
# row = 10
|
|
||||||
|
|
||||||
no_beacons = []
|
|
||||||
sensors_and_beacons.each_slice(2) do |sensor, beacon|
|
|
||||||
dist = sensor.zip(beacon).sum { (_1 - _2).abs }
|
|
||||||
|
|
||||||
dy = (row - sensor[1]).abs
|
|
||||||
next if dy > dist
|
|
||||||
dx = dist - dy
|
|
||||||
|
|
||||||
x_min, x_max = [sensor[0]-dx, sensor[0]+dx].sort
|
|
||||||
|
|
||||||
no_beacons << (x_min..x_max)
|
|
||||||
end
|
|
||||||
|
|
||||||
# remove covered ranges
|
|
||||||
no_beacons = no_beacons.reject {|x| (no_beacons - [x]).any? { _1.cover?(x) }}
|
|
||||||
|
|
||||||
# merge ranges
|
|
||||||
no_beacons = no_beacons.inject([no_beacons.shift]) {|no_beacons, range|
|
|
||||||
next no_beacons if no_beacons.any? { _1.cover?(range) }
|
|
||||||
|
|
||||||
if overlap = no_beacons.find { _1.cover?(range.begin) }
|
|
||||||
range = (overlap.end + 1..range.end)
|
|
||||||
end
|
|
||||||
|
|
||||||
if overlap = no_beacons.find { _1.cover?(range.end) }
|
|
||||||
range = (range.begin..overlap.begin-1)
|
|
||||||
end
|
|
||||||
|
|
||||||
no_beacons << range
|
|
||||||
}
|
|
||||||
|
|
||||||
p no_beacons.sum(&:size) - sensors_and_beacons.to_a.select { _2 == row }.uniq.size
|
|
||||||
|
|
||||||
# part two
|
|
||||||
find_sab = ->(x, y) {
|
|
||||||
sensors_and_beacons.each_slice(2).find {|sensor, beacon|
|
|
||||||
dist = sensor.zip(beacon).sum { (_1 - _2).abs }
|
|
||||||
dist >= sensor.zip([x, y]).sum { (_1 - _2).abs }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
max = 4_000_000
|
|
||||||
# max = 20
|
|
||||||
x = 0
|
|
||||||
y = 0
|
|
||||||
loop do
|
|
||||||
p y if (y % 10_000).zero?
|
|
||||||
|
|
||||||
sensor, _ = find_sab.(x, y)
|
|
||||||
dx = sensor[0] - x
|
|
||||||
if dx >= max / 2
|
|
||||||
dy = sensor[1] - y
|
|
||||||
y += dy.positive? ? 2 * dy + 1 : 1
|
|
||||||
end
|
|
||||||
|
|
||||||
loop do
|
|
||||||
sensor, beacon = find_sab.(x, y)
|
|
||||||
if sensor.nil?
|
|
||||||
p 4_000_000 * x + y
|
|
||||||
exit
|
|
||||||
end
|
|
||||||
|
|
||||||
dist = sensor.zip(beacon).sum { (_1 - _2).abs }
|
|
||||||
dy = (sensor[1] - y).abs
|
|
||||||
dx = (dist - dy).abs
|
|
||||||
x = sensor[0] + dx + 1
|
|
||||||
|
|
||||||
if x > max
|
|
||||||
x = 0
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
y += 1
|
|
||||||
break if y > max
|
|
||||||
end
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue