Skip to content

Commit daeb89c

Browse files
authored
Merge pull request #1 from rust-munich/solutions/sven
solution(sven): providing my ugly custom iterator solution
2 parents 3dae243 + 4824e0e commit daeb89c

2 files changed

Lines changed: 156 additions & 0 deletions

File tree

solutions/sven/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[package]
2+
name = "sven"
3+
version = "0.1.0"
4+
edition = "2024"
5+
6+
[dependencies]

solutions/sven/src/lib.rs

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
struct Grid {
2+
cells: Vec<Vec<char>>,
3+
}
4+
5+
impl Grid {
6+
fn new(input: &str) -> Self {
7+
Self {
8+
cells: input.lines().map(|l| l.trim().chars().collect()).collect(),
9+
}
10+
}
11+
12+
fn width(&self) -> usize {
13+
self.cells.first().map_or(0, |r| r.len())
14+
}
15+
16+
fn height(&self) -> usize {
17+
self.cells.len()
18+
}
19+
20+
fn get(&self, row: usize, col: usize) -> Option<char> {
21+
self.cells.get(row)?.get(col).copied()
22+
}
23+
24+
fn paperolls(&self) -> PaperrollIterator {
25+
PaperrollIterator {
26+
grid: self,
27+
current_row: 0,
28+
current_col: 0,
29+
}
30+
}
31+
}
32+
33+
struct PaperrollIterator<'a> {
34+
grid: &'a Grid,
35+
current_row: usize,
36+
current_col: usize,
37+
}
38+
39+
impl Iterator for PaperrollIterator<'_> {
40+
type Item = (usize, usize, char);
41+
42+
fn next(&mut self) -> Option<Self::Item> {
43+
loop {
44+
if self.current_row >= self.grid.height() {
45+
return None;
46+
}
47+
if self.current_col >= self.grid.width() {
48+
self.current_col = 0;
49+
self.current_row += 1;
50+
continue;
51+
}
52+
53+
let (x, y) = (self.current_row, self.current_col);
54+
let c = self.grid.get(x, y)?;
55+
56+
if c != '@' {
57+
// no paperroll here, continue
58+
self.current_col += 1;
59+
continue;
60+
}
61+
62+
// we are at (x, y) with '@', so we check now all the neighbors,
63+
// if a neigboar is also '@', we count it,
64+
// if the count is >= 4 we continue the loop on the next position
65+
66+
let mut paperrolls = 0;
67+
for dx in -1..=1 {
68+
for dy in -1..=1 {
69+
if dx == 0 && dy == 0 {
70+
continue;
71+
}
72+
let nx = x as isize + dx;
73+
let ny = y as isize + dy;
74+
if nx >= 0 && ny >= 0 {
75+
if let Some(nc) = self.grid.get(nx as usize, ny as usize) {
76+
if nc == '@' {
77+
paperrolls += 1;
78+
}
79+
}
80+
}
81+
82+
if paperrolls >= 4 {
83+
break;
84+
}
85+
}
86+
}
87+
88+
self.current_col += 1;
89+
if paperrolls >= 4 {
90+
continue; // this was not a valid paperroll
91+
}
92+
// else we found a valid paperroll
93+
return Some((x, y, c));
94+
}
95+
}
96+
}
97+
98+
#[cfg(test)]
99+
mod tests {
100+
use super::*;
101+
102+
fn grid() -> Grid {
103+
Grid::new(
104+
r#"..@@.@@@@.
105+
@@@.@.@.@@
106+
@@@@@.@.@@
107+
@.@@@@..@.
108+
@@.@@@@.@@
109+
.@@@@@@@.@
110+
.@.@.@.@@@
111+
@.@@@.@@@@
112+
.@@@@@@@@.
113+
@.@.@@@.@."#,
114+
)
115+
}
116+
117+
#[test]
118+
fn test_grid() {
119+
let g = grid();
120+
121+
assert_eq!(g.height(), 10);
122+
assert_eq!(g.width(), 10);
123+
124+
assert_eq!(g.get(0, 0), Some('.'));
125+
assert_eq!(g.get(0, 2), Some('@'));
126+
assert_eq!(g.get(1, 0), Some('@'));
127+
assert_eq!(g.get(1, 3), Some('.'));
128+
assert_eq!(g.get(1, 4), Some('@'));
129+
assert_eq!(g.get(9, 9), Some('.'));
130+
assert_eq!(g.get(10, 0), None);
131+
}
132+
133+
#[test]
134+
fn test_iterator() {
135+
let g = grid();
136+
137+
for (x, y, c) in g.paperolls() {
138+
println!("({x}, {y}) = {c}");
139+
}
140+
141+
assert_eq!(g.paperolls().count(), 13);
142+
}
143+
144+
#[test]
145+
fn test_input_final() {
146+
let g = Grid::new(include_str!("../../../input.txt"));
147+
let paperrolls = g.paperolls().count();
148+
println!("Paperolls = {paperrolls}");
149+
}
150+
}

0 commit comments

Comments
 (0)