1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
pub mod matrix {
pub type Pos = (usize, usize);
pub type PosDelta = (isize, isize);
#[derive(Clone)]
pub struct Matrix<T> {
dots: Vec<Vec<T>>,
pub limit: Pos,
}
impl<T> Matrix<T> {
pub fn new<F>(text: &str, parse: F) -> Self
where
F: Fn(char) -> T,
{
let dots: Vec<Vec<T>> = text
.lines()
.map(|row| row.chars().map(|c| parse(c)).collect())
.collect();
let limit = (dots.len(), dots[0].len());
Self { dots, limit }
}
pub fn get(&self, (x, y): Pos) -> &T {
&self.dots[x][y]
}
pub fn set(&mut self, (x, y): Pos, dot: T) {
self.dots[x][y] = dot;
}
pub fn pos_move(&self, (x, y): Pos, (dx, dy): PosDelta) -> Option<Pos> {
let x2 = x as isize + dx;
if x2 < 0 || x2 >= self.limit.0 as isize {
return None;
}
let y2 = y as isize + dy;
if y2 < 0 || y2 >= self.limit.1 as isize {
return None;
}
Some((x2 as usize, y2 as usize))
}
}
use std::fmt;
impl<T> fmt::Display for Matrix<T>
where
T: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for row in &self.dots {
write!(
f,
"{}\n",
row.iter().map(|c| c.to_string()).collect::<String>()
)?;
}
fmt::Result::Ok(())
}
}
}
pub fn run_day<S1, S2>(day: &str, p1: S1, p2: S2)
where
S1: FnOnce(&str) -> String,
S2: FnOnce(&str) -> String,
{
let input_file = format!("inputs/{day}");
let input = std::fs::read_to_string(input_file).unwrap();
println!("==== DAY {day}");
println!("Result (P1): {}", p1(&input));
println!("Result (P2): {}", p2(&input));
}
|