use std::convert::TryFrom; use std::env::args; use std::fs::File; use std::io::BufRead; use std::io::BufReader; fn get_ranges(s: &str) -> ((i32, i32), (i32, i32), (i32, i32)) { let parsed = s .split(",") .map(|r| match r[2..] .split("..") .collect::>()[..] { [left, right] => ( left.parse::().unwrap(), right.parse::().unwrap(), ), _ => unreachable!(), } ) .collect::>(); return match parsed[..] { [x, y, z] => (x, y, z), _ => unreachable!(), }; } fn map_range(a: i32, b: i32) -> Result, std::num::TryFromIntError> { assert!(a < b); if b < -50 || a > 50 { return Ok(1..=0); } else { let au = usize::try_from(if a < -50 {0} else if a > 50 {100} else {a + 50})?; let bu = usize::try_from(if b < -50 {0} else if b > 50 {100} else {b + 50})?; return Ok(au..=bu); } } fn main() { let path = args().nth(1).unwrap(); let file = File::open(path).unwrap(); let mut cubes = [false; 101 * 101 * 101]; for line in BufReader::new(file).lines() { match line.unwrap().split(" ").collect::>()[..] { [a, b] => { let on = a == "on"; let ((x1, x2), (y1, y2), (z1, z2)) = get_ranges(b); for z in map_range(z1, z2).unwrap() { for y in map_range(y1, y2).unwrap() { for x in map_range(x1, x2).unwrap() { cubes[z * 101 * 101 + y * 101 + x] = on; } } } }, _ => unreachable!(), } } println!("{}", cubes.iter().filter(|x| **x).count()); }