AoC2021/src/bin/day5.rs

114 lines
2.5 KiB
Rust

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::<i32>().unwrap(),
y1: cap[2].parse::<i32>().unwrap(),
x2: cap[3].parse::<i32>().unwrap(),
y2: cap[4].parse::<i32>().unwrap(),
}
}
fn main() -> Result<(), Box<dyn Error>> {
let file = File::open("inputs/day5.txt")?;
let lines: Vec<Line> = 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(())
}