Skip to content

Commit 1e18ad2

Browse files
committed
day6
1 parent df84150 commit 1e18ad2

File tree

6 files changed

+209
-8
lines changed

6 files changed

+209
-8
lines changed

2024/README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Advent of Code in Rust 🦀
22

33
![AoC2024](https://img.shields.io/badge/Advent_of_Code-2024-8A2BE2)
4-
![Stars: 10](https://img.shields.io/badge/Stars-10⭐-blue)
5-
![Rust: 5](https://img.shields.io/badge/Rust-5-cyan?logo=Rust)
4+
![Stars: 12](https://img.shields.io/badge/Stars-12⭐-blue)
5+
![Rust: 6](https://img.shields.io/badge/Rust-6-cyan?logo=Rust)
66
![Python: 4](https://img.shields.io/badge/Python-4-cyan?logo=Python)
77

8-
## 2024 ([Calendar](https://adventofcode.com/2024)) ([Solutions](../2024/)) : 10
8+
## 2024 ([Calendar](https://adventofcode.com/2024)) ([Solutions](../2024/)) : 12
99

1010
Puzzle | Stars | Languages
1111
---------------------------------------------------------------- | ----- | -----------
@@ -14,3 +14,4 @@ Puzzle | Stars | Langu
1414
[Day 3: Mull It Over](https://adventofcode.com/2024/day/3) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2024/day3/day3.rs) [![Python](../scripts/assets/python.png)](../2024/day3/day3.py) [![Go](../scripts/assets/go.png)](../2024/day3/day3.go) [![Perl](../scripts/assets/perl.png)](../2024/day3/day3.pl)
1515
[Day 4: Ceres Search](https://adventofcode.com/2024/day/4) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2024/day4/day4.rs) [![Python](../scripts/assets/python.png)](../2024/day4/day4.py)
1616
[Day 5: Print Queue](https://adventofcode.com/2024/day/5) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2024/day5/day5.rs)
17+
[Day 6: Guard Gallivant](https://adventofcode.com/2024/day/6) | ⭐⭐ | [![Rust](../scripts/assets/rust.png)](../2024/day6/day6.rs)

2024/day6/Cargo.toml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
[package]
2+
name = "day6"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
aoc = { path = "../../aoc" }
8+
9+
[[bin]]
10+
name = "day6"
11+
path = "day6.rs"

2024/day6/day6.rs

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
//! [Day 6: Guard Gallivant](https://adventofcode.com/2024/day/6)
2+
3+
use aoc::{grid, grid::Direction, grid::Grid};
4+
use std::collections::HashSet;
5+
6+
struct Puzzle {
7+
grid: Grid<char>,
8+
start: (usize, usize),
9+
}
10+
11+
impl Puzzle {
12+
fn new() -> Puzzle {
13+
Puzzle {
14+
grid: grid![],
15+
start: (0, 0),
16+
}
17+
}
18+
19+
/// Get the puzzle input.
20+
fn configure(&mut self, path: &str) {
21+
let data = std::fs::read_to_string(path).unwrap();
22+
23+
self.grid = aoc::grid::Grid::<char>::parse(&data);
24+
25+
for (x, y, p) in self.grid.iter() {
26+
if p == &'^' {
27+
self.start = (x, y);
28+
break;
29+
}
30+
}
31+
}
32+
33+
fn move_guard(
34+
&self,
35+
x: &mut usize,
36+
y: &mut usize,
37+
direction: &mut grid::Direction,
38+
obstruction: (usize, usize),
39+
) -> bool {
40+
match direction {
41+
Direction::East => {
42+
if *x == 0 {
43+
return true;
44+
} else if self.grid[(*x - 1, *y)] == '#' || (*x - 1, *y) == obstruction {
45+
*direction = Direction::North;
46+
} else {
47+
*x -= 1;
48+
}
49+
}
50+
Direction::West => {
51+
if *x == self.grid.size().0 - 1 {
52+
return true;
53+
} else if self.grid[(*x + 1, *y)] == '#' || (*x + 1, *y) == obstruction {
54+
*direction = Direction::South;
55+
} else {
56+
*x += 1;
57+
}
58+
}
59+
Direction::North => {
60+
if *y == 0 {
61+
return true;
62+
} else if self.grid[(*x, *y - 1)] == '#' || (*x, *y - 1) == obstruction {
63+
*direction = Direction::West;
64+
} else {
65+
*y -= 1;
66+
}
67+
}
68+
Direction::South => {
69+
if *y == self.grid.size().1 - 1 {
70+
return true;
71+
} else if self.grid[(*x, *y + 1)] == '#' || (*x, *y + 1) == obstruction {
72+
*direction = Direction::East;
73+
} else {
74+
*y += 1;
75+
}
76+
}
77+
};
78+
79+
false
80+
}
81+
82+
/// Solve part one.
83+
fn part1(&self) -> usize {
84+
let (mut x, mut y) = self.start;
85+
let mut direction = grid::Direction::North;
86+
let mut leave = false;
87+
88+
let mut seen = HashSet::new();
89+
90+
let obstruction = (usize::MAX, usize::MAX);
91+
92+
while !leave {
93+
seen.insert((x, y));
94+
95+
leave = self.move_guard(&mut x, &mut y, &mut direction, obstruction);
96+
}
97+
98+
seen.len()
99+
}
100+
101+
/// Solve part two.
102+
fn part2(&self) -> u32 {
103+
// repeat part 1 to eliminate positions that are never visited
104+
let (mut x, mut y) = self.start;
105+
let mut direction = grid::Direction::North;
106+
let mut leave = false;
107+
let obstruction = (usize::MAX, usize::MAX);
108+
109+
let mut normal_walk = HashSet::new();
110+
111+
while !leave {
112+
normal_walk.insert((x, y));
113+
leave = self.move_guard(&mut x, &mut y, &mut direction, obstruction);
114+
}
115+
116+
let mut stuck = 0;
117+
118+
for (ox, oy, c) in self.grid.iter() {
119+
// optimization: if the guard never walks to this position,
120+
// an obstruction cannot deviate him
121+
if !normal_walk.contains(&(ox, oy)) {
122+
continue;
123+
}
124+
125+
if c == &'.' {
126+
// can choose this position for the obstruction
127+
128+
let obstruction = (ox, oy);
129+
130+
let (mut x, mut y) = self.start;
131+
let mut direction = grid::Direction::North;
132+
let mut leave = false;
133+
let mut seen: HashSet<(usize, usize, Direction)> = HashSet::new();
134+
135+
while !leave {
136+
if seen.contains(&(x, y, direction)) {
137+
// same pos, same direction : the guard is stuck
138+
stuck += 1;
139+
break;
140+
}
141+
seen.insert((x, y, direction));
142+
143+
leave = self.move_guard(&mut x, &mut y, &mut direction, obstruction);
144+
}
145+
}
146+
}
147+
148+
stuck
149+
}
150+
}
151+
152+
fn main() {
153+
let args = aoc::parse_args();
154+
let mut puzzle = Puzzle::new();
155+
puzzle.configure(args.path.as_str());
156+
println!("{}", puzzle.part1());
157+
println!("{}", puzzle.part2());
158+
}
159+
160+
/// Test from puzzle input
161+
#[cfg(test)]
162+
mod test {
163+
use super::*;
164+
165+
#[test]
166+
fn test01() {
167+
let mut puzzle = Puzzle::new();
168+
puzzle.configure("test.txt");
169+
assert_eq!(puzzle.part1(), 41);
170+
}
171+
172+
#[test]
173+
fn test02() {
174+
let mut puzzle = Puzzle::new();
175+
puzzle.configure("test.txt");
176+
assert_eq!(puzzle.part2(), 6);
177+
}
178+
}

2024/day6/test.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
....#.....
2+
.........#
3+
..........
4+
..#.......
5+
.......#..
6+
..........
7+
.#..^.....
8+
........#.
9+
#.........
10+
......#...

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Advent of Code in Rust 🦀
22

3-
![Stars: 460](https://img.shields.io/badge/Stars-460⭐-blue)
4-
![Rust: 176](https://img.shields.io/badge/Rust-176-cyan?logo=Rust)
3+
![Stars: 462](https://img.shields.io/badge/Stars-462⭐-blue)
4+
![Rust: 177](https://img.shields.io/badge/Rust-177-cyan?logo=Rust)
55
![Python: 117](https://img.shields.io/badge/Python-117-cyan?logo=Python)
66

77
Solutions of [Advent of Code](https://adventofcode.com/) in [Rust](https://www.rust-lang.org), and sometimes in [Python](https://www.python.org/).
88

99
Made for fun 😎 and to practice Rust. Many thanks to [Eric Wastl](https://twitter.com/ericwastl).
1010

11-
## 2024 (current event) ([Calendar](https://adventofcode.com/2024)) ([Solutions](2024/)) : 10
11+
## 2024 (current event) ([Calendar](https://adventofcode.com/2024)) ([Solutions](2024/)) : 12
1212

1313
Puzzle | Stars | Languages
1414
---------------------------------------------------------------- | ----- | -----------
@@ -17,12 +17,13 @@ Puzzle | Stars | Langu
1717
[Day 3: Mull It Over](https://adventofcode.com/2024/day/3) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](./2024/day3/day3.rs) [![Python](./scripts/assets/python.png)](./2024/day3/day3.py) [![Go](./scripts/assets/go.png)](./2024/day3/day3.go) [![Perl](./scripts/assets/perl.png)](./2024/day3/day3.pl)
1818
[Day 4: Ceres Search](https://adventofcode.com/2024/day/4) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](./2024/day4/day4.rs) [![Python](./scripts/assets/python.png)](./2024/day4/day4.py)
1919
[Day 5: Print Queue](https://adventofcode.com/2024/day/5) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](./2024/day5/day5.rs)
20+
[Day 6: Guard Gallivant](https://adventofcode.com/2024/day/6) | ⭐⭐ | [![Rust](./scripts/assets/rust.png)](./2024/day6/day6.rs)
2021

2122
## Paste years
2223

2324
Calendar | Solutions | Stars | Rust | Python
2425
-------- | --------- | ----- | ---- | ------
25-
[Advent of Code 2024](https://adventofcode.com/2024) | [Solutions](2024/README.md) | 10⭐ | 5 | 4
26+
[Advent of Code 2024](https://adventofcode.com/2024) | [Solutions](2024/README.md) | 12⭐ | 6 | 4
2627
[Advent of Code 2023](https://adventofcode.com/2023) | [Solutions](2023/README.md) | 50⭐ | 24 | 11
2728
[Advent of Code 2022](https://adventofcode.com/2022) | [Solutions](2022/README.md) | 50⭐ | 24 | 18
2829
[Advent of Code 2021](https://adventofcode.com/2021) | [Solutions](2021/README.md) | 50⭐ | 23 | 12

aoc/src/grid.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const NEIGHBORS: [(isize, isize); 8] = [
1414
];
1515

1616
/// The four directions
17-
#[derive(PartialEq, Clone, Copy, Eq, Debug)]
17+
#[derive(PartialEq, Clone, Copy, Eq, Hash, Debug)]
1818
pub enum Direction {
1919
North,
2020
East,

0 commit comments

Comments
 (0)