Skip to content

Commit 82262a2

Browse files
committed
Day 4
1 parent 45a2125 commit 82262a2

File tree

4 files changed

+82
-8
lines changed

4 files changed

+82
-8
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
1414
| [Day 1](./src/bin/01.rs) | `66.9µs` | `82.5µs` |
1515
| [Day 2](./src/bin/02.rs) | `128.2µs` | `224.5µs` |
1616
| [Day 3](./src/bin/03.rs) | `717.8µs` | `830.1µs` |
17+
| [Day 4](./src/bin/04.rs) | `810.2µs` | `298.7µs` |
1718

18-
**Total: 2.05ms**
19+
**Total: 3.16ms**
1920
<!--- benchmarking table --->
2021

2122
---

mygrid/src/direction.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ pub const DOWN: Direction = Direction::new(1, 0);
1414
pub const LEFT: Direction = Direction::new(0, -1);
1515
pub const RIGHT: Direction = Direction::new(0, 1);
1616
pub const ORTHOGONAL: [Direction; 4] = [UP, DOWN, LEFT, RIGHT];
17+
pub const DIAGONALS: [Direction; 4] = [
18+
UP.add_direction(&RIGHT),
19+
RIGHT.add_direction(&DOWN),
20+
DOWN.add_direction(&LEFT),
21+
LEFT.add_direction(&UP),
22+
];
1723
pub const ALL_AROUND: [Direction; 8] = [
1824
UP,
1925
UP.add_direction(&RIGHT),
@@ -155,6 +161,15 @@ impl Add<Direction> for Direction {
155161
}
156162
}
157163

164+
impl Add<Point> for Direction {
165+
type Output = Point;
166+
167+
#[inline]
168+
fn add(self, rhs: Point) -> Self::Output {
169+
rhs.apply_direction(self)
170+
}
171+
}
172+
158173
impl Mul<isize> for Direction {
159174
type Output = Direction;
160175

mygrid/src/grid.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ impl<T> Grid<T> {
2424
}
2525

2626
#[inline]
27-
pub fn new_from_str(input: &str, map_char: &dyn Fn(char) -> T) -> Self
27+
pub fn new_from_str<F>(input: &str, map_char: F) -> Self
2828
where
29-
T: From<char>,
29+
F: Fn(char) -> T,
3030
{
3131
let width = input.lines().next().unwrap().len();
3232
let content = input
@@ -196,6 +196,15 @@ impl<T> Grid<T> {
196196
.enumerate()
197197
.map(move |(i, t)| (Point::new_usize(i / self.width, i % self.width), t))
198198
}
199+
200+
#[inline]
201+
pub fn get_item(&self, point: Point) -> Option<&T> {
202+
if self.is_in_bounds(point) {
203+
Some(&self.content[((point.line as usize) * self.width) + (point.column as usize)])
204+
} else {
205+
None
206+
}
207+
}
199208
}
200209

201210
impl<T> Index<Point> for Grid<T> {
@@ -232,7 +241,7 @@ impl<T> Grid<T> {
232241
}
233242
}
234243

235-
impl std::fmt::Display for Grid<String> {
244+
impl<T: std::fmt::Display> std::fmt::Display for Grid<T> {
236245
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237246
for r in 0..self.height {
238247
for c in 0..self.width {

src/bin/04.rs

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,60 @@
1+
use mygrid::{
2+
direction::{ALL_AROUND, DOWN, LEFT, RIGHT, UP},
3+
grid::Grid,
4+
};
5+
16
advent_of_code::solution!(4);
27

38
pub fn part_one(input: &str) -> Option<u32> {
4-
None
9+
let grid = Grid::new_from_str(input, |c| c);
10+
11+
let res = grid
12+
.iter_item_and_position()
13+
.flat_map(|(point, &c)| ALL_AROUND.iter().map(move |d| (point, c, *d)))
14+
.filter(|&(_, c, _)| c == 'X')
15+
.filter(|&(point, _, d)| grid.is_in_bounds(point + (d * 3)))
16+
.filter(|&(point, _, d)| {
17+
let x_pos = point;
18+
let m_pos = x_pos + d;
19+
let a_pos = m_pos + d;
20+
let s_pos = a_pos + d;
21+
let spells_xmas = grid[x_pos] == 'X'
22+
&& grid[m_pos] == 'M'
23+
&& grid[a_pos] == 'A'
24+
&& grid[s_pos] == 'S';
25+
26+
spells_xmas
27+
})
28+
.count();
29+
30+
Some(res as u32)
531
}
632

733
pub fn part_two(input: &str) -> Option<u32> {
8-
None
34+
let grid = Grid::new_from_str(input, |c| c);
35+
36+
let res = grid
37+
.iter_item_and_position()
38+
.filter(|&(_, &c)| c == 'A')
39+
.filter(|&(point, _)| {
40+
let (Some(&top_left), Some(&top_right), Some(&bot_left), Some(&bot_right)) = (
41+
grid.get_item(point + UP + LEFT),
42+
grid.get_item(point + UP + RIGHT),
43+
grid.get_item(point + DOWN + LEFT),
44+
grid.get_item(point + DOWN + RIGHT),
45+
) else {
46+
return false;
47+
};
48+
49+
let spells_xmas_diag1 =
50+
(top_left == 'M' && bot_right == 'S') || (top_left == 'S' && bot_right == 'M');
51+
let spells_xmas_diag2 =
52+
(top_right == 'M' && bot_left == 'S') || (top_right == 'S' && bot_left == 'M');
53+
spells_xmas_diag1 && spells_xmas_diag2
54+
})
55+
.count();
56+
57+
Some(res as u32)
958
}
1059

1160
#[cfg(test)]
@@ -15,12 +64,12 @@ mod tests {
1564
#[test]
1665
fn test_part_one() {
1766
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
18-
assert_eq!(result, None);
67+
assert_eq!(result, Some(18));
1968
}
2069

2170
#[test]
2271
fn test_part_two() {
2372
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
24-
assert_eq!(result, None);
73+
assert_eq!(result, Some(9));
2574
}
2675
}

0 commit comments

Comments
 (0)