aboutsummaryrefslogtreecommitdiff
path: root/2022
diff options
context:
space:
mode:
Diffstat (limited to '2022')
-rw-r--r--2022/.cargo/config.toml2
-rw-r--r--2022/.gitignore6
-rw-r--r--2022/.gitlab-ci.yml26
-rw-r--r--2022/Cargo.lock2078
-rw-r--r--2022/Cargo.toml71
-rw-r--r--2022/fake_inputs/day14148
-rw-r--r--2022/fake_inputs/day92000
-rw-r--r--2022/flake.lock147
-rw-r--r--2022/flake.nix72
-rw-r--r--2022/src/day01.rs21
-rw-r--r--2022/src/day02.rs105
-rw-r--r--2022/src/day03.rs62
-rw-r--r--2022/src/day04.rs35
-rw-r--r--2022/src/day05.rs145
-rw-r--r--2022/src/day06.rs47
-rw-r--r--2022/src/day07.rs110
-rw-r--r--2022/src/day08.rs110
-rw-r--r--2022/src/day09.html38
-rw-r--r--2022/src/day09.rs238
-rw-r--r--2022/src/day10.rs82
-rw-r--r--2022/src/day11.rs127
-rw-r--r--2022/src/day12.rs141
-rw-r--r--2022/src/day13.rs132
-rw-r--r--2022/src/day14.html38
-rw-r--r--2022/src/day14.rs230
-rw-r--r--2022/src/utils.rs59
26 files changed, 6270 insertions, 0 deletions
diff --git a/2022/.cargo/config.toml b/2022/.cargo/config.toml
new file mode 100644
index 0000000..435ed75
--- /dev/null
+++ b/2022/.cargo/config.toml
@@ -0,0 +1,2 @@
+[build]
+target = "wasm32-unknown-unknown" \ No newline at end of file
diff --git a/2022/.gitignore b/2022/.gitignore
new file mode 100644
index 0000000..d7ecf3b
--- /dev/null
+++ b/2022/.gitignore
@@ -0,0 +1,6 @@
+.envrc
+.direnv
+inputs
+target/
+dist/
+public/ \ No newline at end of file
diff --git a/2022/.gitlab-ci.yml b/2022/.gitlab-ci.yml
new file mode 100644
index 0000000..48a1625
--- /dev/null
+++ b/2022/.gitlab-ci.yml
@@ -0,0 +1,26 @@
+image: rust:latest
+
+variables:
+ CARGO_HOME: $CI_PROJECT_DIR/.cargo
+ TRUNK_VERSION: v0.16.0
+
+stages:
+ - build
+
+pages:
+ stage: build
+ image: rust:latest
+ before_script:
+ - rustup target add wasm32-unknown-unknown
+ - wget -qO- https://github.com/thedodd/trunk/releases/download/${TRUNK_VERSION}/trunk-x86_64-unknown-linux-gnu.tar.gz | tar -xzf-
+ script:
+ - mkdir -p public/
+ - ./trunk build -d public/day9 --release --public-url /aoc-2022/day9 src/day09.html
+ - ./trunk build -d public/day14 --release --public-url /aoc-2022/day14 src/day14.html
+ artifacts:
+ paths:
+ - public/
+ cache:
+ paths:
+ - target/
+ - .cargo/
diff --git a/2022/Cargo.lock b/2022/Cargo.lock
new file mode 100644
index 0000000..0d15d2c
--- /dev/null
+++ b/2022/Cargo.lock
@@ -0,0 +1,2078 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "ab_glyph"
+version = "0.2.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcdbc68024b653943864d436fe8a24b028095bc1cf91a8926f8241e4aaffe59"
+dependencies = [
+ "ab_glyph_rasterizer",
+ "owned_ttf_parser",
+]
+
+[[package]]
+name = "ab_glyph_rasterizer"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "330223a1aecc308757b9926e9391c9b47f8ef2dbd8aea9df88312aea18c5e8d6"
+
+[[package]]
+name = "accesskit"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3083ac5a97521e35388ca80cf365b6be5210962cc59f11ee238cd92ac2fa9524"
+dependencies = [
+ "enumset",
+ "kurbo",
+]
+
+[[package]]
+name = "accesskit_consumer"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df122220244ca3ab93f6a42da59a5f8b379c8846dbcaedf922d95636d22c4e10"
+dependencies = [
+ "accesskit",
+ "parking_lot",
+]
+
+[[package]]
+name = "accesskit_macos"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55c97d7b5cbb2409e05b016406a1bd057237d120205cb63220ca86c2ea3790a1"
+dependencies = [
+ "accesskit",
+ "accesskit_consumer",
+ "objc2",
+ "once_cell",
+ "parking_lot",
+]
+
+[[package]]
+name = "accesskit_windows"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b0cfda25182b83b24e350434a3f63676252a00a295f32760a14d3f55feb8493"
+dependencies = [
+ "accesskit",
+ "accesskit_consumer",
+ "arrayvec 0.7.2",
+ "once_cell",
+ "parking_lot",
+ "paste",
+ "windows",
+]
+
+[[package]]
+name = "accesskit_winit"
+version = "0.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdf20fecd6573e03bebcb4de267f82431e5ea39a293b62aa51a45bdfd69ef39b"
+dependencies = [
+ "accesskit",
+ "accesskit_macos",
+ "accesskit_windows",
+ "parking_lot",
+ "winit",
+]
+
+[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "ahash"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf6ccdb167abbf410dcb915cabd428929d7f6a04980b54a11f26a39f1c7f7107"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+ "version_check",
+]
+
+[[package]]
+name = "arboard"
+version = "3.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6041616acea41d67c4a984709ddab1587fd0b10efe5cc563fee954d2f011854"
+dependencies = [
+ "clipboard-win",
+ "log",
+ "objc",
+ "objc-foundation",
+ "objc_id",
+ "once_cell",
+ "parking_lot",
+ "thiserror",
+ "winapi",
+ "x11rb",
+]
+
+[[package]]
+name = "arrayref"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
+
+[[package]]
+name = "arrayvec"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
+
+[[package]]
+name = "arrayvec"
+version = "0.7.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6"
+
+[[package]]
+name = "atomic_refcell"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73b5e5f48b927f04e952dedc932f31995a65a0bf65ec971c74436e51bf6e970d"
+
+[[package]]
+name = "autocfg"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
+
+[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "block"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
+
+[[package]]
+name = "block-sys"
+version = "0.1.0-beta.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa55741ee90902547802152aaf3f8e5248aab7e21468089560d4c8840561146"
+dependencies = [
+ "objc-sys",
+]
+
+[[package]]
+name = "block2"
+version = "0.2.0-alpha.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8dd9e63c1744f755c2f60332b88de39d341e5e86239014ad839bd71c106dec42"
+dependencies = [
+ "block-sys",
+ "objc2-encode",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
+
+[[package]]
+name = "bytemuck"
+version = "1.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f"
+dependencies = [
+ "bytemuck_derive",
+]
+
+[[package]]
+name = "bytemuck_derive"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5fe233b960f12f8007e3db2d136e3cb1c291bfd7396e384ee76025fc1a3932b4"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "bytes"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfb24e866b15a1af2a1b663f10c6b6b8f397a84aadb828f12e5b289ec23a3a3c"
+
+[[package]]
+name = "calloop"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19457a0da465234abd76134a5c2a910c14bd3c5558463e4396ab9a37a328e465"
+dependencies = [
+ "log",
+ "nix 0.25.1",
+ "slotmap",
+ "thiserror",
+ "vec_map",
+]
+
+[[package]]
+name = "cc"
+version = "1.0.77"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
+
+[[package]]
+name = "cesu8"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "cfg_aliases"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
+
+[[package]]
+name = "cgl"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ced0551234e87afee12411d535648dd89d2e7f34c78b753395567aff3d447ff"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "clipboard-win"
+version = "4.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4ab1b92798304eedc095b53942963240037c0516452cb11aeba709d420b2219"
+dependencies = [
+ "error-code",
+ "str-buf",
+ "winapi",
+]
+
+[[package]]
+name = "cmake"
+version = "0.1.49"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db34956e100b30725f2eb215f90d4871051239535632f84fea3bc92722c66b7c"
+dependencies = [
+ "cc",
+]
+
+[[package]]
+name = "cocoa"
+version = "0.24.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f425db7937052c684daec3bd6375c8abe2d146dca4b8b143d6db777c39138f3a"
+dependencies = [
+ "bitflags",
+ "block",
+ "cocoa-foundation",
+ "core-foundation",
+ "core-graphics",
+ "foreign-types 0.3.2",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "cocoa-foundation"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318"
+dependencies = [
+ "bitflags",
+ "block",
+ "core-foundation",
+ "core-graphics-types",
+ "foreign-types 0.3.2",
+ "libc",
+ "objc",
+]
+
+[[package]]
+name = "combine"
+version = "4.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35ed6e9d84f0b51a7f52daf1c7d71dd136fd7a3f41a8462b8cdb8c78d920fad4"
+dependencies = [
+ "bytes",
+ "memchr",
+]
+
+[[package]]
+name = "console_error_panic_hook"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "core-foundation"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146"
+dependencies = [
+ "core-foundation-sys",
+ "libc",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+
+[[package]]
+name = "core-graphics"
+version = "0.22.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2581bbab3b8ffc6fcbd550bf46c355135d16e9ff2a6ea032ad6b9bf1d7efe4fb"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "core-graphics-types",
+ "foreign-types 0.3.2",
+ "libc",
+]
+
+[[package]]
+name = "core-graphics-types"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b"
+dependencies = [
+ "bitflags",
+ "core-foundation",
+ "foreign-types 0.3.2",
+ "libc",
+]
+
+[[package]]
+name = "core-text"
+version = "19.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25"
+dependencies = [
+ "core-foundation",
+ "core-graphics",
+ "foreign-types 0.3.2",
+ "libc",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "crossfont"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21fd3add36ea31aba1520aa5288714dd63be506106753226d0eb387a93bc9c45"
+dependencies = [
+ "cocoa",
+ "core-foundation",
+ "core-foundation-sys",
+ "core-graphics",
+ "core-text",
+ "dwrote",
+ "foreign-types 0.5.0",
+ "freetype-rs",
+ "libc",
+ "log",
+ "objc",
+ "once_cell",
+ "pkg-config",
+ "servo-fontconfig",
+ "winapi",
+]
+
+[[package]]
+name = "cty"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b365fabc795046672053e29c954733ec3b05e4be654ab130fe8f1f94d7051f35"
+
+[[package]]
+name = "darling"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c"
+dependencies = [
+ "darling_core 0.13.4",
+ "darling_macro 0.13.4",
+]
+
+[[package]]
+name = "darling"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0dd3cd20dc6b5a876612a6e5accfe7f3dd883db6d07acfbf14c128f61550dfa"
+dependencies = [
+ "darling_core 0.14.2",
+ "darling_macro 0.14.2",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a784d2ccaf7c98501746bf0be29b2022ba41fd62a2e622af997a03e9f972859f"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.13.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835"
+dependencies = [
+ "darling_core 0.13.4",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.14.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7618812407e9402654622dd402b0a89dff9ba93badd6540781526117b92aab7e"
+dependencies = [
+ "darling_core 0.14.2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "dispatch"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b"
+
+[[package]]
+name = "dlib"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794"
+dependencies = [
+ "libloading",
+]
+
+[[package]]
+name = "downcast-rs"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
+
+[[package]]
+name = "dwrote"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "serde",
+ "serde_derive",
+ "winapi",
+ "wio",
+]
+
+[[package]]
+name = "ecolor"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b601108bca3af7650440ace4ca55b2daf52c36f2635be3587d77b16efd8d0691"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "eframe"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ea929ec5819fef373728bb0e55003ce921975039cfec3ca8305bb024e5b7b32"
+dependencies = [
+ "bytemuck",
+ "egui",
+ "egui-winit",
+ "egui_glow",
+ "glow",
+ "glutin",
+ "js-sys",
+ "percent-encoding",
+ "raw-window-handle 0.5.0",
+ "tracing",
+ "wasm-bindgen",
+ "wasm-bindgen-futures",
+ "web-sys",
+ "winit",
+]
+
+[[package]]
+name = "egui"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65a5e883a316e53866977450eecfbcac9c48109c2ab3394af29feb83fcde4ea9"
+dependencies = [
+ "accesskit",
+ "ahash",
+ "epaint",
+ "nohash-hasher",
+ "tracing",
+]
+
+[[package]]
+name = "egui-winit"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5696bdbe60898b81157f07ae34fe02dbfd522174bd6e620942c269cd7307901f"
+dependencies = [
+ "accesskit_winit",
+ "arboard",
+ "egui",
+ "instant",
+ "smithay-clipboard",
+ "tracing",
+ "webbrowser",
+ "winit",
+]
+
+[[package]]
+name = "egui_glow"
+version = "0.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d4b5960cb1bae1c403a6c9027a745210a41913433b10c73b6e7d76a1017f8b4"
+dependencies = [
+ "bytemuck",
+ "egui",
+ "glow",
+ "memoffset",
+ "tracing",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "emath"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5277249c8c3430e7127e4f2c40a77485e7baf11ae132ce9b3253a8ed710df0a0"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "enumset"
+version = "1.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19be8061a06ab6f3a6cf21106c873578bf01bd42ad15e0311a9c76161cb1c753"
+dependencies = [
+ "enumset_derive",
+]
+
+[[package]]
+name = "enumset_derive"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03e7b551eba279bf0fa88b83a46330168c1560a52a94f5126f892f0b364ab3e0"
+dependencies = [
+ "darling 0.14.2",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "epaint"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de14b65fe5e423e0058f77a8beb2c863b056d0566d6c4ce0d097aa5814cb705a"
+dependencies = [
+ "ab_glyph",
+ "ahash",
+ "atomic_refcell",
+ "bytemuck",
+ "ecolor",
+ "emath",
+ "nohash-hasher",
+ "parking_lot",
+]
+
+[[package]]
+name = "error-code"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21"
+dependencies = [
+ "libc",
+ "str-buf",
+]
+
+[[package]]
+name = "expat-sys"
+version = "2.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa"
+dependencies = [
+ "cmake",
+ "pkg-config",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "foreign-types"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
+dependencies = [
+ "foreign-types-shared 0.1.1",
+]
+
+[[package]]
+name = "foreign-types"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965"
+dependencies = [
+ "foreign-types-macros",
+ "foreign-types-shared 0.3.1",
+]
+
+[[package]]
+name = "foreign-types-macros"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8469d0d40519bc608ec6863f1cc88f3f1deee15913f2f3b3e573d81ed38cccc"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
+
+[[package]]
+name = "foreign-types-shared"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "freetype-rs"
+version = "0.26.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "74eadec9d0a5c28c54bb9882e54787275152a4e36ce206b45d7451384e5bf5fb"
+dependencies = [
+ "bitflags",
+ "freetype-sys",
+ "libc",
+]
+
+[[package]]
+name = "freetype-sys"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a"
+dependencies = [
+ "cmake",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "gethostname"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "gl_generator"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a95dfc23a2b4a9a2f5ab41d194f8bfda3cabec42af4e39f08c339eb2a0c124d"
+dependencies = [
+ "khronos_api",
+ "log",
+ "xml-rs",
+]
+
+[[package]]
+name = "glow"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8bd5877156a19b8ac83a29b2306fe20537429d318f3ff0a1a2119f8d9c61919"
+dependencies = [
+ "js-sys",
+ "slotmap",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "glutin"
+version = "0.30.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "524d807cd49a0c56a53ef9a6738cd15e7c8c4e9d37a3b7fdb3c250c1cd5bf7a3"
+dependencies = [
+ "bitflags",
+ "cfg_aliases",
+ "cgl",
+ "cocoa",
+ "core-foundation",
+ "glutin_egl_sys",
+ "glutin_glx_sys",
+ "glutin_wgl_sys",
+ "libloading",
+ "objc",
+ "once_cell",
+ "raw-window-handle 0.5.0",
+ "wayland-sys 0.30.1",
+ "windows-sys 0.36.1",
+ "x11-dl",
+]
+
+[[package]]
+name = "glutin_egl_sys"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3adbb8fec0e18e340f990c78f79f5f0e142d0d83f46b10909aaa7d251c00afdf"
+dependencies = [
+ "gl_generator",
+ "windows-sys 0.36.1",
+]
+
+[[package]]
+name = "glutin_glx_sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "947c4850c58211c9627969c2b4e2674764b81ae5b47bab2c9a477d7942f96e0f"
+dependencies = [
+ "gl_generator",
+ "x11-dl",
+]
+
+[[package]]
+name = "glutin_wgl_sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "20c33975a6c9d49d72c8f032a60079bf8df536954fbf9e4cee90396ace815c57"
+dependencies = [
+ "gl_generator",
+]
+
+[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
+name = "idna"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
+dependencies = [
+ "unicode-bidi",
+ "unicode-normalization",
+]
+
+[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "jni"
+version = "0.20.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "039022cdf4d7b1cf548d31f60ae783138e5fd42013f6271049d7df7afadef96c"
+dependencies = [
+ "cesu8",
+ "combine",
+ "jni-sys",
+ "log",
+ "thiserror",
+ "walkdir",
+]
+
+[[package]]
+name = "jni-sys"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "khronos_api"
+version = "3.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
+
+[[package]]
+name = "kurbo"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a53776d271cfb873b17c618af0298445c88afc52837f3e948fa3fafd131f449"
+dependencies = [
+ "arrayvec 0.7.2",
+]
+
+[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.138"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
+
+[[package]]
+name = "libloading"
+version = "0.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
+dependencies = [
+ "cfg-if",
+ "winapi",
+]
+
+[[package]]
+name = "lock_api"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df"
+dependencies = [
+ "autocfg",
+ "scopeguard",
+]
+
+[[package]]
+name = "log"
+version = "0.4.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "malloc_buf"
+version = "0.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "memchr"
+version = "2.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
+
+[[package]]
+name = "memmap2"
+version = "0.5.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4b182332558b18d807c4ce1ca8ca983b34c3ee32765e47b3f0f69b90355cc1dc"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "memoffset"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "miniz_oxide"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
+dependencies = [
+ "adler",
+]
+
+[[package]]
+name = "mio"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
+dependencies = [
+ "libc",
+ "log",
+ "wasi",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "ndk"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
+dependencies = [
+ "bitflags",
+ "jni-sys",
+ "ndk-sys",
+ "num_enum",
+ "raw-window-handle 0.5.0",
+ "thiserror",
+]
+
+[[package]]
+name = "ndk-context"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b"
+
+[[package]]
+name = "ndk-glue"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0434fabdd2c15e0aab768ca31d5b7b333717f03cf02037d5a0a3ff3c278ed67f"
+dependencies = [
+ "libc",
+ "log",
+ "ndk",
+ "ndk-context",
+ "ndk-macro",
+ "ndk-sys",
+ "once_cell",
+ "parking_lot",
+]
+
+[[package]]
+name = "ndk-macro"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0df7ac00c4672f9d5aece54ee3347520b7e20f158656c7db2e6de01902eb7a6c"
+dependencies = [
+ "darling 0.13.4",
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "ndk-sys"
+version = "0.4.1+23.1.7779620"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cf2aae958bd232cac5069850591667ad422d263686d75b52a065f9badeee5a3"
+dependencies = [
+ "jni-sys",
+]
+
+[[package]]
+name = "nix"
+version = "0.24.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
+dependencies = [
+ "bitflags",
+ "cfg-if",
+ "libc",
+ "memoffset",
+]
+
+[[package]]
+name = "nix"
+version = "0.25.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4"
+dependencies = [
+ "autocfg",
+ "bitflags",
+ "cfg-if",
+ "libc",
+ "memoffset",
+]
+
+[[package]]
+name = "nohash-hasher"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451"
+
+[[package]]
+name = "nom"
+version = "7.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "num_enum"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf5395665662ef45796a4ff5486c5d41d29e0c09640af4c5f17fd94ee2c119c9"
+dependencies = [
+ "num_enum_derive",
+]
+
+[[package]]
+name = "num_enum_derive"
+version = "0.5.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3b0498641e53dd6ac1a4f22547548caa6864cc4933784319cd1775271c5a46ce"
+dependencies = [
+ "proc-macro-crate",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "objc"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+dependencies = [
+ "malloc_buf",
+]
+
+[[package]]
+name = "objc-foundation"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
+dependencies = [
+ "block",
+ "objc",
+ "objc_id",
+]
+
+[[package]]
+name = "objc-sys"
+version = "0.2.0-beta.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "df3b9834c1e95694a05a828b59f55fa2afec6288359cda67146126b3f90a55d7"
+
+[[package]]
+name = "objc2"
+version = "0.3.0-beta.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe31e5425d3d0b89a15982c024392815da40689aceb34bad364d58732bcfd649"
+dependencies = [
+ "block2",
+ "objc-sys",
+ "objc2-encode",
+]
+
+[[package]]
+name = "objc2-encode"
+version = "2.0.0-pre.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "abfcac41015b00a120608fdaa6938c44cb983fee294351cc4bac7638b4e50512"
+dependencies = [
+ "objc-sys",
+]
+
+[[package]]
+name = "objc_id"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
+dependencies = [
+ "objc",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
+
+[[package]]
+name = "owned_ttf_parser"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "18904d3c65493a9f0d7542293d1a7f69bfdc309a6b9ef4f46dc3e58b0577edc5"
+dependencies = [
+ "ttf-parser",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.12.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
+dependencies = [
+ "lock_api",
+ "parking_lot_core",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "redox_syscall",
+ "smallvec",
+ "windows-sys 0.42.0",
+]
+
+[[package]]
+name = "paste"
+version = "1.0.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cf1c2c742266c2f1041c914ba65355a83ae8747b05f208319784083583494b4b"
+
+[[package]]
+name = "percent-encoding"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
+
+[[package]]
+name = "pkg-config"
+version = "0.3.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160"
+
+[[package]]
+name = "png"
+version = "0.17.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638"
+dependencies = [
+ "bitflags",
+ "crc32fast",
+ "flate2",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "proc-macro-crate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9"
+dependencies = [
+ "once_cell",
+ "thiserror",
+ "toml",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.47"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quick-start-simple"
+version = "0.1.0"
+dependencies = [
+ "bumpalo",
+ "console_error_panic_hook",
+ "eframe",
+ "egui",
+ "nom",
+ "wasm-bindgen-futures",
+ "wasm-rs-dbg",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "raw-window-handle"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b800beb9b6e7d2df1fe337c9e3d04e3af22a124460fb4c30fcc22c9117cefb41"
+dependencies = [
+ "cty",
+]
+
+[[package]]
+name = "raw-window-handle"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed7e3d950b66e19e0c372f3fa3fbbcf85b1746b571f74e0c2af6042a5c93420a"
+dependencies = [
+ "cty",
+]
+
+[[package]]
+name = "redox_syscall"
+version = "0.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
+dependencies = [
+ "bitflags",
+]
+
+[[package]]
+name = "safe_arch"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "same-file"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "scoped-tls"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
+
+[[package]]
+name = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "sctk-adwaita"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61270629cc6b4d77ec1907db1033d5c2e1a404c412743621981a871dc9c12339"
+dependencies = [
+ "crossfont",
+ "log",
+ "smithay-client-toolkit",
+ "tiny-skia",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.150"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91"
+
+[[package]]
+name = "serde_derive"
+version = "1.0.150"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "servo-fontconfig"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c"
+dependencies = [
+ "libc",
+ "servo-fontconfig-sys",
+]
+
+[[package]]
+name = "servo-fontconfig-sys"
+version = "5.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388"
+dependencies = [
+ "expat-sys",
+ "freetype-sys",
+ "pkg-config",
+]
+
+[[package]]
+name = "slotmap"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342"
+dependencies = [
+ "version_check",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
+
+[[package]]
+name = "smithay-client-toolkit"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f307c47d32d2715eb2e0ece5589057820e0e5e70d07c247d1063e844e107f454"
+dependencies = [
+ "bitflags",
+ "calloop",
+ "dlib",
+ "lazy_static",
+ "log",
+ "memmap2",
+ "nix 0.24.3",
+ "pkg-config",
+ "wayland-client",
+ "wayland-cursor",
+ "wayland-protocols",
+]
+
+[[package]]
+name = "smithay-clipboard"
+version = "0.6.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0a345c870a1fae0b1b779085e81b51e614767c239e93503588e54c5b17f4b0e8"
+dependencies = [
+ "smithay-client-toolkit",
+ "wayland-client",
+]
+
+[[package]]
+name = "str-buf"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
+
+[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
+name = "syn"
+version = "1.0.105"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "thiserror"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
+dependencies = [
+ "thiserror-impl",
+]
+
+[[package]]
+name = "thiserror-impl"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tiny-skia"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "642680569bb895b16e4b9d181c60be1ed136fa0c9c7f11d004daf053ba89bf82"
+dependencies = [
+ "arrayref",
+ "arrayvec 0.5.2",
+ "bytemuck",
+ "cfg-if",
+ "png",
+ "safe_arch",
+ "tiny-skia-path",
+]
+
+[[package]]
+name = "tiny-skia-path"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c114d32f0c2ee43d585367cb013dfaba967ab9f62b90d9af0d696e955e70fa6c"
+dependencies = [
+ "arrayref",
+ "bytemuck",
+]
+
+[[package]]
+name = "tinyvec"
+version = "1.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
+
+[[package]]
+name = "toml"
+version = "0.5.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1333c76748e868a4d9d1017b5ab53171dfd095f70c712fdb4653a406547f598f"
+dependencies = [
+ "serde",
+]
+
+[[package]]
+name = "tracing"
+version = "0.1.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
+dependencies = [
+ "cfg-if",
+ "pin-project-lite",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
+dependencies = [
+ "once_cell",
+]
+
+[[package]]
+name = "ttf-parser"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "375812fa44dab6df41c195cd2f7fecb488f6c09fbaafb62807488cefab642bff"
+
+[[package]]
+name = "unicode-bidi"
+version = "0.3.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
+
+[[package]]
+name = "unicode-normalization"
+version = "0.1.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
+dependencies = [
+ "tinyvec",
+]
+
+[[package]]
+name = "url"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+]
+
+[[package]]
+name = "vec_map"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
+
+[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
+name = "walkdir"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
+dependencies = [
+ "same-file",
+ "winapi",
+ "winapi-util",
+]
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-futures"
+version = "0.4.33"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
+dependencies = [
+ "cfg-if",
+ "js-sys",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
+name = "wasm-rs-dbg"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "61e5fe4ac478ca5cf1db842029f41a5881da39e70320deb0006912f226ea63f4"
+dependencies = [
+ "web-sys",
+]
+
+[[package]]
+name = "wayland-client"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715"
+dependencies = [
+ "bitflags",
+ "downcast-rs",
+ "libc",
+ "nix 0.24.3",
+ "scoped-tls",
+ "wayland-commons",
+ "wayland-scanner",
+ "wayland-sys 0.29.5",
+]
+
+[[package]]
+name = "wayland-commons"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902"
+dependencies = [
+ "nix 0.24.3",
+ "once_cell",
+ "smallvec",
+ "wayland-sys 0.29.5",
+]
+
+[[package]]
+name = "wayland-cursor"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6865c6b66f13d6257bef1cd40cbfe8ef2f150fb8ebbdb1e8e873455931377661"
+dependencies = [
+ "nix 0.24.3",
+ "wayland-client",
+ "xcursor",
+]
+
+[[package]]
+name = "wayland-protocols"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6"
+dependencies = [
+ "bitflags",
+ "wayland-client",
+ "wayland-commons",
+ "wayland-scanner",
+]
+
+[[package]]
+name = "wayland-scanner"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "xml-rs",
+]
+
+[[package]]
+name = "wayland-sys"
+version = "0.29.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4"
+dependencies = [
+ "dlib",
+ "lazy_static",
+ "pkg-config",
+]
+
+[[package]]
+name = "wayland-sys"
+version = "0.30.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96b2a02ac608e07132978689a6f9bf4214949c85998c247abadd4f4129b1aa06"
+dependencies = [
+ "dlib",
+ "lazy_static",
+ "log",
+ "pkg-config",
+]
+
+[[package]]
+name = "web-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[package]]
+name = "webbrowser"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a0cc7962b5aaa0dfcebaeef0161eec6edf5f4606c12e6777fd7d392f52033a5"
+dependencies = [
+ "jni",
+ "ndk-context",
+ "objc",
+ "raw-window-handle 0.5.0",
+ "url",
+ "web-sys",
+ "widestring",
+ "winapi",
+]
+
+[[package]]
+name = "widestring"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-wsapoll"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "windows"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0286ba339aa753e70765d521bb0242cc48e1194562bfa2a2ad7ac8a6de28f5d5"
+dependencies = [
+ "windows-implement",
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.0",
+ "windows_i686_gnu 0.42.0",
+ "windows_i686_msvc 0.42.0",
+ "windows_x86_64_gnu 0.42.0",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.0",
+]
+
+[[package]]
+name = "windows-implement"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9539b6bd3eadbd9de66c9666b22d802b833da7e996bc06896142e09854a61767"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2"
+dependencies = [
+ "windows_aarch64_msvc 0.36.1",
+ "windows_i686_gnu 0.36.1",
+ "windows_i686_msvc 0.36.1",
+ "windows_x86_64_gnu 0.36.1",
+ "windows_x86_64_msvc 0.36.1",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc 0.42.0",
+ "windows_i686_gnu 0.42.0",
+ "windows_i686_msvc 0.42.0",
+ "windows_x86_64_gnu 0.42.0",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc 0.42.0",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41d2aa71f6f0cbe00ae5167d90ef3cfe66527d6f613ca78ac8024c3ccab9a19e"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dd0f252f5a35cac83d6311b2e795981f5ee6e67eb1f9a7f64eb4500fbc4dcdb4"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbeae19f6716841636c28d695375df17562ca208b2b7d0dc47635a50ae6c5de7"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "84c12f65daa39dd2babe6e442988fc329d6243fdce47d7d2d155b8d874862246"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf7b1b21b5362cbc318f686150e5bcea75ecedc74dd157d874d754a2ca44b0ed"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09d525d2ba30eeb3297665bd434a54297e4170c7f1a44cad4ef58095b4cd2028"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.36.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.42.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
+
+[[package]]
+name = "winit"
+version = "0.27.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb796d6fbd86b2fd896c9471e6f04d39d750076ebe5680a3958f00f5ab97657c"
+dependencies = [
+ "bitflags",
+ "cocoa",
+ "core-foundation",
+ "core-graphics",
+ "dispatch",
+ "instant",
+ "libc",
+ "log",
+ "mio",
+ "ndk",
+ "ndk-glue",
+ "objc",
+ "once_cell",
+ "parking_lot",
+ "percent-encoding",
+ "raw-window-handle 0.4.3",
+ "raw-window-handle 0.5.0",
+ "sctk-adwaita",
+ "smithay-client-toolkit",
+ "wasm-bindgen",
+ "wayland-client",
+ "wayland-protocols",
+ "web-sys",
+ "windows-sys 0.36.1",
+ "x11-dl",
+]
+
+[[package]]
+name = "wio"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "x11-dl"
+version = "2.20.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1536d6965a5d4e573c7ef73a2c15ebcd0b2de3347bdf526c34c297c00ac40f0"
+dependencies = [
+ "lazy_static",
+ "libc",
+ "pkg-config",
+]
+
+[[package]]
+name = "x11rb"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507"
+dependencies = [
+ "gethostname",
+ "nix 0.24.3",
+ "winapi",
+ "winapi-wsapoll",
+ "x11rb-protocol",
+]
+
+[[package]]
+name = "x11rb-protocol"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67"
+dependencies = [
+ "nix 0.24.3",
+]
+
+[[package]]
+name = "xcursor"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "xml-rs"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
diff --git a/2022/Cargo.toml b/2022/Cargo.toml
new file mode 100644
index 0000000..3f1332d
--- /dev/null
+++ b/2022/Cargo.toml
@@ -0,0 +1,71 @@
+[package]
+name = "quick-start-simple"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+bumpalo = "^3"
+nom = "^7"
+egui = "^0.20"
+eframe = "^0.20"
+wasm-bindgen-futures = "^0.4"
+console_error_panic_hook = "^0.1"
+wasm-rs-dbg = "0.1.2"
+
+[[bin]]
+name = "day1"
+path = "src/day01.rs"
+
+[[bin]]
+name = "day2"
+path = "src/day02.rs"
+
+[[bin]]
+name = "day3"
+path = "src/day03.rs"
+
+[[bin]]
+name = "day4"
+path = "src/day04.rs"
+
+[[bin]]
+name = "day5"
+path = "src/day05.rs"
+
+[[bin]]
+name = "day6"
+path = "src/day06.rs"
+
+[[bin]]
+name = "day7"
+path = "src/day07.rs"
+
+[[bin]]
+name = "day8"
+path = "src/day08.rs"
+
+[[bin]]
+name = "day9"
+path = "src/day09.rs"
+
+[[bin]]
+name = "day10"
+path = "src/day10.rs"
+
+[[bin]]
+name = "day11"
+path = "src/day11.rs"
+
+[[bin]]
+name = "day12"
+path = "src/day12.rs"
+
+[[bin]]
+name = "day13"
+path = "src/day13.rs"
+
+[[bin]]
+name = "day14"
+path = "src/day14.rs" \ No newline at end of file
diff --git a/2022/fake_inputs/day14 b/2022/fake_inputs/day14
new file mode 100644
index 0000000..436b23f
--- /dev/null
+++ b/2022/fake_inputs/day14
@@ -0,0 +1,148 @@
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+502,32 -> 507,32
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+516,32 -> 521,32
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+512,30 -> 517,30
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+520,130 -> 520,133 -> 515,133 -> 515,138 -> 533,138 -> 533,133 -> 525,133 -> 525,130
+506,34 -> 511,34
+529,112 -> 529,116 -> 526,116 -> 526,122 -> 541,122 -> 541,116 -> 535,116 -> 535,112
+498,13 -> 498,15 -> 492,15 -> 492,23 -> 506,23 -> 506,15 -> 501,15 -> 501,13
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+523,63 -> 523,66 -> 515,66 -> 515,71 -> 529,71 -> 529,66 -> 528,66 -> 528,63
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+512,173 -> 517,173
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+498,13 -> 498,15 -> 492,15 -> 492,23 -> 506,23 -> 506,15 -> 501,15 -> 501,13
+545,94 -> 550,94
+539,100 -> 544,100
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+529,112 -> 529,116 -> 526,116 -> 526,122 -> 541,122 -> 541,116 -> 535,116 -> 535,112
+553,100 -> 558,100
+501,170 -> 506,170
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+498,13 -> 498,15 -> 492,15 -> 492,23 -> 506,23 -> 506,15 -> 501,15 -> 501,13
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+498,13 -> 498,15 -> 492,15 -> 492,23 -> 506,23 -> 506,15 -> 501,15 -> 501,13
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+546,100 -> 551,100
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+542,97 -> 547,97
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+535,97 -> 540,97
+533,108 -> 533,109 -> 538,109 -> 538,108
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+509,32 -> 514,32
+513,34 -> 518,34
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+520,130 -> 520,133 -> 515,133 -> 515,138 -> 533,138 -> 533,133 -> 525,133 -> 525,130
+507,164 -> 512,164
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+557,103 -> 562,103
+538,94 -> 543,94
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+520,130 -> 520,133 -> 515,133 -> 515,138 -> 533,138 -> 533,133 -> 525,133 -> 525,130
+520,130 -> 520,133 -> 515,133 -> 515,138 -> 533,138 -> 533,133 -> 525,133 -> 525,130
+498,13 -> 498,15 -> 492,15 -> 492,23 -> 506,23 -> 506,15 -> 501,15 -> 501,13
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+523,63 -> 523,66 -> 515,66 -> 515,71 -> 529,71 -> 529,66 -> 528,66 -> 528,63
+501,28 -> 506,28
+505,173 -> 510,173
+531,87 -> 531,88 -> 543,88
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+520,130 -> 520,133 -> 515,133 -> 515,138 -> 533,138 -> 533,133 -> 525,133 -> 525,130
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+524,126 -> 524,127 -> 528,127 -> 528,126
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+523,63 -> 523,66 -> 515,66 -> 515,71 -> 529,71 -> 529,66 -> 528,66 -> 528,63
+508,28 -> 513,28
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+523,63 -> 523,66 -> 515,66 -> 515,71 -> 529,71 -> 529,66 -> 528,66 -> 528,63
+511,167 -> 516,167
+549,97 -> 554,97
+541,91 -> 546,91
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+520,34 -> 525,34
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+505,30 -> 510,30
+543,103 -> 548,103
+510,146 -> 515,146
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+498,173 -> 503,173
+498,13 -> 498,15 -> 492,15 -> 492,23 -> 506,23 -> 506,15 -> 501,15 -> 501,13
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+523,63 -> 523,66 -> 515,66 -> 515,71 -> 529,71 -> 529,66 -> 528,66 -> 528,63
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+498,13 -> 498,15 -> 492,15 -> 492,23 -> 506,23 -> 506,15 -> 501,15 -> 501,13
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+533,108 -> 533,109 -> 538,109 -> 538,108
+517,146 -> 522,146
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+513,144 -> 518,144
+515,170 -> 520,170
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+520,130 -> 520,133 -> 515,133 -> 515,138 -> 533,138 -> 533,133 -> 525,133 -> 525,130
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+523,63 -> 523,66 -> 515,66 -> 515,71 -> 529,71 -> 529,66 -> 528,66 -> 528,63
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+519,173 -> 524,173
+532,100 -> 537,100
+524,126 -> 524,127 -> 528,127 -> 528,126
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+529,112 -> 529,116 -> 526,116 -> 526,122 -> 541,122 -> 541,116 -> 535,116 -> 535,112
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+521,148 -> 526,148
+504,167 -> 509,167
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+529,112 -> 529,116 -> 526,116 -> 526,122 -> 541,122 -> 541,116 -> 535,116 -> 535,112
+520,130 -> 520,133 -> 515,133 -> 515,138 -> 533,138 -> 533,133 -> 525,133 -> 525,130
+514,148 -> 519,148
+510,141 -> 515,141
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+533,108 -> 533,109 -> 538,109 -> 538,108
+524,126 -> 524,127 -> 528,127 -> 528,126
+550,103 -> 555,103
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+529,103 -> 534,103
+504,26 -> 509,26
+529,112 -> 529,116 -> 526,116 -> 526,122 -> 541,122 -> 541,116 -> 535,116 -> 535,112
+508,170 -> 513,170
+523,63 -> 523,66 -> 515,66 -> 515,71 -> 529,71 -> 529,66 -> 528,66 -> 528,63
+499,34 -> 504,34
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+529,112 -> 529,116 -> 526,116 -> 526,122 -> 541,122 -> 541,116 -> 535,116 -> 535,112
+495,32 -> 500,32
+507,148 -> 512,148
+515,60 -> 515,52 -> 515,60 -> 517,60 -> 517,55 -> 517,60 -> 519,60 -> 519,50 -> 519,60 -> 521,60 -> 521,56 -> 521,60 -> 523,60 -> 523,53 -> 523,60 -> 525,60 -> 525,53 -> 525,60
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+531,87 -> 531,88 -> 543,88
+536,103 -> 541,103
+501,161 -> 501,152 -> 501,161 -> 503,161 -> 503,157 -> 503,161 -> 505,161 -> 505,155 -> 505,161 -> 507,161 -> 507,154 -> 507,161 -> 509,161 -> 509,155 -> 509,161
+522,84 -> 522,76 -> 522,84 -> 524,84 -> 524,75 -> 524,84 -> 526,84 -> 526,81 -> 526,84 -> 528,84 -> 528,74 -> 528,84 -> 530,84 -> 530,79 -> 530,84 -> 532,84 -> 532,77 -> 532,84 -> 534,84 -> 534,78 -> 534,84 -> 536,84 -> 536,80 -> 536,84
+522,47 -> 522,43 -> 522,47 -> 524,47 -> 524,41 -> 524,47 -> 526,47 -> 526,39 -> 526,47 -> 528,47 -> 528,39 -> 528,47
+498,30 -> 503,30
+492,34 -> 497,34
+529,112 -> 529,116 -> 526,116 -> 526,122 -> 541,122 -> 541,116 -> 535,116 -> 535,112 \ No newline at end of file
diff --git a/2022/fake_inputs/day9 b/2022/fake_inputs/day9
new file mode 100644
index 0000000..27249a2
--- /dev/null
+++ b/2022/fake_inputs/day9
@@ -0,0 +1,2000 @@
+D 17
+D 5
+R 2
+R 2
+U 9
+U 8
+L 7
+R 4
+D 1
+D 7
+U 1
+R 10
+U 15
+D 5
+U 9
+L 9
+R 2
+D 2
+D 2
+D 2
+U 1
+R 9
+L 4
+L 9
+D 1
+D 2
+D 2
+U 11
+R 7
+R 5
+D 2
+R 5
+U 2
+R 6
+L 8
+L 10
+L 3
+D 5
+U 8
+L 3
+L 7
+D 4
+D 1
+D 4
+D 4
+U 14
+R 1
+U 7
+L 4
+R 3
+D 8
+L 4
+D 4
+R 7
+D 7
+R 6
+U 8
+R 2
+R 5
+L 2
+R 12
+U 13
+D 4
+L 3
+R 2
+U 9
+L 7
+R 5
+D 3
+L 8
+D 5
+U 11
+U 6
+U 3
+U 5
+R 10
+U 2
+R 1
+D 2
+R 3
+U 4
+R 14
+R 1
+L 15
+D 1
+D 1
+D 7
+L 6
+L 6
+D 2
+U 1
+U 3
+R 11
+R 11
+L 1
+L 8
+L 13
+U 4
+R 11
+L 1
+D 1
+U 6
+L 1
+U 3
+R 15
+L 2
+U 1
+L 3
+L 8
+U 1
+R 11
+D 1
+D 1
+U 1
+R 2
+R 11
+R 7
+U 10
+L 1
+U 3
+D 9
+D 1
+L 11
+U 5
+L 4
+D 1
+U 4
+R 2
+L 3
+L 19
+U 4
+D 13
+D 11
+L 6
+U 10
+U 8
+R 2
+L 4
+U 2
+R 9
+U 15
+L 5
+R 10
+U 5
+R 8
+L 2
+R 6
+D 3
+L 4
+L 7
+U 10
+L 3
+R 4
+D 8
+R 3
+R 8
+D 16
+R 5
+L 5
+D 5
+R 11
+L 5
+L 5
+L 1
+U 6
+U 12
+U 17
+L 4
+L 12
+L 6
+L 9
+L 12
+D 15
+L 2
+D 10
+L 3
+U 1
+U 5
+L 4
+L 3
+L 4
+U 1
+R 2
+U 16
+L 3
+D 10
+U 2
+D 12
+L 12
+U 13
+D 4
+R 9
+U 6
+U 14
+U 3
+D 3
+R 2
+D 10
+U 2
+U 1
+U 8
+L 15
+U 9
+L 6
+D 1
+D 1
+L 4
+R 5
+R 7
+D 4
+R 1
+D 6
+D 10
+U 1
+R 4
+R 9
+L 17
+L 4
+R 1
+D 7
+L 5
+R 2
+U 13
+U 3
+R 5
+U 14
+D 3
+L 15
+U 17
+D 1
+R 7
+R 10
+R 1
+R 1
+U 11
+L 3
+R 13
+D 5
+D 1
+L 6
+L 17
+D 1
+L 2
+D 10
+L 12
+U 9
+L 3
+L 7
+U 3
+U 3
+D 3
+R 5
+D 12
+R 10
+D 6
+U 7
+R 1
+U 4
+R 2
+U 4
+U 12
+U 3
+L 1
+R 4
+R 1
+L 2
+D 5
+D 7
+L 3
+U 1
+D 5
+D 12
+R 1
+D 6
+L 11
+U 9
+U 15
+D 2
+D 5
+U 1
+R 5
+D 3
+R 2
+D 10
+U 13
+R 15
+U 3
+R 2
+D 6
+U 2
+U 13
+R 6
+R 6
+L 5
+U 6
+R 6
+U 3
+U 4
+R 7
+D 5
+L 2
+R 2
+D 1
+D 8
+U 2
+R 9
+D 8
+D 6
+U 1
+R 1
+R 2
+L 2
+L 1
+R 2
+R 17
+R 6
+U 7
+R 4
+D 11
+D 3
+R 3
+D 8
+U 13
+R 1
+U 9
+U 17
+U 3
+D 6
+D 1
+D 4
+R 1
+D 7
+L 3
+L 12
+L 6
+D 2
+R 1
+D 15
+D 2
+U 2
+L 5
+R 5
+L 16
+R 2
+L 3
+U 1
+D 15
+R 15
+R 8
+R 1
+D 5
+L 8
+D 12
+R 3
+L 5
+L 5
+U 6
+L 12
+U 4
+L 1
+U 10
+U 6
+U 2
+D 3
+D 4
+D 3
+U 11
+L 5
+D 1
+L 15
+L 10
+L 2
+L 4
+R 8
+U 5
+D 7
+U 10
+D 6
+R 9
+R 6
+L 3
+D 3
+U 8
+D 6
+R 15
+D 3
+U 6
+L 2
+R 4
+U 2
+U 4
+D 4
+D 11
+L 7
+D 7
+U 3
+U 6
+U 3
+D 7
+R 2
+L 1
+R 13
+R 12
+R 1
+U 3
+R 14
+L 2
+R 6
+D 2
+L 2
+L 5
+D 2
+R 7
+R 12
+L 3
+U 5
+U 1
+U 4
+L 3
+D 11
+L 4
+D 6
+D 6
+U 4
+U 4
+D 2
+U 16
+R 3
+D 9
+L 6
+U 1
+U 13
+D 2
+U 2
+D 4
+U 3
+D 2
+L 7
+R 1
+L 2
+R 12
+U 1
+L 1
+D 1
+U 11
+U 5
+L 4
+L 11
+R 10
+L 14
+R 1
+U 2
+D 2
+D 11
+D 3
+D 14
+D 10
+D 2
+U 13
+L 2
+L 4
+D 4
+L 6
+L 6
+R 4
+R 1
+L 5
+D 12
+R 18
+D 4
+D 6
+U 5
+U 2
+R 11
+U 3
+U 5
+R 9
+R 2
+U 2
+R 4
+L 6
+D 4
+D 2
+D 4
+D 2
+D 6
+R 9
+D 1
+D 3
+R 5
+D 7
+L 12
+R 5
+R 1
+U 11
+U 14
+L 6
+L 10
+L 4
+R 4
+L 2
+U 4
+L 4
+U 5
+R 3
+D 4
+U 5
+R 9
+L 7
+D 15
+U 15
+R 2
+R 3
+U 5
+U 3
+D 2
+D 6
+U 7
+R 10
+L 1
+U 2
+L 4
+R 6
+U 6
+L 3
+L 3
+L 1
+R 1
+R 2
+L 7
+D 5
+L 7
+R 2
+R 4
+L 8
+D 1
+L 3
+U 8
+L 10
+D 8
+D 12
+D 2
+U 6
+L 4
+L 2
+D 5
+D 5
+R 6
+R 8
+D 1
+D 1
+R 1
+U 3
+L 7
+L 8
+D 5
+L 3
+D 3
+R 4
+D 4
+U 1
+R 3
+R 2
+D 10
+L 13
+D 2
+D 1
+R 1
+L 3
+L 6
+R 5
+U 6
+D 1
+U 2
+D 3
+L 2
+D 4
+L 7
+R 12
+U 4
+D 10
+L 5
+L 4
+U 19
+L 2
+L 3
+R 3
+U 5
+U 4
+L 1
+R 9
+D 9
+R 11
+R 3
+R 12
+R 8
+D 1
+R 4
+L 16
+R 4
+U 2
+R 2
+L 1
+L 6
+U 6
+U 3
+U 1
+L 5
+R 13
+U 3
+L 1
+U 6
+U 4
+D 6
+L 14
+L 11
+U 2
+U 10
+D 5
+L 2
+R 2
+U 2
+L 2
+L 2
+R 4
+D 7
+U 1
+R 10
+L 10
+U 1
+D 5
+R 3
+L 8
+L 5
+L 5
+L 6
+U 5
+D 10
+L 4
+U 1
+D 5
+L 3
+D 4
+D 14
+L 2
+R 7
+R 18
+D 2
+U 18
+U 8
+L 3
+D 7
+D 4
+L 14
+L 3
+D 6
+L 13
+R 4
+L 13
+L 4
+L 12
+R 3
+L 11
+D 11
+D 3
+R 8
+L 8
+U 13
+D 10
+D 1
+L 16
+L 5
+D 3
+R 12
+R 12
+L 5
+U 1
+L 8
+D 3
+R 5
+R 5
+D 1
+R 5
+L 3
+U 8
+L 5
+D 11
+R 2
+U 16
+D 4
+L 5
+L 15
+R 14
+D 1
+L 2
+D 1
+R 4
+L 1
+U 17
+R 5
+L 15
+R 8
+D 5
+D 8
+D 2
+R 3
+L 3
+U 2
+D 1
+R 6
+U 9
+D 4
+R 1
+D 1
+L 8
+U 10
+L 3
+R 2
+R 4
+D 3
+R 8
+L 4
+D 9
+D 11
+L 7
+R 2
+U 17
+D 3
+D 7
+L 6
+L 11
+R 12
+R 12
+D 8
+D 2
+L 12
+U 4
+R 13
+L 12
+L 4
+D 5
+R 11
+D 7
+U 2
+L 6
+U 3
+D 1
+R 13
+D 12
+U 6
+D 1
+U 1
+L 5
+U 1
+D 12
+R 15
+L 3
+U 15
+L 10
+U 2
+R 6
+L 2
+U 7
+R 9
+L 5
+U 5
+R 8
+R 3
+L 10
+U 10
+R 10
+L 17
+D 3
+U 5
+D 1
+L 4
+R 5
+L 2
+D 10
+L 11
+R 13
+D 1
+R 9
+R 9
+U 2
+L 7
+R 1
+D 3
+D 3
+U 4
+D 8
+L 4
+L 4
+D 5
+U 1
+U 6
+D 6
+R 1
+D 3
+L 8
+L 10
+L 4
+L 1
+D 8
+D 11
+U 5
+L 1
+U 3
+U 3
+L 4
+R 1
+D 10
+R 2
+R 3
+U 6
+L 13
+L 4
+R 6
+D 6
+L 2
+D 1
+U 7
+D 5
+U 17
+U 9
+L 1
+L 3
+D 18
+U 5
+D 18
+R 1
+D 13
+D 1
+U 2
+U 1
+U 3
+U 19
+D 4
+L 1
+U 7
+U 5
+R 2
+U 4
+D 14
+L 10
+L 2
+L 6
+R 6
+L 7
+L 3
+L 2
+L 2
+D 10
+U 16
+U 12
+L 2
+D 1
+R 6
+R 6
+R 7
+D 2
+L 8
+L 2
+L 1
+L 5
+U 3
+U 9
+R 5
+L 1
+D 3
+D 3
+L 7
+D 13
+D 16
+U 2
+R 1
+U 1
+R 2
+U 2
+U 2
+U 2
+R 11
+U 3
+L 12
+U 4
+D 3
+R 6
+D 2
+D 4
+D 4
+D 4
+U 2
+L 3
+D 1
+U 1
+R 7
+U 1
+R 4
+U 6
+R 14
+L 10
+R 8
+R 5
+D 4
+U 1
+R 11
+R 1
+D 11
+L 2
+U 16
+R 3
+R 1
+L 2
+U 4
+U 4
+U 1
+D 1
+L 9
+R 1
+D 1
+D 4
+L 7
+U 2
+L 2
+U 10
+L 7
+U 2
+U 15
+U 2
+U 5
+R 3
+U 2
+R 6
+U 6
+R 1
+D 2
+D 2
+R 13
+R 18
+U 2
+D 3
+L 2
+L 9
+D 10
+U 1
+U 11
+D 3
+R 6
+R 1
+U 2
+U 1
+U 12
+U 8
+D 13
+U 2
+D 12
+L 13
+D 1
+L 2
+D 4
+R 4
+L 5
+D 10
+R 4
+R 6
+R 1
+U 3
+R 5
+R 8
+D 9
+L 2
+U 1
+R 4
+R 2
+R 7
+L 9
+R 1
+D 3
+L 14
+R 1
+U 11
+L 2
+D 4
+U 19
+U 3
+L 6
+D 1
+R 3
+R 14
+D 6
+L 6
+R 16
+U 11
+L 2
+L 13
+U 2
+D 5
+U 8
+U 9
+R 14
+U 3
+L 14
+U 5
+L 9
+D 1
+R 8
+U 8
+U 13
+D 6
+R 18
+U 5
+L 14
+D 3
+R 5
+R 2
+L 2
+U 3
+R 4
+R 13
+R 8
+D 10
+U 5
+R 3
+R 5
+R 3
+R 9
+R 8
+D 16
+D 2
+R 8
+D 12
+D 3
+R 3
+L 4
+U 6
+L 3
+L 1
+L 10
+L 8
+R 3
+L 2
+U 6
+R 10
+D 12
+D 4
+R 9
+D 2
+D 2
+L 6
+R 9
+R 3
+L 4
+U 7
+R 16
+R 8
+U 3
+L 4
+U 2
+L 7
+D 5
+L 6
+R 1
+D 7
+D 4
+L 1
+L 12
+U 7
+L 4
+D 2
+L 5
+L 17
+R 5
+D 2
+L 2
+R 3
+L 2
+R 1
+D 7
+L 3
+L 13
+L 5
+D 11
+D 11
+D 3
+R 1
+R 5
+U 8
+D 11
+L 1
+L 2
+U 6
+D 2
+D 2
+R 8
+U 13
+U 1
+R 1
+R 4
+L 3
+R 4
+U 12
+U 1
+D 5
+D 15
+L 2
+U 5
+L 7
+U 1
+D 2
+L 7
+R 4
+U 8
+L 2
+U 3
+D 8
+R 15
+U 2
+D 8
+L 6
+L 8
+U 14
+D 3
+U 15
+L 4
+U 6
+L 1
+U 2
+D 7
+L 4
+L 12
+L 14
+L 10
+U 7
+L 10
+U 4
+R 3
+L 4
+D 1
+U 6
+U 4
+D 6
+L 4
+R 11
+L 4
+D 9
+R 2
+R 13
+R 3
+R 4
+R 5
+L 2
+L 4
+U 3
+U 1
+U 2
+U 3
+D 10
+D 1
+R 5
+D 9
+R 13
+R 1
+L 2
+L 5
+L 1
+L 6
+L 8
+U 2
+D 2
+D 8
+L 5
+D 7
+U 6
+R 10
+U 3
+L 15
+R 7
+L 12
+L 8
+U 1
+L 11
+U 1
+L 2
+D 7
+R 9
+D 14
+R 11
+U 7
+U 5
+R 3
+L 6
+R 15
+D 10
+U 2
+U 4
+L 5
+R 12
+L 6
+L 17
+U 4
+L 8
+L 6
+R 3
+R 3
+D 8
+R 3
+U 17
+L 1
+L 1
+R 4
+U 4
+L 12
+R 9
+D 9
+D 8
+D 4
+R 8
+R 5
+D 11
+D 7
+D 5
+R 1
+R 2
+R 2
+R 2
+L 3
+U 3
+D 12
+L 8
+D 5
+U 7
+D 5
+U 5
+R 1
+U 1
+D 2
+U 12
+D 1
+D 3
+L 8
+D 8
+L 5
+R 5
+R 1
+R 12
+R 2
+R 8
+R 1
+L 9
+D 5
+U 2
+L 11
+L 2
+R 4
+R 4
+L 11
+L 2
+U 8
+D 9
+U 7
+R 10
+U 1
+D 7
+R 11
+L 3
+D 4
+L 3
+U 11
+L 16
+U 4
+L 3
+U 17
+U 1
+U 6
+R 1
+D 4
+D 2
+R 5
+R 5
+U 2
+L 3
+D 7
+R 6
+L 1
+U 5
+L 4
+L 2
+R 4
+R 7
+R 3
+U 10
+U 1
+L 11
+L 3
+L 9
+L 7
+R 12
+U 6
+U 2
+L 3
+D 1
+L 5
+L 2
+R 1
+R 3
+D 4
+R 2
+U 7
+U 12
+U 1
+D 2
+U 1
+L 7
+U 15
+U 7
+U 3
+U 3
+D 6
+D 8
+U 6
+U 4
+U 6
+D 4
+U 6
+U 1
+R 9
+L 10
+L 2
+L 3
+D 16
+D 2
+L 3
+L 12
+L 7
+R 6
+L 2
+R 11
+U 2
+U 9
+R 3
+D 5
+R 3
+R 1
+R 1
+U 4
+D 4
+D 2
+U 9
+R 4
+R 11
+R 2
+L 2
+U 9
+L 8
+D 7
+L 6
+R 3
+L 4
+D 6
+D 4
+R 5
+R 4
+U 7
+L 4
+R 7
+L 6
+R 2
+D 15
+U 1
+D 18
+R 3
+L 5
+D 3
+L 1
+L 5
+D 1
+U 1
+R 4
+D 3
+R 1
+D 1
+D 1
+L 3
+R 1
+U 9
+U 3
+R 4
+L 3
+U 2
+D 13
+L 1
+R 4
+L 2
+U 7
+U 7
+U 6
+U 4
+R 4
+U 11
+L 3
+R 2
+D 6
+R 6
+R 8
+R 12
+R 8
+R 8
+R 1
+U 8
+R 4
+U 12
+L 9
+L 7
+U 6
+D 3
+R 8
+R 8
+R 2
+D 5
+D 17
+R 3
+R 4
+D 6
+R 1
+R 18
+R 15
+U 5
+R 2
+U 1
+D 5
+D 3
+R 6
+R 11
+L 1
+L 16
+R 3
+L 14
+L 7
+U 1
+D 10
+D 8
+L 3
+U 2
+R 7
+L 4
+R 8
+U 7
+U 2
+L 3
+D 1
+R 4
+D 1
+U 4
+L 11
+U 2
+L 2
+U 10
+L 5
+D 1
+R 2
+U 7
+D 5
+L 2
+U 12
+D 8
+L 1
+U 1
+D 4
+U 5
+U 1
+D 9
+U 6
+U 3
+R 12
+R 8
+R 3
+U 4
+D 5
+R 1
+L 2
+R 14
+U 7
+R 10
+R 11
+U 6
+D 1
+L 7
+R 4
+R 7
+R 3
+R 1
+D 4
+D 15
+L 10
+R 9
+L 3
+D 9
+U 1
+D 8
+D 6
+L 8
+D 5
+U 8
+U 9
+D 8
+R 4
+R 7
+R 1
+U 9
+R 8
+R 9
+L 10
+L 5
+D 11
+L 1
+U 3
+D 3
+L 2
+L 5
+L 9
+R 8
+D 8
+L 2
+L 5
+U 6
+R 7
+L 7
+D 1
+L 2
+R 3
+L 13
+L 9
+U 15
+D 17
+L 2
+L 1
+R 3
+D 4
+D 9
+L 3
+R 6
+L 4
+U 2
+U 2
+U 3
+U 6
+R 12
+L 12
+L 16
+D 1
+R 1
+R 6
+L 1
+R 9
+R 3
+U 2
+D 9
+R 1
+L 8
+R 2
+U 1
+R 4
+R 8
+U 6
+L 9
+R 2
+U 3
+R 8
+U 10
+D 5
+R 12
+U 4
+L 5
+R 17
+D 14
+L 16
+R 2
+L 4
+R 3
+R 1
+D 15
+R 3
+R 12
+U 14
+U 6
+R 9
+D 4
+U 3
+D 7
+D 2
+D 16
+R 12
+L 4
+R 2
+D 12
+R 1
+D 3
+D 4
+D 10
+D 7
+R 5
+D 12
+R 3
+D 1
+R 1
+L 4
+U 1
+D 2
+D 3
+R 5
+D 14
+D 3
+L 1
+D 1
+L 4
+U 2
+L 8
+R 10
+D 2
+U 3
+D 2
+L 2
+U 9
+R 1
+D 2
+L 5
+R 8
+U 1
+R 6
+L 7
+R 13
+R 9
+L 4
+R 3
+D 18
+R 2
+U 5
+U 7
+D 1
+D 13
+R 15
+R 2
+D 6
+R 8
+D 1
+L 15
+L 2
+L 1
+L 3
+D 11
+R 5
+L 3
+D 1
+U 8
+U 10
+U 10
+D 1
+U 15
+R 2
+R 8
+R 4
+R 1
+L 3
+D 10
+D 17
+U 7
+D 9
+L 16
+L 8
+L 1
+D 1
+R 5
+R 8
+R 1
+U 2
+U 5
+U 5
+U 5
+L 4
+L 5
+D 8
+L 9
+D 5
+D 2
+D 18
+R 11
+U 9
+U 5
+R 1
+D 5
+U 3
+L 9
+L 7
+U 4
+D 7
+L 3
+R 7
+D 2
+D 8
+D 6
+U 1
+D 6
+L 3
+L 2
+R 8
+L 8
+L 4
+U 2
+R 4
+L 4
+R 6
+U 1
+R 8
+R 1
+U 2
+R 2
+L 2
+D 7
+D 12
+L 8
+U 5
+U 5
+R 10
+U 6
+R 6
+D 1
+D 2
+R 2
+L 2
+U 9
+L 11
+R 3
+U 5
+L 11
+L 7
+R 2
+D 8
+L 2
+L 8
+U 9
+R 10
+U 1
+L 11
+U 3
+R 4
+R 9
+L 10
+L 3
+D 3
+R 5
+D 1
+R 1
+R 4
+D 4
+L 1
+U 6
+D 3
+R 2
+U 1
+U 1
+L 10
+L 9
+U 9
+L 3
+L 7
+D 15
+D 3
+L 1
+R 2
+D 12
+D 6
+U 1
+L 2
+L 9
+R 1
+D 1
+R 4
+R 6
+R 4
+U 4
+U 10
+L 5
+U 6
+R 13
+L 5
+L 9
+U 6
+U 9
+L 1
+R 1
+L 3
+U 10
+R 2
+L 5
+D 8
+L 8
+R 8
+D 6
+R 1
+U 4
+R 2
+D 4
+U 2
+L 3
+L 2
+U 6
+D 3
+D 9
+R 9
+D 6
+D 6
+R 7
+D 2
+D 6
+U 1
+U 8
+U 1
+L 5
+R 6
+L 3
+R 5
+U 7
+D 1
+R 4
+L 1
+D 2
+L 5
+R 2
+U 1
+R 4
+R 4
+R 18
+R 9
+U 5
+U 6
+U 12
+R 5
+U 4
+L 1
+D 2
+R 1
+U 5
+D 7
+R 12
+R 18
+D 2
+R 5
+L 5
+D 17
+U 9
+D 1
+R 16
+U 6
+D 2
+L 1
+R 4
+D 4
+U 1
+L 5
+D 12
+R 6
+R 8
+L 9
+R 6
+D 3
+L 15
+U 8
+L 5
+D 5
+L 2
+L 6
+D 3
+D 4
+R 2
+L 4
+U 1
+D 8
+L 13
+U 11
+U 17
+D 11
+L 2
+D 6
+R 12
+R 7
+D 2
+U 12
+L 6
+D 6
+U 2
+D 2
+D 10
+D 4
+L 2
+L 5
+L 3
+U 2
+U 1
+L 6
+R 6
+L 2
+R 12
+D 5
+U 6
+U 4
+L 13
+U 5
+U 1
+D 1
+L 3
+L 14
+D 5
+D 7
+R 4
+L 16
+D 15
+L 2
+D 5
+U 4
+D 6
+U 1
+L 6
+U 14
+D 6
+R 2
+R 1
+R 13
+U 2
+D 3
+R 2
+L 2
+D 10
+R 10
+R 1
+L 5
+D 6
+R 10
+U 15
+U 8
+U 3
+L 11
+L 1
+U 4
+R 4
+R 10
+R 9
+L 1
+R 5
+D 8
+D 8
+U 1
+R 14
+R 1
+R 10
+U 4
+D 2
+U 7
+L 10
+D 3
+D 10
+D 3
+L 1
+U 7
+L 2
+D 2
+U 7
+L 9
+U 13
+U 9
+D 7
+U 3
+D 3
+D 6
+L 16
+U 6
+D 3
+L 1
+L 3
+D 5
+L 3
+R 12
+U 11
+R 5
+L 15
+L 3
+D 9
+D 1
+D 2
+D 2
+U 11
+D 7
+U 6
+D 4
+L 10
+U 1
+L 16
+R 7
+U 5
+R 10
+D 4 \ No newline at end of file
diff --git a/2022/flake.lock b/2022/flake.lock
new file mode 100644
index 0000000..6cd4e18
--- /dev/null
+++ b/2022/flake.lock
@@ -0,0 +1,147 @@
+{
+ "nodes": {
+ "crane": {
+ "inputs": {
+ "flake-compat": "flake-compat",
+ "flake-utils": "flake-utils",
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "rust-overlay": "rust-overlay"
+ },
+ "locked": {
+ "lastModified": 1669853699,
+ "narHash": "sha256-SvyPRwJeET7PCifBOvu+reQUUlyc4Ya1K37GrtZyiXY=",
+ "owner": "ipetkov",
+ "repo": "crane",
+ "rev": "0428181b7b8f619e71095cf2fab051bccdf10041",
+ "type": "github"
+ },
+ "original": {
+ "owner": "ipetkov",
+ "repo": "crane",
+ "type": "github"
+ }
+ },
+ "flake-compat": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1650374568,
+ "narHash": "sha256-Z+s0J8/r907g149rllvwhb4pKi8Wam5ij0st8PwAh+E=",
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "rev": "b4a34015c698c7793d592d66adbab377907a2be8",
+ "type": "github"
+ },
+ "original": {
+ "owner": "edolstra",
+ "repo": "flake-compat",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "locked": {
+ "lastModified": 1667395993,
+ "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "flake-utils_2": {
+ "locked": {
+ "lastModified": 1667395993,
+ "narHash": "sha256-nuEHfE/LcWyuSWnS8t12N1wc105Qtau+/OdUAjtQ0rA=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "5aed5285a952e0b949eb3ba02c12fa4fcfef535f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1669867399,
+ "narHash": "sha256-Z8RXSFYOsIsTG96ROKtV0eZ8Q7u4irFWm6ELqfw7mT8=",
+ "owner": "NixOS",
+ "repo": "nixpkgs",
+ "rev": "38e591dd05ffc8bdf79dc752ba78b05e370416fa",
+ "type": "github"
+ },
+ "original": {
+ "owner": "NixOS",
+ "ref": "nixpkgs-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "crane": "crane",
+ "flake-utils": "flake-utils_2",
+ "nixpkgs": "nixpkgs",
+ "rust-overlay": "rust-overlay_2"
+ }
+ },
+ "rust-overlay": {
+ "inputs": {
+ "flake-utils": [
+ "crane",
+ "flake-utils"
+ ],
+ "nixpkgs": [
+ "crane",
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1667487142,
+ "narHash": "sha256-bVuzLs1ZVggJAbJmEDVO9G6p8BH3HRaolK70KXvnWnU=",
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "rev": "cf668f737ac986c0a89e83b6b2e3c5ddbd8cf33b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "type": "github"
+ }
+ },
+ "rust-overlay_2": {
+ "inputs": {
+ "flake-utils": [
+ "flake-utils"
+ ],
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1669862269,
+ "narHash": "sha256-/ar+cbAKAxd2Ng9b7EhrIMz9CP353RbmLecvyOidyUM=",
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "rev": "bfdf688742cf984c4837dbbe1c6cbca550365613",
+ "type": "github"
+ },
+ "original": {
+ "owner": "oxalica",
+ "repo": "rust-overlay",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/2022/flake.nix b/2022/flake.nix
new file mode 100644
index 0000000..7d55163
--- /dev/null
+++ b/2022/flake.nix
@@ -0,0 +1,72 @@
+{
+ description = "AOC 2022";
+
+ inputs = {
+ nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
+
+ crane = {
+ url = "github:ipetkov/crane";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+
+ flake-utils.url = "github:numtide/flake-utils";
+
+ rust-overlay = {
+ url = "github:oxalica/rust-overlay";
+ inputs = {
+ nixpkgs.follows = "nixpkgs";
+ flake-utils.follows = "flake-utils";
+ };
+ };
+ };
+
+ outputs = { self, nixpkgs, crane, flake-utils, rust-overlay, ... }:
+ flake-utils.lib.eachDefaultSystem (system:
+ let
+ pkgs = import nixpkgs {
+ inherit system;
+ overlays = [ (import rust-overlay) ];
+ };
+
+ toolchain = pkgs.rust-bin.nightly.latest.default.override {
+ targets = ["wasm32-unknown-unknown"];
+ };
+ craneLib = (crane.mkLib pkgs).overrideToolchain toolchain;
+ buildInputs = [
+ pkgs.cmake
+ pkgs.pkg-config
+ pkgs.fontconfig
+ pkgs.trunk
+ ];
+ my-crate = craneLib.buildPackage {
+ src = craneLib.cleanCargoSource ./.;
+ doCheck = false;
+
+ buildInputs = buildInputs ++ pkgs.lib.optionals pkgs.stdenv.isDarwin [
+ # Additional darwin specific inputs can be set here
+ pkgs.libiconv
+ ];
+ };
+ in
+ {
+ checks = {
+ inherit my-crate;
+ };
+
+ packages.default = my-crate;
+
+ apps.default = flake-utils.lib.mkApp {
+ drv = my-crate;
+ };
+
+ devShells.default = pkgs.mkShell {
+ inputsFrom = builtins.attrValues self.checks;
+
+ nativeBuildInputs = buildInputs ++ (with pkgs; [
+ (toolchain.override {
+ extensions = ["rust-analyzer" "rust-src" "miri"];
+ })
+ ]);
+ };
+ });
+}
diff --git a/2022/src/day01.rs b/2022/src/day01.rs
new file mode 100644
index 0000000..a328975
--- /dev/null
+++ b/2022/src/day01.rs
@@ -0,0 +1,21 @@
+use crate::utils::max_n;
+
+mod utils;
+
+fn main() {
+ let input = utils::read_input();
+
+ let mut elf_cal_counts: Vec<usize> = input
+ .split("\n\n")
+ .map(|xs| {
+ xs.lines()
+ .map(|x| x.parse::<usize>().unwrap())
+ .sum::<usize>()
+ })
+ .collect();
+
+ let top_3 = max_n(&mut elf_cal_counts, 3);
+
+ println!("Max: {}", top_3.last().unwrap());
+ println!("Sum of top 3: {}", top_3.iter().sum::<usize>());
+}
diff --git a/2022/src/day02.rs b/2022/src/day02.rs
new file mode 100644
index 0000000..d0b0c5f
--- /dev/null
+++ b/2022/src/day02.rs
@@ -0,0 +1,105 @@
+mod utils;
+
+use utils::read_input;
+
+fn main() {
+ let input = read_input();
+
+ let turns_both_moves: Vec<_> = input
+ .lines()
+ .map(|xs| {
+ let mut parts = xs.split(' ').take(2).map(Move::parse);
+ (parts.next().unwrap(), parts.next().unwrap())
+ })
+ .collect();
+
+ let total_score_p1: usize = turns_both_moves
+ .iter()
+ .map(|(them, us)| score(*them, *us))
+ .sum();
+
+ let total_score_p2: usize = turns_both_moves
+ .into_iter()
+ .map(|(them, us)| (them, us.to_outcome()))
+ .map(|(them, outcome)| (them, them.to_get(outcome)))
+ .map(|(them, us)| score(them, us))
+ .sum();
+
+ println!("Part 1: {}", total_score_p1);
+ println!("Part 2: {}", total_score_p2);
+}
+
+fn score(them: Move, us: Move) -> usize {
+ let won_val = match (them.beats(us), us.beats(them)) {
+ (true, false) => 0,
+ (false, true) => 6,
+ (false, false) => 3,
+ (a, b) => unreachable!("they beat us: {}, we beat them: {}", a, b),
+ };
+ us.value() + won_val
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Move {
+ Rock,
+ Paper,
+ Scissors,
+}
+
+impl Move {
+ fn parse(inp: &str) -> Self {
+ match inp {
+ "A" => Move::Rock,
+ "B" => Move::Paper,
+ "C" => Move::Scissors,
+ "X" => Move::Rock,
+ "Y" => Move::Paper,
+ "Z" => Move::Scissors,
+ _ => panic!("unrecognised move: {}", inp),
+ }
+ }
+
+ fn to_outcome(self) -> Outcome {
+ match self {
+ Move::Rock => Outcome::Lose,
+ Move::Paper => Outcome::Draw,
+ Move::Scissors => Outcome::Win,
+ }
+ }
+
+ fn beats(self, other: Move) -> bool {
+ matches!(
+ (self, other),
+ (Move::Paper, Move::Rock)
+ | (Move::Rock, Move::Scissors)
+ | (Move::Scissors, Move::Paper)
+ )
+ }
+
+ fn to_get(self, outcome: Outcome) -> Self {
+ match (self, outcome) {
+ (_, Outcome::Draw) => self,
+ (Move::Rock, Outcome::Win) => Move::Paper,
+ (Move::Paper, Outcome::Win) => Move::Scissors,
+ (Move::Scissors, Outcome::Win) => Move::Rock,
+ (Move::Rock, Outcome::Lose) => Move::Scissors,
+ (Move::Paper, Outcome::Lose) => Move::Rock,
+ (Move::Scissors, Outcome::Lose) => Move::Paper,
+ }
+ }
+
+ fn value(self) -> usize {
+ match self {
+ Move::Rock => 1,
+ Move::Paper => 2,
+ Move::Scissors => 3,
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Outcome {
+ Win,
+ Draw,
+ Lose,
+}
diff --git a/2022/src/day03.rs b/2022/src/day03.rs
new file mode 100644
index 0000000..7e245de
--- /dev/null
+++ b/2022/src/day03.rs
@@ -0,0 +1,62 @@
+mod utils;
+
+use std::collections::HashSet;
+
+use utils::read_input;
+
+fn main() {
+ let input = read_input();
+
+ // Convert each line to a tuple of hashsets, one for each backpack pocket
+ let rucksack_items: Vec<_> = input
+ .lines()
+ .map(|line| (&line[..line.len() / 2], &line[line.len() / 2..]))
+ .map(|(a, b)| -> (HashSet<char>, HashSet<char>) {
+ (a.chars().collect(), b.chars().collect())
+ })
+ .collect();
+
+ let sum_error_priorities: u32 = rucksack_items
+ .iter()
+ .map(|(a, b)| {
+ *a.intersection(b)
+ .next()
+ .expect("no common item between two backpack segments!")
+ }) // Get common item
+ .map(priority)
+ .sum();
+
+ let sum_badge_priorities: u32 = rucksack_items // Construct chunked iterator
+ .iter()
+ .step_by(3)
+ .zip(rucksack_items.iter().skip(1).step_by(3))
+ .zip(rucksack_items.iter().skip(2).step_by(3))
+ .map(|(((e1l, e1r), (e2l, e2r)), (e3l, e3r))| {
+ for item in e1l.union(e1r) {
+ if (e2l.contains(item) || e2r.contains(item))
+ && (e3l.contains(item) || e3r.contains(item))
+ {
+ return *item;
+ }
+ }
+ panic!(
+ "group has no badge! {:?}",
+ ((e1l, e1r), (e2l, e2r), (e3l, e3r))
+ )
+ })
+ .map(priority)
+ .sum();
+
+ println!("Part 1: {}", sum_error_priorities);
+ println!("Part 2: {}", sum_badge_priorities);
+}
+
+fn priority(chr: char) -> u32 {
+ if chr.is_ascii_lowercase() {
+ chr as u32 - 96
+ } else if chr.is_ascii_uppercase() {
+ chr as u32 - 38
+ } else {
+ panic!("unrecognised item {}", chr)
+ }
+}
diff --git a/2022/src/day04.rs b/2022/src/day04.rs
new file mode 100644
index 0000000..052dde1
--- /dev/null
+++ b/2022/src/day04.rs
@@ -0,0 +1,35 @@
+mod utils;
+
+use std::ops::RangeInclusive;
+
+use utils::{iter_pair, read_input};
+
+fn main() {
+ let input = read_input();
+
+ let pairs = input.lines().map(|x| {
+ iter_pair(x.split(',').map(|x| -> RangeInclusive<usize> {
+ let (start, end) = iter_pair(x.split('-'));
+ start.parse().unwrap()..=end.parse().unwrap()
+ }))
+ });
+
+ let (fully_contains, partially_contains) = pairs
+ .map(|(a, b)| (fully_overlap(&a, &b), partially_overlap(&a, &b)))
+ .fold((0, 0), |(acc_full, acc_part), (full, part)| {
+ (acc_full + full as usize, acc_part + part as usize)
+ });
+
+ println!("Part 1: {}", fully_contains);
+ println!("Part 2: {}", partially_contains);
+}
+
+#[inline(always)]
+fn fully_overlap<T: PartialOrd>(a: &RangeInclusive<T>, b: &RangeInclusive<T>) -> bool {
+ (a.contains(b.start()) && a.contains(b.end())) || (b.contains(a.start()) && b.contains(a.end()))
+}
+
+#[inline(always)]
+fn partially_overlap<T: PartialOrd>(a: &RangeInclusive<T>, b: &RangeInclusive<T>) -> bool {
+ a.contains(b.start()) || a.contains(b.end()) || b.contains(a.start()) || b.contains(a.end())
+}
diff --git a/2022/src/day05.rs b/2022/src/day05.rs
new file mode 100644
index 0000000..f45cd0a
--- /dev/null
+++ b/2022/src/day05.rs
@@ -0,0 +1,145 @@
+//! Day 5: Supply Stacks
+
+extern crate bumpalo;
+
+mod utils;
+
+use bumpalo::Bump;
+use std::cell::Cell;
+use utils::{parse_num, parse_static, read_input};
+
+/// Base type for a crate
+#[derive(Debug, Clone)]
+struct Crate<'a> {
+ letter: char,
+ below: Cell<Option<&'a Crate<'a>>>,
+}
+
+impl Default for Crate<'_> {
+ fn default() -> Self {
+ Crate {
+ letter: ' ',
+ below: None.into(),
+ }
+ }
+}
+
+/// A move the crane may make
+#[derive(Debug, Clone, Copy)]
+struct Move {
+ reps: usize,
+ from: usize,
+ to: usize,
+}
+type Tops<'arena> = Vec<Option<&'arena Crate<'arena>>>;
+
+fn main() {
+ let input = read_input();
+
+ {
+ let arena = Bump::new();
+ let mut tops = construct_piles(&input, &arena);
+ for mv in parse_moves(&input) {
+ perform_move_9000(&mut tops, mv);
+ }
+
+ println!("Part 1: {}", top_letters(tops));
+ }
+
+ {
+ let arena = Bump::new();
+ let mut tops = construct_piles(&input, &arena);
+ for mv in parse_moves(&input) {
+ perform_move_9001(&mut tops, mv);
+ }
+
+ println!("Part 2: {}", top_letters(tops));
+ }
+}
+
+/// Get the message / the top letters of each stack
+fn top_letters(tops: Tops<'_>) -> String {
+ tops.iter().map(|x| x.as_ref().unwrap().letter).collect()
+}
+
+/// Perform a move for part 1
+fn perform_move_9000(tops: &mut Tops<'_>, mv: Move) {
+ for _ in 0..mv.reps {
+ let from = tops[mv.from].take().unwrap();
+ let to = tops[mv.to].take();
+
+ tops[mv.from] = from.below.replace(to);
+ tops[mv.to] = Some(from);
+ }
+}
+
+/// Perform a move for part 2
+fn perform_move_9001(tops: &mut Tops<'_>, mv: Move) {
+ let pickup_top = tops[mv.from].take().unwrap();
+
+ let mut pickup_bot = pickup_top;
+ for _ in 1..mv.reps {
+ pickup_bot = pickup_bot.below.get().as_ref().unwrap();
+ }
+
+ let to = tops[mv.to].take();
+
+ tops[mv.from] = pickup_bot.below.replace(to);
+ tops[mv.to] = Some(pickup_top);
+}
+
+// Annoying parsing code!
+
+fn construct_piles<'a>(input: &str, arena: &'a Bump) -> Tops<'a> {
+ let mut piles = Vec::new();
+ for layer_iter in input
+ .lines()
+ .take_while(|x| x.chars().find(|x| *x != ' ').unwrap() == '[')
+ .map(|x| x.chars().skip(1).step_by(4))
+ {
+ for (stack, chr) in layer_iter.enumerate() {
+ if piles.len() < stack + 1 {
+ piles.resize(stack + 1, None);
+ }
+
+ if chr != ' ' {
+ let val = &*arena.alloc(Crate {
+ letter: chr,
+ below: None.into(),
+ });
+ if piles[stack].is_none() {
+ piles[stack] = Some(val);
+ } else {
+ let mut top = *piles[stack].as_ref().unwrap();
+ while let Some(below) = top.below.get() {
+ top = below;
+ }
+
+ top.below.set(Some(val));
+ }
+ }
+ }
+ }
+
+ piles
+}
+
+fn parse_moves(input: &str) -> impl Iterator<Item = Move> + '_ {
+ input
+ .lines()
+ .skip_while(|line| !line.starts_with('m'))
+ .map(|line| {
+ let line = parse_static("move ", line);
+ let (reps, line) = parse_num(line);
+ let line = parse_static(" from ", line);
+ let (from, line) = parse_num::<usize>(line);
+ let line = parse_static(" to ", line);
+ let (to, _) = parse_num::<usize>(line);
+
+ Move {
+ reps,
+ from: from - 1,
+ to: to - 1,
+ }
+ })
+}
diff --git a/2022/src/day06.rs b/2022/src/day06.rs
new file mode 100644
index 0000000..8bbfe6d
--- /dev/null
+++ b/2022/src/day06.rs
@@ -0,0 +1,47 @@
+mod utils;
+use utils::read_input;
+
+fn main() {
+ let input = read_input();
+
+ println!("Part 1: {}", find_chunk_nodup::<4>(&input));
+ println!("Part 2: {}", find_chunk_nodup::<14>(&input));
+}
+
+fn find_chunk_nodup<const N: usize>(input: &str) -> usize {
+ let mut window = ['a'; N];
+ let mut chars = input.chars();
+
+ // Fill up initial window
+ for item in window.iter_mut() {
+ *item = chars.next().unwrap();
+ }
+
+ for i in 0..input.len() {
+ // Shuffle everything in window down
+ for j in 0..N - 1 {
+ window[j] = window[j + 1];
+ }
+ window[N - 1] = chars.next().unwrap();
+
+ if window
+ .iter()
+ .fold(Some(0), |acc, chr| add_char(acc?, *chr))
+ .is_some()
+ {
+ return i + N + 1;
+ }
+ }
+
+ panic!("no solution!")
+}
+
+#[inline]
+fn add_char(bits: u32, chr: char) -> Option<u32> {
+ let add = 1 << (chr.to_ascii_lowercase() as u32 - 97);
+ if (bits | add) != bits {
+ Some(bits | add)
+ } else {
+ None
+ }
+}
diff --git a/2022/src/day07.rs b/2022/src/day07.rs
new file mode 100644
index 0000000..88bb647
--- /dev/null
+++ b/2022/src/day07.rs
@@ -0,0 +1,110 @@
+mod utils;
+use utils::read_input;
+
+fn main() {
+ let input = read_input();
+
+ let mut unused = 0;
+ let mut sum_under_threshold = 0;
+
+ for size in DirectorySizes::new(&input) {
+ if size < 100_000 {
+ sum_under_threshold += size;
+ }
+ unused = 70_000_000 - size;
+ }
+
+ println!("Part 1: {}", sum_under_threshold);
+ let deficit = 30_000_000 - unused;
+ println!(
+ "Part 2: {}",
+ DirectorySizes::new(&input)
+ .filter(|x| *x > deficit)
+ .min()
+ .unwrap()
+ );
+}
+
+struct DirectorySizes<'a> {
+ lines: std::str::Lines<'a>,
+ directory_stack: [usize; 64],
+ stack_top: usize,
+}
+
+impl<'a> DirectorySizes<'a> {
+ fn new(input: &'a str) -> Self {
+ let mut lines = input.lines();
+ assert_eq!(lines.next(), Some("$ cd /"));
+
+ DirectorySizes {
+ lines,
+ directory_stack: [0; 64],
+ stack_top: 0,
+ }
+ }
+}
+
+impl Iterator for DirectorySizes<'_> {
+ type Item = usize;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ for line in self.lines.by_ref() {
+ let line: Line = line.into();
+
+ match line {
+ Line::Cd(up) => {
+ if up {
+ self.directory_stack[self.stack_top - 1] +=
+ self.directory_stack[self.stack_top];
+ self.stack_top -= 1;
+ return Some(self.directory_stack[self.stack_top + 1]);
+ } else {
+ self.stack_top += 1;
+ self.directory_stack[self.stack_top] = 0;
+ }
+ }
+ Line::FileSize(size) => {
+ self.directory_stack[self.stack_top] += size;
+ }
+ Line::Ls => (),
+ Line::Dir => (),
+ };
+ }
+
+ if self.stack_top > 0 {
+ self.directory_stack[self.stack_top - 1] += self.directory_stack[self.stack_top];
+ self.stack_top -= 1;
+ Some(self.directory_stack[self.stack_top + 1])
+ } else if self.directory_stack[0] != 0 {
+ Some(std::mem::replace(&mut self.directory_stack[0], 0))
+ } else {
+ None
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Line {
+ /// True = .., False = other
+ Cd(bool),
+ Ls,
+ FileSize(usize),
+ Dir,
+}
+
+impl From<&str> for Line {
+ fn from(value: &str) -> Self {
+ if value.starts_with("$ cd ") {
+ let mut args = value.split("cd ");
+ args.next().unwrap();
+ Line::Cd(args.next().unwrap() == "..")
+ } else if value.starts_with("$ ls") {
+ Line::Ls
+ } else if value.starts_with("dir") {
+ Line::Dir
+ } else {
+ let num_index = value.chars().take_while(|chr| chr.is_numeric()).count();
+ Line::FileSize(value[..num_index].parse().unwrap())
+ }
+ }
+}
diff --git a/2022/src/day08.rs b/2022/src/day08.rs
new file mode 100644
index 0000000..514cb21
--- /dev/null
+++ b/2022/src/day08.rs
@@ -0,0 +1,110 @@
+mod utils;
+
+use utils::read_input;
+
+fn main() {
+ let input = read_input();
+
+ let mut grid: Vec<Vec<_>> = input
+ .lines()
+ .map(|x| {
+ x.chars()
+ .map(|x| (x.to_digit(10).unwrap() as u8, false))
+ .collect()
+ })
+ .collect();
+ in_all_directions!(check_vis_along_run, grid);
+
+ println!(
+ "Part 1: {}",
+ grid.iter()
+ .map(|x| x.iter().filter(|x| x.1).count())
+ .sum::<usize>()
+ );
+
+ let mut grid: Vec<Vec<(u8, u32)>> = grid
+ .into_iter()
+ .map(|x| x.into_iter().map(|(x, _)| (x, 1)).collect())
+ .collect();
+ in_all_directions!(vis_score_along_run, grid);
+
+ println!(
+ "Part 2: {}",
+ grid.iter()
+ .map(|row| row.iter().map(|(_, vis)| vis).max().unwrap())
+ .max()
+ .unwrap()
+ );
+}
+
+fn check_vis_along_run(
+ mut run: impl Iterator<Item = (usize, usize)>,
+ grid: &mut [Vec<(u8, bool)>],
+) {
+ let mut curr_height = {
+ let (row_idx, col_idx) = run.next().unwrap();
+
+ grid[row_idx][col_idx].1 = true;
+
+ grid[row_idx][col_idx].0
+ };
+ for (row_idx, col_idx) in run {
+ let height = grid[row_idx][col_idx].0;
+ if height > curr_height {
+ curr_height = height;
+ grid[row_idx][col_idx].1 = true;
+ }
+ }
+}
+
+fn vis_score_along_run(run: impl Iterator<Item = (usize, usize)>, grid: &mut [Vec<(u8, u32)>]) {
+ let mut next_values = [0; 10];
+ for (row_idx, col_idx) in run {
+ let height = grid[row_idx][col_idx].0;
+ grid[row_idx][col_idx].1 *= next_values[height as usize];
+
+ for (val, score) in next_values.iter_mut().enumerate() {
+ *score = if *score == 0 || val > height as usize {
+ *score + 1
+ } else {
+ 1
+ };
+ }
+ }
+}
+
+#[macro_use]
+mod codegen {
+ #[macro_export]
+ macro_rules! in_all_directions {
+ ($f:ident, $grid: ident) => {
+ let grid_rows = $grid.len();
+ let grid_cols = $grid[0].len();
+
+ (0..grid_rows).for_each(|grid_row| {
+ $f(
+ (0..grid_cols).map(move |grid_col| (grid_row, grid_col)),
+ &mut $grid,
+ );
+ $f(
+ (0..grid_cols)
+ .rev()
+ .map(move |grid_col| (grid_row, grid_col)),
+ &mut $grid,
+ )
+ });
+ (0..grid_cols).for_each(|grid_col| {
+ $f(
+ (0..grid_rows).map(move |grid_row| (grid_row, grid_col)),
+ &mut $grid,
+ );
+ $f(
+ (0..grid_rows)
+ .rev()
+ .map(move |grid_row| (grid_row, grid_col)),
+ &mut $grid,
+ )
+ });
+ };
+ }
+}
diff --git a/2022/src/day09.html b/2022/src/day09.html
new file mode 100644
index 0000000..d3ed12b
--- /dev/null
+++ b/2022/src/day09.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <link data-trunk rel="rust" data-wasm-opt="2" href="../Cargo.toml" data-bin="day9" />
+
+ <style>
+ html {
+ /* Remove touch delay: */
+ touch-action: manipulation;
+ }
+
+ html,
+ body {
+ overflow: hidden;
+ margin: 0 !important;
+ padding: 0 !important;
+ height: 100%;
+ width: 100%;
+ }
+
+ canvas {
+ margin-right: auto;
+ margin-left: auto;
+ display: block;
+ position: absolute;
+ top: 0%;
+ left: 50%;
+ transform: translate(-50%, 0%);
+ }
+ </style>
+</head>
+
+<body>
+ <canvas id="canvas"></canvas>
+</body>
+
+</html>
diff --git a/2022/src/day09.rs b/2022/src/day09.rs
new file mode 100644
index 0000000..23b08b3
--- /dev/null
+++ b/2022/src/day09.rs
@@ -0,0 +1,238 @@
+mod utils;
+use std::{
+ cmp::min,
+ collections::{HashSet, VecDeque},
+ time::Duration,
+};
+
+use egui::{Color32, Sense, Stroke};
+use utils::{iter_pair, read_input};
+
+#[cfg(target_arch = "wasm32")]
+fn main() {
+ console_error_panic_hook::set_once();
+
+ let input = include_str!("../fake_inputs/day9");
+ let input = parse_moves(&input).collect();
+
+ let options = eframe::WebOptions::default();
+ wasm_bindgen_futures::spawn_local(async {
+ eframe::start_web("canvas", options, Box::new(|_cc| Box::new(App::new(input))))
+ .await
+ .expect("unable to start eframe");
+ });
+}
+
+#[cfg(not(target_arch = "wasm32"))]
+fn main() {
+ let input = read_input();
+
+ println!("Part 1: {}", visited_from_moves::<2>(parse_moves(&input)));
+ println!("Part 2: {}", visited_from_moves::<10>(parse_moves(&input)));
+}
+
+type Pos = (i32, i32);
+type Move = (Direction, u8);
+
+fn visited_from_moves<const N: usize>(moves: impl Iterator<Item = Move>) -> usize {
+ let mut tail_visited = HashSet::new();
+ tail_visited.insert((0, 0));
+ let mut knots = [(0, 0); N];
+ for mv in moves {
+ make_move(mv, &mut knots, &mut tail_visited);
+ }
+
+ tail_visited.len()
+}
+
+fn make_move(mv: Move, knots: &mut [Pos], tail_visited: &mut HashSet<Pos>) {
+ let (dir, count) = mv;
+
+ for _ in 0..count {
+ // Move head of rope
+ match dir {
+ Direction::Up => knots[0].1 += 1,
+ Direction::Down => knots[0].1 -= 1,
+ Direction::Right => knots[0].0 += 1,
+ Direction::Left => knots[0].0 -= 1,
+ };
+
+ for front_idx in 0..knots.len() - 1 {
+ let (fx, fy) = knots[front_idx];
+ let (bx, by) = &mut knots[front_idx + 1];
+ let (dx, dy) = (fx - *bx, fy - *by);
+ if (dx.abs() == 2 && dy == 0) || (dy.abs() == 2 && dx == 0) || (dy.abs() + dx.abs() > 2)
+ {
+ *bx += (dx.signum()) * min(dx.abs(), 1);
+ *by += (dy.signum()) * min(dy.abs(), 1);
+ }
+ }
+ tail_visited.insert(knots[knots.len() - 1]);
+ }
+}
+
+fn parse_moves(input: &str) -> impl Iterator<Item = Move> + '_ {
+ input.lines().map(|x| {
+ let (dir, count) = iter_pair(x.split(' '));
+ let count = count.parse().unwrap();
+
+ (
+ match dir {
+ "L" => Direction::Left,
+ "R" => Direction::Right,
+ "U" => Direction::Up,
+ "D" => Direction::Down,
+ _ => panic!("invalid direction, {}", dir),
+ },
+ count,
+ )
+ })
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Direction {
+ Up,
+ Down,
+ Left,
+ Right,
+}
+
+struct App {
+ orig_input: VecDeque<Move>,
+ input: VecDeque<Move>,
+ knots: Vec<Pos>,
+ tail_visited: HashSet<Pos>,
+ desired_knot_count: usize,
+ speed: usize,
+}
+
+impl App {
+ fn new(input: VecDeque<Move>) -> Self {
+ App {
+ orig_input: input.clone(),
+ input,
+ knots: vec![],
+ tail_visited: HashSet::new(),
+ desired_knot_count: 2,
+ speed: 0,
+ }
+ }
+
+ fn reset_knots(&mut self) {
+ self.input = self.orig_input.clone();
+ self.knots = vec![(0, 0); self.desired_knot_count];
+ self.tail_visited.clear();
+ self.tail_visited.insert((0, 0));
+ }
+
+ fn step(&mut self) {
+ match self.input.pop_front() {
+ Some(mv) => make_move(mv, &mut self.knots, &mut self.tail_visited),
+ None => (),
+ }
+ }
+}
+
+impl eframe::App for App {
+ fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
+ if self.desired_knot_count != self.knots.len() {
+ self.reset_knots()
+ }
+ egui::SidePanel::right("instructions").show(ctx, |ui| {
+ egui::ScrollArea::vertical().show(ui, |ui| {
+ if ui.button("Step").clicked() {
+ self.step();
+ }
+ if ui.button("Reset").clicked() {
+ self.reset_knots()
+ }
+ ui.label(format!("Tail Visited: {}", self.tail_visited.len()));
+ ui.add(egui::Slider::new(&mut self.desired_knot_count, 2..=20).text("Knot count"));
+ ui.add(egui::Slider::new(&mut self.speed, 0..=20).text("Speed"));
+ ui.heading("Instructions:");
+ for (i, ins) in self.input.iter().take(20).enumerate() {
+ let arrow = match ins.0 {
+ Direction::Up => "⬆",
+ Direction::Down => "⬇",
+ Direction::Right => "➡",
+ Direction::Left => "⬅",
+ };
+ if i == 0 {
+ ui.colored_label(Color32::YELLOW, arrow.repeat(ins.1 as _));
+ } else {
+ ui.label(arrow.repeat(ins.1 as _));
+ }
+ }
+ if self.input.len() > 20 {
+ ui.label(format!("+ {} more", self.input.len() - 20));
+ }
+ })
+ });
+
+ if self.speed > 0 && self.input.len() > 0 {
+ for _ in 0..self.speed {
+ self.step();
+ }
+ ctx.request_repaint_after(Duration::from_millis(100))
+ }
+
+ egui::CentralPanel::default().show(ctx, |ui| {
+ let mut painter_size = ui.available_size_before_wrap();
+ if !painter_size.is_finite() {
+ painter_size = egui::vec2(500.0, 500.0);
+ }
+
+ const SIDE: f32 = 5.0;
+
+ let (res, painter) = ui.allocate_painter(painter_size, Sense::hover());
+ let center = res.rect.center().to_vec2();
+
+ let to_panel_pos = |pos: &Pos| {
+ (egui::vec2(pos.0 as f32 * SIDE, pos.1 as f32 * SIDE) + center).to_pos2()
+ };
+
+ let half_width = (painter_size.x / SIDE).floor() as i32;
+ let half_height = (painter_size.y / SIDE).floor() as i32;
+
+ for x in -half_width..half_width {
+ for y in -half_height..half_height {
+ let dot = (x, y);
+ let color = if dot == (0, 0) {
+ Color32::WHITE
+ } else if self.tail_visited.contains(&dot) {
+ Color32::DARK_RED
+ } else {
+ continue;
+ };
+
+ let dot_pos = to_panel_pos(&dot);
+ painter.circle_stroke(dot_pos, 1.0, Stroke::new(1.0, color));
+ }
+ }
+
+ // paint the head
+ painter.circle_stroke(
+ to_panel_pos(&self.knots[0]),
+ SIDE / 2.0,
+ Stroke::new(SIDE / 2.0, Color32::GREEN),
+ );
+ for knot in self.knots.iter().skip(1) {
+ painter.circle_stroke(
+ to_panel_pos(knot),
+ SIDE / 2.0,
+ Stroke::new(SIDE / 2.0, Color32::YELLOW),
+ );
+ }
+
+ for (a, b) in self.knots.iter().zip(self.knots.iter().skip(1)) {
+ let head_pos = to_panel_pos(a);
+ let tail_pos = to_panel_pos(b);
+ painter.arrow(
+ tail_pos,
+ head_pos - tail_pos,
+ Stroke::new(1.0, Color32::YELLOW),
+ )
+ }
+ });
+ }
+}
diff --git a/2022/src/day10.rs b/2022/src/day10.rs
new file mode 100644
index 0000000..4c74444
--- /dev/null
+++ b/2022/src/day10.rs
@@ -0,0 +1,82 @@
+mod utils;
+use utils::{parse_num, parse_static, read_input};
+
+fn main() {
+ let input = read_input();
+
+ let mut cmds = input.lines().map(parse_cmd);
+ let mut state = State {
+ x: 1,
+ add_next: None,
+ add_next_start: None,
+ crt_pos: 0,
+ };
+
+ let mut acc = 0;
+ run_steps::<20>(&mut state, &mut cmds);
+ acc += state.x * 20;
+ for i in 1..=5 {
+ run_steps::<40>(&mut state, &mut cmds);
+ acc += state.x * (20 + (i * 40));
+ }
+
+ run_steps::<{ TOTAL_STEPS - 220 }>(&mut state, &mut cmds);
+
+ println!("Part 1: {}", acc);
+}
+
+struct State {
+ x: isize,
+ add_next: Option<isize>,
+ add_next_start: Option<isize>,
+ crt_pos: usize,
+}
+
+const CRT_WIDTH: usize = 40;
+const CRT_HEIGHT: usize = 6;
+const TOTAL_STEPS: usize = CRT_WIDTH * CRT_HEIGHT;
+
+fn run_steps<const N: usize>(state: &mut State, cmd: &mut impl Iterator<Item = Command>) {
+ for _ in 0..N {
+ if let Some(add) = state.add_next_start.take() {
+ state.x += add;
+ }
+
+ if (state.x - (state.crt_pos % CRT_WIDTH) as isize).abs() < 2 {
+ print!("█");
+ } else {
+ print!(" ");
+ }
+ state.crt_pos += 1;
+ if (state.crt_pos % CRT_WIDTH) == 0 {
+ println!();
+ }
+
+ if let Some(add) = state.add_next.take() {
+ state.add_next_start = Some(add);
+ } else {
+ match cmd.next() {
+ Some(Command::NoOp) => (),
+ Some(Command::AddX(add)) => state.add_next = Some(add),
+ None => (),
+ }
+ }
+ }
+}
+
+fn parse_cmd(cmd: &str) -> Command {
+ if cmd == "noop" {
+ Command::NoOp
+ } else {
+ let cmd = parse_static("addx ", cmd);
+ let (add, _) = parse_num(cmd);
+
+ Command::AddX(add)
+ }
+}
+
+#[derive(Debug)]
+enum Command {
+ NoOp,
+ AddX(isize),
+}
diff --git a/2022/src/day11.rs b/2022/src/day11.rs
new file mode 100644
index 0000000..aad0b48
--- /dev/null
+++ b/2022/src/day11.rs
@@ -0,0 +1,127 @@
+mod utils;
+extern crate nom;
+use nom::{
+ branch::alt,
+ bytes::complete::{tag, take_until},
+ character::complete::{digit0, u32},
+ multi::separated_list0,
+ IResult,
+};
+use utils::{max_n, read_input};
+
+fn main() {
+ let input = read_input();
+
+ let (_, monkeys_items) = separated_list0(tag("\n\n"), Monkey::parse)(&input).unwrap();
+ let (monkeys, items): (Vec<_>, Vec<_>) = monkeys_items.into_iter().unzip();
+
+ println!(
+ "Part 1: {}",
+ monkey_business::<3, 20>(&monkeys, items.clone(), usize::MAX),
+ );
+ println!(
+ "Part 2: {}",
+ monkey_business::<1, 10000>(&monkeys, items, monkeys.iter().map(|x| x.test).product())
+ );
+}
+
+fn monkey_business<const REDUCER: usize, const ROUNDS: usize>(
+ monkeys: &[Monkey],
+ mut items: Vec<Vec<usize>>,
+ additional_reducer: usize,
+) -> usize {
+ let mut inspections = vec![0; monkeys.len()];
+ for _ in 0..ROUNDS {
+ for monkey_idx in 0..monkeys.len() {
+ let curr_monkey = &monkeys[monkey_idx];
+ while let Some(worry) = items[monkey_idx].pop() {
+ let new_worry = (curr_monkey.do_op(worry) / REDUCER) % additional_reducer;
+ inspections[monkey_idx] += 1;
+ let throw_to = curr_monkey.throw_to(new_worry);
+
+ items[throw_to].push(new_worry);
+ }
+ }
+ }
+
+ max_n(&mut inspections, 2).iter().product::<usize>()
+}
+
+#[derive(Debug)]
+struct Monkey {
+ op: Operation,
+ test: usize,
+ next_monkey: (usize, usize),
+}
+
+impl Monkey {
+ fn parse(i: &str) -> IResult<&str, (Monkey, Vec<usize>)> {
+ let (i, _) = tag("Monkey ")(i)?;
+ let (i, _) = digit0(i)?;
+ let (i, _) = tag(":\n Starting items: ")(i)?;
+ let (i, items) = separated_list0(tag(", "), u32)(i)?;
+ let (i, _) = tag("\n Operation: new = ")(i)?;
+ let (i, op) = Operation::parse(i)?;
+ let (i, _) = take_until("\n")(i)?;
+ let (i, _) = tag("\n Test: divisible by ")(i)?;
+ let (i, test) = u32(i)?;
+ let (i, _) = tag("\n If true: throw to monkey ")(i)?;
+ let (i, monkey_t) = u32(i)?;
+ let (i, _) = tag("\n If false: throw to monkey ")(i)?;
+ let (i, monkey_f) = u32(i)?;
+
+ Ok((
+ i,
+ (
+ Monkey {
+ op,
+ test: test as usize,
+ next_monkey: (monkey_t as usize, monkey_f as usize),
+ },
+ items.into_iter().map(|x| x as usize).collect(),
+ ),
+ ))
+ }
+
+ fn do_op(&self, x: usize) -> usize {
+ match self.op {
+ Operation::Square => x * x,
+ Operation::Add(c) => x + c,
+ Operation::Mult(c) => x * c,
+ }
+ }
+ fn throw_to(&self, x: usize) -> usize {
+ if (x % self.test) == 0 {
+ self.next_monkey.0
+ } else {
+ self.next_monkey.1
+ }
+ }
+}
+
+#[derive(Debug)]
+enum Operation {
+ Square,
+ Add(usize),
+ Mult(usize),
+}
+
+impl Operation {
+ fn parse(i: &str) -> IResult<&str, Operation> {
+ let (i, _) = tag("old ")(i)?;
+ let (i, op) = alt((tag("* "), tag("+ ")))(i)?;
+ if let Ok((i, _)) = tag::<&str, &str, (&str, nom::error::ErrorKind)>("old")(i) {
+ Ok((i, Operation::Square))
+ } else {
+ let (i, x) = u32(i)?;
+ Ok((
+ i,
+ match op {
+ "* " => Operation::Mult(x as usize),
+ "+ " => Operation::Add(x as usize),
+ _ => unreachable!(),
+ },
+ ))
+ }
+ }
+}
diff --git a/2022/src/day12.rs b/2022/src/day12.rs
new file mode 100644
index 0000000..c446c74
--- /dev/null
+++ b/2022/src/day12.rs
@@ -0,0 +1,141 @@
+mod utils;
+use std::collections::BinaryHeap;
+
+use utils::read_input;
+
+fn main() {
+ let input = read_input();
+
+ let width = input.lines().next().unwrap().len();
+ let height = input.lines().count();
+ let mut heights = vec![0; width * height];
+
+ let mut start = (0, 0);
+ let mut end = (0, 0);
+
+ for (y, line) in input.lines().enumerate() {
+ for (x, c) in line.chars().enumerate() {
+ let val = if c == 'S' {
+ start = (x as isize, y as isize);
+ 0
+ } else if c == 'E' {
+ end = (x as isize, y as isize);
+ 25
+ } else {
+ c.to_ascii_lowercase() as isize - 97
+ };
+ heights[(y * width) + x] = val;
+ }
+ }
+
+ let cost = pathfind(&heights, width, end);
+
+ println!("Part 1: {:?}", cost[pos_to_index(&start, width)]);
+ println!(
+ "Part 2: {:?}",
+ (0..height as isize)
+ .map(|y| (0..width as isize)
+ .map(|x| pos_to_index(&(x, y), width))
+ .filter(|idx| heights[*idx] == 0)
+ .map(|idx| cost[idx])
+ .min()
+ .unwrap())
+ .min()
+ .unwrap()
+ )
+}
+
+type HeightMap = Vec<isize>;
+type Pos = (isize, isize);
+
+fn pathfind(heights: &HeightMap, width: usize, end: Pos) -> Vec<usize> {
+ let mut min_cost = vec![usize::MAX; heights.len()];
+ let mut frontier: BinaryHeap<GraphPos> = BinaryHeap::new();
+ frontier.push(GraphPos { pos: end, moves: 0 });
+ while let Some(curr) = frontier.pop() {
+ let idx = pos_to_index(&curr.pos, width);
+ if curr.moves >= min_cost[idx] {
+ continue;
+ } else {
+ min_cost[idx] = curr.moves;
+ }
+
+ for neighbour in CanReach::new(heights, width, curr.pos) {
+ frontier.push(GraphPos {
+ pos: neighbour,
+ moves: curr.moves + 1,
+ })
+ }
+ }
+
+ min_cost
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+struct GraphPos {
+ pos: Pos,
+ moves: usize,
+}
+
+impl PartialOrd for GraphPos {
+ fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+ self.moves.partial_cmp(&other.moves).map(|x| x.reverse())
+ }
+}
+
+impl Ord for GraphPos {
+ fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+ self.moves.cmp(&other.moves).reverse()
+ }
+}
+
+struct CanReach<'a> {
+ heights: &'a HeightMap,
+ curr: Pos,
+ step: usize,
+ width: usize,
+}
+
+impl<'a> CanReach<'a> {
+ fn new(heights: &'a HeightMap, width: usize, pos: Pos) -> Self {
+ CanReach {
+ heights,
+ curr: pos,
+ step: 0,
+ width,
+ }
+ }
+}
+impl Iterator for CanReach<'_> {
+ type Item = Pos;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let (curr_x, curr_y) = self.curr;
+ loop {
+ let (x, y) = match self.step {
+ 0 => (curr_x + 1, curr_y),
+ 1 => (curr_x - 1, curr_y),
+ 2 => (curr_x, curr_y + 1),
+ 3 => (curr_x, curr_y - 1),
+ _ => break,
+ };
+ self.step += 1;
+
+ if (x >= 0
+ && x < self.width as isize
+ && y >= 0
+ && y < (self.heights.len() / self.width) as isize)
+ && self.heights[pos_to_index(&(x, y), self.width)]
+ >= self.heights[pos_to_index(&(curr_x, curr_y), self.width)] - 1
+ {
+ return Some((x, y));
+ }
+ }
+ None
+ }
+}
+
+#[inline(always)]
+fn pos_to_index(pos: &Pos, width: usize) -> usize {
+ ((pos.1 * width as isize) + pos.0) as usize
+}
diff --git a/2022/src/day13.rs b/2022/src/day13.rs
new file mode 100644
index 0000000..17b55eb
--- /dev/null
+++ b/2022/src/day13.rs
@@ -0,0 +1,132 @@
+mod utils;
+use std::{
+ cmp::Ordering,
+ iter::{once, Peekable},
+};
+
+extern crate nom;
+use nom::{bytes::complete::tag, character::complete::u32};
+use utils::read_input;
+
+fn main() {
+ let input = read_input();
+
+ let mut full: Vec<_> = input.lines().filter(|x| !x.is_empty()).collect();
+
+ println!(
+ "Part 1: {}",
+ full.iter()
+ .step_by(2)
+ .zip(full.iter().skip(1).step_by(2))
+ .map(|(left, right)| { compare(left, right) })
+ .enumerate()
+ .filter_map(|(i, cmp)| match cmp {
+ Ordering::Greater => None,
+ _ => Some(i + 1),
+ })
+ .sum::<usize>()
+ );
+
+ full.sort_by(|l, r| compare(l, r));
+
+ println!(
+ "Part 2: {}",
+ full.iter()
+ .enumerate()
+ .filter_map(|(i, val)| match *val {
+ "[[2]]" | "[[6]]" => Some(i + 1),
+ _ => None,
+ })
+ .product::<usize>()
+ );
+}
+
+fn compare(left: &str, right: &str) -> Ordering {
+ let mut left = Packet(left).peekable();
+ let mut right = Packet(right).peekable();
+ assert_eq!(left.next(), Some(PacketContents::StartList));
+ assert_eq!(right.next(), Some(PacketContents::StartList));
+ compare_lists(&mut left, &mut right)
+}
+
+fn compare_lists(
+ left: &mut Peekable<impl Iterator<Item = PacketContents>>,
+ right: &mut Peekable<impl Iterator<Item = PacketContents>>,
+) -> Ordering {
+ loop {
+ match (left.next().unwrap(), right.next().unwrap()) {
+ (PacketContents::EndList, PacketContents::EndList) => {
+ return Ordering::Equal;
+ }
+ (PacketContents::EndList, _) => {
+ while !matches!(right.next(), Some(PacketContents::EndList)) {}
+ return Ordering::Less;
+ }
+ (_, PacketContents::EndList) => {
+ while !matches!(left.next(), Some(PacketContents::EndList)) {}
+
+ return Ordering::Greater;
+ }
+ (PacketContents::StartList, PacketContents::StartList) => {
+ match compare_lists(left, right) {
+ Ordering::Equal => (),
+ x => return x,
+ }
+ }
+ (l @ PacketContents::Integer(_), PacketContents::StartList) => {
+ match compare_lists(
+ &mut once(l).chain(once(PacketContents::EndList)).peekable(),
+ right,
+ ) {
+ Ordering::Equal => (),
+ x => return x,
+ }
+ }
+ (PacketContents::StartList, r @ PacketContents::Integer(_)) => {
+ match compare_lists(
+ left,
+ &mut once(r).chain(once(PacketContents::EndList)).peekable(),
+ ) {
+ Ordering::Equal => (),
+ x => return x,
+ }
+ }
+ (PacketContents::Integer(l), PacketContents::Integer(r)) => match l.cmp(&r) {
+ Ordering::Equal => (),
+ x => return x,
+ },
+ };
+ }
+}
+
+#[derive(Debug, PartialEq, Eq)]
+enum PacketContents {
+ Integer(usize),
+ StartList,
+ EndList,
+}
+
+struct Packet<'a>(&'a str);
+
+impl Iterator for Packet<'_> {
+ type Item = PacketContents;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ loop {
+ if let Ok((i, _)) = tag::<_, _, (&str, nom::error::ErrorKind)>("[")(self.0) {
+ self.0 = i;
+ return Some(PacketContents::StartList);
+ } else if let Ok((i, _)) = tag::<_, _, (&str, nom::error::ErrorKind)>("]")(self.0) {
+ self.0 = i;
+ return Some(PacketContents::EndList);
+ } else if let Ok((i, x)) = u32::<_, (&str, nom::error::ErrorKind)>(self.0) {
+ self.0 = i;
+ return Some(PacketContents::Integer(x as usize));
+ } else if let Ok((i, _)) = tag::<_, _, (&str, nom::error::ErrorKind)>(",")(self.0) {
+ self.0 = i;
+ } else {
+ return None;
+ }
+ }
+ }
+}
diff --git a/2022/src/day14.html b/2022/src/day14.html
new file mode 100644
index 0000000..c441303
--- /dev/null
+++ b/2022/src/day14.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <link data-trunk rel="rust" data-wasm-opt="2" href="../Cargo.toml" data-bin="day14" />
+
+ <style>
+ html {
+ /* Remove touch delay: */
+ touch-action: manipulation;
+ }
+
+ html,
+ body {
+ overflow: hidden;
+ margin: 0 !important;
+ padding: 0 !important;
+ height: 100%;
+ width: 100%;
+ }
+
+ canvas {
+ margin-right: auto;
+ margin-left: auto;
+ display: block;
+ position: absolute;
+ top: 0%;
+ left: 50%;
+ transform: translate(-50%, 0%);
+ }
+ </style>
+</head>
+
+<body>
+ <canvas id="canvas"></canvas>
+</body>
+
+</html>
diff --git a/2022/src/day14.rs b/2022/src/day14.rs
new file mode 100644
index 0000000..903f919
--- /dev/null
+++ b/2022/src/day14.rs
@@ -0,0 +1,230 @@
+mod utils;
+use std::{
+ cmp::{max, min},
+ collections::HashSet,
+ ops::Add,
+ time::Duration,
+};
+
+use egui::{Color32, Rect, Sense, Stroke};
+use nom::{bytes::complete::tag, character::complete::u32, multi::separated_list0, IResult};
+
+fn main() {
+ console_error_panic_hook::set_once();
+
+ let input = include_str!("../fake_inputs/day14");
+
+ let options = eframe::WebOptions::default();
+ wasm_bindgen_futures::spawn_local(async {
+ eframe::start_web("canvas", options, Box::new(|_cc| Box::new(App::new(input))))
+ .await
+ .expect("unable to start eframe");
+ });
+}
+
+struct App {
+ structures: Vec<Structure>,
+ sand_grains: HashSet<Pos>,
+ speed: usize,
+ finished: bool,
+}
+
+impl App {
+ fn new(input: &str) -> Self {
+ let mut structures = separated_list0(tag("\n"), Structure::parse)(input)
+ .unwrap()
+ .1;
+ let floor_y = structures
+ .iter()
+ .map(|s| s.points.iter().map(|p| p.1).max().unwrap())
+ .max()
+ .unwrap()
+ + 2;
+ structures.push(Structure::new(vec![
+ Pos(isize::MIN, floor_y),
+ Pos(isize::MAX, floor_y),
+ ]));
+
+ App {
+ structures,
+ sand_grains: HashSet::new(),
+ speed: 0,
+ finished: false,
+ }
+ }
+
+ fn reset(&mut self) {
+ self.sand_grains.clear();
+ }
+
+ fn step(&mut self) {
+ let mut pos = Pos(500, 0);
+ if self.sand_grains.contains(&pos) {
+ self.finished = true;
+ return;
+ }
+ loop {
+ // TODO
+ pos = if !self.inhabited(pos + Pos(0, 1)) {
+ pos + Pos(0, 1)
+ } else if !self.inhabited(pos + Pos(-1, 1)) {
+ pos + Pos(-1, 1)
+ } else if !self.inhabited(pos + Pos(1, 1)) {
+ pos + Pos(1, 1)
+ } else {
+ self.sand_grains.insert(pos);
+ return;
+ };
+ }
+ }
+
+ fn inhabited(&self, pos: Pos) -> bool {
+ self.structures.iter().any(|s| s.contains(pos)) || self.sand_grains.contains(&pos)
+ }
+}
+
+#[derive(Debug)]
+struct Structure {
+ points: Vec<Pos>,
+ bbox_min: Pos,
+ bbox_max: Pos,
+}
+
+impl Structure {
+ fn new(points: Vec<Pos>) -> Self {
+ let bbox_min = points.iter().fold(Pos(isize::MAX, isize::MAX), |acc, pos| {
+ Pos(min(acc.0, pos.0), min(acc.1, pos.1))
+ });
+ let bbox_max = points.iter().fold(Pos(isize::MAX, isize::MAX), |acc, pos| {
+ Pos(max(acc.0, pos.0), max(acc.1, pos.1))
+ });
+
+ Structure {
+ points,
+ bbox_max,
+ bbox_min,
+ }
+ }
+ fn parse(i: &str) -> IResult<&str, Self> {
+ let (i, points) = separated_list0(tag(" -> "), Pos::parse)(i)?;
+
+ Ok((i, Structure::new(points)))
+ }
+
+ fn contains(&self, pos: Pos) -> bool {
+ if pos.0 < self.bbox_min.0
+ || pos.0 > self.bbox_max.0
+ || pos.1 < self.bbox_min.1
+ || pos.1 > self.bbox_max.1
+ {
+ return false;
+ }
+ for (a, b) in self.points.iter().zip(self.points.iter().skip(1)) {
+ if a.0 == b.0 {
+ if pos.0 == a.0 && pos.1 >= min(a.1, b.1) && pos.1 <= max(a.1, b.1) {
+ return true;
+ }
+ } else {
+ // a.1 == b.1
+ if pos.1 == a.1 && pos.0 >= min(a.0, b.0) && pos.0 <= max(a.0, b.0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+struct Pos(isize, isize);
+impl Pos {
+ fn parse(i: &str) -> IResult<&str, Self> {
+ let (i, x) = u32(i)?;
+ let (i, _) = tag(",")(i)?;
+ let (i, y) = u32(i)?;
+
+ Ok((i, Pos(x as _, y as _)))
+ }
+}
+impl From<Pos> for egui::Pos2 {
+ fn from(value: Pos) -> Self {
+ egui::Pos2 {
+ x: value.0 as _,
+ y: value.1 as _,
+ }
+ }
+}
+
+impl Add for Pos {
+ type Output = Pos;
+
+ fn add(self, rhs: Self) -> Self::Output {
+ Pos(self.0 + rhs.0, self.1 + rhs.1)
+ }
+}
+
+impl eframe::App for App {
+ fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
+ egui::SidePanel::right("instructions").show(ctx, |ui| {
+ egui::ScrollArea::vertical().show(ui, |ui| {
+ if ui.button("Step").clicked() && !self.finished {
+ self.step();
+ }
+ if ui.button("Reset").clicked() {
+ self.reset()
+ }
+ ui.label(format!(
+ "{} grains, finished: {}",
+ self.sand_grains.len(),
+ self.finished
+ ));
+ ui.add(egui::Slider::new(&mut self.speed, 0..=100).text("Speed"));
+ })
+ });
+
+ if self.speed > 0 {
+ for _ in 0..self.speed {
+ self.step();
+ }
+ ctx.request_repaint_after(Duration::from_millis(100))
+ }
+
+ egui::CentralPanel::default().show(ctx, |ui| {
+ let mut painter_size = ui.available_size_before_wrap();
+ if !painter_size.is_finite() {
+ painter_size = egui::vec2(500.0, 500.0);
+ }
+
+ const RANGE: f32 = 200.0;
+ const SHIFT: egui::Pos2 = egui::pos2(400.0, 5.0);
+ let (_, painter) = ui.allocate_painter(painter_size, Sense::hover());
+
+ let transform_point = |p: &Pos| -> egui::Pos2 {
+ egui::pos2(
+ ((p.0 as f32 - SHIFT.x) / RANGE) * painter_size.x,
+ ((p.1 as f32 + SHIFT.y) / RANGE) * painter_size.y,
+ )
+ };
+ for structure in self.structures.iter() {
+ for (a, b) in structure.points.iter().zip(structure.points.iter().skip(1)) {
+ painter.line_segment(
+ [transform_point(a), transform_point(b)],
+ Stroke::new(1.0, Color32::RED),
+ );
+ }
+ }
+
+ for grain in self.sand_grains.iter() {
+ painter.rect(
+ Rect {
+ min: transform_point(grain),
+ max: transform_point(&Pos(grain.0 + 1, grain.1 + 1)),
+ },
+ egui::Rounding::none(),
+ Color32::YELLOW,
+ Stroke::NONE,
+ )
+ }
+ });
+ }
+}
diff --git a/2022/src/utils.rs b/2022/src/utils.rs
new file mode 100644
index 0000000..8230c69
--- /dev/null
+++ b/2022/src/utils.rs
@@ -0,0 +1,59 @@
+#![allow(unused)]
+use std::{fs::File, io::Read, str::FromStr};
+
+pub fn read_input() -> String {
+ let mut args = std::env::args();
+
+ let mut file = File::open(
+ args.nth(1)
+ .expect("first argument should be input filename"),
+ )
+ .expect("could not open input");
+ let mut out = String::new();
+ file.read_to_string(&mut out)
+ .expect("could not read input file");
+
+ out
+}
+
+pub fn max_n<T: Ord>(vec: &mut Vec<T>, n: usize) -> &[T] {
+ top_n_by(vec, |a, b| a > b, n)
+}
+
+pub fn top_n_by<T, F: FnMut(&T, &T) -> bool>(vec: &mut Vec<T>, mut f: F, n: usize) -> &[T] {
+ for _ in 0..n {
+ for i in 0..vec.len() - 1 {
+ if f(&vec[i], &vec[i + 1]) {
+ vec.swap(i, i + 1);
+ }
+ }
+ }
+
+ &vec[vec.len() - n..]
+}
+
+pub fn iter_pair<T>(mut i: impl Iterator<Item = T>) -> (T, T) {
+ (i.next().unwrap(), i.next().unwrap())
+}
+
+pub fn iter_triple<T>(mut i: impl Iterator<Item = T>) -> (T, T, T) {
+ (i.next().unwrap(), i.next().unwrap(), i.next().unwrap())
+}
+
+#[inline(always)]
+pub fn parse_num<T: FromStr>(string: &str) -> (T, &str)
+where
+ <T as FromStr>::Err: std::fmt::Debug,
+{
+ let count = string
+ .chars()
+ .take_while(|x| x.is_numeric() || *x == '-')
+ .count();
+
+ (string[..count].parse().unwrap(), &string[count..])
+}
+
+#[inline(always)]
+pub fn parse_static<'a>(exp: &'static str, source: &'a str) -> &'a str {
+ &source[exp.len()..]
+}