summaryrefslogtreecommitdiff
path: root/2024/day05.rs
diff options
context:
space:
mode:
Diffstat (limited to '2024/day05.rs')
-rw-r--r--2024/day05.rs106
1 files changed, 106 insertions, 0 deletions
diff --git a/2024/day05.rs b/2024/day05.rs
new file mode 100644
index 0000000..bf4303a
--- /dev/null
+++ b/2024/day05.rs
@@ -0,0 +1,106 @@
+#![allow(dead_code)]
+#![allow(unused_variables)]
+#![allow(unused_mut)]
+use std::env;
+use std::fs::File;
+use std::io::Read;
+
+fn is_valid(update: &Vec<usize>, rules: &Vec<(usize, usize)>) -> bool {
+ for (i, n) in update.iter().enumerate() {
+ for (l, r) in rules {
+ if n == l {
+ if let Some(pr) = update.iter().position(|a| a == r) {
+ if pr < i {
+ return false;
+ }
+ }
+ }
+ if n == r {
+ if let Some(pl) = update.iter().position(|a| a == l) {
+ if pl > i {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ true
+}
+
+fn make_valid(update: &Vec<usize>, rules: &Vec<(usize, usize)>) -> Vec<usize> {
+ let mut uv = update.clone();
+ for i in 0..uv.len() {
+ let n = uv[i];
+ for (l, r) in rules {
+ if n == *l {
+ if let Some(pr) = uv.iter().position(|a| a == r) {
+ if pr < i {
+ uv[pr] = n;
+ uv[i] = *r;
+ break;
+ }
+ }
+ }
+ if n == *r {
+ if let Some(pl) = uv.iter().position(|a| a == l) {
+ if i < pl {
+ uv[pl] = n;
+ uv[i] = *l;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ uv
+}
+
+fn main() {
+ let args: Vec<String> = env::args().collect();
+ let filename = if args.len() == 1 {
+ "in/".to_owned() + args[0].split('/').last().unwrap() + ".pzl"
+ } else {
+ args[1].clone()
+ };
+ let mut f = File::open(filename).expect("cannot open file");
+ let mut content = String::new();
+ f.read_to_string(&mut content).expect("cannot read file");
+ let (paragraph1, paragraph2) = content.trim_end().split_once("\n\n").unwrap();
+ let paragraph1 = paragraph1.trim_end().split("\n");
+ let paragraph2 = paragraph2.trim_end().split("\n");
+
+ let mut rules: Vec<(usize, usize)> = Vec::new();
+ for line in paragraph1 {
+ let (a, b) = line.split_once("|").unwrap();
+ rules.push((a.parse().unwrap(), b.parse().unwrap()));
+ }
+ //println!("{:?}", rules);
+
+ let mut updates: Vec<Vec<usize>> = Vec::new();
+ for line in paragraph2 {
+ updates.push(line.split(",").map(|a| a.parse().unwrap()).collect());
+ }
+ //println!("{:?}", updates);
+
+ let mut res1 = 0;
+ let mut res2 = 0;
+ for u in updates {
+ let ret = is_valid(&u, &rules);
+ if ret {
+ res1 += u[u.len() / 2];
+ } else {
+ let mut uv = make_valid(&u, &rules);
+ while !is_valid(&uv, &rules) {
+ uv = make_valid(&uv, &rules);
+ }
+ res2 += uv[uv.len() / 2];
+ }
+ }
+
+ println!("res1: {}", res1);
+ println!("res2: {}", res2);
+ assert_eq!(res1, 4766);
+ assert_eq!(res2, 6257);
+}