From ae7dae8b79652646ee1e4a990c2dc13cf87f59ed Mon Sep 17 00:00:00 2001 From: george Date: Wed, 14 Dec 2022 20:30:04 +0000 Subject: [PATCH] day 13 --- day13/Cargo.lock | 89 +++++++++++++++++++++++++++++++++++++++++++ day13/Cargo.toml | 10 +++++ day13/src/main.rs | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 day13/Cargo.lock create mode 100644 day13/Cargo.toml create mode 100644 day13/src/main.rs diff --git a/day13/Cargo.lock b/day13/Cargo.lock new file mode 100644 index 0000000..932f6cc --- /dev/null +++ b/day13/Cargo.lock @@ -0,0 +1,89 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day13" +version = "0.1.0" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + +[[package]] +name = "proc-macro2" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "serde" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e326c9ec8042f1b5da33252c8a37e9ffbd2c9bef0155215b6e6c80c790e05f91" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42a3df25b0713732468deadad63ab9da1f1fd75a48a15024b50363f128db627e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "syn" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" diff --git a/day13/Cargo.toml b/day13/Cargo.toml new file mode 100644 index 0000000..3e401de --- /dev/null +++ b/day13/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "day13" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/day13/src/main.rs b/day13/src/main.rs new file mode 100644 index 0000000..017a3aa --- /dev/null +++ b/day13/src/main.rs @@ -0,0 +1,97 @@ +#![feature(iter_array_chunks)] +#![feature(is_some_and)] +use std::cmp::Ordering; + +fn main() { + let json = std::fs::read_to_string("/dev/stdin").unwrap(); + let mut p1_tot = 0; + let mut p2_tot = 1; + + let starting_packet: serde_json::Value = serde_json::from_str("[[2]]").unwrap(); + let ending_packet: serde_json::Value = serde_json::from_str("[[6]]").unwrap(); + + for (i, [left, right]) in json + .lines() + .filter(|l| !l.is_empty()) + .array_chunks() + .enumerate() + { + let left: serde_json::Value = serde_json::from_str(left).unwrap(); + let right: serde_json::Value = serde_json::from_str(right).unwrap(); + + let right_order = serde_cmp(Some(&left), Some(&right)).1; + if right_order { + p1_tot += i + 1; + } + } + + let mut all = json + .lines() + .filter(|l| !l.is_empty()) + .map(|l| serde_json::from_str::(l).unwrap()) + .collect::>(); + + all.push(starting_packet.clone()); + all.push(ending_packet.clone()); + + all.sort_by(|a, b| match serde_cmp(Some(a), Some(b)).1 { + true => Ordering::Less, + false => Ordering::Greater, + }); + + for (idx, line) in all.iter().enumerate() { + if *line == starting_packet || *line == ending_packet { + p2_tot *= idx + 1; + } + } + + println!("P1: {}, P2: {}", p1_tot, p2_tot); +} + +// cmp returns two bools: keep checking?, and current values in right order? +fn serde_cmp(l: Option<&serde_json::Value>, r: Option<&serde_json::Value>) -> (bool, bool) { + if l.is_none() && r.is_none() { + panic!("both values are none"); + } + + match (l, r) { + (Some(_), None) => return (false, false), + (None, Some(_)) => return (false, true), + (None, None) => return (true, false), + (_, _) => (), + } + + let (l, r) = (l.unwrap(), r.unwrap()); + + if l.is_number() && r.is_number() { + let (ln, rn) = (l.as_i64().unwrap(), r.as_i64().unwrap()); + + match ln.cmp(&rn) { + Ordering::Greater => return (false, false), + Ordering::Equal => return (true, false), + Ordering::Less => return (false, true), + } + } + + let (fl, fr) = (to_flat_vec(l), to_flat_vec(r)); + for i in 0..std::cmp::max(fl.len(), fr.len()) { + let (more, res) = serde_cmp(fl.get(i).copied(), fr.get(i).copied()); + if !more { + return (more, res); + } + } + + (true, true) +} + +fn to_flat_vec(val: &serde_json::Value) -> Vec<&serde_json::Value> { + if val.is_number() { + return vec![val]; + } + + if val.is_array() { + return val.as_array().unwrap().iter().collect::>(); + } + + panic!("val is neither array or num") +}