use std::fs; use std::path::Path; use std::collections::HashSet; /* AOC21 Day 13: https://adventofcode.com/2021/day/13 */ fn main() { let input = Path::new("resources").join("input.txt"); let content = fs::read_to_string(input).expect("Unable to read input file"); let (points,instructions) = content.split_once("\n\n").expect("Malformed input"); let points: HashSet<(u32,u32)> = points.lines().map(|l| { let (x,y) = l.split_once(',').expect("Malformed input"); (x.parse().unwrap(),y.parse().unwrap()) }).collect(); let instructions: Vec<(bool,u32)> = instructions.lines().map(|l| { let (axis,idx) = l.split_whitespace() .nth(2).expect("Malformed input") .split_once('=').expect("Malformed input"); (axis=="x", idx.parse().unwrap()) }).collect(); ex1(points.clone(), instructions[0]); ex2(points, &instructions); } fn ex1(points: HashSet<(u32,u32)>, instruction: (bool,u32)) { println!("Ex1: The result is {}", fold(points, instruction).len()); } fn ex2(points: HashSet<(u32,u32)>, instructions: &[(bool,u32)]) { let code = instructions.iter().fold(points, |ps,i| fold(ps, *i)); let code = { let x_max = 1 + code.iter().map(|(x,_)| *x).max().unwrap() as usize; let y_max = 1 + code.iter().map(|(_,y)| *y).max().unwrap() as usize; code.iter().fold(vec![vec![" ";x_max];y_max], |mut c, (x,y)| { c[*y as usize][*x as usize] = "█"; c }) }; println!("Ex2: The result is"); code.iter().for_each(|row| println!("{}", row.join(""))); } fn fold(mut points: HashSet<(u32,u32)>, instruction: (bool,u32)) -> HashSet<(u32,u32)> { let (x_axis, idx) = instruction; if x_axis { points.drain().map(|(x,y)| if x > idx { (2*idx - x, y) } else { (x,y) }).collect() } else { points.drain().map(|(x,y)| if y > idx { (x, 2*idx - y) } else { (x,y) }).collect() } }