114 lines
2.5 KiB
Rust
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(())
|
|
}
|