use std::collections::HashMap; use std::error::Error; use std::fs::File; use std::io::{self, BufRead}; use std::vec::Vec; #[macro_use] extern crate lazy_static; extern crate regex; use regex::Regex; #[derive(Debug)] struct Line { x1: i32, y1: i32, x2: i32, y2: i32, } impl Line { fn is_vertical(&self) -> bool { self.x1 == self.x2 } fn is_horizontal(&self) -> bool { self.y1 == self.y2 } fn points(&self) -> Vec<(i32, i32)> { let mut points: Vec<(i32, i32)> = Vec::new(); let mut x = self.x1; let x2 = self.x2; let mut y = self.y1; let y2 = self.y2; points.push((x, y)); while x != x2 || y != y2 { if x < x2 { x += 1; } else if x > x2 { x -= 1; } if y < y2 { y += 1; } else if y > y2 { y -= 1; } points.push((x, y)) } points } } fn parse_line(line: String) -> Line { lazy_static! { static ref LINE_RE: Regex = Regex::new(r"^([0-9]+),([0-9]+) -> ([0-9]+),([0-9]+)$").unwrap(); } let cap = LINE_RE.captures_iter(&line).nth(0).unwrap(); Line { x1: cap[1].parse::().unwrap(), y1: cap[2].parse::().unwrap(), x2: cap[3].parse::().unwrap(), y2: cap[4].parse::().unwrap(), } } fn main() -> Result<(), Box> { let file = File::open("inputs/day5.txt")?; let lines: Vec = io::BufReader::new(file) .lines() .map(|l| parse_line(l.unwrap())) .collect(); let lines1 = lines .iter() .filter(|l| l.is_vertical() || l.is_horizontal()); let mut points1: HashMap<(i32, i32), i32> = HashMap::new(); for line in lines1 { for point in line.points() { points1 .entry(point) .and_modify(|c| *c = *c + 1) .or_insert(1); } } let intersections1 = points1.iter().filter(|(_, c)| **c > 1).count(); println!("Answer1: {}", intersections1); let mut points2: HashMap<(i32, i32), i32> = HashMap::new(); for line in lines { for point in line.points() { points2 .entry(point) .and_modify(|c| *c = *c + 1) .or_insert(1); } } let intersections2 = points2.iter().filter(|(_, c)| **c > 1).count(); println!("Answer2: {}", intersections2); Ok(()) }