#![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, 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; } } } } } true } fn make_valid(update: &Vec, rules: &Vec<(usize, usize)>) -> Vec { 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; } } } } } uv } fn main() { let args: Vec = 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::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 = u; 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); }