use std::{fs, env, collections::HashSet}; fn read_input(path: &str) -> String { return fs::read_to_string(path).expect("Cannot read file."); } fn parse_input(s: &str) -> (HashSet<(i32, i32)>, Vec<(char, i32)>) { let mut is_fold = false; let mut t = HashSet::new(); let mut i = vec![]; for l in s.lines() { if l == "" { is_fold = true; continue; } if !is_fold { let x = l.split_once(",").unwrap(); t.insert((x.0.parse().unwrap(), x.1.parse().unwrap())); } else { let x = l.split_once("=").unwrap(); i.push((x.0.chars().last().unwrap(), x.1.parse().unwrap())); } } return (t, i); } fn apply_n_folds(i: &HashSet<(i32, i32)>, f: &Vec<(char, i32)>, n: usize) -> HashSet<(i32, i32)> { let mut h = i.clone(); for x in 0..n { for c in h.clone().iter() { if f[x].0 == 'y' { h.insert((c.0, if c.1 > f[x].1 { c.1 - (c.1 - f[x].1) * 2 } else { c.1 })); if c.1 > f[x].1 { h.remove(c); } } else { h.insert((if c.0 > f[x].1 { c.0 - (c.0 - f[x].1) * 2 } else { c.0 }, c.1)); if c.0 > f[x].1 { h.remove(c); } } } } return h; } fn show_array(i: &HashSet<(i32, i32)>) { let m = i.iter().map(|e| e.0).max().unwrap(); let n = i.iter().map(|e| e.1).max().unwrap(); for y in 0..=n { print!("\t\t"); for x in 0..=m { if i.contains(&(x, y)) { print!("{}", '#'); } else { print!(" "); } } println!(); } } fn main() { let args: Vec = env::args().collect(); for arg in args.iter().skip(1) { let input = read_input(&arg); let vec_in = parse_input(&input); println!("[{}]", &arg); println!("\t[Part 1] => Answer is '{}'.", apply_n_folds(&vec_in.0, &vec_in.1, 1).len()); println!("\t[Part 2] => Answer is:"); show_array(&apply_n_folds(&vec_in.0, &vec_in.1, vec_in.1.len())); } }