diff options
Diffstat (limited to '2024/day05.rs')
| -rw-r--r-- | 2024/day05.rs | 106 |
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); +} |
