From 610d0d2475d432dc22bf94ee39d7381b848236b8 Mon Sep 17 00:00:00 2001 From: Stanislav Nikolov Date: Fri, 5 Aug 2022 20:45:35 +0300 Subject: [PATCH] Initial commit --- .gitignore | 3 + Cargo.lock | 194 +++ Cargo.toml | 12 + LICENSE | 19 + src/lib.rs | 19 + src/main.rs | 81 + src/t01_sonar_sweep/mod.rs | 36 + src/t01_sonar_sweep/prod.in | 10 + src/t01_sonar_sweep/test.in | 2000 +++++++++++++++++++++++ src/t02_dive/mod.rs | 79 + src/t02_dive/prod.in | 6 + src/t02_dive/test.in | 1000 ++++++++++++ src/t03_binary_diagnostic/mod.rs | 83 + src/t03_binary_diagnostic/prod.in | 1000 ++++++++++++ src/t03_binary_diagnostic/test.in | 12 + src/t04_giant_squid/mod.rs | 170 ++ src/t04_giant_squid/prod.in | 601 +++++++ src/t04_giant_squid/test.in | 19 + src/t05_hydrothermal_venture/mod.rs | 143 ++ src/t05_hydrothermal_venture/prod.in | 500 ++++++ src/t05_hydrothermal_venture/test.in | 10 + src/t06_lanternfish/mod.rs | 95 ++ src/t06_lanternfish/prod.in | 1 + src/t06_lanternfish/test.in | 1 + src/t07_the_treachery_of_whales/mod.rs | 67 + src/t07_the_treachery_of_whales/prod.in | 1 + src/t07_the_treachery_of_whales/test.in | 1 + src/t08_seven_segment_search/mod.rs | 128 ++ src/t08_seven_segment_search/prod.in | 200 +++ src/t08_seven_segment_search/test.in | 10 + src/t09_smoke_basin/mod.rs | 143 ++ src/t09_smoke_basin/prod.in | 100 ++ src/t09_smoke_basin/test.in | 5 + src/t10_syntax_scoring/mod.rs | 96 ++ src/t10_syntax_scoring/prod.in | 110 ++ src/t10_syntax_scoring/test.in | 10 + src/t11_dumbo_octopus/mod.rs | 157 ++ src/t11_dumbo_octopus/prod.in | 10 + src/t11_dumbo_octopus/test.in | 10 + src/t12_passage_passing/mod.rs | 154 ++ src/t12_passage_passing/prod.in | 23 + src/t12_passage_passing/test.in | 18 + src/t13_transparent_origami/mod.rs | 153 ++ src/t13_transparent_origami/prod.in | 763 +++++++++ src/t13_transparent_origami/test.in | 21 + src/t14_extended_polymerisation/mod.rs | 136 ++ src/t14_extended_polymerisation/prod.in | 102 ++ src/t14_extended_polymerisation/test.in | 18 + src/t15_chiton/mod.rs | 157 ++ src/t15_chiton/prod.in | 100 ++ src/t15_chiton/test.in | 10 + src/t16_packet_decoder/mod.rs | 279 ++++ src/t16_packet_decoder/prod.in | 1 + src/t16_packet_decoder/test.in | 10 + src/t16_packet_decoder/test1.in | 4 + src/t16_packet_decoder/test2.in | 8 + src/t17_trick_shot/mod.rs | 116 ++ src/t17_trick_shot/prod.in | 1 + src/t17_trick_shot/test.in | 1 + src/t18_snailfish/mod.rs | 270 +++ src/t18_snailfish/prod.in | 100 ++ src/t18_snailfish/test.in | 10 + src/types/mod.rs | 36 + 63 files changed, 9633 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 LICENSE create mode 100644 src/lib.rs create mode 100644 src/main.rs create mode 100644 src/t01_sonar_sweep/mod.rs create mode 100644 src/t01_sonar_sweep/prod.in create mode 100644 src/t01_sonar_sweep/test.in create mode 100644 src/t02_dive/mod.rs create mode 100644 src/t02_dive/prod.in create mode 100644 src/t02_dive/test.in create mode 100644 src/t03_binary_diagnostic/mod.rs create mode 100644 src/t03_binary_diagnostic/prod.in create mode 100644 src/t03_binary_diagnostic/test.in create mode 100644 src/t04_giant_squid/mod.rs create mode 100644 src/t04_giant_squid/prod.in create mode 100644 src/t04_giant_squid/test.in create mode 100644 src/t05_hydrothermal_venture/mod.rs create mode 100644 src/t05_hydrothermal_venture/prod.in create mode 100644 src/t05_hydrothermal_venture/test.in create mode 100644 src/t06_lanternfish/mod.rs create mode 100644 src/t06_lanternfish/prod.in create mode 100644 src/t06_lanternfish/test.in create mode 100644 src/t07_the_treachery_of_whales/mod.rs create mode 100644 src/t07_the_treachery_of_whales/prod.in create mode 100644 src/t07_the_treachery_of_whales/test.in create mode 100644 src/t08_seven_segment_search/mod.rs create mode 100644 src/t08_seven_segment_search/prod.in create mode 100644 src/t08_seven_segment_search/test.in create mode 100644 src/t09_smoke_basin/mod.rs create mode 100644 src/t09_smoke_basin/prod.in create mode 100644 src/t09_smoke_basin/test.in create mode 100644 src/t10_syntax_scoring/mod.rs create mode 100644 src/t10_syntax_scoring/prod.in create mode 100644 src/t10_syntax_scoring/test.in create mode 100644 src/t11_dumbo_octopus/mod.rs create mode 100644 src/t11_dumbo_octopus/prod.in create mode 100644 src/t11_dumbo_octopus/test.in create mode 100644 src/t12_passage_passing/mod.rs create mode 100644 src/t12_passage_passing/prod.in create mode 100644 src/t12_passage_passing/test.in create mode 100644 src/t13_transparent_origami/mod.rs create mode 100644 src/t13_transparent_origami/prod.in create mode 100644 src/t13_transparent_origami/test.in create mode 100644 src/t14_extended_polymerisation/mod.rs create mode 100644 src/t14_extended_polymerisation/prod.in create mode 100644 src/t14_extended_polymerisation/test.in create mode 100644 src/t15_chiton/mod.rs create mode 100644 src/t15_chiton/prod.in create mode 100644 src/t15_chiton/test.in create mode 100644 src/t16_packet_decoder/mod.rs create mode 100644 src/t16_packet_decoder/prod.in create mode 100644 src/t16_packet_decoder/test.in create mode 100644 src/t16_packet_decoder/test1.in create mode 100644 src/t16_packet_decoder/test2.in create mode 100644 src/t17_trick_shot/mod.rs create mode 100644 src/t17_trick_shot/prod.in create mode 100644 src/t17_trick_shot/test.in create mode 100644 src/t18_snailfish/mod.rs create mode 100644 src/t18_snailfish/prod.in create mode 100644 src/t18_snailfish/test.in create mode 100644 src/types/mod.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c94da9d --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +/.idea/ +/.vscode/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..5938d6b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,194 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" +dependencies = [ + "memchr", +] + +[[package]] +name = "aoc-2021" +version = "0.1.0" +dependencies = [ + "bitvec", + "regex", + "serde", + "serde_yaml", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "bitvec" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "funty" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "proc-macro2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f84e92c0f7c9d58328b85a78557813e4bd845130db68d7184635344399423b1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "serde" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9875c23cf305cd1fd7eb77234cbb705f21ea6a72c637a5c6db5fe4b8e7f008" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc0db5cb2556c0e558887d9bbdcf6ac4471e83ff66cf696e5419024d1606276" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_yaml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "syn" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "wyz" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" +dependencies = [ + "tap", +] + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..aec5019 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "aoc-2021" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bitvec = "0.22.3" +serde = { version = "1.0", features = ["derive"] } +serde_yaml = "0.8" +regex = "1" \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..9093283 --- /dev/null +++ b/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2022 Stanislav Nikolov + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..cb311d5 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,19 @@ +pub mod t01_sonar_sweep; +pub mod t02_dive; +pub mod t03_binary_diagnostic; +pub mod t04_giant_squid; +pub mod t05_hydrothermal_venture; +pub mod t06_lanternfish; +pub mod t07_the_treachery_of_whales; +pub mod t08_seven_segment_search; +pub mod t09_smoke_basin; +pub mod t10_syntax_scoring; +pub mod t11_dumbo_octopus; +pub mod t12_passage_passing; +pub mod t13_transparent_origami; +pub mod t14_extended_polymerisation; +pub mod t15_chiton; +pub mod t16_packet_decoder; +pub mod t17_trick_shot; +pub mod t18_snailfish; +pub mod types; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..c2d9c55 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,81 @@ +use aoc_2021::{ + t01_sonar_sweep::{sonar_sweep_1, sonar_sweep_2}, + t02_dive::{dive_1, dive_2}, + t03_binary_diagnostic::{binary_diagnostic_1, binary_diagnostic_2}, + t04_giant_squid::{giant_squid_1, giant_squid_2}, + t05_hydrothermal_venture::{hydrothermal_venture_1, hydrothermal_venture_2}, + t06_lanternfish::{lanternfish_1, lanternfish_2}, + t07_the_treachery_of_whales::{the_treachery_of_whales_1, the_treachery_of_whales_2}, + t08_seven_segment_search::{seven_segment_search_1, seven_segment_search_2}, + t09_smoke_basin::{smoke_basin_1, smoke_basin_2}, + t10_syntax_scoring::{syntax_scoring_1, syntax_scoring_2}, + t11_dumbo_octopus::{dumbo_octopus_1, dumbo_octopus_2}, + t12_passage_passing::{passage_passing_1, passage_passing_2}, + t13_transparent_origami::{transparent_origami_1, transparent_origami_2}, + t14_extended_polymerisation::{extended_polymerisation_1, extended_polymerisation_2}, + t15_chiton::{chiton_1, chiton_2}, + t16_packet_decoder::{packet_decoder_1, packet_decoder_2}, + t17_trick_shot::{trick_shot_1, trick_shot_2}, + t18_snailfish::{snailfish_1, snailfish_2}, +}; +use std::env; + +fn main() { + let mut args = env::args(); + args.next(); + let task = args + .next() + .unwrap_or_else(|| panic!("Task not given!")) + .parse() + .unwrap(); + let subtask = args + .next() + .unwrap_or_else(|| panic!("Subtask not given!")) + .parse() + .unwrap(); + let test_mode = args + .next() + .unwrap_or_else(|| panic!("Test mode not given!")) + .parse() + .unwrap(); + + match (task, subtask) { + (1, 1) => sonar_sweep_1(test_mode), + (1, 2) => sonar_sweep_2(test_mode), + (2, 1) => dive_1(test_mode), + (2, 2) => dive_2(test_mode), + (3, 1) => binary_diagnostic_1(test_mode), + (3, 2) => binary_diagnostic_2(test_mode), + (4, 1) => giant_squid_1(test_mode), + (4, 2) => giant_squid_2(test_mode), + (5, 1) => hydrothermal_venture_1(test_mode), + (5, 2) => hydrothermal_venture_2(test_mode), + (6, 1) => lanternfish_1(test_mode), + (6, 2) => lanternfish_2(test_mode), + (7, 1) => the_treachery_of_whales_1(test_mode), + (7, 2) => the_treachery_of_whales_2(test_mode), + (8, 1) => seven_segment_search_1(test_mode), + (8, 2) => seven_segment_search_2(test_mode), + (9, 1) => smoke_basin_1(test_mode), + (9, 2) => smoke_basin_2(test_mode), + (10, 1) => syntax_scoring_1(test_mode), + (10, 2) => syntax_scoring_2(test_mode), + (11, 1) => dumbo_octopus_1(test_mode), + (11, 2) => dumbo_octopus_2(test_mode), + (12, 1) => passage_passing_1(test_mode), + (12, 2) => passage_passing_2(test_mode), + (13, 1) => transparent_origami_1(test_mode), + (13, 2) => transparent_origami_2(test_mode), + (14, 1) => extended_polymerisation_1(test_mode), + (14, 2) => extended_polymerisation_2(test_mode), + (15, 1) => chiton_1(test_mode), + (15, 2) => chiton_2(test_mode), + (16, 1) => packet_decoder_1(test_mode), + (16, 2) => packet_decoder_2(test_mode), + (17, 1) => trick_shot_1(test_mode), + (17, 2) => trick_shot_2(test_mode), + (18, 1) => snailfish_1(test_mode), + (18, 2) => snailfish_2(test_mode), + _ => panic!("Unknown task combination!"), + } +} diff --git a/src/t01_sonar_sweep/mod.rs b/src/t01_sonar_sweep/mod.rs new file mode 100644 index 0000000..e931ec3 --- /dev/null +++ b/src/t01_sonar_sweep/mod.rs @@ -0,0 +1,36 @@ +use std::io::{BufRead, BufReader}; + +use crate::types::TestMode; + +fn parse_input(test_mode: TestMode) -> Vec { + let f = test_mode.input_file(file!()); + BufReader::new(f) + .lines() + .map(|line| line.unwrap().parse().unwrap()) + .collect() +} + +pub fn sonar_sweep_1(test_mode: TestMode) { + let nums = parse_input(test_mode); + + let mut count = 0; + for i in 1..nums.len() { + if nums[i] > nums[i - 1] { + count += 1; + } + } + println!("{}", count) +} + +pub fn sonar_sweep_2(test_mode: TestMode) { + let nums = parse_input(test_mode); + + const WINDOW: usize = 3; + let mut count = 0u64; + for i in WINDOW..nums.len() { + if nums[i - WINDOW + 1..i + 1].iter().sum::() > nums[i - WINDOW..i].iter().sum() { + count += 1; + } + } + println!("{}", count) +} diff --git a/src/t01_sonar_sweep/prod.in b/src/t01_sonar_sweep/prod.in new file mode 100644 index 0000000..167e291 --- /dev/null +++ b/src/t01_sonar_sweep/prod.in @@ -0,0 +1,10 @@ +199 +200 +208 +210 +200 +207 +240 +269 +260 +263 diff --git a/src/t01_sonar_sweep/test.in b/src/t01_sonar_sweep/test.in new file mode 100644 index 0000000..1903500 --- /dev/null +++ b/src/t01_sonar_sweep/test.in @@ -0,0 +1,2000 @@ +178 +205 +212 +210 +215 +220 +223 +224 +230 +232 +235 +225 +226 +227 +238 +248 +249 +251 +252 +261 +273 +283 +284 +286 +296 +297 +303 +317 +320 +333 +370 +339 +342 +345 +325 +323 +334 +325 +326 +327 +333 +329 +337 +340 +363 +353 +341 +344 +345 +364 +356 +357 +355 +357 +358 +360 +372 +373 +377 +379 +354 +349 +355 +356 +361 +363 +366 +371 +354 +356 +350 +360 +377 +369 +373 +376 +375 +376 +360 +362 +378 +381 +399 +405 +428 +430 +435 +458 +459 +465 +466 +488 +499 +509 +514 +524 +531 +552 +553 +557 +589 +611 +628 +633 +635 +639 +641 +643 +645 +647 +649 +651 +656 +652 +657 +655 +658 +664 +665 +671 +681 +693 +705 +708 +704 +700 +702 +703 +705 +706 +709 +721 +726 +724 +727 +734 +735 +738 +739 +759 +761 +763 +766 +769 +768 +779 +782 +786 +787 +809 +820 +821 +822 +823 +831 +835 +842 +843 +849 +851 +852 +856 +852 +856 +857 +859 +871 +875 +850 +865 +875 +895 +902 +903 +905 +910 +911 +922 +936 +937 +938 +939 +948 +955 +954 +955 +958 +965 +966 +972 +979 +975 +981 +982 +978 +979 +991 +1009 +1010 +1009 +988 +985 +989 +990 +999 +1012 +1013 +1015 +1018 +1021 +1038 +1036 +1051 +1059 +1076 +1077 +1081 +1082 +1111 +1115 +1114 +1127 +1129 +1153 +1156 +1157 +1163 +1164 +1168 +1174 +1180 +1187 +1188 +1203 +1207 +1182 +1183 +1180 +1181 +1182 +1180 +1190 +1189 +1186 +1187 +1191 +1207 +1231 +1246 +1235 +1240 +1242 +1244 +1241 +1245 +1248 +1251 +1252 +1260 +1270 +1273 +1274 +1270 +1285 +1281 +1285 +1306 +1305 +1304 +1313 +1318 +1352 +1371 +1380 +1379 +1380 +1382 +1390 +1394 +1395 +1408 +1406 +1407 +1413 +1425 +1446 +1447 +1448 +1450 +1473 +1482 +1490 +1488 +1479 +1484 +1502 +1507 +1508 +1509 +1511 +1512 +1517 +1520 +1532 +1536 +1538 +1537 +1538 +1539 +1571 +1574 +1542 +1548 +1549 +1550 +1551 +1549 +1551 +1563 +1565 +1558 +1559 +1589 +1590 +1591 +1592 +1593 +1595 +1573 +1582 +1608 +1619 +1625 +1627 +1638 +1666 +1665 +1685 +1687 +1690 +1700 +1707 +1714 +1720 +1729 +1765 +1767 +1768 +1752 +1749 +1764 +1765 +1774 +1775 +1777 +1778 +1787 +1788 +1789 +1793 +1794 +1795 +1800 +1802 +1808 +1809 +1803 +1804 +1815 +1816 +1823 +1822 +1828 +1830 +1835 +1837 +1846 +1863 +1865 +1869 +1872 +1873 +1876 +1893 +1894 +1901 +1903 +1904 +1900 +1911 +1913 +1914 +1916 +1923 +1946 +1949 +1951 +1964 +1965 +1967 +1978 +2001 +2004 +2016 +2021 +2023 +2026 +2027 +2029 +2027 +2028 +2031 +2041 +2033 +2041 +2042 +2034 +2040 +2043 +2045 +2058 +2056 +2061 +2054 +2064 +2063 +2068 +2069 +2073 +2076 +2077 +2075 +2077 +2066 +2067 +2071 +2072 +2073 +2077 +2081 +2082 +2090 +2086 +2118 +2122 +2145 +2151 +2176 +2177 +2179 +2189 +2205 +2218 +2223 +2248 +2249 +2250 +2254 +2247 +2264 +2265 +2271 +2272 +2290 +2292 +2326 +2328 +2327 +2328 +2335 +2338 +2339 +2347 +2348 +2349 +2356 +2353 +2362 +2363 +2367 +2369 +2377 +2384 +2395 +2397 +2408 +2409 +2410 +2409 +2411 +2407 +2369 +2372 +2376 +2378 +2377 +2382 +2383 +2384 +2388 +2390 +2395 +2393 +2425 +2418 +2423 +2446 +2452 +2464 +2469 +2473 +2474 +2472 +2471 +2473 +2475 +2476 +2477 +2479 +2494 +2500 +2501 +2502 +2503 +2534 +2542 +2541 +2542 +2560 +2563 +2570 +2582 +2577 +2581 +2579 +2578 +2586 +2598 +2599 +2602 +2606 +2616 +2618 +2620 +2622 +2592 +2595 +2596 +2629 +2624 +2626 +2634 +2635 +2654 +2655 +2658 +2630 +2650 +2661 +2662 +2663 +2665 +2686 +2687 +2690 +2685 +2696 +2697 +2704 +2707 +2709 +2710 +2711 +2708 +2712 +2714 +2717 +2721 +2719 +2724 +2729 +2730 +2761 +2770 +2772 +2773 +2791 +2802 +2803 +2804 +2798 +2800 +2803 +2799 +2796 +2801 +2804 +2805 +2814 +2817 +2801 +2806 +2807 +2811 +2829 +2832 +2820 +2821 +2858 +2860 +2863 +2885 +2889 +2891 +2892 +2902 +2913 +2916 +2917 +2918 +2919 +2918 +2927 +2928 +2932 +2934 +2951 +2953 +2954 +2978 +2981 +3004 +2999 +3018 +3017 +3018 +3019 +3020 +3018 +3030 +3040 +3042 +3046 +3072 +3087 +3102 +3141 +3142 +3163 +3166 +3179 +3190 +3191 +3194 +3197 +3203 +3220 +3224 +3232 +3236 +3255 +3257 +3261 +3279 +3278 +3279 +3284 +3310 +3330 +3332 +3334 +3335 +3365 +3380 +3381 +3386 +3373 +3378 +3398 +3418 +3422 +3425 +3427 +3435 +3442 +3446 +3447 +3446 +3448 +3444 +3445 +3447 +3448 +3449 +3453 +3466 +3467 +3476 +3479 +3482 +3483 +3486 +3500 +3499 +3501 +3492 +3490 +3491 +3493 +3499 +3501 +3505 +3490 +3499 +3500 +3513 +3514 +3535 +3550 +3548 +3549 +3546 +3547 +3553 +3554 +3574 +3575 +3582 +3583 +3582 +3585 +3587 +3600 +3601 +3605 +3610 +3609 +3617 +3598 +3599 +3601 +3602 +3585 +3598 +3615 +3617 +3623 +3628 +3631 +3633 +3636 +3634 +3635 +3630 +3617 +3650 +3652 +3655 +3660 +3669 +3685 +3686 +3674 +3684 +3685 +3686 +3694 +3693 +3694 +3699 +3708 +3709 +3722 +3720 +3724 +3745 +3740 +3744 +3762 +3761 +3783 +3784 +3785 +3786 +3781 +3792 +3797 +3812 +3814 +3813 +3788 +3796 +3795 +3802 +3805 +3815 +3816 +3817 +3818 +3819 +3822 +3829 +3833 +3836 +3847 +3850 +3851 +3852 +3850 +3851 +3870 +3871 +3873 +3871 +3874 +3879 +3888 +3894 +3900 +3904 +3907 +3909 +3912 +3913 +3921 +3894 +3896 +3897 +3898 +3909 +3914 +3915 +3913 +3941 +3945 +3946 +3947 +3948 +3954 +3955 +3980 +3983 +3985 +3986 +3993 +3988 +3992 +3997 +4002 +4014 +4022 +4039 +4044 +4043 +4040 +4042 +4053 +4055 +4066 +4049 +4070 +4073 +4081 +4084 +4085 +4094 +4107 +4098 +4107 +4121 +4140 +4143 +4144 +4145 +4156 +4157 +4174 +4177 +4163 +4138 +4143 +4132 +4118 +4119 +4120 +4134 +4137 +4134 +4168 +4186 +4190 +4192 +4202 +4206 +4214 +4216 +4217 +4213 +4217 +4216 +4238 +4237 +4245 +4251 +4255 +4261 +4276 +4278 +4282 +4287 +4290 +4283 +4277 +4287 +4290 +4291 +4292 +4299 +4302 +4325 +4326 +4344 +4339 +4341 +4343 +4346 +4345 +4346 +4348 +4349 +4350 +4365 +4364 +4365 +4367 +4369 +4373 +4377 +4375 +4374 +4400 +4407 +4409 +4410 +4413 +4395 +4400 +4401 +4404 +4413 +4408 +4403 +4405 +4412 +4417 +4449 +4469 +4486 +4492 +4507 +4513 +4516 +4517 +4531 +4540 +4551 +4561 +4566 +4568 +4570 +4571 +4564 +4572 +4573 +4575 +4576 +4605 +4612 +4602 +4603 +4608 +4610 +4617 +4618 +4620 +4621 +4622 +4626 +4639 +4640 +4661 +4660 +4658 +4665 +4664 +4685 +4686 +4691 +4694 +4679 +4684 +4708 +4709 +4704 +4721 +4725 +4727 +4730 +4731 +4733 +4741 +4757 +4759 +4779 +4786 +4812 +4818 +4820 +4836 +4838 +4839 +4840 +4844 +4845 +4851 +4852 +4858 +4854 +4860 +4887 +4853 +4857 +4867 +4881 +4883 +4868 +4869 +4881 +4862 +4858 +4860 +4861 +4862 +4867 +4872 +4876 +4892 +4893 +4894 +4895 +4897 +4915 +4924 +4927 +4929 +4937 +4938 +4940 +4943 +4950 +4957 +4985 +4984 +4989 +4978 +4983 +4984 +4985 +4978 +4981 +4983 +4986 +5012 +5013 +5014 +5029 +5031 +5033 +5034 +5032 +5033 +5035 +5037 +5047 +5049 +5045 +5048 +5053 +5055 +5057 +5071 +5072 +5070 +5098 +5091 +5086 +5072 +5074 +5076 +5077 +5078 +5077 +5078 +5082 +5085 +5107 +5135 +5140 +5142 +5143 +5146 +5127 +5130 +5133 +5144 +5148 +5150 +5151 +5158 +5161 +5165 +5166 +5172 +5179 +5180 +5181 +5179 +5181 +5211 +5212 +5217 +5215 +5216 +5214 +5234 +5236 +5239 +5240 +5253 +5263 +5276 +5293 +5305 +5308 +5313 +5319 +5324 +5325 +5328 +5335 +5337 +5365 +5352 +5350 +5352 +5354 +5355 +5369 +5375 +5382 +5387 +5386 +5393 +5399 +5403 +5404 +5406 +5418 +5423 +5433 +5434 +5435 +5436 +5437 +5438 +5457 +5454 +5459 +5460 +5461 +5463 +5478 +5490 +5503 +5512 +5510 +5517 +5522 +5525 +5537 +5553 +5563 +5553 +5557 +5563 +5565 +5573 +5605 +5579 +5580 +5581 +5593 +5596 +5621 +5612 +5616 +5621 +5625 +5633 +5637 +5647 +5649 +5661 +5666 +5657 +5661 +5664 +5667 +5679 +5698 +5699 +5698 +5706 +5710 +5712 +5716 +5692 +5707 +5709 +5710 +5711 +5712 +5713 +5716 +5730 +5731 +5732 +5733 +5736 +5735 +5737 +5738 +5740 +5741 +5742 +5741 +5748 +5751 +5759 +5761 +5766 +5769 +5781 +5800 +5801 +5811 +5813 +5814 +5813 +5814 +5821 +5822 +5821 +5825 +5844 +5846 +5858 +5868 +5875 +5886 +5889 +5890 +5896 +5902 +5905 +5926 +5925 +5923 +5897 +5898 +5924 +5926 +5943 +5945 +5956 +5969 +5980 +5989 +5998 +6027 +6028 +6038 +6039 +6024 +6026 +6041 +6058 +6059 +6063 +6064 +6068 +6075 +6081 +6078 +6059 +6060 +6088 +6099 +6104 +6103 +6104 +6099 +6100 +6117 +6113 +6120 +6121 +6126 +6157 +6171 +6172 +6177 +6178 +6172 +6173 +6174 +6179 +6181 +6191 +6192 +6197 +6210 +6209 +6204 +6205 +6206 +6215 +6229 +6232 +6231 +6241 +6262 +6263 +6269 +6270 +6271 +6278 +6285 +6287 +6288 +6289 +6294 +6298 +6299 +6312 +6317 +6323 +6317 +6318 +6317 +6319 +6323 +6322 +6321 +6325 +6329 +6348 +6371 +6368 +6355 +6332 +6333 +6342 +6347 +6351 +6359 +6346 +6334 +6331 +6334 +6355 +6364 +6365 +6386 +6391 +6396 +6370 +6393 +6395 +6396 +6399 +6403 +6411 +6410 +6417 +6428 +6429 +6450 +6426 +6428 +6429 +6436 +6437 +6438 +6464 +6471 +6475 +6476 +6483 +6489 +6490 +6494 +6490 +6500 +6501 +6508 +6516 +6519 +6520 +6521 +6524 +6534 +6541 +6547 +6549 +6555 +6556 +6566 +6568 +6572 +6586 +6587 +6590 +6600 +6605 +6607 +6609 +6606 +6605 +6606 +6616 +6630 +6640 +6625 +6624 +6608 +6618 +6623 +6627 +6625 +6646 +6654 +6655 +6656 +6659 +6655 +6656 +6663 +6658 +6659 +6657 +6666 +6667 +6670 +6671 +6682 +6662 +6663 +6664 +6682 +6692 +6690 +6704 +6705 +6712 +6715 +6719 +6726 +6727 +6730 +6728 +6748 +6759 +6772 +6773 +6771 +6773 +6775 +6766 +6772 +6784 +6787 +6789 +6792 +6795 +6797 +6799 +6789 +6790 +6798 +6800 +6804 +6803 +6804 +6797 +6808 +6814 +6816 +6819 +6822 +6833 +6829 +6830 +6837 +6839 +6840 +6842 +6843 +6849 +6851 +6853 +6837 +6843 +6844 +6849 +6856 +6858 +6859 +6857 +6860 +6862 +6864 +6863 +6865 +6870 +6869 +6849 +6850 +6855 +6860 +6856 +6857 +6867 +6872 +6874 +6876 +6866 +6868 +6877 +6881 +6882 +6883 +6893 +6895 +6896 +6897 +6910 +6903 +6904 +6909 +6910 +6932 +6930 +6932 +6944 +6946 +6966 +6971 +6972 +6973 +7000 +7009 +7011 +7010 +7021 +7018 +7017 +7014 +7018 +7017 +7020 +7024 +7027 +7028 +7030 +7031 +7037 +7047 +7056 +7059 +7061 +7047 +7074 +7077 +7078 +7087 +7116 +7117 +7127 +7125 +7101 +7106 +7112 +7113 +7125 +7126 +7129 +7130 +7133 +7137 +7138 +7156 +7158 +7159 +7158 +7159 +7160 +7161 +7163 +7169 +7172 +7195 +7196 +7197 +7199 +7206 +7218 +7219 +7222 +7227 +7239 +7252 +7256 +7257 +7249 +7250 +7256 +7263 +7267 +7268 +7279 +7287 +7290 +7269 +7268 +7274 +7278 +7274 +7282 +7294 +7295 +7300 +7299 +7305 +7297 +7300 +7301 +7328 +7360 +7376 +7365 +7359 +7362 +7364 +7373 +7390 +7398 +7399 +7407 +7402 +7401 +7409 +7411 +7416 +7408 +7405 +7408 +7410 +7414 +7415 +7418 +7422 +7428 +7441 +7442 +7445 +7454 +7458 +7460 +7458 +7467 +7470 +7501 +7500 +7501 +7509 +7521 +7522 +7523 +7537 +7540 +7541 +7551 +7553 +7554 +7564 +7565 +7567 +7563 +7564 +7580 +7603 +7604 +7613 +7614 +7616 +7627 +7621 +7630 +7631 +7641 +7642 +7652 +7647 +7646 +7666 +7690 +7693 +7691 +7693 +7699 +7705 +7682 +7701 +7703 +7702 +7710 +7709 +7711 +7714 +7713 +7718 +7727 +7753 +7756 +7764 +7782 +7788 +7787 +7793 +7794 +7795 +7767 +7771 +7776 +7787 +7791 +7789 +7790 +7805 +7804 +7806 +7814 +7815 +7816 +7830 +7832 +7831 +7830 +7859 +7878 +7894 +7896 +7906 +7927 +7928 +7929 +7924 +7929 +7933 +7934 +7935 +7946 +7948 +7950 +7951 +7973 +7975 +7976 +7975 +7974 +7982 +7964 +7977 +7967 +7975 +7973 +7981 +7999 +8010 +8017 +8020 +8021 +8030 +8055 +8061 +8069 +8071 +8072 +8073 +8082 +8083 +8096 +8116 +8122 +8133 +8134 +8128 +8136 +8115 +8122 +8120 +8126 +8127 +8134 +8157 +8158 +8160 +8164 +8165 +8179 +8180 +8186 +8195 +8205 +8200 +8197 +8198 +8199 +8187 +8193 +8202 +8214 +8225 +8224 +8245 +8235 +8243 +8244 +8249 +8250 +8259 +8264 +8265 +8273 +8269 +8273 +8276 +8278 +8283 +8284 +8280 +8294 +8295 +8296 +8299 +8300 +8301 +8302 +8303 +8305 +8306 +8310 +8324 +8326 +8328 +8335 +8342 +8344 +8338 +8341 +8342 +8348 +8349 +8351 +8347 +8355 +8356 +8357 +8361 +8364 +8365 +8372 +8377 +8392 +8388 +8387 +8388 +8394 +8396 +8407 +8411 +8426 +8427 +8426 +8427 +8430 +8432 +8435 +8436 +8437 +8433 +8428 +8430 +8431 +8441 +8442 +8444 +8441 +8460 +8464 +8466 +8459 +8481 +8486 +8489 +8462 +8461 +8478 +8484 +8483 +8487 +8488 +8489 +8513 +8517 +8518 +8520 +8534 +8537 +8538 +8542 +8546 +8559 +8564 +8569 +8582 +8580 +8582 +8581 +8586 +8599 +8605 +8606 +8593 +8595 +8600 +8603 +8608 +8624 +8632 +8635 +8640 +8641 +8642 +8643 +8662 +8664 +8674 +8684 +8685 +8684 +8692 +8696 +8701 +8710 +8691 +8673 +8674 +8677 +8675 +8674 +8669 +8671 +8670 +8675 +8678 +8693 +8697 +8701 +8702 +8705 +8713 +8715 +8720 +8734 +8741 +8750 +8753 +8755 diff --git a/src/t02_dive/mod.rs b/src/t02_dive/mod.rs new file mode 100644 index 0000000..b17a288 --- /dev/null +++ b/src/t02_dive/mod.rs @@ -0,0 +1,79 @@ +use std::{ + io::{BufRead, BufReader}, + str::FromStr, +}; + +use crate::types::TestMode; + +struct DirectionChange { + direction: Direction, + units: u32, +} + +enum Direction { + Forward, + Up, + Down, +} + +impl FromStr for Direction { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "forward" => Ok(Direction::Forward), + "up" => Ok(Direction::Up), + "down" => Ok(Direction::Down), + _ => Err(format!("Invalid value: {:?}", s)), + } + } +} + +fn parse_input(test_mode: TestMode) -> Vec { + let f = test_mode.input_file(file!()); + BufReader::new(f) + .lines() + .map(|line| { + let line = line.unwrap(); + let mut split = line.split_ascii_whitespace(); + DirectionChange { + direction: split.next().unwrap().parse().unwrap(), + units: split.next().unwrap().parse().unwrap(), + } + }) + .collect() +} + +pub fn dive_1(test_mode: TestMode) { + let directions = parse_input(test_mode); + + let mut x = 0; + let mut y = 0; + for d in directions { + match d.direction { + Direction::Forward => x += d.units, + Direction::Up => y -= d.units, + Direction::Down => y += d.units, + } + } + println!("({},{}) -> {}", x, y, x * y) +} + +pub fn dive_2(test_mode: TestMode) { + let directions = parse_input(test_mode); + + let mut x = 0; + let mut y = 0; + let mut aim = 0; + for d in directions { + match d.direction { + Direction::Forward => { + x += d.units; + y += d.units * aim; + } + Direction::Up => aim -= d.units, + Direction::Down => aim += d.units, + } + } + println!("({},{}) -> {}", x, y, x * y) +} diff --git a/src/t02_dive/prod.in b/src/t02_dive/prod.in new file mode 100644 index 0000000..b7172ac --- /dev/null +++ b/src/t02_dive/prod.in @@ -0,0 +1,6 @@ +forward 5 +down 5 +forward 8 +up 3 +down 8 +forward 2 diff --git a/src/t02_dive/test.in b/src/t02_dive/test.in new file mode 100644 index 0000000..227deb8 --- /dev/null +++ b/src/t02_dive/test.in @@ -0,0 +1,1000 @@ +forward 8 +down 9 +up 4 +down 8 +down 3 +down 3 +down 2 +forward 1 +forward 4 +down 5 +up 7 +forward 1 +down 1 +down 6 +down 9 +down 5 +forward 5 +forward 6 +forward 4 +down 2 +down 8 +forward 3 +down 5 +forward 6 +up 7 +up 2 +forward 2 +forward 4 +forward 1 +up 8 +up 9 +down 8 +up 8 +up 6 +up 2 +down 7 +up 3 +forward 8 +forward 5 +down 8 +down 8 +forward 5 +down 3 +down 4 +down 5 +down 2 +up 7 +down 1 +forward 9 +forward 9 +up 6 +down 5 +up 1 +down 8 +up 1 +forward 2 +down 4 +down 5 +down 2 +up 7 +forward 9 +up 8 +down 3 +up 6 +down 2 +up 2 +forward 3 +up 1 +up 1 +forward 9 +down 3 +down 5 +up 7 +down 1 +up 5 +up 5 +up 7 +down 9 +down 3 +up 3 +forward 9 +forward 7 +up 9 +down 3 +down 2 +up 8 +forward 5 +forward 9 +down 5 +down 2 +down 9 +down 6 +down 6 +up 3 +forward 3 +up 6 +forward 9 +down 3 +down 2 +forward 6 +down 7 +down 2 +down 8 +forward 2 +forward 8 +forward 4 +forward 1 +up 6 +forward 2 +forward 8 +forward 5 +forward 4 +up 1 +down 8 +up 3 +forward 8 +forward 4 +up 6 +down 2 +forward 6 +forward 9 +down 2 +up 3 +forward 8 +down 6 +up 4 +down 7 +up 3 +forward 4 +down 8 +forward 5 +forward 1 +down 3 +forward 1 +forward 8 +down 3 +forward 4 +forward 2 +up 7 +forward 6 +forward 8 +forward 6 +down 5 +down 2 +down 8 +down 2 +down 9 +down 5 +down 3 +down 8 +up 1 +forward 1 +up 5 +up 1 +up 6 +up 3 +up 2 +forward 5 +forward 6 +down 4 +up 3 +up 9 +down 1 +forward 1 +forward 6 +down 9 +forward 5 +forward 3 +forward 2 +down 7 +down 5 +down 8 +forward 9 +forward 4 +down 2 +up 9 +down 1 +forward 5 +forward 1 +forward 9 +down 8 +forward 5 +down 8 +forward 3 +up 4 +down 7 +down 9 +forward 3 +forward 7 +down 9 +up 5 +up 7 +forward 8 +down 3 +down 9 +down 1 +forward 3 +down 1 +up 9 +forward 6 +down 9 +forward 1 +forward 5 +down 6 +up 7 +forward 9 +down 9 +forward 6 +down 3 +up 6 +up 2 +up 1 +up 9 +down 9 +forward 4 +forward 6 +up 7 +forward 2 +down 5 +forward 7 +down 5 +forward 4 +down 8 +up 3 +down 1 +forward 5 +down 5 +up 6 +down 6 +forward 4 +down 8 +down 6 +down 7 +down 9 +down 4 +forward 5 +down 8 +down 7 +forward 3 +forward 5 +up 8 +down 4 +down 1 +up 6 +up 9 +down 2 +down 2 +up 1 +up 7 +forward 1 +down 1 +down 4 +down 8 +forward 1 +forward 3 +down 8 +up 9 +forward 1 +down 6 +forward 3 +down 9 +down 2 +up 8 +forward 5 +up 1 +forward 9 +down 4 +forward 3 +up 6 +up 4 +down 9 +down 8 +down 3 +forward 6 +forward 6 +down 1 +down 2 +down 2 +down 2 +up 7 +down 2 +forward 9 +down 3 +up 5 +forward 9 +up 5 +forward 1 +down 1 +forward 7 +down 8 +down 9 +down 1 +forward 8 +up 1 +forward 8 +down 1 +forward 9 +down 8 +down 2 +forward 4 +up 2 +down 7 +forward 6 +forward 6 +forward 4 +up 8 +up 2 +down 8 +up 7 +forward 2 +forward 6 +forward 3 +up 5 +forward 9 +down 9 +forward 6 +up 2 +down 6 +forward 4 +forward 5 +down 3 +up 2 +forward 3 +forward 2 +up 7 +down 1 +up 1 +up 8 +down 4 +forward 7 +forward 2 +up 2 +down 4 +forward 4 +forward 2 +forward 2 +down 8 +down 2 +down 2 +forward 6 +up 2 +up 9 +down 1 +down 7 +forward 9 +forward 4 +up 8 +forward 2 +forward 5 +down 3 +down 6 +down 4 +forward 7 +up 1 +forward 7 +down 8 +up 2 +down 8 +forward 6 +down 3 +up 9 +up 6 +up 6 +forward 5 +forward 1 +forward 3 +forward 3 +down 7 +down 3 +forward 8 +forward 2 +down 7 +down 1 +up 4 +forward 2 +forward 1 +up 6 +forward 9 +up 4 +forward 5 +up 4 +forward 3 +down 1 +forward 6 +forward 2 +down 3 +down 7 +forward 7 +down 4 +forward 6 +down 8 +forward 5 +up 9 +up 9 +forward 4 +forward 8 +down 6 +down 7 +forward 1 +up 4 +forward 9 +forward 7 +forward 2 +forward 6 +up 4 +forward 4 +down 3 +down 2 +up 4 +forward 4 +forward 3 +up 8 +forward 8 +down 9 +forward 4 +forward 6 +forward 7 +down 5 +forward 6 +down 3 +up 2 +down 4 +forward 1 +up 3 +forward 4 +down 7 +down 9 +down 6 +up 7 +down 2 +down 5 +forward 7 +up 6 +down 2 +forward 4 +down 9 +up 8 +forward 6 +down 4 +down 3 +up 9 +down 6 +down 9 +up 3 +down 2 +forward 3 +down 1 +forward 1 +forward 5 +down 7 +forward 2 +down 8 +down 8 +down 7 +forward 5 +forward 9 +forward 9 +forward 2 +up 5 +down 2 +forward 3 +down 2 +forward 9 +up 1 +forward 1 +up 6 +down 1 +forward 4 +down 5 +forward 2 +up 7 +up 4 +up 3 +forward 6 +down 5 +forward 6 +down 6 +forward 6 +down 2 +down 8 +up 9 +forward 2 +down 4 +forward 4 +forward 9 +up 9 +down 4 +up 7 +down 6 +up 2 +up 7 +down 5 +down 6 +down 8 +down 1 +forward 6 +forward 6 +forward 7 +down 3 +forward 3 +forward 8 +forward 1 +forward 2 +down 8 +forward 6 +down 6 +forward 8 +forward 3 +forward 6 +down 4 +down 2 +forward 4 +forward 6 +forward 8 +down 3 +down 3 +down 4 +up 1 +forward 3 +down 2 +down 3 +down 9 +down 3 +down 8 +down 1 +down 6 +forward 5 +down 5 +down 7 +up 3 +forward 5 +down 7 +down 7 +forward 6 +down 6 +up 6 +forward 2 +up 9 +down 3 +forward 3 +forward 4 +up 6 +down 7 +forward 1 +up 8 +forward 3 +down 1 +forward 6 +forward 7 +down 5 +down 6 +down 8 +up 6 +down 4 +down 5 +down 1 +up 1 +up 9 +up 4 +forward 2 +down 5 +down 7 +forward 5 +forward 2 +up 1 +down 7 +up 6 +forward 5 +down 5 +down 9 +up 4 +down 6 +forward 8 +down 5 +forward 6 +forward 1 +forward 5 +forward 4 +down 2 +down 7 +up 7 +down 9 +down 7 +up 4 +down 3 +up 9 +forward 3 +up 1 +up 7 +forward 4 +forward 6 +up 2 +forward 2 +forward 4 +down 6 +forward 4 +forward 6 +forward 9 +forward 4 +forward 8 +up 9 +up 4 +forward 1 +forward 3 +down 5 +down 4 +up 6 +up 2 +forward 9 +up 9 +up 2 +forward 6 +down 5 +up 7 +forward 3 +forward 4 +down 5 +up 8 +forward 7 +forward 3 +up 5 +down 7 +down 6 +forward 9 +up 2 +forward 5 +down 2 +down 9 +forward 1 +down 4 +forward 3 +up 9 +down 2 +up 5 +down 8 +forward 1 +up 9 +up 7 +up 1 +forward 7 +forward 1 +forward 7 +down 2 +up 6 +forward 6 +down 1 +forward 1 +down 7 +down 9 +forward 9 +up 3 +forward 3 +down 1 +forward 1 +forward 9 +down 7 +forward 2 +down 7 +forward 2 +forward 4 +down 5 +down 5 +forward 5 +down 9 +down 4 +forward 3 +down 4 +down 3 +down 3 +down 2 +forward 1 +up 8 +forward 1 +forward 5 +forward 1 +forward 2 +forward 4 +forward 6 +forward 8 +forward 7 +down 5 +up 6 +forward 8 +down 9 +up 3 +up 2 +down 4 +up 1 +forward 6 +up 6 +forward 9 +forward 3 +down 3 +down 5 +forward 6 +down 6 +down 4 +up 6 +forward 4 +up 8 +down 4 +down 8 +down 3 +down 1 +down 6 +down 7 +down 8 +down 2 +down 5 +forward 4 +forward 6 +forward 7 +down 1 +down 5 +forward 9 +down 6 +forward 6 +forward 7 +forward 4 +forward 2 +forward 2 +up 6 +forward 9 +up 6 +down 1 +forward 4 +down 2 +up 3 +forward 5 +up 1 +forward 4 +forward 4 +up 4 +down 7 +down 5 +up 4 +forward 5 +up 8 +up 4 +up 2 +up 8 +forward 6 +down 9 +down 8 +down 4 +down 4 +up 9 +forward 4 +forward 5 +forward 4 +forward 9 +down 7 +down 4 +down 3 +down 7 +forward 3 +forward 1 +down 1 +forward 5 +forward 6 +down 1 +forward 3 +down 7 +up 4 +forward 4 +forward 7 +up 1 +up 9 +down 7 +down 5 +up 8 +forward 3 +forward 5 +forward 3 +down 6 +down 1 +down 9 +up 9 +forward 5 +down 1 +down 1 +down 8 +forward 8 +up 2 +down 1 +down 2 +down 6 +down 3 +forward 7 +forward 1 +down 4 +up 9 +down 7 +down 6 +down 9 +forward 5 +forward 4 +forward 9 +up 7 +forward 5 +down 6 +forward 9 +forward 2 +forward 8 +up 9 +forward 2 +down 8 +up 8 +down 8 +down 8 +forward 2 +down 1 +forward 5 +down 4 +up 2 +forward 8 +up 4 +up 8 +forward 4 +forward 6 +forward 6 +forward 3 +forward 5 +forward 4 +down 6 +up 6 +forward 7 +up 3 +down 1 +down 1 +down 9 +forward 6 +down 9 +forward 2 +down 7 +down 2 +down 5 +forward 3 +down 4 +down 8 +down 3 +forward 6 +up 9 +forward 1 +forward 4 +forward 8 +up 9 +down 5 +up 5 +up 9 +forward 6 +up 2 +forward 7 +up 5 +forward 8 +forward 6 +down 2 +down 7 +up 8 +up 3 +forward 4 +forward 1 +down 8 +down 4 +forward 6 +forward 6 +up 6 +up 3 +up 7 +forward 6 +up 2 +down 8 +forward 1 +forward 3 +down 3 +forward 8 +forward 5 +forward 3 +forward 9 +down 6 +forward 9 +up 7 +down 3 +down 8 +forward 4 +down 9 +up 8 +up 1 +forward 2 +down 2 +forward 1 +down 8 +forward 7 +up 4 +down 1 +forward 8 +down 2 +forward 3 +forward 9 +down 7 +up 4 +up 2 +forward 1 +down 2 +up 8 +forward 4 +down 1 +forward 5 +forward 1 +down 5 +forward 1 +up 2 +forward 6 +down 5 +down 8 +down 3 +down 2 +forward 1 +forward 5 +down 8 +down 1 +forward 5 +down 7 +down 4 +forward 5 +down 1 +down 1 +forward 9 +down 7 +up 9 +down 6 +forward 4 +up 8 +forward 6 +forward 1 +up 6 +forward 3 +down 3 +up 6 +forward 2 +down 2 +forward 3 +down 2 +up 4 +down 6 +forward 4 +down 6 +down 4 +up 2 +down 2 +up 5 +up 2 +down 9 +down 5 +forward 1 +down 6 +forward 4 +forward 9 +down 1 +down 9 +forward 3 +forward 8 +forward 9 +down 4 +down 1 +up 1 +up 7 +down 5 +down 3 +down 2 +down 8 +forward 5 +up 1 +down 4 +down 8 +down 8 +forward 1 +down 5 +forward 7 +forward 9 +forward 5 +forward 2 +down 9 +up 1 +down 6 +down 5 +forward 4 +forward 3 +down 4 +down 3 +down 8 +forward 6 +down 2 +forward 7 +down 7 +forward 8 +forward 1 +forward 7 +forward 8 +forward 6 diff --git a/src/t03_binary_diagnostic/mod.rs b/src/t03_binary_diagnostic/mod.rs new file mode 100644 index 0000000..3071cdc --- /dev/null +++ b/src/t03_binary_diagnostic/mod.rs @@ -0,0 +1,83 @@ +use std::io::{BufRead, BufReader}; + +use crate::types::TestMode; + +fn parse_input(test_mode: TestMode) -> Vec { + let f = test_mode.input_file(file!()); + BufReader::new(f) + .lines() + .map(|line| line.unwrap()) + .collect() +} + +fn num_symbols_at_pos(input: &[String], symbol: char, position: usize) -> usize { + input + .iter() + .filter(|s| s.chars().nth(position).unwrap() == symbol) + .count() +} + +pub fn binary_diagnostic_1(test_mode: TestMode) { + let nums = parse_input(test_mode); + + let mut gamma = 0; + let mut epsilon = 0; + + for b in 0..nums[0].len() { + let zero_count = num_symbols_at_pos(&nums, '0', b); + let one_count = num_symbols_at_pos(&nums, '1', b); + + let most_common = if one_count >= zero_count { 1 } else { 0 }; + let least_common = if one_count < zero_count { 1 } else { 0 }; + + gamma = (gamma << 1) | most_common; + epsilon = (epsilon << 1) | least_common; + } + + println!("{}, {} -> {}", gamma, epsilon, gamma * epsilon); +} + +pub fn binary_diagnostic_2(test_mode: TestMode) { + let nums = parse_input(test_mode); + + let mut oxygen_generator_ratings = nums.clone(); + for b in 0..nums[0].len() { + if oxygen_generator_ratings.len() == 1 { + break; + }; + + let zero_count = num_symbols_at_pos(&oxygen_generator_ratings, '0', b); + let one_count = num_symbols_at_pos(&oxygen_generator_ratings, '1', b); + + let most_common = if one_count >= zero_count { '1' } else { '0' }; + oxygen_generator_ratings = oxygen_generator_ratings + .into_iter() + .filter(|s| s.chars().nth(b).unwrap() == most_common) + .collect(); + } + + let mut co2_scrubber_ratings = nums.clone(); + for b in 0..nums[0].len() { + if co2_scrubber_ratings.len() == 1 { + break; + } + + let zero_count = num_symbols_at_pos(&co2_scrubber_ratings, '0', b); + let one_count = num_symbols_at_pos(&co2_scrubber_ratings, '1', b); + let least_common = if one_count < zero_count { '1' } else { '0' }; + co2_scrubber_ratings = co2_scrubber_ratings + .into_iter() + .filter(|s| s.chars().nth(b).unwrap() == least_common) + .collect(); + } + + let oxy_gen_rating = usize::from_str_radix(&oxygen_generator_ratings[0], 2).unwrap(); + let co2_scrub_rating = usize::from_str_radix(&co2_scrubber_ratings[0], 2).unwrap(); + + println!( + "{}, {} -> {}", + oxy_gen_rating, + co2_scrub_rating, + oxy_gen_rating * co2_scrub_rating + ); +} diff --git a/src/t03_binary_diagnostic/prod.in b/src/t03_binary_diagnostic/prod.in new file mode 100644 index 0000000..99c0fc4 --- /dev/null +++ b/src/t03_binary_diagnostic/prod.in @@ -0,0 +1,1000 @@ +111011001010 +010011101110 +110001001010 +001101011101 +110100000011 +010110110010 +101000110110 +010100000011 +111001101111 +111001100011 +000110000100 +111011110100 +010001100000 +100011000010 +001001111010 +101001010010 +110000111010 +011100110101 +010111101111 +100011001001 +011110100001 +011101110110 +001011111001 +001110010100 +100001001000 +000100110111 +011111110010 +010101110011 +001101011100 +100001110101 +111000100000 +010111001010 +110000001010 +101011110100 +101010011111 +011001001000 +010010100100 +001100111110 +011111100101 +011010011001 +000010010100 +010001110111 +000101011001 +001110101100 +100011100101 +110001011100 +100101011110 +111000001010 +000010111010 +001001000010 +011011001100 +000111110000 +110110110010 +001011111100 +110111110101 +001000101010 +101010011001 +111110011001 +001000111110 +110110010010 +010011001000 +110100100010 +111000100011 +110111000001 +110110010001 +001100011011 +111100010111 +110110101001 +100010000101 +001001101000 +010000110101 +111010001100 +110000001110 +100111110010 +110101110011 +011100111010 +100000010001 +101000111101 +001010001100 +110100000000 +011001110100 +011010101111 +001011011000 +111100101000 +101001110100 +001111100001 +110111110111 +101100010000 +110000010101 +110111010101 +101110100100 +011010001001 +011101110111 +101011110111 +011001101111 +101101001011 +010000100011 +111011111100 +110101000100 +011111101011 +101000001110 +000111001010 +011100010010 +010011011111 +100000001101 +000110001011 +101100110101 +001001010000 +001111101100 +110100010011 +100011111001 +110000101100 +101111101101 +010011100110 +011000011101 +111110001111 +000100111011 +000001001100 +111110000010 +001001110111 +100000110010 +011000111000 +100010100110 +111110100010 +000001010110 +011010001101 +001100001010 +100111001001 +001010110101 +100111000101 +110011001110 +011100000110 +101111111110 +001110100010 +110101011010 +000011111001 +101011110110 +000111000110 +110010001100 +001001010101 +011111001011 +100010101101 +001000010000 +110111110001 +001111110011 +110111101101 +010011010001 +100110101000 +001011100100 +001010111011 +101000010001 +000101001011 +011010010011 +011011000001 +111111010101 +010000011001 +101100111101 +001001110010 +000010001011 +111000001001 +010001001100 +110110011011 +111011100100 +001000001010 +101110010110 +010010000100 +100000011011 +010000110011 +111111101101 +101010001011 +001011110100 +000111100011 +110011100111 +000011100000 +100101001110 +110100000010 +110101110101 +100001010101 +010100000110 +011010110110 +001011000101 +010010100001 +001001100110 +111011110111 +100110011111 +100111010000 +010010111010 +001000101100 +000101101110 +011001010111 +010001000110 +001110111000 +010001001010 +111000011000 +000011110000 +111100011110 +101110111001 +001101001000 +111010110110 +001110101010 +100001111011 +110010010110 +101001101011 +001100111011 +111001010100 +101111011011 +010010000010 +101101101111 +101000101000 +001100100010 +111001100101 +110110001011 +000110011001 +110010110000 +000111101111 +010010001101 +110110111101 +010100100100 +001111010110 +001101000011 +011110010011 +101111101010 +111001000110 +000110001001 +100100001000 +010100110010 +001011001011 +100010110100 +001110101111 +001001101011 +000111100100 +000001111011 +100111111101 +111011100110 +000100101101 +100110110000 +010001000000 +111111111111 +011010001110 +001100000100 +000010010000 +000100100000 +010100010101 +100100111110 +001100111100 +000001010010 +011010000001 +000000111010 +110011110111 +110011100110 +000011011011 +001001001001 +100111100111 +110000101110 +101100101111 +110001110110 +111011111001 +101000110001 +010000011110 +001011110101 +001100011010 +111001110001 +001110110001 +101011010100 +110110100111 +101011001100 +110010111100 +011111001111 +110001101011 +011100111100 +111101110010 +001111000001 +100101110101 +110001101000 +110001100110 +000011110110 +001111111111 +110101001111 +101000111001 +101100111001 +110011011011 +011100100111 +111000001100 +110010001001 +000101001000 +010101101100 +110010000100 +011000010101 +010001101111 +011000000100 +111111100101 +000011101011 +011001111010 +011010000101 +000001001011 +001111001010 +001011011010 +010011111010 +101001110001 +101001000000 +100101100101 +111100000010 +110000000100 +010110000101 +011011011101 +010110101001 +010011000111 +110000010001 +000101100001 +111000000100 +000011001101 +101101110011 +110101011101 +001111000010 +101110011100 +000100001010 +111101110001 +110110111111 +001011101011 +100001010100 +011001110010 +010001111000 +001101101011 +011011101001 +010111101010 +011110000000 +111111000010 +100010110111 +111010111111 +100110001001 +011111000000 +000111000010 +111001111100 +111010100111 +001010110010 +100011110001 +011100000100 +011110010110 +101001000011 +100011111101 +001100100111 +000110100100 +001001000111 +101000000000 +011100010101 +101110010111 +000110010001 +010101001111 +010010000111 +001010001111 +000111000101 +111101111010 +010010111111 +101111101110 +101100101000 +101101010101 +000011111011 +011111000101 +011111111001 +101000100111 +010101110111 +000111101100 +011010011010 +110001000010 +100110111100 +011110011011 +001101011010 +010001011001 +100110100001 +001010111001 +011100011011 +110001111101 +100111100100 +101111111101 +111000011001 +000000101110 +101111011100 +010100111111 +010001010100 +011001111100 +110100010001 +110001111110 +111001110000 +001110010111 +001100101101 +111001100001 +000100011101 +011101011010 +010110010000 +100000111100 +100100100110 +110111111000 +001111000111 +111111110010 +111010111011 +001000111000 +101010110101 +011001110110 +001100110001 +000111101001 +010011000001 +001101011001 +111001111010 +000110011011 +000101000100 +110000011011 +010011011000 +011100111111 +010101101101 +101100110100 +001011010101 +010001000011 +001000000111 +111111011011 +110000000011 +100101010110 +001001001101 +000101010100 +111101101100 +000111110101 +100101010010 +101110001110 +101011111110 +011011000011 +000111010101 +011010001000 +001010110000 +011110000110 +001111100110 +111001111110 +000101101111 +110111100100 +100011101001 +111000100101 +100100111101 +110001000011 +110000101111 +110001111100 +000101000111 +001011110000 +010000001100 +101101110001 +000110100111 +011101000001 +001111101101 +100000000100 +010010000000 +001111101000 +001010111010 +101010011010 +111010100011 +101111110010 +001011110110 +100010010001 +010110010110 +110111111010 +000111001011 +000001111100 +100101101111 +010100011101 +000010011110 +011100100000 +011101100000 +110000100111 +110111100000 +100001110100 +011111011011 +101110110001 +010000011000 +010011010101 +001101100101 +110110100101 +101000011110 +101011000011 +000010010101 +101001110000 +110001011111 +001101101101 +000001111111 +110010111001 +111001010101 +000010101100 +111011100101 +011111001110 +011000011010 +111111110110 +111010110111 +011010010110 +110011001011 +000010101000 +011101011100 +111010110000 +010011110010 +011110010001 +101111111001 +010010110101 +101010101001 +001101110001 +011111110110 +011110110001 +001111001100 +110000011001 +111001000101 +111110101001 +010011010100 +110011000010 +110000100100 +101000101001 +010101011010 +011001100011 +101110101101 +100100001011 +111010010001 +111010001110 +100110101100 +111010010111 +101111001010 +111101111111 +101111000110 +101111101111 +011001001101 +100110000111 +101101010100 +110100011010 +010111010001 +110011101011 +101001001100 +100111010111 +000011111110 +011110000101 +001011110111 +100000110110 +011110100111 +011100011111 +010100111101 +100100010011 +001000101001 +010111010110 +100000011100 +000000111111 +111101111001 +011011100100 +101011010110 +111010001111 +111101111101 +110100110010 +010001001110 +011001110011 +110100110101 +110010100010 +111111111101 +000110011100 +011010100110 +000000010011 +100100010110 +110110010111 +101011101001 +110000000010 +001110011001 +111111011110 +000111000001 +110010101011 +111111111001 +010001010010 +001111010100 +011011110101 +110000000111 +100011010010 +000010110111 +111100111111 +111111101010 +011000100011 +011111000100 +011100001001 +110001011011 +011011010111 +100000101111 +101001100100 +110000110101 +000001110111 +110101001000 +000001100000 +010001111110 +011110011101 +011011100111 +110000011010 +111010100110 +001101110010 +111000010000 +010110101000 +010001010111 +000010101111 +111000001110 +111011100001 +111100011001 +101111001110 +101011011000 +101100101100 +111111110011 +101010010101 +110110010101 +001100111010 +100001101000 +001100000011 +010110110000 +101110101011 +100001100101 +011001011010 +110110001111 +001000000110 +011101011111 +001010101001 +001111101001 +111100011111 +100010110010 +000001101110 +011110011010 +010110100101 +010010100011 +101010001000 +010000001001 +111100110011 +110010001111 +000101100010 +011111100000 +000100000001 +100100010000 +011110000011 +000010010001 +110010101001 +000000001010 +110010011100 +000000100100 +100010110001 +101111001100 +000001101010 +111011010110 +010101011101 +100110101011 +101001011011 +010011100100 +111000001000 +100111110001 +100100101011 +011001101001 +010101110000 +101000011001 +101111110111 +010111110011 +011111111111 +011100110011 +010010110010 +111011111101 +011110000010 +100001101010 +110100011100 +001001010011 +001110000010 +000110000101 +010110001010 +101000101010 +100000101001 +000001101100 +001001111011 +100011010000 +010000100000 +001111111000 +111011111000 +100011101000 +100110001100 +010001010011 +100110110101 +100001010011 +100100101111 +011101101011 +011110111101 +101110010100 +101010110111 +001010001011 +011111001101 +111011001101 +111011000110 +001100000001 +101100110111 +101100110010 +001000110011 +111010101010 +010101010110 +111100111001 +111000101001 +111000010101 +001000101101 +100111000010 +100000010110 +000100011000 +010100011100 +111010110011 +100011100011 +111111110101 +110101010110 +011001001011 +011101110100 +111110000110 +011010100101 +110100010010 +011111100010 +111010110001 +100111000100 +100000010101 +111000110010 +111100101001 +101010100010 +000110010010 +001111101111 +010011111011 +110010000011 +000010101101 +111111100111 +101001110110 +100111011001 +011010011111 +011011011001 +110001000001 +111011011011 +001011001111 +100101000010 +110000010010 +000011011000 +010111001001 +010001111010 +110101000110 +111011101010 +001100110101 +001111000110 +000000000010 +010100111010 +111101110110 +101101110101 +011001010101 +010110001101 +011110100011 +010101010101 +100110100011 +101111110011 +000111111101 +010011000100 +000010110101 +000001011010 +101100001000 +000101111001 +100001001100 +110110000100 +111010011000 +110000001000 +010111001101 +100111000000 +000001010000 +000110101110 +000100110011 +101011101000 +100110110010 +111011100000 +100000101011 +111100101011 +100010100011 +101001000001 +110001111010 +001001110101 +001000101110 +101011111010 +000110110110 +000100010000 +111001110010 +100010111101 +111110110010 +001111110001 +011111101101 +001001101111 +110111100001 +000010111111 +101110001111 +101011101011 +110001010010 +011010100111 +011011010110 +111100001000 +111100001111 +111101011110 +010000000000 +000000011000 +001000000100 +010111100001 +101110010011 +000101000101 +101100010110 +010111011111 +000010100101 +100001111110 +011101001000 +100010001101 +100111100001 +011010110001 +010110101100 +111010110100 +010110010101 +010100111100 +110001100101 +010010011000 +111110110011 +110001101100 +100011001110 +100001000000 +101001100000 +010111111101 +011000110001 +101001011101 +100110011101 +011101111000 +000000100001 +010000010000 +110100010110 +101100011101 +111011001111 +100101111000 +110101010100 +101111000011 +000101110000 +110101110100 +010110111000 +100010101001 +010111001111 +001011111101 +001111010011 +101001101010 +011110010100 +001100110111 +010111010111 +000001100100 +100001000010 +101001111011 +000011000100 +111000100100 +111010111001 +101101001111 +001010110011 +001000000011 +111111101001 +101001010101 +001010110110 +110101110010 +101101010001 +101010111000 +110100000101 +111100110100 +100010111000 +010010001111 +011000111101 +110011011000 +101010111001 +011000010000 +001001000001 +001100101000 +110111001001 +011001000110 +101001101000 +100010011101 +000001001101 +010001011110 +111111000001 +000111100010 +110110011111 +000001110110 +110101010001 +110100100011 +100110010100 +010101100111 +000000011110 +001000010011 +000101011010 +010101101110 +001010111100 +110100111101 +101101011011 +011011101100 +100000000001 +000101010111 +101010010011 +110001000110 +101110001000 +010110000010 +110100001011 +010110100110 +000110100101 +111110111100 +110010101101 +110111101110 +001111000000 +001101010000 +010011000011 +011110010101 +100001000100 +000000111011 +010011010110 +100110110111 +111000000000 +100101111110 +110011001100 +100001001111 +100100010010 +001101111011 +110010000010 +011101001011 +011000010111 +010000010100 +100100101010 +001100101100 +000100101001 +100100000011 +101010111011 +000001100101 +101011110101 +100101111111 +010101100001 +101000001010 +000011110010 +111001010010 +100001100011 +010111111111 +001110011000 +010001011000 +000011001110 +110010111011 +001100001111 +100001110111 +110000010000 +101110000001 +001011100110 +010101001101 +001001001111 +001110100100 +111110111010 +011101100010 +001010011011 +011011010011 +111000101011 +110110110001 +110100101111 +000000100010 +111111101111 +111000101101 +011001000010 +100000001001 +000101011100 +110100100110 +111011011111 +110110111100 +110011110000 +111110011110 +001101010010 +101000111110 +010101110110 +101100000011 +001111101110 +010101011001 +110010110010 +100100110111 +011100000001 +101110000110 +001011101000 +000011100111 +010101000000 +101011100000 +100100010001 +011011100010 +011010000100 +010010110011 +011010111101 +010010011100 +010010010011 +011000011111 +101101111111 +010100001010 +100100110100 +101011101111 +100100100010 +010001011101 +101101110000 +110010000101 +111011010111 +010011110111 +100101000011 +001100111101 +110110100000 +101001100011 +111001000011 +100001011111 +010000111101 +100011100001 +101100011010 +100110100000 diff --git a/src/t03_binary_diagnostic/test.in b/src/t03_binary_diagnostic/test.in new file mode 100644 index 0000000..a6366a8 --- /dev/null +++ b/src/t03_binary_diagnostic/test.in @@ -0,0 +1,12 @@ +00100 +11110 +10110 +10111 +10101 +01111 +00111 +11100 +10000 +11001 +00010 +01010 diff --git a/src/t04_giant_squid/mod.rs b/src/t04_giant_squid/mod.rs new file mode 100644 index 0000000..bf2820c --- /dev/null +++ b/src/t04_giant_squid/mod.rs @@ -0,0 +1,170 @@ +use std::{ + fs::File, + io::{BufRead, BufReader}, + process::exit, +}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + numbers: Vec, + boards: Vec, +} + +const BOARD_DIMENSION: usize = 5; + +#[derive(Clone, Debug)] +struct Board { + cells: [[u16; BOARD_DIMENSION]; BOARD_DIMENSION], + marked_cell_map: [[bool; BOARD_DIMENSION]; BOARD_DIMENSION], +} + +impl Board { + fn new() -> Self { + Self { + cells: [[0; BOARD_DIMENSION]; BOARD_DIMENSION], + marked_cell_map: [[false; BOARD_DIMENSION]; BOARD_DIMENSION], + } + } + + fn from_bufreader(br: &mut BufReader) -> Option { + let mut buf = String::new(); + if let Ok(n) = br.read_line(&mut buf) { + if n == 0 { + return None; + } + } + let mut ret = Self::new(); + for j in 0..BOARD_DIMENSION { + buf.clear(); + br.read_line(&mut buf).unwrap(); + let line_nums: Vec = buf + .trim_end() + .split_ascii_whitespace() + .map(|n| n.parse().unwrap()) + .collect(); + + ret.cells[j] = line_nums[0..BOARD_DIMENSION].try_into().unwrap(); + } + Some(ret) + } + + fn mark_number(&mut self, number: u16) { + for i in 0..BOARD_DIMENSION { + for j in 0..BOARD_DIMENSION { + if self.cells[i][j] == number { + self.marked_cell_map[i][j] = true; + } + } + } + } + + fn is_winning(&self) -> bool { + for col in 0..BOARD_DIMENSION { + let mut bingo = true; + for row in 0..BOARD_DIMENSION { + if !self.marked_cell_map[row][col] { + bingo = false; + break; + } + } + if bingo { + return true; + } + } + for row in 0..BOARD_DIMENSION { + let mut bingo = true; + for col in 0..BOARD_DIMENSION { + if !self.marked_cell_map[row][col] { + bingo = false; + break; + } + } + if bingo { + return true; + } + } + false + } + + fn score(&self, last_number: u16) -> u64 { + let mut score = 0u64; + for row in 0..BOARD_DIMENSION { + for col in 0..BOARD_DIMENSION { + if !self.marked_cell_map[row][col] { + score += self.cells[row][col] as u64; + } + } + } + score * (last_number as u64) + } +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + let mut buf = String::new(); + let mut br = BufReader::new(f); + br.read_line(&mut buf).unwrap(); + + let numbers: Vec = buf + .split_terminator(',') + .into_iter() + .map(|s| s.trim_end().parse().unwrap()) + .collect(); + + let mut boards = vec![]; + loop { + let b = Board::from_bufreader(&mut br); + if let Some(b) = b { + boards.push(b); + } else { + break; + } + } + + Input { numbers, boards } +} + +pub fn giant_squid_1(test_mode: TestMode) { + let mut input = parse_input(test_mode); + + for n in input.numbers { + for b in &mut input.boards { + b.mark_number(n); + if b.is_winning() { + println!("{}", b.score(n)); + exit(0); + } + } + } +} + +pub fn giant_squid_2(test_mode: TestMode) { + let mut input = parse_input(test_mode); + + let mut last_to_win_board = None; + let mut last_to_win_number = None; + + for n in input.numbers { + let mut new_boards = Vec::::new(); + for b in &mut input.boards { + b.mark_number(n); + if b.is_winning() { + last_to_win_board = Some(b.clone()); + last_to_win_number = Some(n); + } else { + new_boards.push(b.clone()); + } + } + + input.boards = new_boards; + } + + println!( + "{}", + last_to_win_board + .unwrap() + .score(last_to_win_number.unwrap()) + ); +} diff --git a/src/t04_giant_squid/prod.in b/src/t04_giant_squid/prod.in new file mode 100644 index 0000000..c14a3da --- /dev/null +++ b/src/t04_giant_squid/prod.in @@ -0,0 +1,601 @@ +74,79,46,2,19,27,31,90,21,83,94,77,0,29,38,72,42,23,6,62,45,95,41,55,93,69,39,17,12,1,20,53,49,71,61,13,88,25,87,26,50,58,28,51,89,64,3,80,36,65,57,92,52,86,98,78,9,33,44,63,16,34,97,60,40,66,75,4,7,84,22,43,11,85,91,32,48,14,18,76,8,47,24,81,35,30,82,67,37,70,15,5,73,59,54,68,56,96,99,10 + +61 96 92 39 0 +35 25 50 22 60 + 3 88 69 48 62 +75 24 97 51 67 +87 74 94 77 83 + + 1 70 59 40 55 +42 88 10 17 80 +27 24 82 45 23 + 5 19 48 51 11 +75 72 97 74 7 + +58 40 78 83 74 + 4 94 17 63 62 +55 61 5 27 69 +99 84 89 81 59 +64 28 91 49 97 + +92 88 51 12 22 + 0 5 65 32 77 +80 40 3 10 90 +91 47 58 57 14 +86 71 94 36 75 + +71 24 16 66 29 + 8 47 93 68 36 +42 67 69 55 15 +75 6 34 60 70 +95 92 14 0 81 + +52 49 37 41 67 + 9 8 2 13 17 +92 89 38 16 53 +63 46 60 4 87 +57 96 77 85 39 + +84 98 52 95 89 +81 67 99 85 50 +88 11 76 49 8 + 4 30 51 78 20 +70 64 74 40 79 + +45 65 87 79 14 +11 26 98 70 28 +46 85 54 55 48 +97 59 62 57 16 +30 40 95 7 18 + +97 25 38 1 26 +20 86 7 68 39 + 2 55 29 33 65 +46 14 72 47 18 +60 48 41 9 50 + +71 81 15 49 50 +72 28 51 11 35 +20 7 36 84 65 +93 33 14 47 45 +89 0 75 60 16 + +98 90 47 94 55 +69 41 81 1 43 +73 95 65 15 80 +85 99 60 92 0 +13 33 82 51 22 + +47 58 82 67 30 +88 23 64 4 39 +94 52 61 1 75 + 3 8 34 87 49 +13 38 60 54 35 + +91 62 88 29 33 +84 27 6 18 11 +47 87 58 42 34 +69 46 75 40 43 +63 97 53 49 66 + +80 57 73 65 44 +95 55 27 46 10 +82 24 90 97 75 +33 41 31 84 9 + 5 48 18 49 12 + +92 63 91 14 13 +32 12 66 87 79 +44 60 7 96 84 +58 41 42 3 27 +16 59 43 77 11 + +80 36 53 56 62 +26 8 4 79 51 +22 91 69 78 2 +59 13 23 81 93 +30 16 49 33 65 + +52 88 12 67 85 +74 78 75 72 79 +81 26 82 5 0 +23 56 41 3 32 +31 69 15 66 87 + +22 71 80 0 63 +94 31 13 60 42 +41 77 90 92 91 +64 95 5 23 73 +85 15 3 88 10 + +72 75 88 52 38 +17 86 54 79 87 +66 61 51 3 26 +68 47 89 11 41 +50 33 92 7 81 + +82 80 9 65 34 + 3 49 42 36 76 +95 94 61 32 43 +72 67 56 45 54 +77 48 14 6 25 + +44 75 99 62 11 +43 73 2 87 83 +96 63 85 14 30 +32 70 18 29 55 + 1 88 15 27 24 + + 2 38 46 61 7 +45 19 97 31 54 +88 40 14 81 87 +69 39 32 16 21 +22 5 0 29 92 + +78 57 85 4 70 +82 43 12 69 79 +60 34 15 63 45 +90 77 93 31 47 +27 49 25 71 19 + +49 10 40 51 45 + 9 44 86 26 27 +93 98 22 63 95 +88 66 33 74 57 +81 24 28 91 72 + +14 83 60 54 57 +18 15 41 4 47 +39 98 62 33 5 +30 70 6 91 90 +86 21 28 84 81 + +91 46 49 9 32 +85 33 87 83 76 +17 14 37 94 6 +31 13 92 89 78 +15 66 47 74 63 + +55 6 83 19 96 +71 22 88 99 50 +89 84 26 45 38 +57 77 87 93 25 +44 49 16 64 34 + +79 76 46 19 51 +85 90 58 29 3 +34 2 81 62 99 +84 60 78 91 96 + 4 27 43 47 98 + +66 2 38 39 37 +35 25 51 10 82 +91 62 1 12 93 +83 29 47 32 56 +74 19 50 95 49 + +59 57 35 50 51 +27 38 62 76 3 +52 49 83 75 4 +64 16 93 7 91 +40 17 65 41 97 + +18 37 45 44 4 +72 7 28 0 75 + 9 2 95 90 38 +24 79 93 22 88 +94 70 57 6 20 + +11 61 65 50 23 +74 51 80 91 22 + 5 32 27 57 14 +59 86 70 17 10 +21 62 20 18 67 + +98 9 88 79 78 +99 56 91 41 67 +17 39 65 16 38 +75 84 11 21 61 +22 81 52 55 87 + +45 36 74 47 19 +15 22 88 85 32 +38 63 54 16 13 +29 7 48 90 43 +68 3 24 17 30 + +72 77 68 75 57 +43 74 32 61 34 +37 2 47 25 85 +56 12 95 98 0 +80 36 39 22 11 + +77 58 24 57 99 +70 16 33 41 94 +54 61 20 90 30 +29 17 55 0 83 +13 37 42 49 38 + +86 58 13 11 6 +73 26 25 0 67 +56 44 87 5 49 + 4 91 51 66 22 +28 8 1 15 57 + +61 24 50 25 66 +92 42 98 55 96 +46 79 22 33 91 +97 0 69 90 54 +17 38 34 39 52 + +68 28 67 45 87 + 8 80 52 41 54 +34 47 4 78 59 +10 29 32 11 26 +17 33 7 93 35 + +10 15 33 46 14 + 6 56 52 16 92 +47 36 17 8 69 +77 45 73 84 9 +55 60 80 44 64 + +58 18 25 11 83 +75 7 53 42 68 +48 52 6 0 43 +80 97 16 60 1 +29 67 15 5 17 + +77 55 54 24 66 +58 2 4 39 12 +57 86 69 91 8 +67 84 65 13 20 +87 59 40 34 27 + +39 7 40 77 91 +13 76 32 92 56 +34 17 81 27 66 +37 80 83 85 15 +43 36 30 26 63 + +11 50 72 85 34 + 3 92 58 53 7 +98 10 49 97 12 +26 42 14 24 56 +28 20 59 54 4 + +55 56 29 80 96 +63 68 44 22 12 +65 4 95 6 26 +21 35 14 87 8 +17 92 86 30 53 + + 9 42 20 37 19 +65 46 11 54 92 +52 4 56 80 99 +41 55 43 90 17 +60 87 13 50 3 + + 3 29 4 41 95 +14 9 11 23 10 + 7 63 68 58 66 +13 46 67 86 51 +28 36 0 73 84 + +45 1 19 74 36 +58 64 30 86 83 +99 42 70 97 54 +17 75 56 80 81 +93 41 90 10 88 + +24 25 0 94 22 +70 1 50 10 14 +89 77 76 63 46 +33 72 81 28 60 +68 40 12 31 20 + +79 33 30 55 71 +31 91 54 0 82 +10 78 9 49 14 +85 72 5 3 24 +86 38 97 46 61 + +20 84 97 52 79 +45 73 11 18 58 +63 86 21 9 87 +48 90 13 77 49 +44 85 56 71 55 + +16 1 54 13 83 +38 32 69 28 43 + 5 50 57 95 47 +34 76 45 74 89 +46 91 71 39 17 + +82 45 14 28 57 +27 21 17 29 51 +95 32 31 80 91 +89 74 67 76 79 + 6 0 4 43 94 + +52 66 44 74 95 +85 51 79 76 54 +89 34 59 10 27 +45 6 69 98 48 +88 19 3 65 94 + +61 9 67 72 71 +93 48 64 52 11 +74 85 12 13 23 +41 4 94 16 57 +63 88 28 89 40 + +68 23 54 56 44 +13 77 26 2 46 +28 81 15 16 62 +82 51 71 86 72 +99 0 52 41 32 + +99 38 7 87 9 +69 96 22 57 24 +64 81 29 67 14 +48 52 6 88 92 +90 44 51 40 8 + +41 1 23 24 73 +10 4 66 60 22 +17 9 69 53 63 +42 34 99 86 56 +75 82 81 18 79 + +58 64 12 59 30 +21 94 28 77 53 +88 90 97 62 83 +35 70 27 98 26 +65 34 25 73 75 + +81 7 90 91 74 +23 34 67 31 50 +60 87 5 40 77 +69 93 27 49 53 +39 62 68 16 89 + +82 13 28 65 35 + 5 42 90 12 51 +15 85 64 86 25 +87 22 88 37 98 +39 10 46 56 49 + +62 25 93 75 34 +42 89 27 36 18 +32 54 59 26 6 +51 19 47 85 95 +33 39 73 29 79 + +15 27 0 79 69 +13 73 25 19 43 +30 8 46 34 58 + 4 86 66 74 18 +83 33 92 11 47 + +45 25 22 14 4 +83 3 65 17 85 +91 26 5 19 87 +66 89 29 49 64 +52 20 58 93 53 + +30 64 52 14 34 +63 16 97 9 15 + 2 72 65 45 17 +47 98 77 23 0 +50 20 38 60 26 + +46 67 84 66 55 + 7 32 31 75 19 +71 85 37 12 52 +39 27 8 81 44 +89 47 42 16 58 + +74 99 81 86 89 +92 20 7 58 30 +63 96 25 45 2 +97 50 94 33 87 +38 6 51 21 62 + +52 27 20 32 19 +17 80 70 92 96 +49 44 62 60 94 +40 28 86 4 7 +38 91 3 77 29 + + 8 28 89 99 6 +46 54 34 95 3 +88 60 29 91 10 +42 13 62 94 76 +56 52 72 85 59 + +85 50 42 5 91 +67 7 21 6 56 +14 8 70 10 78 +77 80 57 29 96 +17 23 73 16 38 + +59 61 47 43 13 + 7 93 11 72 83 + 0 96 67 27 2 +42 5 41 65 94 +40 34 33 50 3 + +25 79 52 11 94 +73 14 7 99 19 +92 40 2 28 45 +55 34 87 24 96 +36 16 66 78 35 + +11 27 90 50 55 +68 84 63 57 89 +35 14 29 77 24 +92 81 7 1 85 +99 64 20 2 49 + +20 66 85 88 57 +49 17 78 1 80 +18 24 11 31 65 +30 34 45 99 19 +69 40 94 2 58 + +49 2 55 54 61 +48 19 34 5 83 +80 52 67 24 96 +51 91 20 45 68 +87 79 59 9 3 + +47 12 71 88 74 +28 5 79 58 26 +93 67 62 86 23 +66 13 96 46 17 +94 59 19 54 15 + +21 89 98 54 53 +49 44 79 10 93 +64 24 25 9 56 +57 70 55 65 23 +14 36 31 13 4 + +62 60 30 89 94 +88 19 59 41 75 +25 45 74 17 47 + 5 16 76 33 58 +53 68 65 39 67 + +55 2 76 32 26 +37 25 5 27 24 +61 88 33 45 46 +20 96 51 42 49 +66 3 15 11 36 + +60 21 80 9 96 +91 39 24 28 13 +52 11 34 41 82 +66 85 72 38 76 +69 25 67 64 81 + +67 75 42 79 74 +36 26 85 30 25 +50 19 3 33 28 +12 95 54 71 91 + 0 17 87 92 40 + +51 85 12 86 40 +28 36 35 50 97 +55 16 20 14 73 + 7 5 4 68 22 +47 3 67 93 2 + +48 33 92 35 31 +73 40 71 75 62 +19 54 49 20 38 +23 37 9 11 10 +80 63 39 52 56 + +59 70 61 65 62 +42 73 99 39 66 +67 8 93 30 97 +53 37 51 55 11 +48 26 94 44 63 + +99 5 21 8 13 + 0 35 25 19 6 +93 83 40 98 43 +84 18 66 50 62 +86 94 32 52 11 + +55 15 85 39 4 +95 83 27 46 45 +19 47 61 9 66 +82 32 72 77 16 +50 96 14 60 35 + +66 13 84 74 97 +85 67 20 43 34 +95 0 3 58 38 +48 69 93 28 7 +91 98 56 94 35 + +11 15 73 51 77 +13 7 22 53 10 + 2 40 98 79 50 +71 83 49 45 56 + 0 1 68 99 24 + +34 84 37 31 93 +55 7 18 15 65 +80 40 29 44 36 +51 26 99 59 2 +57 45 67 1 41 + +79 90 56 76 58 +78 70 20 26 48 +87 82 46 59 98 +51 81 91 52 44 +21 86 68 64 7 + +12 26 73 30 87 +99 58 45 25 38 +95 97 27 22 37 +98 72 10 6 79 + 4 61 20 85 67 + + 9 26 5 68 2 +97 4 31 11 69 +75 64 0 6 17 +25 95 89 59 38 +16 99 27 53 10 + +89 71 42 70 90 +12 38 8 63 23 +95 77 0 29 43 +81 93 56 2 34 +46 44 55 13 41 + +72 21 50 1 81 +67 44 88 90 82 +98 19 30 48 85 +66 20 79 13 28 +29 62 38 74 89 + + 1 62 20 28 0 +59 52 11 6 74 +32 16 50 34 76 +79 91 31 24 56 +26 37 87 53 57 + +47 79 55 45 9 +63 2 1 60 75 +18 39 97 7 44 +33 29 91 31 23 +50 80 32 49 71 + +41 52 85 2 83 +28 27 49 14 44 +20 1 34 19 17 +62 59 68 86 82 +89 31 37 95 80 + +67 70 59 17 91 + 3 60 12 6 93 +99 44 34 9 21 +31 26 61 20 25 +23 15 43 53 42 + +52 19 16 91 35 +65 29 4 2 48 +90 44 77 38 60 +49 62 53 47 74 +61 15 30 28 70 + +14 97 34 88 55 +50 28 80 36 64 +93 40 60 90 22 +29 77 1 26 56 +33 9 4 67 68 diff --git a/src/t04_giant_squid/test.in b/src/t04_giant_squid/test.in new file mode 100644 index 0000000..49d17bc --- /dev/null +++ b/src/t04_giant_squid/test.in @@ -0,0 +1,19 @@ +7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1 + +22 13 17 11 0 + 8 2 23 4 24 +21 9 14 16 7 + 6 10 3 18 5 + 1 12 20 15 19 + + 3 15 0 2 22 + 9 18 13 17 5 +19 8 7 25 23 +20 11 10 24 4 +14 21 16 12 6 + +14 21 17 24 4 +10 16 15 9 19 +18 8 23 26 20 +22 11 13 6 5 + 2 0 12 3 7 \ No newline at end of file diff --git a/src/t05_hydrothermal_venture/mod.rs b/src/t05_hydrothermal_venture/mod.rs new file mode 100644 index 0000000..10e5bab --- /dev/null +++ b/src/t05_hydrothermal_venture/mod.rs @@ -0,0 +1,143 @@ +use std::{ + cmp::Ordering, + collections::{HashMap, HashSet}, + fmt::Display, + io::{BufRead, BufReader}, +}; + +use crate::types::TestMode; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +struct Point { + x: i64, + y: i64, +} + +impl Display for Point { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("({}, {})", self.x, self.y)) + .unwrap(); + Ok(()) + } +} + +#[derive(Debug, PartialEq, Eq, Hash)] +struct Line { + p1: Point, + p2: Point, +} + +impl Display for Line { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_fmt(format_args!("[{} -> {}]", self.p1, self.p2)) + .unwrap(); + Ok(()) + } +} + +impl Line { + fn points(&self) -> HashSet { + let mut res = HashSet::new(); + + let dx = Self::sign(self.p2.x - self.p1.x); + let dy = Self::sign(self.p2.y - self.p1.y); + + let mut x = self.p1.x; + let mut y = self.p1.y; + loop { + let p = Point { x, y }; + + res.insert(p); + + if x == self.p2.x && y == self.p2.y { + break; + } + + x += dx; + y += dy; + } + + res + } + + fn sign(expr: i64) -> i64 { + match expr.cmp(&0) { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1, + } + } +} + +struct Input { + lines: Vec, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + let br = BufReader::new(f); + let lines = br + .lines() + .map(|line| { + let line = line.unwrap(); + let mut s = line.split_terminator(" -> "); + + let mut m = s.next().unwrap().split_terminator(','); + let p1 = Point { + x: m.next().unwrap().parse().unwrap(), + y: m.next().unwrap().parse().unwrap(), + }; + + let mut m = s.next().unwrap().split_terminator(','); + let p2 = Point { + x: m.next().unwrap().parse().unwrap(), + y: m.next().unwrap().parse().unwrap(), + }; + + Line { p1, p2 } + }) + .collect(); + + Input { lines } +} + +pub fn hydrothermal_venture_1(test_mode: TestMode) { + let input = parse_input(test_mode); + + let orthogonal_lines: Vec<_> = input + .lines + .into_iter() + .filter(|line| line.p1.x == line.p2.x || line.p1.y == line.p2.y) + .collect(); + + let mut point_count = HashMap::::new(); + for line in orthogonal_lines { + for point in line.points() { + *point_count.entry(point).or_insert(0) += 1; + } + } + let num_intersections = point_count + .iter() + .filter(|point_usages| point_usages.1 > &1) + .count(); + + println!("{}", num_intersections); +} + +pub fn hydrothermal_venture_2(test_mode: TestMode) { + let lines = parse_input(test_mode).lines; + + let mut point_count = HashMap::::new(); + + for line in lines { + for point in line.points() { + *point_count.entry(point).or_insert(0) += 1; + } + } + let num_intersections = point_count + .iter() + .filter(|point_usages| point_usages.1 > &1) + .count(); + + println!("{}", num_intersections); +} diff --git a/src/t05_hydrothermal_venture/prod.in b/src/t05_hydrothermal_venture/prod.in new file mode 100644 index 0000000..e11e0a4 --- /dev/null +++ b/src/t05_hydrothermal_venture/prod.in @@ -0,0 +1,500 @@ +541,808 -> 108,808 +982,23 -> 45,960 +558,21 -> 558,318 +907,877 -> 43,13 +532,213 -> 532,801 +599,387 -> 870,387 +762,208 -> 78,208 +739,527 -> 739,907 +64,21 -> 64,958 +258,267 -> 929,938 +22,75 -> 725,778 +347,950 -> 347,345 +705,906 -> 61,906 +53,16 -> 950,913 +468,474 -> 475,481 +567,602 -> 914,602 +570,531 -> 570,530 +180,307 -> 180,823 +546,374 -> 390,374 +750,142 -> 861,31 +586,631 -> 905,950 +971,680 -> 784,680 +428,174 -> 352,174 +825,676 -> 228,676 +630,617 -> 70,617 +156,912 -> 944,124 +805,203 -> 25,983 +726,808 -> 726,96 +986,564 -> 908,642 +594,293 -> 594,458 +182,126 -> 182,476 +979,43 -> 35,987 +642,272 -> 642,446 +759,690 -> 891,690 +951,518 -> 161,518 +357,769 -> 336,769 +904,297 -> 904,533 +326,332 -> 326,316 +758,356 -> 654,460 +432,425 -> 432,819 +31,602 -> 31,421 +318,555 -> 898,555 +326,220 -> 777,671 +708,957 -> 708,273 +26,24 -> 974,972 +341,172 -> 341,394 +33,926 -> 864,95 +486,324 -> 486,704 +850,82 -> 132,800 +62,506 -> 113,506 +816,429 -> 816,141 +184,17 -> 184,328 +40,680 -> 30,670 +640,294 -> 127,807 +654,512 -> 654,296 +722,301 -> 629,301 +255,430 -> 811,430 +376,385 -> 376,379 +227,207 -> 227,947 +363,533 -> 757,533 +150,616 -> 150,284 +943,100 -> 79,964 +275,963 -> 275,461 +409,768 -> 409,574 +516,349 -> 516,656 +19,666 -> 847,666 +962,358 -> 962,907 +781,789 -> 781,870 +778,380 -> 501,657 +895,29 -> 12,912 +12,677 -> 12,761 +614,728 -> 690,652 +415,786 -> 778,423 +683,84 -> 683,574 +973,909 -> 75,11 +854,791 -> 260,197 +965,55 -> 559,55 +624,542 -> 235,153 +924,57 -> 16,965 +540,736 -> 540,65 +293,293 -> 929,293 +587,176 -> 587,432 +389,126 -> 389,590 +267,149 -> 92,149 +424,596 -> 697,323 +412,697 -> 773,697 +473,579 -> 310,416 +149,175 -> 837,863 +848,984 -> 159,295 +608,613 -> 292,613 +344,970 -> 546,970 +589,531 -> 589,74 +220,727 -> 220,831 +651,240 -> 318,240 +717,609 -> 847,479 +917,954 -> 327,364 +780,102 -> 228,654 +201,95 -> 201,921 +403,88 -> 403,79 +755,76 -> 755,529 +654,762 -> 654,97 +957,988 -> 44,75 +899,43 -> 51,891 +855,892 -> 175,212 +295,962 -> 613,962 +284,800 -> 946,800 +494,771 -> 793,472 +212,799 -> 212,784 +25,829 -> 824,30 +277,135 -> 396,135 +981,986 -> 187,192 +794,88 -> 308,88 +425,140 -> 73,140 +155,900 -> 155,500 +339,768 -> 339,621 +720,407 -> 824,303 +746,679 -> 746,490 +672,632 -> 30,632 +74,628 -> 49,628 +534,770 -> 249,485 +59,802 -> 605,256 +481,543 -> 723,301 +163,425 -> 947,425 +10,782 -> 779,782 +185,851 -> 68,968 +536,479 -> 536,217 +987,472 -> 960,472 +802,623 -> 202,23 +548,73 -> 548,838 +711,678 -> 711,655 +91,578 -> 91,162 +803,27 -> 31,27 +198,524 -> 282,608 +45,585 -> 45,973 +741,157 -> 317,581 +263,843 -> 819,843 +240,786 -> 240,272 +453,148 -> 657,148 +646,74 -> 646,758 +367,521 -> 367,185 +355,356 -> 503,356 +306,780 -> 41,780 +783,779 -> 513,779 +81,886 -> 81,531 +403,592 -> 69,926 +575,458 -> 575,709 +406,695 -> 406,563 +342,690 -> 269,690 +712,766 -> 712,693 +929,608 -> 929,355 +562,750 -> 571,759 +353,780 -> 424,780 +296,111 -> 944,759 +341,28 -> 859,28 +415,28 -> 415,153 +104,16 -> 966,878 +554,780 -> 726,780 +749,645 -> 749,466 +188,724 -> 933,724 +806,185 -> 614,185 +244,181 -> 682,181 +104,937 -> 367,937 +400,116 -> 183,333 +749,94 -> 301,542 +638,543 -> 811,716 +694,727 -> 694,44 +46,259 -> 46,721 +467,748 -> 620,595 +739,543 -> 391,543 +734,454 -> 734,101 +200,954 -> 200,654 +592,358 -> 592,581 +758,29 -> 758,401 +386,685 -> 519,685 +538,294 -> 298,294 +82,269 -> 766,269 +840,114 -> 332,114 +924,542 -> 185,542 +936,311 -> 369,878 +820,724 -> 590,724 +277,689 -> 68,689 +76,634 -> 167,634 +255,503 -> 144,503 +753,915 -> 753,27 +288,329 -> 513,554 +729,297 -> 447,297 +128,533 -> 128,530 +252,718 -> 856,114 +947,498 -> 312,498 +142,917 -> 950,109 +815,845 -> 770,845 +863,98 -> 332,98 +927,694 -> 927,276 +682,232 -> 227,687 +640,474 -> 840,274 +98,37 -> 98,149 +203,170 -> 99,170 +736,956 -> 736,539 +686,384 -> 882,580 +976,152 -> 380,748 +80,859 -> 80,208 +687,252 -> 687,748 +819,978 -> 101,260 +17,722 -> 17,306 +99,96 -> 99,929 +713,757 -> 157,201 +469,986 -> 469,393 +813,210 -> 789,186 +360,319 -> 360,43 +777,707 -> 606,707 +928,413 -> 380,961 +566,850 -> 828,850 +380,650 -> 717,650 +863,889 -> 373,399 +521,97 -> 967,97 +12,989 -> 975,26 +965,974 -> 965,848 +639,331 -> 639,948 +815,731 -> 235,151 +823,369 -> 610,369 +22,930 -> 898,54 +635,113 -> 635,495 +462,123 -> 771,123 +445,274 -> 304,133 +743,633 -> 43,633 +811,267 -> 811,936 +745,549 -> 636,549 +321,720 -> 511,530 +949,138 -> 308,138 +563,34 -> 720,191 +449,313 -> 966,830 +857,308 -> 392,773 +244,80 -> 820,80 +212,345 -> 327,460 +28,941 -> 28,22 +122,988 -> 122,50 +51,889 -> 880,60 +328,161 -> 328,820 +703,639 -> 40,639 +107,47 -> 839,779 +338,260 -> 828,750 +947,304 -> 276,975 +509,281 -> 281,281 +200,42 -> 820,662 +728,940 -> 728,897 +511,770 -> 376,635 +197,99 -> 929,99 +699,648 -> 352,301 +915,291 -> 256,950 +641,586 -> 641,346 +337,722 -> 965,722 +739,92 -> 739,884 +656,676 -> 649,676 +369,450 -> 686,450 +33,672 -> 409,296 +336,979 -> 336,595 +95,289 -> 888,289 +286,128 -> 985,827 +471,300 -> 899,300 +824,959 -> 66,201 +884,104 -> 166,822 +562,681 -> 562,948 +987,974 -> 77,64 +61,47 -> 61,528 +359,647 -> 709,647 +34,398 -> 270,398 +526,66 -> 257,335 +744,545 -> 502,787 +805,726 -> 728,803 +184,749 -> 184,839 +136,148 -> 842,148 +538,244 -> 306,476 +202,698 -> 958,698 +264,519 -> 903,519 +367,310 -> 26,310 +391,747 -> 307,831 +580,945 -> 706,945 +199,776 -> 98,776 +408,242 -> 408,474 +929,706 -> 929,570 +351,524 -> 221,524 +773,783 -> 274,783 +770,790 -> 770,653 +572,182 -> 572,574 +979,13 -> 29,963 +175,454 -> 457,736 +170,399 -> 170,202 +570,406 -> 97,406 +813,37 -> 556,37 +80,886 -> 465,501 +317,799 -> 876,799 +602,399 -> 362,639 +891,257 -> 445,257 +346,275 -> 297,275 +345,136 -> 345,755 +252,460 -> 252,731 +17,573 -> 729,573 +901,838 -> 230,167 +754,582 -> 754,970 +415,964 -> 415,605 +857,758 -> 857,612 +319,613 -> 256,613 +34,614 -> 34,802 +443,118 -> 443,891 +335,300 -> 80,45 +284,340 -> 552,608 +154,31 -> 33,31 +440,720 -> 20,720 +331,219 -> 311,219 +163,83 -> 868,788 +775,733 -> 775,284 +859,240 -> 859,159 +144,249 -> 105,210 +710,809 -> 710,910 +76,481 -> 76,86 +825,603 -> 916,603 +404,575 -> 740,575 +612,427 -> 612,571 +63,765 -> 63,538 +979,170 -> 183,966 +781,372 -> 911,372 +237,732 -> 321,648 +457,474 -> 954,971 +887,110 -> 551,446 +894,962 -> 48,116 +276,534 -> 800,534 +40,42 -> 950,952 +986,941 -> 123,78 +348,857 -> 899,857 +57,728 -> 57,802 +776,536 -> 776,462 +683,618 -> 683,443 +468,914 -> 750,914 +420,129 -> 984,693 +254,913 -> 166,913 +832,737 -> 832,422 +472,724 -> 12,724 +483,916 -> 483,226 +206,751 -> 206,250 +890,901 -> 20,31 +156,198 -> 883,925 +972,367 -> 67,367 +409,196 -> 320,196 +59,188 -> 815,188 +856,856 -> 856,756 +84,871 -> 942,13 +475,91 -> 475,784 +363,578 -> 363,405 +219,976 -> 219,717 +243,25 -> 243,173 +115,194 -> 462,194 +91,960 -> 889,162 +20,957 -> 915,62 +60,955 -> 250,765 +882,707 -> 267,92 +122,626 -> 122,202 +705,74 -> 147,632 +418,122 -> 976,680 +500,522 -> 936,522 +715,652 -> 82,19 +118,872 -> 118,479 +918,70 -> 918,811 +968,968 -> 347,347 +985,479 -> 587,877 +749,259 -> 749,841 +475,102 -> 200,102 +808,976 -> 515,976 +761,726 -> 761,358 +778,523 -> 729,474 +266,251 -> 396,251 +46,921 -> 914,921 +384,424 -> 804,844 +442,359 -> 646,155 +929,774 -> 920,783 +344,958 -> 344,281 +33,173 -> 607,173 +40,125 -> 897,982 +345,640 -> 432,640 +845,170 -> 403,612 +763,84 -> 763,885 +855,388 -> 123,388 +861,858 -> 861,940 +449,736 -> 97,384 +576,592 -> 906,262 +868,817 -> 868,633 +14,100 -> 610,696 +878,412 -> 416,412 +43,427 -> 118,502 +250,829 -> 770,829 +814,444 -> 814,769 +647,857 -> 528,857 +648,102 -> 514,102 +956,12 -> 887,12 +665,957 -> 665,891 +760,367 -> 178,949 +704,524 -> 815,524 +269,88 -> 322,88 +414,881 -> 414,788 +550,696 -> 550,788 +624,367 -> 391,367 +133,536 -> 432,835 +635,154 -> 169,154 +396,149 -> 396,166 +796,505 -> 886,505 +348,235 -> 530,235 +428,851 -> 240,851 +535,441 -> 637,441 +661,175 -> 782,175 +589,780 -> 99,290 +771,746 -> 771,239 +16,567 -> 821,567 +320,572 -> 320,136 +200,990 -> 513,990 +984,987 -> 11,14 +60,712 -> 60,137 +629,405 -> 738,405 +541,536 -> 541,225 +250,579 -> 507,579 +825,264 -> 974,264 +380,832 -> 262,832 +598,695 -> 598,159 +716,782 -> 418,782 +124,698 -> 713,698 +930,83 -> 212,801 +389,287 -> 344,287 +571,788 -> 106,788 +519,498 -> 135,114 +281,761 -> 221,761 +295,133 -> 295,654 +686,960 -> 592,960 +984,495 -> 984,913 +677,751 -> 677,102 +252,326 -> 252,824 +921,500 -> 357,500 +608,908 -> 608,381 +587,878 -> 587,677 +392,929 -> 449,929 +239,444 -> 822,444 +87,897 -> 252,897 +865,887 -> 368,887 +368,934 -> 368,308 +64,950 -> 182,950 +747,429 -> 636,540 +378,109 -> 378,865 +187,266 -> 856,935 +159,769 -> 708,769 +71,119 -> 892,940 +629,825 -> 87,283 +900,903 -> 900,656 +749,703 -> 812,703 +225,421 -> 842,421 +15,896 -> 837,74 +800,887 -> 58,145 +456,798 -> 679,798 +434,963 -> 434,166 +508,491 -> 976,959 +809,540 -> 809,614 +624,632 -> 975,983 +733,102 -> 195,640 +83,691 -> 623,151 +140,257 -> 29,257 +429,934 -> 429,482 +702,91 -> 702,137 +986,185 -> 986,386 +84,920 -> 448,920 +927,779 -> 927,679 +903,345 -> 546,345 +303,523 -> 303,862 +360,877 -> 360,202 +544,593 -> 544,802 +27,192 -> 27,837 +105,24 -> 574,24 +955,783 -> 556,384 +416,85 -> 416,322 +923,139 -> 553,139 +527,523 -> 828,523 +788,320 -> 949,320 +391,652 -> 391,166 +754,378 -> 607,378 +563,409 -> 563,27 +285,169 -> 285,883 +16,10 -> 988,982 +452,563 -> 452,479 +881,800 -> 881,542 +564,272 -> 457,272 +887,441 -> 887,298 +941,837 -> 119,15 +606,137 -> 606,152 +135,472 -> 135,322 +881,775 -> 881,132 +566,263 -> 406,103 +912,696 -> 912,965 +123,554 -> 123,911 +735,737 -> 533,939 +61,197 -> 534,197 +91,856 -> 91,465 +624,411 -> 624,247 +607,899 -> 607,786 +139,408 -> 466,735 +89,274 -> 545,730 diff --git a/src/t05_hydrothermal_venture/test.in b/src/t05_hydrothermal_venture/test.in new file mode 100644 index 0000000..b258f68 --- /dev/null +++ b/src/t05_hydrothermal_venture/test.in @@ -0,0 +1,10 @@ +0,9 -> 5,9 +8,0 -> 0,8 +9,4 -> 3,4 +2,2 -> 2,1 +7,0 -> 7,4 +6,4 -> 2,0 +0,9 -> 2,9 +3,4 -> 1,4 +0,0 -> 8,8 +5,5 -> 8,2 diff --git a/src/t06_lanternfish/mod.rs b/src/t06_lanternfish/mod.rs new file mode 100644 index 0000000..456ac2b --- /dev/null +++ b/src/t06_lanternfish/mod.rs @@ -0,0 +1,95 @@ +use std::{ + collections::HashMap, + io::{BufRead, BufReader}, +}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + nums: Vec, +} +#[derive(Debug)] +struct Input2 { + occurances: HashMap, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + + let mut buf = String::new(); + BufReader::new(f).read_line(&mut buf).unwrap(); + + let nums = buf + .split_terminator(',') + .map(|n| n.trim_end().parse().unwrap()) + .collect(); + Input { nums } +} + +fn parse_input_2(test_mode: TestMode) -> Input2 { + let f = test_mode.input_file(file!()); + + let mut buf = String::new(); + BufReader::new(f).read_line(&mut buf).unwrap(); + + let mut occurances = HashMap::new(); + buf.split_terminator(',').for_each(|n| { + let n = n.trim_end().parse().unwrap(); + let e = occurances.entry(n).or_insert(0); + *e += 1; + }); + + Input2 { occurances } +} + +pub fn lanternfish_1(test_mode: TestMode) { + const NUM_DAYS: isize = 80; + + let input = parse_input(test_mode); + // println!("{:?}", input); + + let mut current_gen = input.nums; + for _d in 0..NUM_DAYS { + let mut next_gen: Vec = Vec::new(); + for fish in current_gen { + if fish == 0 { + next_gen.push(6); + next_gen.push(8); + } else { + next_gen.push(fish - 1); + } + } + // println!("day {} - {:?}", d, next_gen); + + current_gen = next_gen; + } + + println!("{}", current_gen.len()); +} + +pub fn lanternfish_2(test_mode: TestMode) { + const NUM_DAYS: isize = 256; + + let input = parse_input_2(test_mode); + // println!("{:?}", input); + + let mut current_gen = input.occurances; + for _d in 0..NUM_DAYS { + let mut next_gen = HashMap::new(); + + for fish in current_gen { + if fish.0 == 0 { + *next_gen.entry(6).or_insert(0) += fish.1; + *next_gen.entry(8).or_insert(0) += fish.1; + } else { + *next_gen.entry(fish.0 - 1).or_insert(0) += fish.1; + } + } + // println!("day {} - {:?}", d, next_gen); + + current_gen = next_gen; + } + + println!("{}", current_gen.values().sum::()); +} diff --git a/src/t06_lanternfish/prod.in b/src/t06_lanternfish/prod.in new file mode 100644 index 0000000..8f54c83 --- /dev/null +++ b/src/t06_lanternfish/prod.in @@ -0,0 +1 @@ +5,1,5,3,2,2,3,1,1,4,2,4,1,2,1,4,1,1,5,3,5,1,5,3,1,2,4,4,1,1,3,1,1,3,1,1,5,1,5,4,5,4,5,1,3,2,4,3,5,3,5,4,3,1,4,3,1,1,1,4,5,1,1,1,2,1,2,1,1,4,1,4,1,1,3,3,2,2,4,2,1,1,5,3,1,3,1,1,4,3,3,3,1,5,2,3,1,3,1,5,2,2,1,2,1,1,1,3,4,1,1,1,5,4,1,1,1,4,4,2,1,5,4,3,1,2,5,1,1,1,1,2,1,5,5,1,1,1,1,3,1,4,1,3,1,5,1,1,1,5,5,1,4,5,4,5,4,3,3,1,3,1,1,5,5,5,5,1,2,5,4,1,1,1,2,2,1,3,1,1,2,4,2,2,2,1,1,2,2,1,5,2,1,1,2,1,3,1,3,2,2,4,3,1,2,4,5,2,1,4,5,4,2,1,1,1,5,4,1,1,4,1,4,3,1,2,5,2,4,1,1,5,1,5,4,1,1,4,1,1,5,5,1,5,4,2,5,2,5,4,1,1,4,1,2,4,1,2,2,2,1,1,1,5,5,1,2,5,1,3,4,1,1,1,1,5,3,4,1,1,2,1,1,3,5,5,2,3,5,1,1,1,5,4,3,4,2,2,1,3 diff --git a/src/t06_lanternfish/test.in b/src/t06_lanternfish/test.in new file mode 100644 index 0000000..55129f1 --- /dev/null +++ b/src/t06_lanternfish/test.in @@ -0,0 +1 @@ +3,4,3,1,2 diff --git a/src/t07_the_treachery_of_whales/mod.rs b/src/t07_the_treachery_of_whales/mod.rs new file mode 100644 index 0000000..35e8dbf --- /dev/null +++ b/src/t07_the_treachery_of_whales/mod.rs @@ -0,0 +1,67 @@ +use std::io::{BufRead, BufReader}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + nums: Vec, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + + let mut buf = String::new(); + BufReader::new(f).read_line(&mut buf).unwrap(); + + let nums = buf + .split_terminator(',') + .map(|n| n.trim_end().parse().unwrap()) + .collect(); + Input { nums } +} + +pub fn the_treachery_of_whales_1(test_mode: TestMode) { + let input = parse_input(test_mode); + + let min = *input.nums.iter().min().unwrap(); + let max = *input.nums.iter().max().unwrap(); + + let mut best_sum = i64::MAX; + let mut best_pos = i64::MAX; + for p in min..=max { + let new_sum = input.nums.iter().map(|n| (n - p).abs()).sum(); + if new_sum < best_sum { + best_sum = new_sum; + best_pos = p; + } + } + + println!("{} fuel @ pos {}", best_sum, best_pos); +} + +pub fn the_treachery_of_whales_2(test_mode: TestMode) { + let input = parse_input(test_mode); + + let min = *input.nums.iter().min().unwrap(); + let max = *input.nums.iter().max().unwrap(); + + let mut best_sum = i64::MAX; + let mut best_pos = i64::MAX; + for p in min..=max { + let new_sum = input + .nums + .iter() + .map(|n| { + let d = (n - p).abs(); + d * (1 + d) / 2 + }) + .sum(); + + if new_sum < best_sum { + best_sum = new_sum; + best_pos = p; + } + } + + println!("{} fuel @ pos {}", best_sum, best_pos); +} diff --git a/src/t07_the_treachery_of_whales/prod.in b/src/t07_the_treachery_of_whales/prod.in new file mode 100644 index 0000000..23b9031 --- /dev/null +++ b/src/t07_the_treachery_of_whales/prod.in @@ -0,0 +1 @@ +1101,1,29,67,1102,0,1,65,1008,65,35,66,1005,66,28,1,67,65,20,4,0,1001,65,1,65,1106,0,8,99,35,67,101,99,105,32,110,39,101,115,116,32,112,97,115,32,117,110,101,32,105,110,116,99,111,100,101,32,112,114,111,103,114,97,109,10,51,812,37,278,203,12,1699,10,24,482,200,197,433,141,1854,148,529,748,46,1366,41,329,300,29,159,767,661,238,586,940,139,1606,273,1093,1687,694,232,1069,264,162,752,250,138,471,828,72,285,136,817,258,586,308,191,478,43,750,570,38,207,1221,434,124,1410,125,743,7,827,963,873,263,478,938,686,250,1022,7,917,717,1354,618,639,24,113,417,550,279,919,736,75,117,1173,32,172,88,1435,15,442,232,272,102,253,113,173,86,57,536,1282,111,18,197,117,738,427,910,740,861,90,706,520,8,1,129,80,79,36,788,1545,119,971,1435,945,808,821,1080,227,1257,973,39,303,818,669,7,197,819,1683,50,2,1248,1459,669,210,653,978,76,509,173,304,183,228,45,1032,672,792,12,540,839,135,153,55,29,1190,42,395,626,487,54,831,956,1,1012,1461,929,561,34,733,629,49,146,469,220,1368,89,265,128,521,402,557,1121,853,240,655,100,341,137,525,371,288,1389,430,1148,398,130,174,176,982,74,923,1438,469,572,33,261,126,456,300,174,27,60,1052,428,196,403,394,392,40,474,27,351,194,619,657,722,181,300,448,1037,525,1388,854,1459,967,211,46,1708,1175,1225,613,1315,479,973,573,324,887,2,116,752,447,3,1074,1135,72,595,601,632,511,1349,267,164,6,1300,172,412,3,298,1120,93,161,176,141,150,67,37,144,421,45,1451,781,1120,205,487,344,372,150,136,614,265,536,1740,265,1367,0,322,204,76,97,1112,717,444,418,279,943,597,309,322,205,1167,292,18,383,367,621,770,13,243,1641,500,313,785,106,184,310,615,248,664,98,221,740,450,460,7,23,1226,183,75,449,806,721,1057,266,254,1083,0,125,27,151,16,664,73,94,44,1347,73,325,958,475,862,1096,1523,114,307,1418,46,113,188,462,194,535,282,1144,26,1106,1465,39,133,445,177,481,233,696,181,72,1466,747,266,44,311,1061,505,140,956,360,716,98,844,1059,305,162,1679,817,873,969,793,1079,320,318,70,417,1170,628,1628,1515,894,482,1757,423,1024,267,1280,10,474,806,684,378,425,816,243,388,27,116,569,777,946,593,646,91,639,508,63,405,1310,639,380,323,75,860,67,42,58,198,35,58,180,75,530,25,194,1743,476,1092,795,243,121,1326,409,1300,218,1393,371,64,412,209,255,648,480,71,125,1398,45,1035,1245,1426,1765,596,187,353,0,261,774,958,1303,397,1024,1076,1225,307,69,789,307,450,143,203,259,21,2,297,963,1236,1292,595,784,100,1194,1246,1820,534,58,244,12,194,1316,211,368,192,741,1232,23,87,551,291,12,512,6,42,1513,619,62,1339,375,743,137,1486,254,53,274,299,1443,844,899,753,414,241,161,52,163,66,86,503,823,528,150,376,403,1346,125,363,412,774,374,1090,1001,177,1379,74,193,49,92,294,679,108,228,199,1203,324,64,321,89,601,32,46,1274,519,1089,1107,63,379,1062,1034,129,736,716,156,526,445,1,299,388,444,1080,1016,101,735,315,517,13,390,537,155,140,1119,975,259,254,402,277,1160,372,55,392,1022,1119,4,735,266,260,1550,389,824,1426,23,65,480,151,176,1761,0,16,139,152,383,358,1155,95,1138,310,232,71,1073,22,1,335,1168,792,136,902,33,204,59,146,1063,1012,103,1083,160,885,445,499,473,278,451,191,1940,249,37,722,325,495,615,70,85,50,107,560,597,75,206,767,990,113,530,94,1343,250,116,67,417,390,500,633,736,132,473,646,1502,249,119,228,3,64,212,19,1005,324,14,418,619,847,20,878,533,204,49,820,216,34,60,62,119,680,88,359,8,473,882,138,387,297,419,664,693,420,101,53,829,3,101,272,726,639,368,363,0,33,70,0,626,525,364,784,271,73,536,318,598,794,34,314,1248,1596,764,34,202,1383,635,158,1095,76,0,119,176,1158,301,409,796,242,1765,808,59,0,278,4,8,359,1111,818,931,220,109,292,353,532,750,333,223,725,1476,199,1,201,55,72,117,37,210,400,108,619,863,187,372,15,574,380,635,332,1,1210,64,897,501,12,822,508,250,263,1044,72,15,210,901,219,471,292,179,572,733,422,1354,1197,202,538,662,261,973,0,465,522,412,9,166,325,237,757,115,1046,273,549,174,30,96,215,113,7,1032,671,262,202,332,1078,629,555,26,8,29,349,206,123,1093,673,1356,513,1454,518,1240,337,96,115,1160,17,331,1450,114,107,782,995,168 diff --git a/src/t07_the_treachery_of_whales/test.in b/src/t07_the_treachery_of_whales/test.in new file mode 100644 index 0000000..18bd32a --- /dev/null +++ b/src/t07_the_treachery_of_whales/test.in @@ -0,0 +1 @@ +16,1,2,0,4,2,7,1,2,14 diff --git a/src/t08_seven_segment_search/mod.rs b/src/t08_seven_segment_search/mod.rs new file mode 100644 index 0000000..e756c68 --- /dev/null +++ b/src/t08_seven_segment_search/mod.rs @@ -0,0 +1,128 @@ +use std::{ + collections::HashSet, + io::{BufRead, BufReader}, +}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Display { + patterns: Vec>, + output_values: Vec>, +} + +#[derive(Debug)] +struct Input { + displays: Vec, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + + let mut displays: Vec = vec![]; + + let mut br = BufReader::new(f); + loop { + let mut buf = String::new(); + br.read_line(&mut buf).unwrap(); + if buf.is_empty() { + break; + } + + let mut s = buf.split_terminator(" | "); + let patterns: Vec<_> = s + .next() + .unwrap() + .split_ascii_whitespace() + .map(|s| s.to_owned()) + .collect(); + let output_values: Vec<_> = s + .next() + .unwrap() + .split_ascii_whitespace() + .map(|s| s.to_owned()) + .collect(); + displays.push(Display { + patterns: patterns.into_iter().map(|p| p.chars().collect()).collect(), + output_values: output_values + .into_iter() + .map(|p| p.chars().collect()) + .collect(), + }); + } + + Input { displays } +} + +pub fn seven_segment_search_1(test_mode: TestMode) { + let input = parse_input(test_mode); + + let mut n = 0; + for display in input.displays { + for p in display.output_values { + if [2, 4, 3, 7].contains(&p.len()) { + n += 1; + } + } + } + println!("{}", n); +} + +fn filter_num_segments(display: &Display, n: usize) -> Vec> { + display + .patterns + .clone() + .into_iter() + .filter(|p| p.len() == n) + .collect() +} + +fn solve_display(display: &Display) -> usize { + let one = filter_num_segments(display, 2).into_iter().next().unwrap(); + let four = filter_num_segments(display, 4).into_iter().next().unwrap(); + let seven = filter_num_segments(display, 3).into_iter().next().unwrap(); + let eight = filter_num_segments(display, 7).into_iter().next().unwrap(); + + let size_6 = filter_num_segments(display, 6); + let f_char = size_6 + .iter() + .find_map(|d| { + if one.is_subset(d) { + None + } else { + Some(*one.intersection(d).next().unwrap()) + } + }) + .unwrap(); + let c_char = *one + .difference(&[f_char].into_iter().collect()) + .next() + .unwrap(); + + let size_5 = filter_num_segments(display, 5); + let five = size_5.iter().find(|d| !d.contains(&c_char)).unwrap(); + let two = size_5.iter().find(|d| !d.contains(&f_char)).unwrap(); + let three = size_5.iter().find(|d| one.is_subset(d)).unwrap(); + + let six = size_6.iter().find(|d| !d.contains(&c_char)).unwrap(); + let nine = size_6.iter().find(|d| four.is_subset(d)).unwrap(); + let zero = size_6.iter().find(|d| !five.is_subset(d)).unwrap(); + + let digits = [ + zero, &one, two, three, &four, five, six, &seven, &eight, nine, + ]; + + let mut sum = 0; + for number in display.output_values.iter() { + let value = digits.iter().position(|p| p == &number).unwrap(); + sum = 10 * sum + value; + } + sum +} + +pub fn seven_segment_search_2(test_mode: TestMode) { + let input = parse_input(test_mode); + + let sum: usize = input.displays.iter().map(solve_display).sum(); + println!("{}", sum); +} diff --git a/src/t08_seven_segment_search/prod.in b/src/t08_seven_segment_search/prod.in new file mode 100644 index 0000000..809c897 --- /dev/null +++ b/src/t08_seven_segment_search/prod.in @@ -0,0 +1,200 @@ +bgcfda gecbda abdgf aedfbg eda efcbd ae agfe bdefagc fbeda | ae egdafb ea fcdeb +gfadb fbagcd cagf agecdb adg fdbcg bdcfaeg bcgfde ga efbda | cbfdge dfcebga aedcgb dgbfa +bgdeca agdbe gfb fdbgce bf eafb dfgab efbgdca gebafd dgcaf | gfbdea gfb bacedg adcgf +fbc becgdf fcbdg adcgf edafgb bgec dcgfbea gbfed bc cbeafd | gfacd gcbdf bgedfa cbdefa +ad dcafeb adcef feagc egdbaf aed cadb bgcedf cbeafgd cdfeb | dabc gabefd ecfdb ecgfbd +badcgf gdaf gadbc ebfcg fceabd gacdbe gedfbac dbf df dfcgb | df adfg cbfgad fdb +cfdb dca bdgca efgbad bafcgd fgdba cgdfea cd abdfegc bagec | agcbe adc dabcgf adc +egdab gcefd ecbgd gdebcaf eacb cb bagcdf abgfde dcegab bdc | bc gedbc dcb fgdec +gefa gedabf cfdbea bdfea bdegcfa dgbfa gfd gdcab fg fecbdg | fgd gf dbfage afbdec +fagdb be abdfe agfebdc eab aefdcb acfed bdec fceadg afegcb | be aegcfb efbcag eb +fdce fcadeg afegdb adceg cgafdb de ebcga dae cdagf abdfgce | efcd efacgd edfc afgcd +gefc defca aefbd ec gfdceba dcabge fgcad cae fcadeg bagfdc | fgcad bdfea ebadgcf ce +cdabe dcg cgef gc beadgf fegbd gcbde edgcfb gecfabd fdgcba | dcg deacb fdegab bdafgc +aefc ebcdfa eabfgd deacb ac dac gdbce gfbadce fdeba gcfbda | adc afdbe aefc ecdafb +eabfdg fdgba fac fc ebdac bfcg fcdabg bgdface bacdf fgedca | fdagcb cedba cf fc +db dbg debag fcgdeb gfeba dagfec ceadg bdfecga deagcb acbd | gbdae afebg cfedgba ecdagb +cabegd befcd aefdcb defbcag dgfb gd edg bfgecd gfdce eagfc | dbgacfe efcdg gd bdfagce +abde fbecag gcabde cefdg bgedc bgcea bgd becgdaf gdcfba bd | baegc egbdc cedgf gdfec +gedc eagbd bgadcef aebcdg dfbag eacfdb cabde fgecab ge aeg | gcbeda gabdfec dgecba gea +afedgc deabf gbfceda fg cgdea dgf bdgfec edgaf ebacgd gafc | fgd gfac cbefgad cagde +gfcbeda bfecda dgca ebgacd gbfae ecg gc gaebc cfgebd dbeca | dfcbea cegab cg cge +adefc eabdf bcafeg bd edb fcbeadg dabegc fdbg baegf fgaebd | fcead fcdea fbgd ecdbga +ac bedgc acdb gacbed bfgeadc degcfb aec cafdeg eagfb cegab | agecb gdbec abgcde agbef +cfgbead cfgdeb gafb baecd bg cgdba bgc adcfbg agfecd dcagf | dgcefb bgaf fdbcgae agcdf +agc dabc dcbgef efadgcb ebdgc baefg ac abgce ebdcag facdeg | ecbdgf ac afdgbec decfbg +fgdcb cbdeaf eabfcg cefdb gcbeadf cdeg gc afbdg cfg ecdgbf | cg eafbcd dgec cbfdge +da dbae fdaecb cdebgf afgced bedfc adf cbfeadg bdacf bfcag | dfbec egbdfc bdfca cefbd +abgfced cf cfdbe geacfd bfac bdacfe gdebc bfedga dcf bdafe | bcfa dbfce cf egdbc +dcagb feagbc dbef edafg fagebd bf fedgac fba bfagd dbcefga | fbdga dgafe cfabge fdbe +gbfce bfc acgb fbgaec bc acfedbg gface cgefad bfacde defgb | cbgfe bgfeca gacb degacf +cfgeda bac dbafg dbcfa bdfcage ecfb acedf cb ecfadb eacbgd | gafbd faced dacfb bcef +fbgec eca cbag cfegba ac efacb bgcedf caegdbf fecgad fdbea | ca acgb ebdfa agcb +acgbf cdabegf egbfd dc dacbef dacg gecabf fdc dbgfc dfcagb | dgabecf befgd acgd abgdefc +dagbfc bc agcdf cgbd bfc ebfad dfcba befgac gaecdf becdgaf | cdgb dbcg abfcdg cfb +bdcga ebdgca da cdeafg dac acfbg daeb cdbgef egbfcda bdegc | bcgad adgcbe fedacgb cegdb +gacfeb aefbg fbaegd cedgfb dfcba gc cgae abcdegf gacbf gbc | cfabd debfgac cega egca +abcfeg fdbegc ac bdafgec ebfad fcdae dcga fcged gdceaf ace | gbcfaed ebfda ac gefcab +gefbc gdeacf cag ac acgebf ceab adebcfg bfcag cgbfed bgfad | cga cagdef gac fcgba +gcbe gacfdbe dfgaeb bfecd ecdgfb dfcgae bef fcedg bcfad be | fadcb ebgc cbfda dfcab +ebcgfd dafe adcfg gfacde cfabge bcadg dfc fd fbdaceg gefac | fceadbg fcgabe fade fbeacg +fbacg cef cagebf gacefd ef bgced cfbeg dagcbf fbea cegfdab | eabf fce cdgeabf agefcb +bca gcadbfe ca edca fbgade dcageb ecbgf egacb ebadg dgcfba | cgafbd feagdb gabecd cba +fcebdg cgefb fagbce edcbg bfed eacbgfd cegda db bcd dfgcba | becdg cdbafg bedgfc cgbeafd +fcadebg edbafc cgfda decba egab gcadb gb debgfc cgbdae gdb | bgd agbe eadcbf gdb +cedfa gad ebcfda aedgc defagb gdafceb gebca dcfg dg edgacf | cdfg fadec gedac bcgae +dafegbc dcfbae dce fcebgd egdaf ecadf dfcbag acbe ec cafbd | ced dce ce ec +fegb ef bdcefg fabdgce efd fegdac cbdaf bcdef ecbdg acbedg | debgac edf ef dfacb +afgedb caedbg egfba baecf efgdb gbcadef fagd age cfegdb ag | afbec degbafc fceab eagbdc +cebd dfb dbecgaf gefcb afbegd bd fdcgb gfcebd cgdaf gfeacb | abecfg gacbfe cgfda bfceg +acdfgb ecbga ba ecgdafb deafgc aedgc aedb aecgdb bag gfecb | cgaefd gabce cdgbae ab +be fcgdae fcbag efdbcg ceb cfebg degb cdebfa fgdec gdcabfe | eb dfegc debg bce +fdecg dafgebc fgcae fgd bcfd bcged edbgfc aecdgb fbgade df | afbdecg bgfaed fcged bgedaf +cabd egdfa fbgac bcgafd ebdafgc bd eagbfc dgb fdabg cgbdef | bd bd dbg cbad +fgecba bd dgcbea gfeda gdb geacb ecbd bfadcg efcabdg bgade | dgbae befgacd ecbag afcebg +ga abefc afg fecadbg egfcbd dgfbac edgfac adbg fcgdb gbcfa | dbag fag fgdbcea dcbfeg +geacf cadfe bfaced fg fcdgae fged ebagc cfg edbfgac bfdacg | afcbged efadc fg fcg +cbd cdefbag cfadg bd bfdac abed fdabce dbegcf egabcf ecbfa | gcebdf faegcb ecdgbf fbeadcg +fagcde cgdfa daef acgde ecgadb dbcgf fca eacgbf gcafbde fa | cdage cebfga adceg deafcgb +feadgcb efcag dbfge edba dfcabg ebgfa ba gefbad ebgdcf bfa | abdefg daeb bfa fdgaecb +dgfcea becdfg bdefg abgdfec beg cgedf eb decb bgefac fgdab | beg fedgc egfacd fcedg +fcagbd adbfeg gbeda bgfde ebfcdg dfae gaceb gda ad fdbcaeg | agd gdeba fdgeab ebcga +dbcefa bfaegd fdcb fdeca agceb fcabe cfaged beagdfc fab fb | edabgf gcabe adefbc fba +eac cfgeab agdfc cdgbe gdbefc dabe gefdbca abcged ea agecd | baegdcf bfcegd gdbfce gfcebd +cdbeaf cd dcf adcgfeb defab gbfca dgbafe cead fdcab bcefdg | dfcabe fcd dc cdfgeb +gdcfbe bag dcebg dgabce cfgdba geacb bdea ba febcagd faegc | gcfea dgbfec fecag cefbgd +ebfdgc baecdfg gabfe acbg bce dgabef cdeaf gfabce ecafb cb | eabcf gdfebc egfabc gafbed +dbgacfe adgcf cedafb ecbad bdfe bf egcdab abfgec fab cbfad | bdfe fba bcfead abedc +dca afdcb befagc gacedf dbecf cgfabd da dbag ceabfdg afbgc | da adgb gfedcba dabfcg +fgcda bcgf cgfeda bfdcga gbd badfg cebafdg gcadeb bg dfbea | fcbg geacfd abfgcd bafgcde +cf gacbfe feadcb cdgaeb fbcd fcdae efdag ecf gcabedf edacb | ecabgd gbcfaed gebcad efdac +ae abcefdg faedbg agedf dgbfce gabcfe adfcg dfbge efa bdae | dcfebg fae agfdbe egfdba +fegdcab dgcaf bfd fgdab edcgaf eadgb fbcg deacbf fb gbdcfa | acefdb gdcaf fcgda gabde +ca cefa bgcfed facdbe dgbfeca adc dbacfg cabde edabg fcbde | dcbefa bedfc dfcgab dbfacg +ce bgcedf cgdef gdabfe cabefd dec aegfdcb dgcfa gcbe fgbde | cegb dce aedbfc ce +fcgaebd ef febdac feb cafbd edcfb fabecg acbdgf dfae ebgcd | feb bfe fegacb bafdec +fgdec adcb dfbega afcgeb egcbd db bcaeg beagdc dbgfcae deb | bd egcdab fecdg bed +ad dcaeg edcbag fgbdeac acd gcdfeb afegc ebda cadbfg dgbce | bfgadc dca ad cda +bdegaf egfdb afb acbegdf fgdba af feda bcfgea fbdecg abgdc | fdegb fabecg degabf adgbef +gdfbe gcf gbcda cadfbg cfdbg gceafb dfca badegc cf cedgbfa | fc fcg egcabfd bdcag +fcbag ebdcgfa ce fgaced fbgeca gfbec cgdfba fbgde efc aecb | beac ce cgbfe bfegd +dcgaef gedfb fegdabc eabfdg dgc cefgdb bafdc cg gecb gcdbf | debgcf gbcfd gbce baefgcd +bfacdeg cedgf gfdbec eca edgcfa dbeaf ca fcdea dcebga cgfa | cefgd gcedfa bdfegc aefdc +cdfea ebgdf ab adebfgc bdcegf gbda fab dagfeb ecgabf ebfad | defba cfdea ba ab +gbefcd cbedf fcaed dgfb dacgbe ebfgca fb bfecadg cfb gcbde | eabgdc egcbdf dcgbef fb +afgedb cabdefg afcdb efdgca ef abgde edf ebfad agdbec fegb | edagcfb cdfba efdagc dcebga +dcfg afbgedc efgdb agbfe fde dgbce dabegc gdbfec df fadcbe | dbfeg gdfc efd faegb +ebgdf acfge bae gbafe efdabc ba feadbg bgda gfebdc gedacfb | fbdcge dbag ab bafedc +abedcg dcagfb cf dagbc afc fceabd fbcag dfcaebg dcgf abefg | afcdbg dcfabe fcabg adgcefb +fdbc egabc bfegc fc gbfced aefbgd gfebd gfacde bgdafec fec | fbcd fedbg daefcg cef +bgacde fegad febc gfacedb gebca gaebf bfa efbgca gfadcb fb | bf dcgfeba fdcgeab fb +cgdfe fagec fbace afecdb acg fgcbead ga abfcge bcgdfa ebga | gabcef cfgde dfgcba gcbdfa +bgae ae acegfdb dbfeg dbcgfe ebgafd dfcba cgefda adebf eda | aebfdgc bedaf feabd fbadc +dfagcb cbdgea efabdcg ecdab gceaf daecbf df cdefa fad befd | afd gefca adgfcbe fd +dcfeg acgf aec degfbc ca efbcgda fcdea gfdeac faedb cegdab | egcdaf gebdcf bdaegc aefdc +cgebaf cbdagef cadgb efda degbaf fgbea dbe bgfdce edbag de | de feda dagbe agfcdbe +eagbcfd eag efcad acefgb ag gadce fadg bdgec baefcd aefgcd | bgecd edcfab baecfg ga +adbcfge eadfb faecd ab dba aebgdc ebdgf ecbfda fcba gdfaec | efcad febdg bfdgeca dba +adgfc dfegc cdfeag edf dbecagf fdabge fbgce ed dcea cagdfb | agdfbe def efd deac +cgb bfgde bdcfa fgcbd fgeadbc fcabed befcag cg dacg bgafcd | cg acfedgb bcagfe bdfagc +fcbdge egdac acgfe efgcad fc cdaf gacefbd fcg faebg dcebag | ecdag efcgda fdac dgcbea +dgabef fdabg bcdagef dcfbg fgac adfcbg fc gdbec cbf fedcba | bdcagf dfagb fabgd cf +defc cgafed ecafbg fbdag aef cdgbae gecad facdgbe ef dgaef | fe fbecga gfdba adgebc +gbdfac gcfbd dgceb bcgdfe fedabcg gdfe fbceag eg baced gec | gacfbe cdgebf cge cge +acgdbe cfa gfba cfdab cbgadf cefdb bcfadeg fa fedgac agcbd | abfg agcbd gcfeabd dfcbe +dagebf defcb dgecaf edfbac aecbdfg deacf be aceb bfdgc fbe | ebac dcfagbe feb bcae +gbcfad fadgbce ag fdcegb gbda ceagfd agc cfdbg gfcba eabcf | dagbcf gdacfb dafcgeb eabfc +dbgcea ag acg dbag aegcd bgdefca bdgce ebgfac cgbedf acefd | agecfb abdegc dgcefb agbd +dgebfca cgdfa bgafe eda cgedfa dfage fgdbac ed ecbfda egdc | befgdac daefg acfdg acdebf +fgadce dcb abgdefc cedgf fecdb cb dgcfbe bgdeca gcfb defab | fcegbd cb gdfce gfebcd +cfbdgea ec dacgf fdeab adfec dbce dbegaf cfe deafbc ebfgca | ec decb ebagfd gcfaedb +gd bcegad afdec dgbf efcdagb cdg fgdcba fgadc abfgc cgafbe | gacfb bdcgea fabcg gd +dbega afebdg ca ecabdg deca cfgbae bca gebdfac gfcbd adgcb | cab caed abc cead +cgdbfe ab fgade gefcab afcdebg agdbe dcbeg bdca abe cgabed | ba debgc gcefba cegdab +cdfegb dbafe abdgce cbfgea bfg fg cgbed dfgc bfceagd dgbfe | gf fadgcbe aebgcf cafegb +ecafb efgcab gbdecaf fbega egabd gef dfbcge fg dcbfae cafg | dcgfeb bafdceg agfbe gf +efdcbg fgbca dcgbf dbfcag faebcd abegc afc egcdabf fadg fa | fa afc adefgbc fbcedg +dfa gcdbeaf dgbafe gacfbe dcagb adcbfe febca df dbfac cefd | adgefbc daecfbg efbca bagefdc +aec fecbgd aegdc fgcad bcedaf bdcge gbea defacgb ae acbgde | ae deacg edgcb afdecb +cdab bedgf dcbegaf gdfac bc efabgc fbc cdbgf afgcbd efdagc | cfb fgebca cgfdab faedbcg +ab eacbgf bdfa fcaedg fdebagc degba bcdeg afdgeb dgeaf gab | gfdbea afdb afdb gcebd +acbed bfeacd aedgc aeg ag gdbfae egbadc bacg fcdeg gcdbfea | gdaec aefbcd gae bdaegcf +fgadbc geafb dafbgec ecdb ce bcega deacgf egc geadbc cgdab | ecgba cdbe gacedf aecgb +gbea eb cfdbaeg cebad gbdac fcdae dgebcf fcabgd adgbce ceb | dagecb ebc dagbc ebc +fbeda ga aeg aebgd agfd bdgcfae fedgab dfeacb fbaceg begcd | ga ag afcbeg bfecad +efabcg bdc fedgc adebgcf gcabed cfdbg dfba db cafgb bfcgda | dcb bdc agfbc afbegcd +fbade bcagfe cgfea cdag dfc cfade begcfd cd gecbdaf dfceag | cgda gcda fcd dc +dbcfa bg gafcde bdceafg gaecbf cbg bgde bcgad aegdc bceagd | gcdab eacgdf bg cgb +ecfagd fbadcg fgbae bdgae gbf befc facgbe gecbfad fb eagcf | gabed fb egabfcd facbegd +abef dcabf ecfdba afbcgde bgdfce af acf cagdb gaefdc bfcde | cfadb abef bcfde cgfdbe +acedbf abcfdeg bdceag bgade acdfgb aeb bgdfe eacg ea gdabc | begda dfbge ae badcg +fcda abgef da dea dacgeb fbdae cedfab bagfced ebcgfd cdfeb | bcedf edcbfg dbaceg bdcfe +dgcfba cadeb agcdb aebfgc gdaf bcfdg gac ga fgebcad fdcebg | dgacbf ebdca egfdcb bcfdg +afbedg egbd bfcdag edgcaf gbdcfae afegb fgdae gbf fcbea gb | dgbe edbg bg efdag +acb abcfde fcgead efacd eabfc dbfa ab egfcb bedgac fdcaebg | defca acb caefd acbdge +afcde dbe fbcaed aecbfgd bfec be eadbc afgdbe dacbg gcfead | be ecfb fgdabe aedgfb +fdeacg cbgfa gefb bfc bf gbafce bdefac agefc aegcdbf agcdb | bf gceaf efbg bfcaeg +fdce gacfb agbdec cgafd df caegd gdcefa bcgadef agfbde adf | fagbc fcgdea fd bfgca +gdfacb aebcg ga dgae egfcbda cedbg dbegca acg gbedfc ecbfa | ga eagd eagd edgfbc +cgbdf eb caged aegfcd egb badecg gdbce ecba egfdba dfbaecg | cagfdbe geb dgcefa dafegc +cd gbecaf acfdb cdfg cda gbdface gfbac dgacfb bfade dgecab | dfcgaeb dc bgdacef bfacd +geab fecdb gb feabcgd ebgcda gdcae gecdb gbc afegdc gbfdac | debcga bgdaec dceagb cbaged +edgfcba agd bacd afcdg degbfc acefg efdgba bgadcf da gdfbc | gcfbd dbac cgfdb gecaf +bfca fcbged dfgab cgbadf cdfabge degcab adfeg cgfbd ab bad | abcf afbc gafdb acfb +gc fdgac fgeadb afdcb gecdfa gac gecafbd cabged gfce gaefd | ecbdgfa cag bgfeda eafgcd +eagdc efdacbg cdgbe cbfdg egadfc egb aebc be gefabd dbecag | bafcgde beg gbacde dcbge +ac afbgcd gfdba fabecgd ebdafg bac cfag adgcbe abcfd cfdeb | adbegf egacdb bac acb +cafbed gf gfd cgdba eadfbcg gfdcb gbef cfdbe fdgeac gedbcf | facbegd cbdag fg fdg +fbgcd fadb fcd fd dfcbga decabg egbcf gacdb fcgeda aecfdgb | bedcafg cgdbaf fabgdec dcbgf +gb bcgeaf aebfcd cdefbga cbaef cgafb gbf dfacg gbcfed bega | bg bfacg bdfcge geba +cadfe afbgced aedfcg cebfg aeb fdageb bfcade bfaec ab bcad | bacef bcafe bfgeda baefgd +cgbde abcg cea dbegca ac agced befdgc bgafdec efgda badefc | cae eca gdfae dcega +ab fgcbed agb cafge cegba deabfcg dbgec aedgbc gfadbe bdac | ab bdca cgfedb dgceb +bfgadce cfadg fa cagdfb bcgdf fagbec gfa fbad bgcefd degca | fa ecgad gceabf dcfgb +gfd dcabegf fg cefdg cbefgd gefb ebgdc egacbd gcafdb dcfae | ebfgdc cegdabf cbafged fdg +dfecagb fbag bdcega gecdaf fg cgbad gfdacb fbcde fgd dfcgb | gfd gfd dgbeac fg +gfaed gad feacg dfaebcg deba efgbdc gefbad ad agdfbc fbdge | dga bdae fegbcd dgfabc +agdbc egdcafb caegdb afgdec cbadfg fdgba efdba bcgf gf fga | dfabg cagfdb eadbf cdfaeg +bgefac fecdabg cebdaf de aedfb ade bcefa gcafed bcde adgbf | ebcgaf fbadg ead dea +edbgc dcba egcfbad cfdage abfegd caged ebd bd gdaecb cgbef | cdebg badc edgbc ebcdg +cgfabe dce fcdba efbcg bdcef bagfecd eabgcd ed ecgbdf dgfe | fdcgbae egfd edc bfegc +fgecad gebda ebgcd egc dbecgf ce cbef cgdfb egacdfb agdbcf | edbfgc cdgbe edgfcb bcefgad +geafcd cdage ec cdegbaf gec cgafeb abgcd gebfda gafed dcef | ce gdbfea egdabfc gec +be abdgfc daecgfb bae dbfag gfdeba dbafe gbfeac egdb dfcae | bdge eba ecfgba gcaedbf +bcge gbeadcf acg bfcdga bfcaeg cfaeg gc feabc bfaecd gedfa | bfeac begc fgdbca bgfedac +gfbed ce ced fceabd dabegf bcdgef egcf becfagd gcdbe gcadb | ce ec bdfaceg cdeafgb +gfdea db cfdgbe badc gbaec ebfagc bde dgbcae egbda cbgedfa | badegc cbeagdf bd egfbcad +deabcg egbca agfdbc edagfb abe eb afbdceg efcag becd agcdb | bced eb be bea +ebfgda bgade dbcea geaf gcbadf dgfba eg gcedabf geb cgfbed | edabg ebg cedgfb bgdcfa +fc adgbecf fbcd abgfdc cgfab aedcfg dgcab gfeab cfg cbdgae | fcg badegcf bgdac fgc +edg egbda dafbgec begc aedcb cadgeb eg eacdfg gafbd cebadf | dfgba bdegac cbge afdbec +bgfecad gdbaf afdbeg egafcb db dba fdbace egafb gdeb dcgfa | fcbade fdagbe bad cdbefa +bcgedf ecba bagcef beg cgafed eb gfedcab gfbad efgba egafc | bace fbgdec cbgefa beg +dgfecb fcd edfbag bcfade fc caegd bcgedfa defab caefd cbaf | dbeafcg fc fabed dcf +ceafg fbad cfeba edbca afebdc bf cegbad bcdfge cgdefab feb | gdbecf faebdgc dcaeb ebf +cgdfba cdabf gfedca efgcadb baegfd bcfg fc caebd gdafb caf | cgfb dgcfab befgadc debgcfa +ebfgca abcfe gca bagde bgcae dbgcfa efbadc gcef agefbcd cg | abegc cbfae acefbgd cag +dfegac gedc bcdaef abgfd egf ge fagecb agefd fecdbga ecfda | gbafd dacbef gdefac gef +feb begcdf fcab edcafb bf aefdc gbade bfead daegfc feagcbd | bcfeagd gcdbfe fbceda fb +baefgcd fedcb cfbaed dgc abdgf bdfgc bcedgf gc gcfe aegdbc | ceafgbd fbcdge bgdface efbdgc +fd gbdae bfda ebfgdc edf gfdea caegf aedgcfb fadgbe bcagde | abedg adegb efd fcaedgb +befg gecdb dbcgafe adebcf dge ecfbd bcefdg aecgdf ge bgcda | bgfe gdebc dge ge +cfdgb be aecfg gefdbc bgfec afbdgec cdabfe egbd cgabdf cbe | fbdgc eagcf eb faegc +gfdbae aedcfg gbcfed bcde dbefgac gfacb ceg bdgfe ce efcbg | efcbg ce edcb ebgadf +ba fecba dbcgfae gcab gfcade febdc adfegb fab aegfbc gcfae | adfgbce gebdaf cefba fba +eadbf acfde cfdeab bagfcde bgfcae eab gafdce cedb dbgfa eb | bea fgeacd eb fegabc +ecb baedc ec adbfgc cedf faedcb acdfb fdgaebc agbde aegcbf | fdce cbfdage bdacgf cedf +fegc cefgdb fdbge bfg badgcf eabcdf fg begad dafgceb fedcb | bgf fdbec gf ebdacf +gfecdab gbeac aebd be eacgd ebc dfegca cbagf agbdce bcdgfe | bec ecdga ecb gabec +cb bcfg cgdfa adegfc bca aegdb afcebd gcdfab dbgca becfdag | bc badcgf bca fcbg +gabdce dc fbgdc gbfec cfda fgadcb bafgd fbdeag abdcegf cdg | fcda adbfg cfgbead dgacfbe +ecgab gbdecaf bcfa cdegbf eabgdf fgeabc ba egfcb gedca gba | fcbeg gacbfe ecdbafg deacg +agc bgfca cg cgafdbe dcfg dcfagb fbdag cabef gdbace gdefab | dcfg agbfc bcfea cag +cagb ga dfcga fdaebc fdebga cbdafg gfcbdea fcgde cfbad afg | cbga cedgf cdbfa afdbcge +cafgdeb aebfd gfbeda ebcgdf agcbf egf decbaf egda abgfe ge | bgacf bdfea agfbe beadcf +be agbefdc aedfgc gabfc adgfeb egb efdag afgbe deba bgfedc | fedgacb dcafge bdae ebad +cfbae dcaegf cdbfaeg fcebga efgca cdfab ageb gcbfde ebc be | acfgde be be bcfagde +bafdgce cea gdbcfe ae agecd agcdbe ebfcad agbe bcdeg fgadc | cebgad ecbgd cbdeg gaeb +bgce agefcbd egbcfa eg fadgb bfcae dfbcae egfab gae fdcega | age gafcbe eacfbg gea +fgacde gfaedb ebacf gc gdfc dcbeafg fadge gec bdcgea cgfea | fdagcbe gfdc aefgcbd gc +gb acfdgb bga aedgf bafdg abdfecg gacfeb bgdc bfcad fcedba | fgaecbd dabcf bcdg bg diff --git a/src/t08_seven_segment_search/test.in b/src/t08_seven_segment_search/test.in new file mode 100644 index 0000000..c9f629b --- /dev/null +++ b/src/t08_seven_segment_search/test.in @@ -0,0 +1,10 @@ +be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe +edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc +fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg +fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb +aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea +fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb +dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe +bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef +egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb +gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce diff --git a/src/t09_smoke_basin/mod.rs b/src/t09_smoke_basin/mod.rs new file mode 100644 index 0000000..dac8b70 --- /dev/null +++ b/src/t09_smoke_basin/mod.rs @@ -0,0 +1,143 @@ +use std::{ + collections::{HashSet, VecDeque}, + io::{BufReader, Read}, + ops::Index, +}; + +use crate::types::TestMode; + +fn parse_input(test_mode: TestMode) -> Floor { + let f = test_mode.input_file(file!()); + + let mut floor: Vec> = vec![]; + + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + for line in buf.split_terminator('\n') { + floor.push( + line.chars() + .map(|c| c.to_digit(10).unwrap().try_into().unwrap()) + .collect(), + ); + } + + Floor { floor } +} + +struct Floor { + floor: Vec>, +} + +impl Floor { + fn rows(&self) -> usize { + self.floor.len() + } + fn cols(&self) -> usize { + self.floor[0].len() + } + fn get_neigbours(&self, p: &Point) -> Vec { + let mut points = vec![]; + if p.row < self.rows() - 1 { + points.push(Point { + row: p.row + 1, + col: p.col, + }) + } + if p.col < self.cols() - 1 { + points.push(Point { + row: p.row, + col: p.col + 1, + }); + } + if p.row > 0 { + points.push(Point { + row: p.row - 1, + col: p.col, + }) + } + if p.col > 0 { + points.push(Point { + row: p.row, + col: p.col - 1, + }) + } + + points + } + + fn find_low_points(&self) -> Vec { + let mut res = vec![]; + + for r in 0..self.rows() { + for c in 0..self.cols() { + let p = Point::new(r, c); + if self.get_neigbours(&p).iter().all(|n| self[n] > self[&p]) { + res.push(p); + } + } + } + + res + } + + fn find_basin_size(&self, p: &Point) -> u32 { + let mut used = HashSet::new(); + + let mut q = VecDeque::from([*p]); + while !q.is_empty() { + let p = q.pop_front().unwrap(); + used.insert(p); + + self.get_neigbours(&p) + .into_iter() + .filter(|p| !used.contains(p) && self[p] != 9) + .for_each(|p| q.push_back(p)); + } + + used.len().try_into().unwrap() + } +} + +impl Index<&Point> for Floor { + type Output = u8; + + fn index(&self, index: &Point) -> &Self::Output { + &self.floor[index.row][index.col] + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +struct Point { + row: usize, + col: usize, +} + +impl Point { + fn new(row: usize, col: usize) -> Self { + Self { row, col } + } +} + +pub fn smoke_basin_1(test_mode: TestMode) { + let floor = parse_input(test_mode); + let sum: u32 = floor + .find_low_points() + .iter() + .map(|p| floor[p] as u32 + 1) + .sum(); + println!("{}", sum); +} + +pub fn smoke_basin_2(test_mode: TestMode) { + let floor = parse_input(test_mode); + + let mut basins: Vec<_> = floor + .find_low_points() + .iter() + .map(|p| floor.find_basin_size(p)) + .collect(); + basins.sort_unstable(); + + let sum: u32 = basins.iter().rev().take(3).product(); + println!("{}", sum); +} diff --git a/src/t09_smoke_basin/prod.in b/src/t09_smoke_basin/prod.in new file mode 100644 index 0000000..2858d84 --- /dev/null +++ b/src/t09_smoke_basin/prod.in @@ -0,0 +1,100 @@ +9987653234589654549865432101235789979765459832101234567943986543101239874321012932397319985214896543 +9898541015678943239876973876545699868954398765212345678932399654592345965432129891985498764323789432 +9765432126789654123998765987897789759893219894333656789543498986989957898543498789976579895454678943 +9879656737899797434589986798998897646789398989454789898959987899876899987654989678899699976565789656 +8998767945678996545678997999569965435678987678967897947898765698765678998799878466798989988676898777 +7679898998799987676789398998439876323999876567898976736569894329954569789987964345987878999788999888 +5569959349898799787892139987321987549898765456789765623478989497542345699876543239876567898999998999 +4398943245999659898993045996210499698759876345678954212349876989321234589876455123954453567899987897 +6997832134678945959889159895432349999898763234567894303456965878943445678954321019843212456789976995 +9876543265789434345678999789943498899987654126898985424579854567894578789986532129654325677899854789 +9987654378894321256789987687894997789976543245789876539798768978965989897898763298767534798998765699 +9998867459943210167899976576789876678898674689894988798999899989876999976987654349879545899999876789 +8989978967894345234989895434598985568789788799933299987988989999987899895498765767989656987899987890 +7679989878965976349876789323987654345699899899321012976567678998998998789329876878998767896789899951 +6567895999876765498765678912396543236899956978932129854323567897899989698934998989679878945698789543 +4367896989989896989824567893459874345789543569549299765434579945799877567895789997543989432397678954 +6456789678998989873213678994598765456795432678998989879765678936998765456789896789732394321234589899 +7867894569987678965302759789679876567894321799997878998976789029876744348978945699901298636346698778 +8998923459876567973212345698789997678965433899876768987897899998765432124567934989893397545458975667 +9769212598765459895463456789894398789877549998765656346789998769876545635688949879799498656867894356 +9854324987654346789654577899943239899988698999854341247898987653987678986799198765678999987978965457 +9985459876532235678968688987652124989998796598763210123567897632598789987891019654569998798989976768 +9876598754321014567999799999873015678999987679874331234898998543469893498989198543456989659497899879 +4987999865432323456789899998754123789687798798765765345789239754567912989678976432345678943236910989 +3999998978543476567896978899875234896545679969896889656890198765678909876549876321234567894345899894 +9899987987654587678965356789986346789639889345987992987999349989999999995434965430999698995456789763 +8789995398765698789643235894398956998798999239899893998978969999898989984329876999878989976568997654 +7679876219876789896542129901239899889897778998765789879569998998787878965510999876567678987879998795 +6569997901989891987843458913498788778976667897654678965456987997676567894323987955476567898989989989 +5498789892399932398954567894987654567895456789642567894235695987543478999499876545313456789899876567 +6987678789999543459987678959876543679932378996543456965123984399864569998989985432101239898798765456 +9876546679898954567999789546987621767891567789654587893239973298765678987879876543212345995697654367 +9965434569767895978999893234598832348932345698765698954398764569976789656568987654323476789987743256 +8954323698956789899998942195679953567893478999876799965499865678989896543459999866455678999976551045 +6561012987545698788987893989998769878987567896987899896989987889298985432198754986566789678985432136 +7432123498699987667896789878899989989987679975699989689678998994367965321096563497678994567986544357 +6543434679987893459945698766789994597899789654599876575569899765459876432985432398989323456987655456 +7654545689876789967897987655679913456789898765989975433456789876767989949874321019998910127898767667 +8965656798765667898998986543489894768998999899879874321387899989898998899865432125987891238989898798 +9878969899874356789999997432356789899567899999867965434458989999999987678976743434976989349876999899 +4989878998543235678989854321247895912456789998759876545789678949899998789987854589865878998785679978 +3497989987654146789679765432346954323457991987643987856894589439789769893498767679764567987654598767 +2356799998763259895434996566459899496567890987732298997893499998698954902999898798943458976543987656 +1345998759998768999323987878698798989698999896521019498902578896587893219899999987654569998651098945 +2349887646789878998909998989789657478989298765432329399312456789476789399789999898765878979732129857 +3498765434899989987898999999896545365679109876543498989423969893345995987678989769876989569843598767 +4599894323987899876667899899987621234568914997656987878944878932239894598547568978989895479955679878 +5689989210196998765456789789876210145679323498979766567895989210198795987832456899998794398766789989 +6799878923965449887567895698765421234789459989898753456789994345989689976541368954989689239877899999 +7899769999874335998789989899876532365678998876789866567899985459878599987430267893976578999988998989 +8998958989910126999895678916998645466989897665789877689939876598766469898521256799865456789799987879 +9987847768921237899934689105679656567898786544598999994324987987654349765432345987674347889659876567 +9876426457892357998925693223998769779987654323987887889212998998743234978545469876544235678998765458 +8765212346895468987998789339899878989876543105986455678929899999832123987676569998432123789989896345 +9893101287896778956789895498799989294987654219875334599998798987654016898987978987654234599868987456 +7654242398969889545678976987689990123499864329883223678998657998762145679398989398766345678956897678 +8765357899954995434569989876578921934987986598761019999999736799763234789239799219875458789345999789 +9876459987899894323678998875467899895976797987652128789989945689654756894345678998986567891239899899 +9987699896798789434789897654323456789985698976543234567968896798765897895656799997897678910198776999 +8998988765667678945896789876212345699996789987654345678959789989878998976767899976798989321987665678 +7999876554354588996945679877103456789869899898765458789345678969989329987878999865659796499895434789 +6789987432143456789439998765213467899953998769896569994234569658991012998989998764546679987654323890 +5679896541012345799598789874327878969892987654987678996545678967989129879099876543234567899795434891 +4598765432123569898987678985456789459789898743498789989756789879878998765146998732125698901989545789 +3759986543234678987656589876769898698657789992109899978997894998767899943237984321016989992978956897 +2349898757655989898743456989899999998745678989234998868789923499656798895349875432234678989867897896 +3498769898767995679754687894999899899987789878976987654689934987543236789767976543345689876546789965 +5957656999898994889898798943499789789998898769897998743476899876432125698978989954496898765435789954 +9843545989919989998989899954987679678969987658789876532545899976521034567899999795987999876323567893 +8732135678909878967879999899995564599357897645679987621236798765432145678978988689999899943213679954 +7643014789998765456568998788994323788969919876798768730345679896543267989569876578998798654323789875 +8654123898999654345457897656789515677896323987898654321656789987655358993459875467987698765434892996 +8766234567898743212345789534994323456965434598989765442767895698767467892398764345696549876545993989 +9874345678999832101234679423989434699799565989679877653458954349878878921987653234986539987656789878 +9965657899298743212345894212878945987678976976547989765669765689989989439876543123497698998767899764 +9876798921019654323456982104567899866567899867435699878878998799997699545998653234598987899889998943 +3989899892198767434569877323456998753467997654526789989989219989876578976789854447679996867995387891 +1298956789299878565678965434567897542346789643214567999894329878964347897899965557798765456894216789 +0987645898989989678789876545878965321578998759323456999765498767894256798949876678987654345892105899 +2698766987678997989898987856989954320789869898937599878978987856943145789432988989998743236789324678 +3499989898598965397997698967898765434899754997999987567899876645894235699921299096999984345679434567 +9988998765467893236789579989999887545678975986878976458998765434689346789890932125789965456796545678 +8976899754359992125679456799999999698789876795467891367999986323478956896799843234699878767899696899 +7895789973298989014568967898989439899994987984356910179898797212667897975689754348789989878998789999 +6434890989987878923699878987678921999893499878268899298789598601457898954579765678895699989349899678 +5423921298756867895789999896569890198789989862156788965678987542356789343467999789934989993210998569 +8737893989943458976799998765476789987679876545034567894589999753478993212979878992129878994921987678 +9656794979899569987999899654345679876543987632123478943499898764589432109898769994939769789892998989 +8767999868767989799898698765476789999432499843234569654986789878997643498789356989898654698789899194 +9879898657657895698795439876987899987654678954545678999875688989019759569653239876789543987698789012 +6998775432348894239679921997898978998767989876789789789654567899998967898764699865678952986567678929 +5987654321256789197598799998929867899898999987899897698973456789787978979978989976789769878454567898 +4598763210368898986487678999213456789949989998921954567892567998656899754989978987899879764323678986 +3459875391239897697396568789428589890129878999530123678943688974545799843499867898963989875214567895 +2345965485446797543212345678937678932398767985432654789764569763234899754998756789642199932108678914 +1459879876568999852101267899548789654987659876543465999875678954356999879877645678921019853219989103 +2345989987879998763254345678959898767899536987754576789986789765456895998763234599934329764324598912 +3589996598989899854395456789967999878998745699865679896597897987587894309854123578896449895434567893 +4678965409599798765986577899878986999899656789986789965498986987698963219767012456789567976545998954 +5789654312345679876897689910989754346798787891099899876899765698999654397654323767897689987656899865 diff --git a/src/t09_smoke_basin/test.in b/src/t09_smoke_basin/test.in new file mode 100644 index 0000000..6dee4a4 --- /dev/null +++ b/src/t09_smoke_basin/test.in @@ -0,0 +1,5 @@ +2199943210 +3987894921 +9856789892 +8767896789 +9899965678 diff --git a/src/t10_syntax_scoring/mod.rs b/src/t10_syntax_scoring/mod.rs new file mode 100644 index 0000000..d440110 --- /dev/null +++ b/src/t10_syntax_scoring/mod.rs @@ -0,0 +1,96 @@ +use std::{ + collections::{HashMap, HashSet}, + io::{BufReader, Read}, +}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + lines: Vec, + opening_chars: HashSet, + opposites: HashMap, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + + let lines = buf.split_terminator('\n').map(|s| s.to_owned()).collect(); + let opening_chars = HashSet::from(['(', '[', '{', '<']); + let opposites = HashMap::from([ + ('(', ')'), + ('[', ']'), + ('{', '}'), + ('<', '>'), + (')', '('), + (']', '['), + ('}', '{'), + ('>', '<'), + ]); + + Input { + lines, + opening_chars, + opposites, + } +} + +pub fn syntax_scoring_1(test_mode: TestMode) { + let input = parse_input(test_mode); + + let score_chart = HashMap::from([(')', 3), (']', 57), ('}', 1197), ('>', 25137)]); + + let mut score = 0; + for line in input.lines { + let mut stack = vec![]; + for s in line.chars() { + if input.opening_chars.contains(&s) { + stack.push(s); + } else { + let old_char = stack.pop(); + if old_char.is_none() || old_char.unwrap() != input.opposites[&s] { + score += score_chart[&s]; + break; + } + } + } + } + println!("{}", score); +} + +pub fn syntax_scoring_2(test_mode: TestMode) { + let input = parse_input(test_mode); + + let score_chart = HashMap::from([(')', 1), (']', 2), ('}', 3), ('>', 4)]); + + let mut scores = vec![]; + for line in input.lines { + let mut stack = vec![]; + let mut valid = true; + for s in line.chars() { + if input.opening_chars.contains(&s) { + stack.push(s); + } else { + let old_char = stack.pop(); + if old_char.is_none() || old_char.unwrap() != input.opposites[&s] { + valid = false; + break; + } + } + } + if valid { + let mut local_score: u64 = 0; + stack + .iter() + .rev() + .map(|c| input.opposites[c]) + .for_each(|c| local_score = 5 * local_score + score_chart[&c]); + scores.push(local_score) + } + } + scores.sort_unstable(); + println!("{}", scores[scores.len() / 2]); +} diff --git a/src/t10_syntax_scoring/prod.in b/src/t10_syntax_scoring/prod.in new file mode 100644 index 0000000..674cd38 --- /dev/null +++ b/src/t10_syntax_scoring/prod.in @@ -0,0 +1,110 @@ +{{{[(<<[[[<<([[]()]<()<>>)((()()))>([(()><{}[]>]({()[]}))>{[{(<>[]){{}[]}}<({}()){{}[]}>][<<(){}>(()<>)>{[{ +{<<((({{<<[<<{[]()}(())>([[]()])><[[{}{}]<[]<>>](({}())[{}<>])>][([{[]{}}](<<>{}>{()()})){({[]{}}<<><>>}{({} +(<[{<{<(<[[<<<[][]>(<>)>><{<(){}>{[]{}}}<{{}[]}{()[]}]>][<([{}<>]<[]<>>)<{[]()}[()<>]>>[{{<><>}<<>{ +([{([{{{<[[{[{{}()}<{}[]>]{{<>()}<()>}}{<<{}()>{<>{}}>}]]<(<<[<><>]<<><>>>{<{}()>({}())}>){(<{()<>}><<< +{(<{[{[{([<<{<()()>((){})}[[{}{})<()[]>]>>{([<{}<>><<>[]>]<{<>[]}[{}<>]>){<[<><>]{{}{}}><( +[<([<(<{[<[{<<()[]>{()[]}>}{<[{}][[]{}]){[()()]{<>[]}}}]>{(<(<[]()><{}<>>)(<{}<>><{}()>)><<(<>())>>) +(<{<[<[(({([(([][])([]())){(()[]){[][]}}][({[][]})[[[]{}]({}[])]])}{{{[{<>()}{()[]}](<{}[]><[]<>>)}<( +<<(({([[[([{[[()()]{<>[]}]<[<>[]]({}[])>}]((<[[]())(()<>)>(<{}()>([][])))<([<>[]](()[]))>))[<[[<{}<>>([][])] +(({[{[{<(({([{[]{}}(()())]{{()()}<<>()>})([{{}{}}[{}{}]]<<(){}>[()<>]>)}<{{(()[])}}{{[[]() +[<{<<<{<[[[[(((){})(()[])){<[]{}>}](<[<>[]][<>()]><[()<>]<<>[]>>)]({{[<><>]}<<<>{}>[{}<>]>}[{{{}{}}([]{})} +{[<({<{{<([(<<<>{}>{<>[]}>{{()<>}<<>{}>})(<<[]>((){})>)][<[<()<>>[()]]<((){})<<><>>>>[<{()[]}<{}[]>>]])>}{{< +([[<{([{<<[{<[{}<>]{<>{}}>{[(){}][()()]}}<{(<>[])(<>())}([<><>])>]>{{{<([][]){<>()}>{([]()><()()>}}{{({}() +(<[[({{<([[[[{{}<>}[<>()]][(<>[])<<>()>]]]([([[]()][()()])]([[{}[]]<{}[]>]{[{}<>]{<><>}}))))>( +<<{[([(<<({{([{}[]]<<>()>)<<()[]>[{}<>]>}({(<><>)[{}()]})}[{<[(){}]>{{<>[]}[<>{}]}}[<(<><>){{}[]}>{{<>{ +[<({[({[<{[(<[{}()][{}<>]>{{()[]}(<>())})({{{}<>}<[]()>}{<()<>>})]}[<<{{[]}({}{})}([[]<>][()<>])>>[[[ +(<<[[<{<(<<<<[()[]]<<>()>>({[]<>}[[]()])>([<<><>>](([]()){[]()}))>{<[{{}<>}<<>[]>]<<<>><[]()>>>{ +<[[{[<({{[{(<([]())<{}[]>>(<<>{}>{<>})){[{[][]}{<>[]}]{[[]{}]<[]>}}}<<(([]{})[<>{}]){[{}()](<>{})}>[[([]{})[{ +([(<[<[[{([[(({}{})[(){}])([<>[]]{()[]})]([[()<>][<><>]])]{[<{[][]}[[][]]>{<[]()><()[]>}]<[(<>())<<>{}>]>})} +([([{<<{{{({<<<>[]><<><>>>[[<>[]]<[]()>]}<<{[][]}[{}<>]>{[<>()]{()[]}}>)[[[<<><>>{(){}}>[({}[ +[[<[[({{(<[{<{[]{}>>({[]()}{[]<>})}{(([]{})[<>{}])[(<>{})<[][]>]}]>){{<[{<{}<>>}<([][])([]<>)>]((<(){}>(() +([[{<[<((<{([{[]<>}({}[])]){{[[]]{<><>}}[<[][]>([][])]}}{[(((){})([]())>]{{{[]()}<<>()>}}}>){<[( +{<(<{{<{[{<{{<(){}>{<><>}}}[{[{}<>][{}<>]}[[[]{}](()[])]]>}][<<<{[{}[]]<()()>}(((){})[()[]])>)((<(() +{([<{<{([(<{[{{}[]}[(){}]]<{()}<{}()>>}[[[[]{}]{<>[]}}]>{[[[<>]<<>()>]{<()<>>{[]<>}}]})<<{[{<>()}<{}<>>] +{<<(<[<[[[[{{(()())([]<>)](<<>>({}()))}<[{<>()}[()<>]]>]({[[[]()]<()<>>]}[[<[]<>><()<>>]{<{}()>[ +[<{(<<[<[(<[{(<>{})<{}()>}]<[[()<>]{<>()}]>>)]](({<{<[()()]{[]()}>((<>())(<>{}))}{[<{}()>]<(<>[ +[<({({[[[<{<[[()<>]<<><>>]{([]<>)([][])}>[[(<>[]){(){}}]]}{{<{<>{}}<<>>>(([]{})[[]<>])}[<(()[]){{}{}}>]}>[{ +{(<<{<[{[{({{[<><>]{{}[]}}}(([{}[]]<[]<>>)})[<(<[]{}><<>()>)[<{}<>>[<>[]]]>(<((){})[{}<>]>{( +[<(({<<([{[{{{<><>}([]<>)}}]}](<(<[([][])<{}[]>]{{{}{}}[{}{}]}>{(<[][]>{{}{}})})>)){[([{{<[][]><()>} +[({[[[(<<((<(<{}()>([]<>))(<()()}<{}[]>)>(([{}[]](<>{}))[{[]<>}(<>[])])))>>)][<{({<[[<{}{}>{[]()}]{(<>{}){ +{(([((([<[{[(({}[]){()<>})[[{}[]]({}())]]{<[[][]](()<>)>{[{}[]]{[]()}}}}<{(<<><>><()<>>)<({}[]) +{([{{[[{<({([[<><>]<{}<>>]<[()[]]<()[]>>)}[[{[{}{}]{{}{}}}]{[{[]{}}([]{})]{(()())[<>()]})])>}]< +([<[{{{([{{<[[{}{}]]{<()()>}>{{{()[]}([]())}}}<<{<[][]>{<>{}}}>{[[{}()]([]{})]{([]{})(()())}}>}])<<<((<<{}{} +[{{[<[[[<({[[<(){}>{{}[])]{{[]<>}([])}]}<({{<>()}[{}{}]}{[()()]{[]<>}})[{[()<>][()[]]}]>)>[<(<{{ +(<{{({{{[({([({}[])<{}{}>](([]{})[{}{}]))})[(<<((){}){()<>}>[[[]<>][{}[]]]>{<([]){{}<>}>([[]{}])}){[((( +<[<{{(<(<<[{([(){}][()()])((<>())]}]>>)>)}[{(({({[[{(){}}]][{(()()){{}[]}}<(()())(<>())>]}{([{[]<>}<[]<>>] +{({<[[<<{<{(({<>{}}<<>{}>))[<<{}()><<>()>><<(){}>({}())>]}<(([{}[]][{}{}]){<{}>}){[<[][]>(( +(<[{{[{([<<<(((){})([][]))>([[<>{}])[<{}()>{<>{}}])>>{{{{<[]{}>[()()]}[(<>{}){<>{}}]}{([[]{ +{(<[{({<<(<<<(<>())[{}[]]>>{([()()]({}{})){<[]()>[[]<>]}}>[[<[{}{}]{{}<>}>{[<>()][<><>]}]{<[<>][[]<>]>((<>{ +{[<<(<<({(<<[{<>[]}]{[{}{}]<[]()>}>(((())<<><>>)((<>{})[{}[]]))>[<({<><>}[[]{}])[<()[]>{()()}]>{{({}[])({}() +<<<(<((([<{[{{{}<>}{{}[]}}[(<>)<<>[]>]]<[([])]<{()()}{<>{}}>>}><{<[[[]<>]<{}<>>]>[(({}[])<[]<> +{<(([[{{[({(([[]{}]<{}()>)<([]())[[][]}>)<<<<>>{()[]}>[<<>()>]>})<<[({[]<>}[[]<>])<<{}()>({})>]{<<()[]>(()[ +([<([{<[<{<([<()>({}[])](<<>{}>{{}{}}))<<({}{}){{}()}>[([]{})[[]()]]>>{{<[()<>]{()<>}>((<>())[{}<>])}<[(< +<([{({({<({[[(()[])[[][]]][(()){()[]}]](<{()<>}(()())><[[]()]([][])>)}{[{[<><>][{}{}]}<(<>[]){{}[]}>] +(({[<<[[{{<[{{[][]}(()[])}{<()<>>}]([<[]<>><{}<>>]{<{}()>[<><>]})><{{<<>{}>[[]{}]}{<{}<>>[[]{})}}<<<{}<>> +<{{<(({{(<[<<[[][]]{[]()}>><<{()[]}{<>)>(({}{})(()()))>]{(<({})({}{})>([()()]<{}<>>)){([{}[]]([]{}))[<[] +{({[<<[[<[<(<{<>{}}{{}()]>([{}[]][()[]])){{[()[]]{<><>}}({<>()}[<>()])}><<{[()<>]<[]>}<({}[] +<{{<<{<{<([(([<>()])<({}())<{}[]>>)[[(()())[()()]]{{()()}<{}()>}]])<[([<{}{}><[][]>])[[<[]<>>{[]<>} +<{<([[<{[{([[[[][]]<[]<>>][({}()){()()}]]<(([]())[<>[]]){[()<>]}>)[[<<{}<>>([]{})>[(()<>)[[]()]]]]}((((<<>> +[[{[<<([[({{<<{}<>>{<><>}>[<(){}>([]<>)]}<{<{}[]>{()[]}}((<>{})<()[]>}>}[<([[][]]([][]))({()()}<() +[{[[{(<({(<({({}<>){{}[]}}{<<>[]>{()[]}})<(({}())[[]{}])>><[<{{}[]}>{<[][]>[()]}]{((<>{})(<> +{{<{[[[(<({<(<[][]><{}<>>)[(<>{})<<><>>]>})>)]]]}{([[<<{[{<<()[]>({}{})>({{}()})}]<{[{()()}]<[[]]<()>> +[{{[<((<<(({{[[]()]([]())}{<[]{}>[{}{}]}}<({<>{}}{()[]})<{{}}{{}[]}>>)(<<<{}[])<[]()>>({[] +([[[<(<([{(({{{}[]}[{}]}[[()()][{}{}]]}({(<>{})({}())}({()()}([]<>)))){{({()<>}(<>[]))[(()())<[][]> +{([<<{<(<((({({}[])({}[])}([<><>]([]())))<<<[]{}><<><>>>({{}[]}{()[]})>}(<[({}[]){<>[]}](<[][]>{{ +{{(<{<([[<[[(((){})<{}[]>)[[[]<>][<>()]]]{((<>[])(<>())){<<>>([]{})}}]<[([[][]][{}])]>><(({{<>()}}[<[][]>]) +{[[{<<<{{{[[(<(){}>{[]{}})]]}({<[[{}()][{}{}]]{({}[])[{}<>]}>{{{[]<>}[<>[]]}<{[][]}(<>[])>}})}{[<{[([][]){< +<[<{<[{<({(<<([][])<()[]>><[<>()]{{}()}>)<([()<>]<<>{}>)(({}<>)[()<>])>)})>}][(<<<[[({{}()}{{}[ +<{{(<<{[{<{{{{[]<>}{()()}}{(<>()){()[]}}}[{(<>[])}(({}[])[()[]])]}<<[{<>()}]<{<>()}<{}()>>>{((< +{[<[{{[[<[{<<[[][]]<{}[]>>><<<()[]>({}[])>>}([[[[][]]]((<>())<<>()>)](<[{}()]<[][]>>({<>[]}{[]()}))>]{{<[{{} +<([[{[{<<(<{<[{}[]]{(){}}>(<{}<>>{<>()})}{(<(){}>{[]))((()<>)[{}[]])}><(<<(){}><()>>){(<()<>>(()()))<({}())[ +{<(<<{<[<<<[[<[]{}><[]()>]<{{}{}}{{}<>}>]>[[(<<><>>((){}))]({<()()><{}{}>}({<>()}))]>>]([(({<{()()}[ +([{[([({[[<[{(<>[])<<>()>}[[{}[]]<[][]>]]><(<<()<>>({}<>)><(()[])(()())>)({[[]{}]{<>()}}{[[] +[(({([{[<<[{{((){})({}())}}]{{{<()<>>[[]()]}((<>[])(<>()))}[[[<><>]([]())]({()[]}{()[]})]}>>({[[<< +<{{(([[[<(<(([[]()]<[]{}>))[<[{}{}](()())>[[()<>](()())]]>{<{<()<>>}(<{}<>>[[]()])>})>[({< +[<{([{{<<{{(<([]{})[<>{}]>[<()<>><()[]>])({(()<>)<<>[]>)(([]{})([]<>)))}}>[{[({({}())[(){}]}<( +<([<<[<(<<<<({()[]}<{}<>>)[[()[]][[]()]]><({{}{}}){[[][]]}>>{[((()[])[[][]]>{{()()}{()<>}}]<{< +<((<{<{<{<<[[<<>()>{<>}]{({}[])<<><>>}]([{()<>}{[][]}]([[]<>](<>())))>[<<[[]<>]<()()>>[{()()}<(){ +<<{[{[{[<{{<<[<>()]<[]<>>>[[()()][{}{}]]>([{{}[]}<()<>>])}[((([]{})[[]<>])<<{}{}>{<>[]}))]}><[{( +{{{{<<[{<{(({<{}()><[]<>>})[{<[]{}><()()>}{<<>[]>[[][]]}))<{<[<>[]][[]{}]>{[(){}][[]()]}}{{ +<<{([({{[{{<[<[][]>{[]<>}][<[]()>]>{{[{}][()[]]}({{}[]}[()[]])}}{[[<<>{}>](<()()>)][<[[]{}]<{}{}>> +[{{<{([[<{(({<[]{}><[]()>}<<()<>><<>()>>)<{(<>()}[{}<>]}>){(<{<>{}}({}[])><{()<>}>)}}[({(<[]()>({}<>))<[[] +{{{({({<{<{[[{[]{}}{[]()}]<{{}()}<{}[]>>]({<[]<>>[[]()]}<[<>[]}<{}<>>>)}{<<(()[])<()[]>>[(<>[])<()[]>]>(<[[]( +<{[(([[[([[<[[{}()]([]<>)][(()[])[<><>]]>(([<>{}]({}()))<{{}}[[][]]>)]({{<{}[]><[]()>}({[]{})[[ +{(<({({(<(<(([<>()][{}<>])<{()<>}<{}()>>)[[[()[]]<[]{}>][[()<>]<[]{}>]]>{<<<[]><[]()>><(<><>)<[]{}>>>})(([ +<{<(([(<<<<<{(()<>)}{<()()>(<>[])}>>>>>){{(<<[[{<>[]}(<><>)]<{[]{}}>]>>)[([{[[<><>]<()()>]{(()[])<<><>>} +({{[(<([({((([()[]]{{}{}})[(<>{})([][])])){{({<><>}[()()]){<{}[]>[<><>]}}}}{(<[<<>[]>]>><<[{()}<()()>] +([{[[([{<[({{({}[]><[][]>}}((<()()>[<>[]])<({}())({}())>))]<[[[(<>{}){[]}]{{[][]}{()[]}}]]<{<<{}<>><< +({{<[[({{((<[{()<>}[{}[]]]([[]()](()[]))>{[{()[]}{{}[]}][{{}{}}{[]{}}]})({{[{}](<><>)}[([]() +[<<{[{({{[[{{<[]{}>[<>[]]}<({}[])[()[]]>>{[[<>()]{{}[]}][{[]{}}{[]()}]}][<<([]()){[]<>}>((<>){{}()})>[{{{}( +(<{[{<{[[[<[<{{}<>}<()>>{[<><>][()()]}][<[<>()]{{}{}}>([[]())[[]<>])]>]{[(<[()()]{<><>}>{[{}[]]< +<{[[[{(({{<({(()[])(<>{})}(<[][]>[<>]))({([]<>)<<>[]>}<[<><>][()()]>)>[<[[<><>][()()]](<()>[()<>] +[<[([[<<[{((<[<>{}][{}[]]><(<>{}){[]<>}>))}][{{<<<[][]><{}<>>>><({()[]}<()[]>)>}<([<(){}>({}())]<[{}][()]>)[ +[([({{[[{{[[{{{}{}}<[]<>>}]]<{{{{}{}}<<>()>}((()())({}[]))}[[<(){}>(<>{})][[<>{}]{{}<>}]]> +<<[{<<([[({([[[][]]{{}()}])[[{{}[]}<{}()>]{[(){}]{<>[]}}]}([{{[][]}>]<{{()[]}<()[]>}<(()<>) +[[[{(<[[{(({<({}())>{{<>{}}[{}{}]]}<{{()()}[{}<>]}[<{}<>>(<><>)]>))<<<{<<>[]>}{[{}()][{}{}]}>[<[(){}][{}{} +{<([{[[([{[{(<()()><<>[]>)(({}{})[{}<>])}[<<()[]>[()<>]>{({}<>){()()}}]]<<{(<>[]){()()}}<{{}[]}(<><>)>>(( +(({{<(<({[[{({{}[]}([][]))[{[]<>}<<>[]>]}[<{[]{}}([])>]]{{([<>[]]({}()))(<()<>>{[]{}})}}][{<<{<>() +{{[<[<(([<{[([()()][[]<>])[<()<>>{()[]}]]}>[{({{()()}([][])}({()}(()<>)))[[({}())]{{<>()}[<>]}]}]]{<{({({ +{{([([({[<((<{<><>}>{(<>[])})([({}{}){<>()}]))<[{<{}{}>{<>[]}}]<(<(){}>{()<>}){<<><>>}>>>[{[ +[<{<[(<{{[((<[<><>]{(){}}>(([]<>)[()()]))(<{{}()}[{}[]]>{<<><>>{()<>}}))({[<()()>{<><>}]<{[]< +<((([(<[{<<[<<<>()>({})>][((()[]))<{{}()><<><>>>]>>({[[[<>{}][<><>]]({{}()}<{}{}>)]}((<<[]> +[[{({[({[[[[<[<>()]{<>{}}>]{([<>{}](()<>))[[{}<>]({}[])]}]{{{(<>{})({}[]]}}[{[()<>]{()()}}]}]]<<{[((<>())<()< +{<{{{([(<([<[{<>()}{<>{}}]<([]{})<[][]>>>([<(){}>[[][]]]{<()<>><<>[]>})]<<<[()()]>>[([()()] +[([[(({[[{{<{(<>{})<(){}>}[({}{})[<><>]]>({<<>{}>[<>{}]})}}[[<{<()><{}{}>}{{<><>}}>([[()()]{{ +{{[({({([([<({()}([]()))>[[(<>[]){<><>}][{[]{}]<{}>]]]{{[({}{}){<><>}][[[]<>][<>[]]]}((([]< +{{<<[<<(({[[{{{}()}({}{})}<{()[]}{()()}>][{{<>{}}[()<>]}([{}[]]{{}[]})]]<[{{[]<>}{<>{}}}{[<>[]]<[][]>}] +[{<({({<{{({{{<>{}}<{}()>}{(<>())[<>{}]}}[(<<>{}>[{}])])((<<<><>><{}()>>(<<><>>([])))(<([]<>)>{{ +{[<[((<{{[{{<({}{})>}<((<>)<[]<>>)[[<>()]{{}}]>}]}}>))]({[{{([[<<<{}[]>><<<>()><<>[]>>>[{{(){}}}<[[]{}]({} +<<<[<({[(<(<<(()<>)<{}{}>>{([]<>){<>{}}}>{{<{}<>>(<>{})}<[()<>]>})<{[({}())[<>[]]]({<>()}<<>{}>)><{ +({<<[{<<[{{<([(){}]<<>()>)<<<>()>[[]()]>>(<{<>()}([]())>{[[]<>](<>{})})}}]]{<(<<[<<><>>((){})]{ +<([{{[{<<[[{{[{}[]][()]}<[{}()][[][]]>}}[<{[<>[]]{{}()}}>{(<()()><[][]>)({()<>})}]]<[<[<{}<>>([]<>) +([<<[[([(<<[({()<>})<{[]()}{()}>]({{()<>}})>{[([<>()]([]()))[{[]{}}]]}>{{{(<[]()><[]>)<{{}{}}[{ +([[{[[{<{[{<({()()}[<>{}])<<{}{}><<>()>>><[[<>{}](<>()]]<<[][]>{<>{}}>>}][<{(<<>()>[()[]])<{<>{}} +<{<<{<((([{[<(())<{}[]>>]<(<{}()><<>{}>)<<<>{}>>>}<{{<<>()>{{}()}}<<(){}>>}[[{[]()}({}())]((<> +([[([(<[<<{[<[()<>][[]()]>[[[]<>]<()()>]][[(<><>)]<<<>>(<>[])>]}><{([(<><>)]{[()<>}})}>><<[[(< +{{(<<({<([([{{[]()}}([<>{}]{{}()})])])[[[[[[<>{}>({}())]{{[]{}}({}())}]]([{{<>}(()<>)}[{<>()}<[][]>]])](<[[[ +((({{<[<<{{{<<[]()>[<>[]]>[({}[])([]{})]}<<[[]{}]<()<>>><({}())(())>>}[<<[(){}]<[]()>>[{{}<>} +[<([<{[([[[(<[<>{}]({}{})>([()[]]({})))([{()()}{()[]}]<[<><>]{()()}>)]({({(){}}{<><>})<[<>()]{{}() +<(({(<[[{[{[((<>())[{}])[[<>]{<>()}]](<{[][]}{<>()}>([<>{}>{[]<>}))}[[({<>{}}{<>()})((()[])<<> +<{{{{<{[[<[({{<>[]}(()<>)})<(<<>{}>[(){}])[{<>{}}{<>{}}]>]({[{<>()}<()<>>]{<[]()><{}()>}}([ diff --git a/src/t10_syntax_scoring/test.in b/src/t10_syntax_scoring/test.in new file mode 100644 index 0000000..b1518d9 --- /dev/null +++ b/src/t10_syntax_scoring/test.in @@ -0,0 +1,10 @@ +[({(<(())[]>[[{[]{<()<>> +[(()[<>])]({[<{<<[]>>( +{([(<{}[<>[]}>{[]{[(<()> +(((({<>}<{<{<>}{[]{[]{} +[[<[([]))<([[{}[[()]]] +[{[{({}]{}}([{[{{{}}([] +{<[[]]>}<{[{[{[]{()[[[] +[<(<(<(<{}))><([]([]() +<{([([[(<>()){}]>(<<{{ +<{([{{}}[<[[[<>{}]]]>[]] diff --git a/src/t11_dumbo_octopus/mod.rs b/src/t11_dumbo_octopus/mod.rs new file mode 100644 index 0000000..96d0e7d --- /dev/null +++ b/src/t11_dumbo_octopus/mod.rs @@ -0,0 +1,157 @@ +use std::io::{BufReader, Read}; + +use crate::types::TestMode; + +const NUM_ROWS: usize = 10; +const NUM_COLS: usize = 10; + +#[derive(Debug)] +struct Input { + map: Vec>, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + + let mut map = Vec::new(); + for line in buf.split_terminator('\n') { + let m = line.chars().map(|c| c.to_digit(10).unwrap()).collect(); + map.push(m); + } + + Input { map } +} + +fn flash(m: &mut [Vec], fm: &mut [[bool; NUM_COLS]; NUM_ROWS], r: usize, c: usize) -> u32 { + let dirs: [(i8, i8); 8] = [ + (-1, -1), + (-1, 0), + (-1, 1), + (0, -1), + (0, 1), + (1, -1), + (1, 0), + (1, 1), + ]; + + if fm[r][c] { + return 0; + } + + fm[r][c] = true; + + let mut num_flashes = 1; + + for (d_r, d_c) in dirs { + let r: i8 = ((d_r as isize) + (r as isize)).try_into().unwrap(); + let c: i8 = ((d_c as isize) + (c as isize)).try_into().unwrap(); + + if r < 0 || c < 0 || r as usize >= m.len() || c as usize >= m[0].len() { + continue; + } + let r: usize = r.try_into().unwrap(); + let c: usize = c.try_into().unwrap(); + + m[r][c] += 1; + + if m[r][c] > 9 { + num_flashes += flash(m, fm, r, c); + } + } + + num_flashes +} + +fn print_matrix(m: &[Vec]) { + for row in m { + for c in row { + print!("{}", *c); + } + println!() + } + println!() +} + +pub fn dumbo_octopus_1(test_mode: TestMode) { + let mut input = parse_input(test_mode); + + const NUM_STEPS: usize = 100; + + println!("Before any steps:"); + print_matrix(&input.map); + + let mut num_flashes = 0; + for s in 1..=NUM_STEPS { + let mut fm = [[false; 10]; 10]; + + for r in 0..NUM_ROWS { + for c in 0..NUM_COLS { + input.map[r][c] += 1; + } + } + for r in 0..NUM_ROWS { + for c in 0..NUM_COLS { + if input.map[r][c] > 9 { + num_flashes += flash(&mut input.map, &mut fm, r, c); + } + } + } + for (r, row) in fm.iter().enumerate() { + for (c, cell) in row.iter().enumerate() { + if *cell { + input.map[r][c] = 0; + } + } + } + + println!("After step {}", s); + print_matrix(&input.map); + } + println!("{}", num_flashes); +} + +pub fn dumbo_octopus_2(test_mode: TestMode) { + let mut input = parse_input(test_mode); + + println!("Before any steps:"); + print_matrix(&input.map); + + let mut s = 0; + loop { + s += 1; + + let mut fm = [[false; 10]; 10]; + + for r in 0..NUM_ROWS { + for c in 0..NUM_COLS { + input.map[r][c] += 1; + } + } + let mut num_flashes = 0; + for r in 0..NUM_ROWS { + for c in 0..NUM_COLS { + if input.map[r][c] > 9 { + num_flashes += flash(&mut input.map, &mut fm, r, c); + } + } + } + for (r, row) in fm.iter().enumerate() { + for (c, cell) in row.iter().enumerate() { + if *cell { + input.map[r][c] = 0; + } + } + } + + println!("After step {}", s); + print_matrix(&input.map); + + if num_flashes as usize == NUM_ROWS * NUM_COLS { + println!("{}", s); + break; + } + } +} diff --git a/src/t11_dumbo_octopus/prod.in b/src/t11_dumbo_octopus/prod.in new file mode 100644 index 0000000..601f999 --- /dev/null +++ b/src/t11_dumbo_octopus/prod.in @@ -0,0 +1,10 @@ +8261344656 +7773351175 +7527856852 +1763614673 +8674556743 +6853382153 +4135852388 +2846715522 +7477425863 +4723888888 diff --git a/src/t11_dumbo_octopus/test.in b/src/t11_dumbo_octopus/test.in new file mode 100644 index 0000000..03743f6 --- /dev/null +++ b/src/t11_dumbo_octopus/test.in @@ -0,0 +1,10 @@ +5483143223 +2745854711 +5264556173 +6141336146 +6357385478 +4167524645 +2176841721 +6882881134 +4846848554 +5283751526 diff --git a/src/t12_passage_passing/mod.rs b/src/t12_passage_passing/mod.rs new file mode 100644 index 0000000..e48c2d1 --- /dev/null +++ b/src/t12_passage_passing/mod.rs @@ -0,0 +1,154 @@ +use std::{ + collections::{HashMap, HashSet}, + io::{BufReader, Read}, + ops::{AddAssign, SubAssign}, +}; + +use crate::types::TestMode; + +#[derive(Clone, Debug)] +struct Input { + graph: HashMap>, + start: Cave, + end: Cave, +} + +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +enum Cave { + Small(String), + Big(String), +} + +impl From<&str> for Cave { + fn from(s: &str) -> Self { + if s.to_lowercase() == s { + Cave::Small(s.to_owned()) + } else { + Cave::Big(s.to_owned()) + } + } +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + + let mut graph = HashMap::new(); + for line in buf.split_terminator('\n') { + let mut s = line.split_terminator('-'); + let a = Cave::from(s.next().unwrap()); + let b = Cave::from(s.next().unwrap()); + + graph + .entry(a.to_owned()) + .or_insert_with(HashSet::new) + .insert(b.to_owned()); + graph.entry(b).or_default().insert(a.to_owned()); + } + + Input { + graph, + start: Cave::from("start"), + end: Cave::from("end"), + } +} + +fn find_paths(input: &Input, path: &mut Vec) -> usize { + let current_node = path.last().unwrap(); + if current_node == &input.end { + // println!("{}", path.join(",")); + return 1; + } + + let mut paths = 0; + + for n in &input.graph[current_node] { + let n = n.to_owned(); + + let is_small_cave = match n { + Cave::Small(_) => true, + Cave::Big(_) => false, + }; + + if !is_small_cave || !path.contains(&n) { + path.push(n.to_owned()); + paths += find_paths(input, path); + path.pop(); + } + } + + paths +} + +fn find_paths2( + input: &Input, + path: &mut Vec, + small_cave_occurances: &mut HashMap, +) -> usize { + let current_node = path.last().unwrap(); + if current_node == &input.end { + // let v: Vec<_> = path + // .iter() + // .map(|p| match p { + // Cave::Small(n) => n.to_owned(), + // Cave::Big(n) => n.to_owned(), + // }) + // .collect(); + // println!("{}", v.join(",")); + return 1; + } + + let mut num_paths = 0; + + let has_double = small_cave_occurances.values().filter(|v| **v == 2).count() >= 1; + + for n in &input.graph[current_node] { + if n == &input.start { + continue; + } + + let e = small_cave_occurances.entry(n.to_owned()).or_default(); + if *e >= 2 || (*e == 1 && has_double) { + continue; + } + if let Cave::Small(_) = n { + e.add_assign(1) + }; + + path.push(n.to_owned()); + + num_paths += find_paths2(input, path, small_cave_occurances); + + if let Cave::Small(_) = n { + small_cave_occurances + .entry(n.to_owned()) + .or_default() + .sub_assign(1) + }; + + path.pop(); + } + + num_paths +} + +pub fn passage_passing_1(test_mode: TestMode) { + let input = parse_input(test_mode); + println!("{:?}", input); + + let mut path = vec![input.start.clone()]; + let paths = find_paths(&input, &mut path); + println!("{}", paths); +} + +pub fn passage_passing_2(test_mode: TestMode) { + let input = parse_input(test_mode); + println!("{:?}", input); + + let mut path = vec![input.start.clone()]; + let mut small_cave_occurances = HashMap::new(); + let paths = find_paths2(&input, &mut path, &mut small_cave_occurances); + println!("{}", paths); +} diff --git a/src/t12_passage_passing/prod.in b/src/t12_passage_passing/prod.in new file mode 100644 index 0000000..107ff4f --- /dev/null +++ b/src/t12_passage_passing/prod.in @@ -0,0 +1,23 @@ +start-YA +ps-yq +zt-mu +JS-yi +yq-VJ +QT-ps +start-yq +YA-yi +start-nf +nf-YA +nf-JS +JS-ez +yq-JS +ps-JS +ps-yi +yq-nf +QT-yi +end-QT +nf-yi +zt-QT +end-ez +yq-YA +end-JS diff --git a/src/t12_passage_passing/test.in b/src/t12_passage_passing/test.in new file mode 100644 index 0000000..65f3833 --- /dev/null +++ b/src/t12_passage_passing/test.in @@ -0,0 +1,18 @@ +fs-end +he-DX +fs-he +start-DX +pj-DX +end-zg +zg-sl +zg-pj +pj-he +RW-he +fs-DX +pj-RW +zg-RW +start-pj +he-WI +zg-he +pj-fs +start-RW diff --git a/src/t13_transparent_origami/mod.rs b/src/t13_transparent_origami/mod.rs new file mode 100644 index 0000000..69dfa45 --- /dev/null +++ b/src/t13_transparent_origami/mod.rs @@ -0,0 +1,153 @@ +use std::{ + collections::HashSet, + io::{BufReader, Read}, +}; + +use crate::types::TestMode; + +#[derive(Clone, Debug, Eq, Hash, PartialEq)] +struct Point { + x: u16, + y: u16, +} + +#[derive(Clone, Debug)] +enum Fold { + X(u16), + Y(u16), +} + +#[derive(Debug)] +struct Input { + points: HashSet, + folds: Vec, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + let lines = buf.split_terminator('\n'); + + let mut first_input_stage = true; + + let mut points = HashSet::new(); + let mut folds = vec![]; + + for line in lines { + if line.is_empty() { + first_input_stage = false; + continue; + } + if first_input_stage { + let mut s = line.split_terminator(','); + points.insert(Point { + x: s.next().unwrap().parse().unwrap(), + y: s.next().unwrap().parse().unwrap(), + }); + } else { + let mut s = line + .strip_prefix("fold along ") + .unwrap() + .split_terminator('='); + let f = match s.next().unwrap() { + "x" => Fold::X(s.next().unwrap().parse().unwrap()), + "y" => Fold::Y(s.next().unwrap().parse().unwrap()), + _ => panic!(), + }; + folds.push(f); + } + } + + Input { points, folds } +} + +pub fn transparent_origami_1(test_mode: TestMode) { + let input = parse_input(test_mode); + println!("{:?}", input); + + let mut paper_points = input.points.clone(); + let mut new_paper_points = HashSet::new(); + match input.folds[0] { + Fold::X(x) => { + for p in paper_points { + if p.x < x { + new_paper_points.insert(p); + } else { + new_paper_points.insert(Point { + x: 2 * x - p.x, + ..p + }); + } + } + } + Fold::Y(y) => { + for p in paper_points { + if p.y < y { + new_paper_points.insert(p); + } else { + new_paper_points.insert(Point { + y: 2 * y - p.y, + ..p + }); + } + } + } + } + paper_points = new_paper_points; + + println!("{:?}", paper_points); + println!("num points: {}", paper_points.len()); +} + +fn show_paper(paper_points: &HashSet) { + for y in 0..=paper_points.iter().map(|p| p.y).max().unwrap() { + for x in 0..=paper_points.iter().map(|p| p.x).max().unwrap() { + if paper_points.contains(&Point { x, y }) { + print!("*"); + } else { + print!(" "); + } + } + println!(); + } +} + +pub fn transparent_origami_2(test_mode: TestMode) { + let input = parse_input(test_mode); + + let mut paper_points = input.points.clone(); + for f in input.folds { + let mut new_paper_points = HashSet::new(); + match f { + Fold::X(x) => { + for p in paper_points { + if p.x < x { + new_paper_points.insert(p); + } else { + new_paper_points.insert(Point { + x: 2 * x - p.x, + ..p + }); + } + } + } + Fold::Y(y) => { + for p in paper_points { + if p.y < y { + new_paper_points.insert(p); + } else { + new_paper_points.insert(Point { + y: 2 * y - p.y, + ..p + }); + } + } + } + } + paper_points = new_paper_points; + } + + show_paper(&paper_points); +} diff --git a/src/t13_transparent_origami/prod.in b/src/t13_transparent_origami/prod.in new file mode 100644 index 0000000..faf0195 --- /dev/null +++ b/src/t13_transparent_origami/prod.in @@ -0,0 +1,763 @@ +1288,822 +842,72 +693,68 +561,254 +1007,192 +405,794 +929,45 +58,296 +411,317 +164,3 +894,317 +371,306 +272,205 +646,865 +1027,700 +920,667 +728,665 +1240,105 +390,227 +972,257 +561,640 +954,128 +440,194 +1136,712 +37,516 +1072,93 +1210,576 +390,486 +682,611 +343,368 +236,840 +366,889 +238,644 +55,130 +939,388 +619,726 +1092,23 +1180,458 +338,189 +176,516 +915,210 +550,100 +773,466 +351,554 +460,389 +266,560 +154,810 +604,646 +969,880 +627,793 +211,0 +842,520 +460,647 +678,72 +1007,702 +863,170 +371,836 +716,233 +1260,695 +682,84 +710,745 +852,94 +200,756 +574,383 +112,306 +1072,698 +1103,460 +617,826 +276,827 +1158,73 +959,702 +454,327 +90,502 +790,463 +480,742 +985,577 +1205,334 +298,766 +371,388 +320,754 +1004,252 +765,437 +1290,550 +1191,210 +1170,296 +865,522 +262,663 +504,714 +406,222 +174,630 +402,609 +30,169 +164,127 +1074,54 +663,77 +136,353 +316,632 +164,52 +512,718 +1038,82 +351,453 +1027,413 +68,600 +1110,756 +5,18 +1160,180 +632,822 +600,793 +798,718 +428,625 +964,443 +904,672 +596,122 +174,745 +366,403 +648,252 +1121,164 +920,606 +464,807 +749,254 +624,501 +1282,543 +1126,494 +554,891 +236,54 +333,483 +1233,459 +843,504 +928,171 +500,278 +1168,512 +937,504 +6,177 +830,264 +584,105 +1287,788 +375,250 +982,58 +788,695 +386,324 +1273,378 +88,129 +756,3 +218,471 +686,501 +20,326 +326,114 +885,750 +536,182 +209,56 +20,568 +944,98 +428,94 +1101,693 +644,413 +373,410 +912,830 +1096,833 +390,219 +0,828 +93,684 +1038,306 +1101,390 +1037,493 +1290,763 +288,403 +346,317 +1191,140 +840,821 +962,131 +1116,505 +688,458 +55,460 +416,196 +405,100 +856,474 +528,376 +929,849 +873,381 +483,621 +1002,317 +1004,730 +375,644 +279,250 +378,442 +1128,317 +1022,768 +681,843 +164,630 +80,606 +20,763 +112,588 +972,189 +514,150 +1084,766 +433,782 +373,484 +1180,436 +894,196 +1089,560 +1290,26 +1192,731 +576,672 +1185,145 +296,228 +38,441 +870,733 +1059,747 +1006,856 +1255,434 +1275,278 +718,38 +806,714 +1304,177 +313,14 +412,563 +877,112 +238,698 +976,502 +1168,624 +1139,397 +1038,588 +1010,308 +242,115 +679,393 +935,838 +959,620 +62,550 +8,29 +1230,383 +1256,745 +1252,632 +1184,376 +140,296 +1002,353 +594,774 +734,222 +1242,70 +1146,400 +296,725 +87,187 +786,10 +982,562 +1128,577 +1096,385 +542,285 +1198,588 +433,112 +161,82 +492,854 +209,504 +80,624 +984,556 +325,364 +126,868 +1128,50 +760,346 +1287,554 +1059,644 +54,745 +865,372 +283,33 +288,5 +1038,597 +944,348 +863,252 +994,262 +788,505 +37,378 +1174,311 +1124,374 +990,140 +383,764 +1037,885 +874,812 +1120,171 +662,754 +1119,116 +142,718 +492,171 +326,506 +1146,630 +1283,793 +234,382 +990,754 +1230,606 +1287,106 +1116,4 +1148,499 +296,666 +437,381 +944,770 +209,693 +472,437 +749,192 +296,218 +1248,102 +1183,502 +885,592 +8,865 +820,2 +130,94 +774,387 +1086,263 +119,140 +962,252 +1236,161 +683,793 +539,642 +147,190 +632,374 +932,173 +7,525 +50,621 +528,742 +806,266 +832,516 +835,256 +537,649 +1014,423 +15,816 +1166,661 +1223,747 +105,334 +408,507 +636,465 +1138,84 +273,9 +405,346 +1139,716 +761,560 +559,12 +328,836 +1238,665 +126,119 +1310,828 +981,418 +390,606 +348,252 +80,383 +600,275 +502,98 +875,130 +405,548 +756,563 +351,441 +232,292 +510,213 +358,808 +241,11 +1290,131 +190,171 +1232,672 +306,730 +340,404 +1198,509 +840,73 +744,765 +935,250 +612,462 +308,17 +174,264 +271,802 +970,404 +338,705 +229,750 +782,518 +937,670 +574,288 +271,259 +1148,575 +1303,817 +47,56 +808,613 +956,801 +28,543 +994,705 +130,542 +119,618 +775,460 +519,824 +1248,744 +574,848 +1303,824 +592,102 +303,702 +303,340 +928,619 +219,578 +798,644 +1037,849 +150,180 +1305,876 +1180,94 +908,285 +706,646 +490,52 +214,283 +6,588 +236,137 +584,718 +218,306 +850,330 +981,866 +1136,264 +818,171 +710,275 +0,605 +873,65 +207,434 +1255,460 +952,808 +850,135 +1201,737 +594,661 +718,856 +23,788 +1184,308 +1044,101 +416,698 +325,577 +1165,887 +535,140 +162,575 +1021,602 +932,721 +118,546 +1184,294 +634,868 +584,294 +528,518 +596,150 +902,507 +627,742 +810,278 +63,266 +115,476 +985,317 +870,161 +529,590 +214,611 +20,131 +49,520 +1039,259 +972,262 +26,588 +1261,520 +375,838 +1027,861 +343,526 +771,642 +1146,127 +838,577 +77,459 +907,634 +492,275 +1195,670 +1235,634 +126,308 +62,38 +58,324 +390,288 +191,116 +905,794 +478,378 +846,737 +1163,190 +830,546 +1230,507 +1031,364 +674,429 +1084,317 +1220,392 +791,824 +592,344 +522,505 +174,149 +464,82 +1220,502 +276,4 +346,353 +112,385 +266,793 +1077,192 +1062,448 +42,432 +528,824 +346,577 +1084,128 +383,802 +395,210 +1027,33 +592,150 +1195,700 +574,894 +648,754 +592,856 +1267,77 +1267,58 +340,490 +749,702 +421,702 +863,460 +251,147 +1238,341 +698,462 +440,611 +249,346 +964,281 +172,138 +664,865 +115,726 +136,801 +155,845 +810,362 +283,506 +412,779 +219,477 +944,5 +226,128 +1022,403 +636,429 +984,562 +388,334 +70,401 +764,759 +1074,502 +50,695 +846,157 +972,632 +666,413 +1146,3 +383,316 +1149,82 +356,128 +1180,800 +103,44 +174,712 +273,493 +629,51 +499,49 +1274,742 +416,252 +683,242 +596,296 +316,637 +882,129 +1103,684 +226,317 +1077,702 +1093,65 +846,807 +817,812 +144,233 +130,800 +724,70 +522,340 +985,364 +1310,156 +1207,850 +683,652 +959,254 +1297,462 +390,675 +856,518 +1248,38 +574,831 +1061,548 +447,460 +818,40 +182,801 +676,26 +308,613 +272,689 +1292,541 +333,484 +694,348 +1146,842 +792,353 +1185,749 +492,619 +54,149 +207,460 +736,270 +681,51 +1222,250 +985,353 +319,402 +316,262 +272,306 +20,282 +406,672 +990,541 +1027,194 +584,124 +1260,646 +190,801 +850,759 +1178,505 +1091,130 +1103,194 +325,353 +194,505 +1223,187 +686,277 +105,177 +308,283 +216,763 +288,546 +1260,173 +13,462 +523,852 +512,644 +850,389 +806,378 +1263,56 +764,135 +718,150 +736,0 +773,354 +1092,471 +440,733 +1138,810 +874,530 +775,684 +959,640 +818,275 +775,434 +1155,49 +841,80 +88,196 +546,135 +1265,873 +782,586 +283,413 +1081,144 +308,353 +200,138 +929,401 +80,224 +354,588 +550,346 +1222,765 +522,695 +832,378 +920,219 +937,581 +171,397 +728,229 +830,854 +25,51 +226,331 +1037,9 +1176,431 +686,871 +694,98 +928,597 +1038,569 +939,588 +288,768 +375,56 +827,621 +709,401 +1021,292 +340,42 +281,448 +1148,52 +744,250 +422,548 +437,9 +1014,725 +662,140 +1002,283 +928,588 +736,471 +792,541 +70,124 +726,572 +300,84 +157,746 +390,238 +1260,273 +1088,520 +447,252 +1078,346 +234,512 +577,883 +1002,765 +288,348 +207,724 +249,11 +185,528 +771,224 +464,535 +714,122 +731,260 +691,726 +616,403 +694,403 +1168,718 +279,530 +894,698 +686,23 +771,726 +1280,169 +892,392 +413,435 +781,590 +1175,742 +774,182 +313,880 +828,138 +88,250 +539,224 +582,105 +724,518 +551,268 +490,891 +23,106 +991,402 +229,144 +566,250 +1285,51 +1068,779 +182,577 +472,885 +770,840 +1007,340 +80,288 +644,848 +574,176 +251,644 +1014,218 +1272,43 +248,448 +468,520 +810,616 +25,724 +348,642 +194,389 +604,695 +189,164 +216,131 +1116,564 +674,465 +125,749 +907,147 +10,413 +937,410 +550,822 + +fold along x=655 +fold along y=447 +fold along x=327 +fold along y=223 +fold along x=163 +fold along y=111 +fold along x=81 +fold along y=55 +fold along x=40 +fold along y=27 +fold along y=13 +fold along y=6 diff --git a/src/t13_transparent_origami/test.in b/src/t13_transparent_origami/test.in new file mode 100644 index 0000000..282114c --- /dev/null +++ b/src/t13_transparent_origami/test.in @@ -0,0 +1,21 @@ +6,10 +0,14 +9,10 +0,3 +10,4 +4,11 +6,0 +6,12 +4,1 +0,13 +10,12 +3,4 +3,0 +8,4 +1,10 +2,14 +8,10 +9,0 + +fold along y=7 +fold along x=5 diff --git a/src/t14_extended_polymerisation/mod.rs b/src/t14_extended_polymerisation/mod.rs new file mode 100644 index 0000000..87b3505 --- /dev/null +++ b/src/t14_extended_polymerisation/mod.rs @@ -0,0 +1,136 @@ +use std::{ + collections::{HashMap, HashSet}, + io::{BufRead, BufReader}, + ops::AddAssign, +}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + template: HashMap, + rules: HashMap>, + template_terminal_chars: HashSet, +} + +fn split_template(s: &str) -> HashMap { + let x: Vec<_> = s + .as_bytes() + .windows(2) + .map(|w| String::from_utf8(w.to_vec()).unwrap()) + .collect(); + + let mut hm: HashMap = HashMap::new(); + for e in x { + hm.entry(e).or_default().add_assign(1); + } + hm +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + let mut br = BufReader::new(f); + + let mut template = String::new(); + br.read_line(&mut template).unwrap(); + template.truncate(template.len() - 1); + + let template_terminal_chars = template + .char_indices() + .filter_map(|(i, c)| { + if i == 0 || i == template.len() - 1 { + Some(c) + } else { + None + } + }) + .collect(); + + let template = split_template(template.trim_end()); + + let mut buf = String::new(); + br.read_line(&mut buf).unwrap(); + + let mut rules = HashMap::new(); + loop { + buf.clear(); + br.read_line(&mut buf).unwrap(); + if buf.is_empty() { + break; + } + + let mut s = buf.trim_end().split_terminator(" -> "); + let pattern = s.next().unwrap().to_owned(); + let pattern_chars: Vec<_> = pattern.chars().collect(); + let new_letter = s.next().unwrap().to_owned(); + + let mut pattern_chars_it = pattern_chars.iter(); + + rules.insert( + pattern, + vec![ + format!("{}{}", pattern_chars_it.next().unwrap(), new_letter), + format!("{}{}", new_letter, pattern_chars_it.next().unwrap()), + ], + ); + } + + Input { + template, + template_terminal_chars, + rules, + } +} + +fn run_for_steps(input: &Input, steps: usize) { + let mut template = input.template.clone(); + for _ in 0..steps { + let mut new_template = HashMap::::new(); + for (t, num_t) in template { + if input.rules.contains_key(&t) { + for i in input.rules[&t].iter() { + new_template + .entry(i.to_owned()) + .or_default() + .add_assign(num_t); + } + } else { + new_template.entry(t).or_default().add_assign(num_t); + } + } + template = new_template; + } + + // println!("{:?}", template); + + let mut occurances = HashMap::::new(); + for (s, i) in template { + for c in s.chars() { + occurances.entry(c).or_default().add_assign(i); + } + } + for (s, i) in occurances.iter_mut() { + if input.template_terminal_chars.contains(s) { + *i = *i / 2 + 1; + } else { + *i /= 2; + } + } + + println!("{:?}", occurances); + + let min = occurances.values().min().unwrap(); + let max = occurances.values().max().unwrap(); + + println!("{:?}", max - min); +} + +pub fn extended_polymerisation_1(test_mode: TestMode) { + let input = parse_input(test_mode); + run_for_steps(&input, 10); +} + +pub fn extended_polymerisation_2(test_mode: TestMode) { + let input = parse_input(test_mode); + run_for_steps(&input, 40); +} diff --git a/src/t14_extended_polymerisation/prod.in b/src/t14_extended_polymerisation/prod.in new file mode 100644 index 0000000..02d9c64 --- /dev/null +++ b/src/t14_extended_polymerisation/prod.in @@ -0,0 +1,102 @@ +SVCHKVFKCSHVFNBKKPOC + +NC -> H +PK -> V +SO -> C +PH -> F +FP -> N +PN -> B +NP -> V +NK -> S +FV -> P +SB -> S +VN -> F +SC -> H +OB -> F +ON -> O +HN -> V +HC -> F +SN -> K +CB -> H +OP -> K +HP -> H +KS -> S +BC -> S +VB -> V +FC -> B +BH -> C +HH -> O +KH -> S +VF -> F +PF -> P +VV -> F +PP -> V +BO -> H +BF -> B +PS -> K +FO -> O +KF -> O +FN -> H +CK -> B +VP -> V +HK -> F +OV -> P +CS -> V +FF -> P +OH -> N +VS -> H +VO -> O +CP -> O +KC -> V +KV -> P +BK -> B +VK -> S +NF -> V +OO -> V +FH -> H +CN -> O +SP -> B +KN -> V +OF -> H +NV -> H +FK -> B +PV -> N +NB -> B +KK -> P +VH -> P +CC -> B +HV -> V +OC -> H +PO -> V +NO -> O +BP -> C +NH -> H +BN -> O +BV -> S +CV -> B +HS -> O +NN -> S +NS -> P +KB -> F +CO -> H +HO -> P +PB -> B +BS -> P +SH -> H +FS -> V +SF -> O +OK -> F +KP -> S +BB -> C +PC -> B +OS -> C +SV -> N +SK -> K +KO -> C +SS -> V +CF -> C +HB -> K +VC -> B +CH -> P +HF -> K +FB -> V diff --git a/src/t14_extended_polymerisation/test.in b/src/t14_extended_polymerisation/test.in new file mode 100644 index 0000000..b5594dd --- /dev/null +++ b/src/t14_extended_polymerisation/test.in @@ -0,0 +1,18 @@ +NNCB + +CH -> B +HH -> N +CB -> H +NH -> C +HB -> C +HC -> B +HN -> C +NN -> C +BH -> H +NC -> B +NB -> B +BN -> B +BB -> N +BC -> B +CC -> N +CN -> C diff --git a/src/t15_chiton/mod.rs b/src/t15_chiton/mod.rs new file mode 100644 index 0000000..a8319e3 --- /dev/null +++ b/src/t15_chiton/mod.rs @@ -0,0 +1,157 @@ +use std::{ + collections::{BinaryHeap, HashMap}, + io::{BufReader, Read}, +}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + risk_level_map: Vec>, +} + +fn _print_table(t: &[Vec], separator: &str) { + for row in t { + println!( + "{}", + row.iter() + .map(|u| u.to_string()) + .collect::>() + .join(separator) + ); + } + println!(); +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + + let mut risk_level_map = Vec::new(); + + for line in buf.split_terminator('\n') { + let line: Vec<_> = line.chars().map(|c| c.to_digit(10).unwrap()).collect(); + risk_level_map.push(line); + } + + Input { risk_level_map } +} + +fn get_neigbours(index: (usize, usize), n: usize) -> Vec<(usize, usize)> { + let mut res = Vec::new(); + if index.0 > 0 { + res.push((index.0 - 1, index.1)); + } + if index.1 > 0 { + res.push((index.0, index.1 - 1)); + } + if index.0 < n - 1 { + res.push((index.0 + 1, index.1)); + } + if index.1 < n - 1 { + res.push((index.0, index.1 + 1)); + } + res +} + +#[derive(Eq, PartialEq)] +struct State { + node: (usize, usize), + cost: u32, +} + +impl Ord for State { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + other + .cost + .cmp(&self.cost) + .then_with(|| self.node.cmp(&other.node)) + } +} + +impl PartialOrd for State { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +fn find_min(table: &[Vec]) -> Option { + let n = table.len(); + + let start_node = (0, 0); + let end_node = (n - 1, n - 1); + + let mut best_paths = HashMap::new(); + best_paths.insert(start_node, 0); + + let mut frontline = BinaryHeap::from([State { + node: start_node, + cost: 0, + }]); + + while let Some(State { node, cost }) = frontline.pop() { + if node == end_node { + return Some(cost); + } + + if cost > *best_paths.entry(node).or_insert(u32::MAX) { + continue; + } + + let neigbours = get_neigbours(node, n); + + for neighbour in neigbours { + let neigbour_cost = table[neighbour.0][neighbour.1]; + let best_neigbour_cost = best_paths.entry(neighbour).or_insert(u32::MAX); + + if cost + neigbour_cost < *best_neigbour_cost { + *best_neigbour_cost = cost + neigbour_cost; + + frontline.push(State { + node: neighbour, + cost: *best_neigbour_cost, + }); + } + } + } + None +} + +pub fn chiton_1(test_mode: TestMode) { + let input = parse_input(test_mode); + let min = find_min(&input.risk_level_map).unwrap(); + println!("{}", min); +} + +fn new_val(v: &u32) -> u32 { + if *v == 9 { + 1 + } else { + *v + 1 + } +} + +pub fn chiton_2(test_mode: TestMode) { + let input = parse_input(test_mode); + + let n = input.risk_level_map.len(); + const FACTOR: usize = 5; + + let mut new_risk_level_map = input.risk_level_map; + for i in 0..FACTOR - 1 { + for line in new_risk_level_map.iter_mut() { + line.extend(line.clone()[n * i..n * (i + 1)].iter().map(new_val)); + } + } + for i in 0..FACTOR - 1 { + for line in new_risk_level_map.clone().iter().skip(n * i).take(n) { + new_risk_level_map.push(line.iter().map(new_val).collect()); + } + } + + // 2973 - too high + // 2966 - just right! + let min = find_min(&new_risk_level_map).unwrap(); + println!("{}", min); +} diff --git a/src/t15_chiton/prod.in b/src/t15_chiton/prod.in new file mode 100644 index 0000000..c8b996c --- /dev/null +++ b/src/t15_chiton/prod.in @@ -0,0 +1,100 @@ +8795561346959611984851795223993199426691978637498615942935297722897942579728189182383276311836891971 +9971917929239749392313919138788785878436257678478978964999643688839227886859465518439985489795943919 +1519761672617778785983978488277814115999116451991978869729122618211379791865816152742849499151214682 +9897768578325969757223986999919271436414939289747483386572979869519481591978913852845739134918128698 +6131844837515911671618346728935389713865862689991891968992859599212148719512981655915843896819419699 +9994158898369771516892943629594768792167999156447986693115896589979189597554487929195418898275991939 +7899714915991971118529915219739988517292138842395144993792669384948991998684649619885511938319926529 +8439945422238997549198746429761826973391669898967884389843379199899887495381477519258959688562189998 +8193158996336869219329798167599696253894399636289548599616776971684358719751199457412129189416339337 +8915467845679571319719627819399444276933882997919488941218392246725699575931358682988728811692994888 +2183821795618759299397119999912447724899136432675238876256982162673596561194541917989927328994884775 +8789678487971129849969177111293971322992799168799694179116768117969482793885681672825369745192292798 +9899995799751915683316369897193479341895969161197819529318324971956766824967977979682349271859692499 +9738389836681141541749679428151189548958914789921712997989991986792969749119449656969797779397987971 +9699386193977846925881916878943588579248899536993991794576926484969985986958761239832944749381396877 +2938918897233812797889785112782764111371659727455889948919937998893948984527919431599729431858423312 +6669951996546696289498264116385727972556973497368864657695549198987126379129178799142291929595944531 +9593327798991199813978669827818164893823995153184287992392877622665469666148268197736278655385853893 +4489883181443655445696668196922477872145911769238794459937988771294974551878994626812499591419882438 +9828537889259279861788699459666699933159822299169969994311839953287658281994334947114298299449399739 +4188562547592911131922397722799988999499427811169546472448222946122399994149695698195849512899141156 +7812927129675599119818993368441873851158999359195519823173938847593874317319938262871877982994151854 +8925469217741929237517277969589678521292549411978981218821255391918872181337782152599971935434586641 +5539173242188516261195962935992419699921211771998999829366384756736985679791323524894919899791751927 +7997814295618599112279785547892749118824587414992484558129913948987899996139582741731588699495997181 +9294699723167493823939899799875297999693938976152179786642196948529943458129635959926986719188788299 +3382299747968914256996638119179579489495894917369311729612961928153965889817885929465121747699993923 +1269933289896689643116489371719798989991587811658981468139317814827819327181648686519922623159872716 +8749822282959139712191898935929168514293911199984129154669719688839883778199899299699619241169648787 +7789461829886475855754227981617959439666958496998884492729328586718954493775988189711859281328961118 +1996981999456693988591117919251641821968898256445988799178396189162182741171111899482722939388958511 +3281911384597899419698914798194911889589839273747496947197364795912194969393957795992989291837591999 +1293812999287868589289214241179594649119899992343411877615638772289591199319196215849889992628429262 +2598787636835395941715619539222694792812975975481748539877868612571891699419489899939987379366597698 +4781462274896758851786199964998495994884799928116913548959881394813979886818979751785863571721749154 +9781899957313649191946278938943668952725533114949839896192161387789132989919592489457498991499145634 +8939291595887684897787947956711653882547657238349261375815578499482296127299179887193666585829749989 +3987392781148476892679669911899929328939559696918985892627927769683956664885969479599936511452997261 +9718491979119959846848498131157967812971882896718922983832319776899132516188992612996481749999992686 +8919943758399972755642585691411913377667687791139364126793319649518996979999699899691164918399189872 +7377178689183729718471814618846971671488612597556998591379995391219797917687997492569812892162829899 +6198691883598199239981463965166178891395862717797769949534348818992699479916324441967852879113914389 +9216989165552946188295851854481689328373995258899376993895872229212951841639956946995929695927819249 +9188886992578419341444721993392494111118832893996694812192621891797989996585963719519899668496979761 +6178959769221537294292836517919989929381873925111177297994731171813548771847917883712814928381315828 +3716898729898898116791923615175892681249798369195979923194893399955242992199314988739418974466288117 +6712671172426933931999899491979987495165963185198717561866882185885895989659986798139793799819433118 +4584379959151684983916286557263499959997582313992956794499595279918993992689611978329772677199695197 +9983899196819771699641681959945138993831935591154986184953899351941365399295712466533478897952142168 +6899162163198818566972762787289989382494938538296469493317537999999195467999754271988141381266789918 +1452932263797497952199118888137861961329529437698719177689997249821121712191719777639699188944321936 +8937299999674997371979425811822714647182423856472824694292841198359827339725542547754913932519964957 +9994946989869977763295691999117176543478371299189888681177844256187727685388616713239797198891771592 +7554973739824921451596999899131383498318934996922147599937751455999839159799296692986193923888918716 +2183293736212193119141897255991593533998965599699986684333511369999247828115626787252781948997399355 +7166988753117411929413382997948886498187158558318973167282939868978289154979461968949393388198748635 +3848991198627879899197562857896159183619819718874617129918483191133991967698128553471899459892397929 +2765314119181599176729133659328796299792767869687928921291778482422185719921369149813699944966311469 +8482691159398923761627882926982881117188945644896835748384958683499176311775975826629528934976436159 +8629967953659486936456699817244387935152911955491258868396712994893218779896713818697822473611899472 +9869569395962994217619893792989865797229926372388199383181753799972387947281751917911412193198648899 +2911975492385168179852911515718689961977743548821737615588468287984829778119138931993495899999411139 +6627692176997581928496111176845898128798398982139541832937981149719315979978979925639977479916288297 +7971686592726999387593121969616452677783738499693549294716146947144911287158388446849188523198921159 +9654356698192284395828218447993789572441791288511865165275957319726133989295828997899981479293199367 +1983295918471185535848787124187154967288585591968899954121721297447389146121365419765845984999697995 +3772299933945255981887183847913843946135928498137753611472573189883189388898147899899311559517594526 +6935119987289199372691298387496561978547581187375589699139538917889149981989973389296691993898137585 +9596981933155656783964173864653743482911961278323228972783896794973182687777999797879485992688899864 +7946745867994687182819593938168758438993987764997671339742591814996711459998829197381873761169833199 +7998761391174687853825798296855419379326297812911135911535769961499179699318147216113263387981953698 +6975995197822218189738184719494471188758894169771883498878198461499469547885896968499963693355941716 +4351931919415521116137351999816179752593389213165382519362992963377712912373918797312697527115653474 +4219916669692263574989959697799511818886799247369637226524896979114739798437327795849691299932928316 +9469815173589995599191717511929851241512129287419528975628498911949738259719499364539555799899987749 +8479915281919179814239178416812398824865776973192848267616874181477979169919153488172116912595685919 +1289893698599996944651792299632392688252343961243995892218884283891981753441377799862931899681885987 +1918997431886381819198395396582984757593892248817191118278199825665792383989396744979898488291819787 +1593953997936192775781629434971795219615284969133998265488117988899576939192195943941191263898454787 +4116191989544268918925399499117319147593767434896144251686491796711286886419319219768919724488339918 +5724615913863188944231161142188759223298646797932191661684846867251942817233499629528599748994238819 +9568989891141898878889593392781881437292997772591628197913688948429735171975377969524966319878852198 +1451975884978888899851513598956919574939335964999412895192972398975389988737989199973987816587729912 +8266921296948786193491779253862131431671987882857169537999157578838774176914698161799177147198972998 +9899977419231149419726862744398113392793194994238576864681993162199811196897926857981885899436634991 +8863975882112417779869387818526982917699448259848195932976179866278536198163191794669219691194232985 +8964676952961795683996858297181963591827634248715774196944191928959643811872914981968142899983398969 +3819129921898559367111958191971712538989297786949383519349717524859963945439921799892281989822321974 +6843888714292337419966941942419999999577112282934993189218898131672285193999999299488947947756888796 +4897177883982914929221319627191749689347559979399184189239223629815698729511514457552661229971845791 +7951497555381399499653191719458486151898656381679791193539839579318194299745115665134795986878886958 +8999796933696665971996778728127922964493478822898217169185834914999629245188781933911948789292989969 +9196969381136611468918217972388437845173999195912928197355989571899481559772197996243198878913819631 +7166988339662186997128362499643382919978799844892892946796715324518121699785894695193874729916993919 +9298281551968695911458882111884212373479298692144188529258731314391839459899983882393129697999711159 +8558438898992511996283529341897299969324918789817899999965999939196128992393994111199692651355275955 +7689899924699293736392725716697734919419784152918395812482316549583957919989329617954687594936783898 +1169796382849566792128293597457371455827987519511199778291917942178294599929539841167862969924979581 +9496929588378869969158122779414228929724985988984299699786358995268989949878981121159539739996566173 +9791763949837198338991393152592978229948887552199237768112426143281161433828316999916998589965921948 diff --git a/src/t15_chiton/test.in b/src/t15_chiton/test.in new file mode 100644 index 0000000..ab80887 --- /dev/null +++ b/src/t15_chiton/test.in @@ -0,0 +1,10 @@ +1163751742 +1381373672 +2136511328 +3694931569 +7463417111 +1319128137 +1359912421 +3125421639 +1293138521 +2311944581 diff --git a/src/t16_packet_decoder/mod.rs b/src/t16_packet_decoder/mod.rs new file mode 100644 index 0000000..8120412 --- /dev/null +++ b/src/t16_packet_decoder/mod.rs @@ -0,0 +1,279 @@ +use bitvec::prelude::*; +use serde::Serialize; +use std::{ + fmt::Debug, + io::{BufReader, Read}, +}; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + lines: Vec, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + + let lines = buf.lines().map(|l| l.to_owned()).collect(); + + Input { lines } +} + +fn decode_to_binary(s: &str) -> BitVec { + let d: Vec = s + .chars() + .collect::>() + .chunks(2) + .map(|c| u8::from_str_radix(&String::from_iter(c.iter()), 16).unwrap()) + .collect(); + + d.view_bits::().to_owned() +} + +const TYPE_ID_LITERAL: u8 = 4; +const LENGTH_TYPE_TOTAL_LEN: bool = false; +const LENGTH_TYPE_NUM_PACKETS: bool = true; + +#[derive(Clone, Debug, Serialize)] +struct Packet { + #[serde(skip)] + version: u8, + packet_type: PacketType, +} + +#[derive(Clone, Debug, Serialize)] +enum PacketType

