summaryrefslogtreecommitdiff
path: root/2024
diff options
context:
space:
mode:
Diffstat (limited to '2024')
-rw-r--r--2024/05/rust/Cargo.lock7
-rw-r--r--2024/05/rust/Cargo.toml6
-rw-r--r--2024/05/rust/src/main.rs87
3 files changed, 100 insertions, 0 deletions
diff --git a/2024/05/rust/Cargo.lock b/2024/05/rust/Cargo.lock
new file mode 100644
index 0000000..5ae963b
--- /dev/null
+++ b/2024/05/rust/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "aoc_2024-05"
+version = "0.1.0"
diff --git a/2024/05/rust/Cargo.toml b/2024/05/rust/Cargo.toml
new file mode 100644
index 0000000..de0fa13
--- /dev/null
+++ b/2024/05/rust/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "aoc_2024-05"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
diff --git a/2024/05/rust/src/main.rs b/2024/05/rust/src/main.rs
new file mode 100644
index 0000000..bf72727
--- /dev/null
+++ b/2024/05/rust/src/main.rs
@@ -0,0 +1,87 @@
+#![feature(slice_split_once)]
+
+use std::cmp::Ordering;
+use std::collections::HashMap;
+use std::io;
+
+fn main() -> io::Result<()> {
+ let lines = io::stdin().lines().flatten().collect::<Vec<_>>();
+ let (rules, updates) = lines.split_once(String::is_empty).unwrap();
+ let manual = rules.iter().collect::<Manual>();
+
+ let updates = updates
+ .iter()
+ .map(|up| {
+ up.split(',')
+ .map(|p| Page {
+ number: p.parse::<u64>().unwrap(),
+ manual: &manual,
+ })
+ .collect::<_>()
+ })
+ .collect::<Vec<Vec<_>>>();
+
+ let mut silver = 0;
+ let mut gold = 0;
+ for mut up in updates {
+ let mid = up.len() / 2;
+ if up.is_sorted() {
+ silver += up[mid].number;
+ } else {
+ up.sort_unstable();
+ gold += up[mid].number;
+ }
+ }
+
+ println!("silver: {silver}");
+ println!("gold: {gold}");
+
+ return Ok(());
+}
+#[derive(Debug)]
+struct Manual {
+ order: HashMap<u64, Vec<u64>>,
+}
+
+impl<'a> FromIterator<&'a String> for Manual {
+ fn from_iter<T: IntoIterator<Item = &'a String>>(rules: T) -> Self {
+ let mut order = HashMap::<u64, Vec<u64>>::new();
+ for rule in rules {
+ let (pre, post) = rule.split_once('|').unwrap();
+ order
+ .entry(pre.parse().unwrap())
+ .or_default()
+ .push(post.parse().unwrap());
+ }
+ Manual { order }
+ }
+}
+
+#[derive(Clone, Copy)]
+struct Page<'a> {
+ number: u64,
+ manual: &'a Manual,
+}
+
+impl PartialEq for Page<'_> {
+ fn eq(&self, other: &Self) -> bool {
+ self.number == other.number
+ }
+}
+impl Eq for Page<'_> {}
+
+impl PartialOrd for Page<'_> {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ if self.manual.order.get(&self.number)?.contains(&other.number) {
+ Some(Ordering::Less)
+ } else {
+ Some(Ordering::Greater)
+ }
+ }
+}
+
+impl Ord for Page<'_> {
+ fn cmp(&self, other: &Self) -> Ordering {
+ self.partial_cmp(other).unwrap()
+ }
+}