111 lines
2.8 KiB
Rust
111 lines
2.8 KiB
Rust
use aoc_runner_derive::{aoc, aoc_generator};
|
|
|
|
#[derive(Debug)]
|
|
pub struct Line {
|
|
x: (i64, i64),
|
|
y: (i64, i64),
|
|
}
|
|
|
|
impl Line {
|
|
fn iter(&self) -> LineIterator {
|
|
let ret = LineIterator {
|
|
line: self,
|
|
px: self.x.0,
|
|
py: self.y.0,
|
|
sx: match self.x.0.cmp(&self.x.1) {
|
|
std::cmp::Ordering::Less => 1,
|
|
std::cmp::Ordering::Equal => 0,
|
|
std::cmp::Ordering::Greater => -1,
|
|
},
|
|
sy: match self.y.0.cmp(&self.y.1) {
|
|
std::cmp::Ordering::Less => 1,
|
|
std::cmp::Ordering::Equal => 0,
|
|
std::cmp::Ordering::Greater => -1,
|
|
},
|
|
};
|
|
assert!(ret.sx != 0 || ret.sy != 0);
|
|
ret
|
|
}
|
|
}
|
|
#[derive(Debug)]
|
|
struct LineIterator<'a> {
|
|
line: &'a Line,
|
|
px: i64,
|
|
py: i64,
|
|
sx: i64,
|
|
sy: i64,
|
|
}
|
|
|
|
impl<'a> Iterator for LineIterator<'a> {
|
|
type Item = (i64, i64);
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
let ret = (self.px, self.py);
|
|
if self.sx > 0 && self.px > self.line.x.1 {
|
|
return None;
|
|
}
|
|
if self.sx < 0 && self.px < self.line.x.1 {
|
|
return None;
|
|
}
|
|
if self.sy > 0 && self.py > self.line.y.1 {
|
|
return None;
|
|
}
|
|
if self.sy < 0 && self.py < self.line.y.1 {
|
|
return None;
|
|
}
|
|
self.px += self.sx;
|
|
self.py += self.sy;
|
|
Some(ret)
|
|
}
|
|
}
|
|
|
|
type Data = Vec<Line>;
|
|
|
|
#[aoc_generator(day05)]
|
|
pub fn input_generator(input: &str) -> Data {
|
|
input
|
|
.lines()
|
|
.map(|line| {
|
|
let parts = line.split(" -> ").collect::<Vec<_>>();
|
|
let start = parts[0]
|
|
.split(',')
|
|
.map(|v| v.parse().unwrap())
|
|
.collect::<Vec<i64>>();
|
|
let end = parts[1]
|
|
.split(',')
|
|
.map(|v| v.parse().unwrap())
|
|
.collect::<Vec<i64>>();
|
|
Line {
|
|
x: (start[0], end[0]),
|
|
y: (start[1], end[1]),
|
|
}
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
#[aoc(day05, part1)]
|
|
pub fn solve_part1(input: &Data) -> usize {
|
|
let mut grid = vec![vec![0u8; 1000]; 1000];
|
|
for (x, y) in input
|
|
.iter()
|
|
.filter(|l| l.x.0 == l.x.1 || l.y.0 == l.y.1)
|
|
.flat_map(|v| v.iter())
|
|
{
|
|
let x: usize = x.try_into().unwrap();
|
|
let y: usize = y.try_into().unwrap();
|
|
grid[x][y] += 1;
|
|
}
|
|
return grid.iter().flatten().filter(|&v| *v > 1).count();
|
|
}
|
|
|
|
#[aoc(day05, part2)]
|
|
pub fn solve_part2(input: &Data) -> usize {
|
|
let mut grid = vec![vec![0u8; 1000]; 1000];
|
|
for (x, y) in input.iter().flat_map(|v| v.iter()) {
|
|
let x: usize = x.try_into().unwrap();
|
|
let y: usize = y.try_into().unwrap();
|
|
grid[x][y] += 1;
|
|
}
|
|
return grid.iter().flatten().filter(|&v| *v > 1).count();
|
|
}
|