{ + L(u64), + Op(OpType, Vec

), +} + +#[derive(Clone, Debug, Serialize)] +enum OpType { + Sum, + Product, + Min, + Max, + GreaterThan, + LessThan, + EqualTo, +} + +impl From for OpType { + fn from(id: u8) -> Self { + match id { + 0 => Self::Sum, + 1 => Self::Product, + 2 => Self::Min, + 3 => Self::Max, + 5 => Self::GreaterThan, + 6 => Self::LessThan, + 7 => Self::EqualTo, + _ => panic!(), + } + } +} + +impl Packet { + fn version_sum(&self) -> u64 { + let s = if let PacketType::Op(_, subpackets) = &self.packet_type { + subpackets.iter().map(|p| p.version_sum()).sum() + } else { + 0 + }; + let v: u64 = self.version.into(); + s + v + } + + fn new_operator(type_id: u8, version: u8, subpackets: Vec) -> Self { + let packet_type = PacketType::Op(OpType::from(type_id), subpackets); + Self { + version, + packet_type, + } + } + + fn new_literal(version: u8, value: u64) -> Self { + Self { + version, + packet_type: PacketType::L(value), + } + } + + fn calculate(&self) -> u64 { + match &self.packet_type { + PacketType::L(value) => *value, + PacketType::Op(operator_type, subpackets) => { + let subs: Vec<_> = subpackets.iter().map(|p| p.calculate()).collect(); + match operator_type { + OpType::Sum => subs.iter().sum(), + OpType::Product => subs.iter().product(), + OpType::Min => *subs.iter().min().unwrap(), + OpType::Max => *subs.iter().max().unwrap(), + OpType::GreaterThan => { + if subs[0] > subs[1] { + 1 + } else { + 0 + } + } + OpType::LessThan => { + if subs[0] < subs[1] { + 1 + } else { + 0 + } + } + OpType::EqualTo => { + if subs[0] == subs[1] { + 1 + } else { + 0 + } + } + } + } + } + } + + fn _get_expr(&self) -> String { + match &self.packet_type { + PacketType::L(value) => format!("{}", value), + PacketType::Op(operator_type, subpackets) => { + let subs = subpackets + .iter() + .map(|s| s._get_expr()) + .collect::>() + .join(", "); + match operator_type { + OpType::Sum => format!("sum({})", subs), + OpType::Product => format!("product({})", subs), + OpType::Min => format!("min({})", subs), + OpType::Max => format!("max({})", subs), + OpType::GreaterThan => format!("gt({})", subs), + OpType::LessThan => format!("lt({})", subs), + OpType::EqualTo => format!("eq({})", subs), + } + } + } + } +} + +fn parse_packet( + packet: &BitSlice, + inner_len: &mut usize, + max_num_packets: Option, +) -> Vec { + // println!("parse_packet: {:?} (max packets: {:?})", packet, max_num_packets); + + let mut packets = Vec::new(); + + let mut i = 0; + + loop { + if i >= packet.len() - 1 || packets.len() >= max_num_packets.unwrap_or(usize::MAX) { + break; + } + + let version = packet[i..i + 3].load_be(); + let type_id = packet[i + 3..i + 6].load_be(); + + // skip header + i += 6; + + match type_id { + TYPE_ID_LITERAL => { + let mut value: u64 = 0; + loop { + let m = &packet[i..i + 5]; + i += 5; + + value = (value << 4) | m[1..].load_be::(); + if !m[0] { + break; + } + } + + packets.push(Packet::new_literal(version, value)); + } + _ => { + // operator + + let length_type_id = packet[i]; + i += 1; + + let subpackets = match length_type_id { + LENGTH_TYPE_TOTAL_LEN => { + let len: usize = packet[i..i + 15].load_be::().into(); + i += 15; + + let mut _unused = 0; + let subpackets = parse_packet(&packet[i..i + len], &mut _unused, None); + assert_eq!(_unused, len); + i += len; + + subpackets + } + LENGTH_TYPE_NUM_PACKETS => { + let num_packets: usize = packet[i..i + 11].load_be(); + i += 11; + + let mut inner_len = 0; + let subpackets = + parse_packet(&packet[i..], &mut inner_len, Some(num_packets)); + i += inner_len; + + subpackets + } + }; + + packets.push(Packet::new_operator(type_id, version, subpackets)); + } + } + } + *inner_len = i; + + packets +} + +pub fn packet_decoder_1(test_mode: TestMode) { + let input = parse_input(test_mode); + + for line in input.lines { + let v = decode_to_binary(&line); + println!("{:?}", line); + // println!("{:?}", v); + + let mut x = 0; + let p = parse_packet(&v, &mut x, Some(1)); + let p = p.first().unwrap(); + println!("{:?}", p); + println!("{}", p.version_sum()); + + println!(); + } +} + +pub fn packet_decoder_2(test_mode: TestMode) { + let input = parse_input(test_mode); + + for line in input.lines { + let v = decode_to_binary(&line); + println!("{:?}", line); + + let mut x = 0; + let p = parse_packet(&v, &mut x, Some(1)); + let p = p.first().unwrap(); + // println!("{:?}", p); + + println!("{}", serde_yaml::to_string(p).unwrap()); + println!("{}", p.calculate()); + // println!("{}", p.get_expr()); + + println!(); + } + + // 327007 - too low +} diff --git a/src/t16_packet_decoder/prod.in b/src/t16_packet_decoder/prod.in new file mode 100644 index 0000000..8650b4e --- /dev/null +++ b/src/t16_packet_decoder/prod.in @@ -0,0 +1 @@ +805311100469800804A3E488ACC0B10055D8009548874F65665AD42F60073E7338E7E5C538D820114AEA1A19927797976F8F43CD7354D66747B3005B401397C6CBA2FCEEE7AACDECC017938B3F802E000854488F70FC401F8BD09E199005B3600BCBFEEE12FFBB84FC8466B515E92B79B1003C797AEBAF53917E99FF2E953D0D284359CA0CB80193D12B3005B4017968D77EB224B46BBF591E7BEBD2FA00100622B4ED64773D0CF7816600B68020000874718E715C0010D8AF1E61CC946FB99FC2C20098275EBC0109FA14CAEDC20EB8033389531AAB14C72162492DE33AE0118012C05EEB801C0054F880102007A01192C040E100ED20035DA8018402BE20099A0020CB801AE0049801E800DD10021E4002DC7D30046C0160004323E42C8EA200DC5A87D06250C50015097FB2CFC93A101006F532EB600849634912799EF7BF609270D0802B59876F004246941091A5040402C9BD4DF654967BFDE4A6432769CED4EC3C4F04C000A895B8E98013246A6016CB3CCC94C9144A03CFAB9002033E7B24A24016DD802933AFAE48EAA3335A632013BC401D8850863A8803D1C61447A00042E3647B83F313674009E6533E158C3351F94C9902803D35C869865D564690103004E74CB001F39BEFFAAD37DFF558C012D005A5A9E851D25F76DD88A5F4BC600ACB6E1322B004E5FE1F2FF0E3005EC017969EB7AE4D1A53D07B918C0B1802F088B2C810326215CCBB6BC140C0149EE87780233E0D298C33B008C52763C9C94BF8DC886504E1ECD4E75C7E4EA00284180371362C44320043E2EC258F24008747785D10C001039F80644F201217401500043A2244B8D200085C3F8690BA78F08018394079A7A996D200806647A49E249C675C0802609D66B004658BA7F1562500366279CCBEB2600ACCA6D802C00085C658BD1DC401A8EB136100 diff --git a/src/t16_packet_decoder/test.in b/src/t16_packet_decoder/test.in new file mode 100644 index 0000000..5416164 --- /dev/null +++ b/src/t16_packet_decoder/test.in @@ -0,0 +1,10 @@ +C200B40A82 +04005AC33890 +880086C3E88112 +CE00C43D881120 +D8005AC2A8F0 +F600BC2D8F +9C005AC2F8F0 +9C0141080250320F1802104A08 +EE00D40C823060 +38006F45291200 diff --git a/src/t16_packet_decoder/test1.in b/src/t16_packet_decoder/test1.in new file mode 100644 index 0000000..a83b475 --- /dev/null +++ b/src/t16_packet_decoder/test1.in @@ -0,0 +1,4 @@ +8A004A801A8002F478 +620080001611562C8802118E34 +C0015000016115A2E0802F182340 +A0016C880162017C3686B18A3D4780 diff --git a/src/t16_packet_decoder/test2.in b/src/t16_packet_decoder/test2.in new file mode 100644 index 0000000..461fdea --- /dev/null +++ b/src/t16_packet_decoder/test2.in @@ -0,0 +1,8 @@ +C200B40A82 +04005AC33890 +880086C3E88112 +CE00C43D881120 +D8005AC2A8F0 +F600BC2D8F +9C005AC2F8F0 +9C0141080250320F1802104A08 diff --git a/src/t17_trick_shot/mod.rs b/src/t17_trick_shot/mod.rs new file mode 100644 index 0000000..35f8b1b --- /dev/null +++ b/src/t17_trick_shot/mod.rs @@ -0,0 +1,116 @@ +use std::io::{BufRead, BufReader}; + +use regex::Regex; + +use crate::types::TestMode; + +#[derive(Debug)] +struct Input { + min_x: i32, + max_x: i32, + min_y: i32, + max_y: i32, +} + +fn parse_input(test_mode: TestMode) -> Input { + let f = test_mode.input_file(file!()); + let mut buf = String::new(); + BufReader::new(f).read_line(&mut buf).unwrap(); + + let r = Regex::new(r"target area: x=(-?\d+)\.\.(-?\d+), y=(-?\d+)\.\.(-?\d+)").unwrap(); + let matches = r.captures(&buf).unwrap(); + let min_x = matches.get(1).unwrap().as_str().parse().unwrap(); + let max_x = matches.get(2).unwrap().as_str().parse().unwrap(); + let min_y = matches.get(3).unwrap().as_str().parse().unwrap(); + let max_y = matches.get(4).unwrap().as_str().parse().unwrap(); + + Input { + min_x, + max_x, + min_y, + max_y, + } +} + +fn find_max_y(v_x: i32, v_y: i32, input: &Input) -> Option { + let mut x = 0; + let mut y = 0; + let mut v_x = v_x; + let mut v_y = v_y; + + let mut max_y = 0; + while x <= input.max_x && y >= input.min_y { + x += v_x; + y += v_y; + + if y > max_y { + max_y = y; + } + + if x >= input.min_x && x <= input.max_x && y >= input.min_y && y <= input.max_y { + return Some(max_y); + } + match v_x.cmp(&0) { + std::cmp::Ordering::Less => v_x += 1, + std::cmp::Ordering::Equal => {} + std::cmp::Ordering::Greater => v_x -= 1, + } + v_y -= 1; + } + + None +} + +pub fn trick_shot_1(test_mode: TestMode) { + let input = parse_input(test_mode); + println!("{:?}", input); + + let mut min_x = 0; + while min_x * (min_x + 1) < 2 * input.min_x { + min_x += 1; + } + let max_x = input.max_x; + let min_y = input.min_y; + + println!("min_x: {}, max_x: {}", min_x, max_x); + + let mut global_max_y = 0; + for x in min_x..=max_x { + for y in min_y..150 { + let max_y = find_max_y(x, y, &input).unwrap_or(0); + if max_y > global_max_y { + global_max_y = max_y; + // println!("x: {}, y: {}, max_y: {}", x, y, max_y); + } + } + } + // 2701 - too low + println!("{}", global_max_y); +} + +pub fn trick_shot_2(test_mode: TestMode) { + let input = parse_input(test_mode); + println!("{:?}", input); + + let mut min_x = 0; + while min_x * (min_x + 1) < 2 * input.min_x { + min_x += 1; + } + let max_x = input.max_x; + let min_y = input.min_y; + // v_y0 = (n^2 - n + 2M) / 2n = n/2 - 1/2 + M/n = (n - 1)/2 + M/n + let max_y = 2 * input.min_y.abs(); + + println!("min_x: {}, max_x: {}", min_x, max_x); + println!("min_y: {}, max_y: {}", min_y, max_y); + + let mut num_options = 0; + for x in min_x..=max_x { + for y in min_y..=max_y { + if find_max_y(x, y, &input).is_some() { + num_options += 1; + } + } + } + println!("{}", num_options); +} diff --git a/src/t17_trick_shot/prod.in b/src/t17_trick_shot/prod.in new file mode 100644 index 0000000..6aedd45 --- /dev/null +++ b/src/t17_trick_shot/prod.in @@ -0,0 +1 @@ +target area: x=81..129, y=-150..-108 diff --git a/src/t17_trick_shot/test.in b/src/t17_trick_shot/test.in new file mode 100644 index 0000000..a07e02d --- /dev/null +++ b/src/t17_trick_shot/test.in @@ -0,0 +1 @@ +target area: x=20..30, y=-10..-5 diff --git a/src/t18_snailfish/mod.rs b/src/t18_snailfish/mod.rs new file mode 100644 index 0000000..4ed8bd7 --- /dev/null +++ b/src/t18_snailfish/mod.rs @@ -0,0 +1,270 @@ +use std::{ + cell::RefCell, + fmt::Display, + io::{BufReader, Read}, + ops::{Add, Deref}, + rc::Rc, + str::FromStr, +}; + +use crate::types::TestMode; + +#[derive(Clone, Debug)] +enum SnailNum { + Pair(Rc>>, Rc>>), + Number(u8), +} + +impl Display for SnailNum { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match &self { + &Self::Pair(left, right) => f.write_fmt(format_args!( + "[{},{}]", + left.as_ref().borrow(), + right.as_ref().borrow() + )), + &Self::Number(n) => f.write_fmt(format_args!("{}", n)), + } + } +} + +impl Add for SnailNum { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + let left = Rc::new(RefCell::new(Box::new(self))); + let right = Rc::new(RefCell::new(Box::new(rhs))); + let n = Self::Pair(left, right); + // println!("after addition: {}", n); + n.resolve_explodes() + } +} + +impl FromStr for SnailNum { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + let mut _unused = 0; + Ok(Self::internal_from_str(s, &mut _unused)) + } +} + +impl SnailNum { + fn internal_from_str(s: &str, consumed_len_out: &mut usize) -> SnailNum { + if s.starts_with('[') { + let mut current_index = 1; + + let mut left_len = 0; + let left = Self::internal_from_str(&s[current_index..], &mut left_len); + + current_index += left_len + 1; + + let mut right_len = 0; + let right = Self::internal_from_str(&s[current_index..], &mut right_len); + + current_index += right_len + 1; + + *consumed_len_out = current_index; + + SnailNum::Pair( + Rc::new(RefCell::new(Box::new(left))), + Rc::new(RefCell::new(Box::new(right))), + ) + } else { + let value = u8::from_str(&s[0..1]).unwrap(); + *consumed_len_out = 1; + SnailNum::Number(value) + } + } + + fn resolve_splits(&self, did_do_splits: &mut bool) -> Self { + let result = self.clone(); + + let mut q = Vec::new(); + if let SnailNum::Pair(left, right) = &result { + q.push(right.clone()); + q.push(left.clone()); + } + + let mut split_pair = None; + let mut split_number = 0; + + while let Some(n) = q.pop() { + let pp = n.deref().borrow_mut(); + + match pp.as_ref() { + SnailNum::Pair(left, right) => { + q.push(right.clone()); + q.push(left.clone()); + } + SnailNum::Number(number) => { + if number > &9 { + split_pair = Some(n.clone()); + split_number = *number; + break; + } + } + } + } + + if let Some(p) = &split_pair { + let left = Rc::new(RefCell::new(Box::new(SnailNum::Number( + (split_number - (split_number % 2)) / 2, + )))); + let right = Rc::new(RefCell::new(Box::new(SnailNum::Number( + (split_number + (split_number % 2)) / 2, + )))); + + *p.deref().borrow_mut() = Box::new(SnailNum::Pair(left, right)); + + // println!("after split: {}", result); + } + + *did_do_splits = split_pair.is_some(); + result + } + + fn resolve_explodes(self) -> Self { + let mut result = self.clone(); + + let mut q = Vec::new(); + if let SnailNum::Pair(left, right) = &result { + q.push((right.clone(), 1)); + q.push((left.clone(), 1)); + } + + let mut numbers = Vec::new(); + let mut exploding_node = None; + + while let Some(n) = q.pop() { + let pp = n.0.deref().borrow_mut(); + + match pp.as_ref() { + SnailNum::Pair(left, right) => { + q.push((right.clone(), n.1 + 1)); + q.push((left.clone(), n.1 + 1)); + + if n.1 > 3 && exploding_node.is_none() { + exploding_node = Some(n.0.clone()); + } + } + SnailNum::Number(_) => { + numbers.push(n.0.clone()); + } + } + } + + if let Some(node) = &exploding_node { + if let SnailNum::Pair(nested_left, nested_right) = node.deref().borrow().as_ref() { + if let SnailNum::Number(nested_left_num) = nested_left.deref().borrow().as_ref() { + let nested_left_index = numbers + .iter() + .position(|x| x.as_ptr() == nested_left.as_ptr()) + .unwrap(); + + if nested_left_index > 0 { + let mut x = numbers[nested_left_index - 1].deref().borrow_mut(); + match **x { + SnailNum::Number(n) => { + *x = Box::new(SnailNum::Number(n + nested_left_num)) + } + _ => panic!(), + } + } + } + if let SnailNum::Number(nested_right_num) = nested_right.deref().borrow().as_ref() { + let nested_right_index = numbers + .iter() + .position(|x| x.as_ptr() == nested_right.as_ptr()) + .unwrap(); + + if nested_right_index < numbers.len() - 1 { + let mut x = numbers[nested_right_index + 1].deref().borrow_mut(); + match **x { + SnailNum::Number(n) => { + *x = Box::new(SnailNum::Number(n + nested_right_num)) + } + _ => panic!(), + } + } + } + } + *node.deref().borrow_mut() = Box::new(SnailNum::Number(0)); + + // println!("after explode: {}", &result); + } + + if exploding_node.is_some() { + result.resolve_explodes() + } else { + let mut resolved_spits = false; + result = result.resolve_splits(&mut resolved_spits); + + if resolved_spits { + result.resolve_explodes() + } else { + result + } + } + } + + fn magnitude(&self) -> u64 { + match self { + SnailNum::Pair(left, right) => { + 3 * left.deref().borrow().magnitude() + 2 * right.deref().borrow().magnitude() + } + SnailNum::Number(n) => *n as u64, + } + } +} + +#[derive(Debug)] +struct Input { + numbers: Vec, +} + +fn parse_input(test_mode: &TestMode) -> Input { + let f = test_mode.input_file(file!()); + let mut buf = String::new(); + BufReader::new(f).read_to_string(&mut buf).unwrap(); + + let numbers = buf.lines().map(|line| line.parse().unwrap()).collect(); + Input { numbers } +} + +pub fn snailfish_1(test_mode: TestMode) { + let input = parse_input(&test_mode); + + let mut s = input.numbers[0].clone(); + for n in input.numbers[1..].into_iter() { + // println!(" {}", s); + // println!("+ {}", n); + s = s + n.clone(); + // println!("= {}\n", s); + } + + println!("{}", s.magnitude()) +} + +pub fn snailfish_2(test_mode: TestMode) { + let mut max = 0; + let input = parse_input(&test_mode); + for i in 0..input.numbers.len() { + for j in 0..input.numbers.len() { + if i != j { + let input = parse_input(&test_mode); + // println!("{}, {}", i, j); + let x = input.numbers[i].clone(); + let y = input.numbers[j].clone(); + let s = x.clone() + y.clone(); + let m = s.magnitude(); + // println!("|{} + {}| = {} ({})", &x, &y, m, s); + if m > max { + max = m; + } + } + } + } + + println!("{}", max); +} diff --git a/src/t18_snailfish/prod.in b/src/t18_snailfish/prod.in new file mode 100644 index 0000000..1aa1391 --- /dev/null +++ b/src/t18_snailfish/prod.in @@ -0,0 +1,100 @@ +[[3,[[6,3],[9,6]]],[6,[[0,9],[9,7]]]] +[[[3,9],[[0,8],[7,6]]],[[[7,9],1],[1,3]]] +[8,[[[9,6],[8,4]],4]] +[5,[[1,2],[3,7]]] +[[[[7,7],5],[[3,5],8]],4] +[[[5,[0,7]],3],[[5,[5,3]],[1,[9,4]]]] +[[[[3,5],[7,1]],6],[[[3,6],[5,6]],[[3,2],5]]] +[[[[2,0],[3,0]],[5,7]],[[4,4],[[9,9],[9,3]]]] +[[[[8,0],7],[[7,1],9]],[[3,[8,6]],8]] +[[6,[7,5]],[[6,8],9]] +[[[9,[1,8]],2],[[[4,0],[9,3]],1]] +[[7,[1,[3,8]]],[[4,7],[8,1]]] +[[[5,5],[[4,5],[2,9]]],[[[7,7],0],8]] +[[[[4,7],3],5],[[[4,3],[3,8]],[[6,5],5]]] +[[[[3,8],2],[1,7]],[[[3,1],4],9]] +[[[[2,1],4],[[9,5],[1,4]]],[[3,5],[[9,1],9]]] +[[[6,[1,8]],[0,0]],[9,[0,3]]] +[[[[2,2],[3,3]],[[4,8],4]],[[[6,8],4],5]] +[4,[[[7,8],[3,4]],[[3,2],9]]] +[[[9,0],3],[[[7,1],4],7]] +[[[1,4],8],[[7,5],[[8,0],[0,7]]]] +[9,[[4,6],[[2,9],1]]] +[[[[1,8],8],6],[[[2,0],6],[0,5]]] +[[[5,5],[6,4]],[[3,8],[9,[7,6]]]] +[[0,[8,[1,4]]],2] +[[[[9,5],0],5],[9,[7,5]]] +[[9,[4,8]],[[8,1],[[8,6],[7,1]]]] +[4,[[[9,6],5],9]] +[[[[3,7],6],0],[[7,7],[[2,7],[9,3]]]] +[[[6,[3,7]],[[8,3],2]],[8,[6,[8,5]]]] +[[[5,[2,7]],[[6,7],3]],[5,[[4,4],1]]] +[[1,0],[[2,8],[[0,4],9]]] +[[[1,4],6],[[[9,8],[1,0]],1]] +[[3,4],[[1,[8,4]],8]] +[[[[9,4],[0,7]],[[5,4],[8,2]]],2] +[5,[[[8,7],[3,4]],[2,4]]] +[[[[1,3],[8,6]],[[3,4],6]],[[8,5],[[9,3],[5,7]]]] +[[0,[[0,9],[7,8]]],[3,9]] +[0,[[8,[2,3]],[[3,5],[4,9]]]] +[[[4,3],[[1,9],[1,5]]],[4,[[9,1],1]]] +[[[[3,6],[2,5]],3],[[8,[8,0]],[[6,9],[5,8]]]] +[7,[[3,[3,6]],[[6,9],[2,7]]]] +[[[[8,3],[6,5]],[[3,9],2]],[6,1]] +[[[2,0],[2,3]],8] +[[1,[[8,7],2]],[[[9,4],8],[4,[9,0]]]] +[[[6,7],[[5,2],3]],[[0,5],[[9,4],[2,6]]]] +[[[9,[5,8]],[[9,3],[6,9]]],5] +[[[5,[4,6]],[5,[3,2]]],[2,[9,[5,4]]]] +[8,6] +[[[4,8],[3,1]],[1,[[7,8],[7,5]]]] +[[4,[[8,8],4]],[5,[8,[3,9]]]] +[[[4,[9,0]],[[0,3],5]],[[5,[3,0]],[6,[2,3]]]] +[[[4,0],8],[[[4,0],7],[[9,6],3]]] +[[8,[[7,8],5]],[[[6,2],8],[1,[0,4]]]] +[[1,[[3,4],[0,8]]],[[6,5],3]] +[[5,2],[[8,6],[1,[9,7]]]] +[5,[6,[[1,3],[1,0]]]] +[[0,[[1,9],[5,6]]],[[[6,2],[5,1]],[[1,2],[1,0]]]] +[[[7,1],4],[[[0,3],3],[[4,8],1]]] +[[3,[9,[3,4]]],[1,[[0,0],[1,4]]]] +[1,[7,[1,[3,7]]]] +[[[0,[5,6]],[[7,4],[5,7]]],[[[6,8],[4,6]],9]] +[[[9,8],[7,[1,3]]],3] +[[[4,[0,3]],[[3,0],6]],[[2,[9,2]],1]] +[[[[1,9],[3,3]],[8,1]],5] +[[7,[5,2]],[[4,[0,1]],[3,3]]] +[[[6,6],[0,6]],[[3,[5,9]],[[4,2],[4,3]]]] +[[[7,[5,4]],[7,1]],9] +[[6,[5,2]],[[7,[0,5]],4]] +[[[8,1],[[7,6],[4,1]]],2] +[[[[4,3],[1,4]],[9,6]],[3,[[2,5],3]]] +[[[[9,3],[5,0]],1],[1,[[9,7],9]]] +[[[8,5],[5,9]],[2,[4,[0,0]]]] +[[[[7,9],2],[[8,8],[6,3]]],[7,[0,9]]] +[[[[6,6],[0,2]],[2,[9,0]]],[[0,9],[9,9]]] +[[[9,[1,3]],[6,5]],[[[1,1],8],[9,[7,2]]]] +[[8,[[8,4],6]],[[4,[5,9]],0]] +[[8,[5,[6,7]]],[[[1,9],9],[0,[0,9]]]] +[[9,[9,[7,3]]],[4,[4,7]]] +[[[[9,3],7],5],[[5,[8,5]],[0,[8,0]]]] +[[[5,[9,0]],[[7,4],[5,3]]],[3,[[1,1],[1,8]]]] +[[1,[[1,4],[5,9]]],[[[9,1],[6,5]],[9,[0,7]]]] +[[[[9,4],9],[5,3]],[[[4,2],[2,2]],[[1,0],0]]] +[[[6,[8,6]],9],[8,[[0,1],[9,7]]]] +[[2,0],[5,[[8,3],4]]] +[[[[0,2],0],8],[8,[[2,5],[8,2]]]] +[[[[7,4],8],[9,[7,5]]],[8,[7,[5,3]]]] +[[2,4],[3,[3,8]]] +[[5,4],[[0,[5,8]],[4,3]]] +[6,[[5,[4,7]],9]] +[[[2,[6,8]],[5,5]],[[[3,0],4],[[6,6],[0,1]]]] +[[[1,[4,2]],[[8,0],8]],[8,[[6,1],[0,0]]]] +[[9,[2,[3,3]]],[[2,6],[[5,2],[5,8]]]] +[[9,[4,4]],[[[8,6],1],2]] +[2,[[[0,7],7],[[7,8],5]]] +[[[4,0],[[1,1],[7,6]]],[[6,7],[[7,2],1]]] +[[[[2,5],0],[[9,5],9]],[6,[7,[6,1]]]] +[[[7,8],1],[[[6,2],0],[[9,7],[3,5]]]] +[[[9,1],0],[3,[[6,1],[6,9]]]] +[[[[9,0],0],[4,[7,0]]],[[6,[4,0]],[8,[4,2]]]] diff --git a/src/t18_snailfish/test.in b/src/t18_snailfish/test.in new file mode 100644 index 0000000..1368dc4 --- /dev/null +++ b/src/t18_snailfish/test.in @@ -0,0 +1,10 @@ +[[[0,[5,8]],[[1,7],[9,6]]],[[4,[1,2]],[[1,4],2]]] +[[[5,[2,8]],4],[5,[[9,9],0]]] +[6,[[[6,2],[5,6]],[[7,6],[4,7]]]] +[[[6,[0,7]],[0,9]],[4,[9,[9,0]]]] +[[[7,[6,4]],[3,[1,3]]],[[[5,5],1],9]] +[[6,[[7,3],[3,2]]],[[[3,8],[5,7]],4]] +[[[[5,4],[7,7]],8],[[8,3],8]] +[[9,3],[[9,9],[6,[4,9]]]] +[[2,[[7,7],7]],[[5,8],[[9,3],[0,2]]]] +[[[[5,2],5],[8,[3,7]]],[[5,[7,5]],[4,4]]] diff --git a/src/types/mod.rs b/src/types/mod.rs new file mode 100644 index 0000000..f5472b0 --- /dev/null +++ b/src/types/mod.rs @@ -0,0 +1,36 @@ +use std::{fs::File, path::PathBuf, str::FromStr}; + +pub enum TestMode { + Test, + Production, +} + +impl TestMode { + fn input_file_name(&self, module_file: &'static str) -> PathBuf { + let in_name = match self { + TestMode::Test => "test.in", + TestMode::Production => "prod.in", + }; + + let mut p = PathBuf::from(module_file); + p.pop(); + p.push(in_name); + p + } + + pub fn input_file(&self, module_file: &'static str) -> File { + File::open(self.input_file_name(module_file)).unwrap() + } +} + +impl FromStr for TestMode { + type Err = &'static str; + + fn from_str(s: &str) -> Result { + match s { + "p" => Ok(TestMode::Production), + "t" => Ok(TestMode::Test), + _ => Err("Unknown test mode!"), + } + } +}