Skip to content

Commit d144396

Browse files
committed
feat: upload day 6
1 parent dfeb1fa commit d144396

File tree

3 files changed

+138
-0
lines changed

3 files changed

+138
-0
lines changed

2024/day-6/Cargo.lock

+16
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

2024/day-6/Cargo.toml

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[package]
2+
name = "day-6"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
glam = "0.29.2"

2024/day-6/src/main.rs

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
// ╭─────────────────────────────────────────────────────────╮
2+
// │ Advent of Code 2024 - Day 6 │
3+
// ╰─────────────────────────────────────────────────────────╯
4+
5+
use std::collections::HashSet;
6+
7+
use glam::{ ivec2, IVec2 };
8+
9+
const LEFT: IVec2 = ivec2(-1, 0);
10+
const RIGHT: IVec2 = ivec2(1, 0);
11+
const UP: IVec2 = ivec2(0, -1);
12+
const DOWN: IVec2 = ivec2(0, 1);
13+
14+
#[derive(PartialEq, Clone)]
15+
enum Tile {
16+
Empty,
17+
Obstruction
18+
}
19+
20+
#[derive(PartialEq, Eq, Hash, Clone, Copy)]
21+
enum Direction {
22+
Left,
23+
Right,
24+
Up,
25+
Down
26+
}
27+
impl Direction {
28+
fn vec(&self) -> IVec2 {
29+
match self {
30+
Direction::Left => LEFT,
31+
Direction::Right => RIGHT,
32+
Direction::Up => UP,
33+
Direction::Down => DOWN
34+
}
35+
}
36+
fn rotate_right(&self) -> Self {
37+
match self {
38+
Direction::Left => Direction::Up,
39+
Direction::Right => Direction::Down,
40+
Direction::Up => Direction::Right,
41+
Direction::Down => Direction::Left,
42+
}
43+
}
44+
}
45+
46+
struct Guard {
47+
pos: IVec2,
48+
initial_pos: IVec2,
49+
direction: Direction,
50+
}
51+
impl Guard {
52+
fn new(pos: IVec2) -> Self {
53+
Guard { pos, initial_pos: pos, direction: Direction::Up }
54+
}
55+
fn reset(&mut self) -> &Self {
56+
self.pos = self.initial_pos;
57+
self.direction = Direction::Up;
58+
self
59+
}
60+
}
61+
62+
fn main() {
63+
let input = include_str!("../input.txt");
64+
65+
let mut guard = Guard::new(ivec2(0, 0));
66+
67+
let map = input
68+
.lines()
69+
.enumerate()
70+
.map(|(y, line)| line.chars().enumerate().map(|(x, tile)| match tile {
71+
'^' => {
72+
guard = Guard::new(ivec2(x as i32, y as i32));
73+
Tile::Empty
74+
},
75+
'#' => Tile::Obstruction,
76+
'.' => Tile::Empty,
77+
_ => panic!("Invalid input")
78+
}).collect::<Vec<_>>()).collect::<Vec<_>>();
79+
let mut positions = HashSet::from([guard.initial_pos]);
80+
// ── Part 1 ──────────────────────────────────────────────────────────
81+
loop {
82+
let next_pos = guard.pos + guard.direction.vec();
83+
if next_pos.x < 0 || next_pos.y < 0 || next_pos.x >= map[0].len() as i32 || next_pos.y >= map.len() as i32 { break; }
84+
if map[next_pos.y as usize][next_pos.x as usize] == Tile::Obstruction {
85+
guard.direction = guard.direction.rotate_right();
86+
continue;
87+
}
88+
guard.pos = next_pos;
89+
positions.insert(next_pos);
90+
}
91+
println!("Number of positions visited: {}", positions.len());
92+
// ── Part 2 ──────────────────────────────────────────────────────────
93+
let mut obstruction_positions: usize = 0;
94+
for pos in positions {
95+
guard.reset();
96+
let mut new_map = map.clone();
97+
new_map[pos.y as usize][pos.x as usize] = Tile::Obstruction;
98+
99+
let mut new_positions = HashSet::new();
100+
loop {
101+
if !new_positions.insert((guard.pos, guard.direction)) {
102+
obstruction_positions += 1;
103+
break;
104+
}
105+
let next_pos = guard.pos + guard.direction.vec();
106+
if next_pos.x < 0 || next_pos.y < 0 || next_pos.x >= map[0].len() as i32 || next_pos.y >= map.len() as i32 { break; }
107+
if new_map[next_pos.y as usize][next_pos.x as usize] == Tile::Obstruction {
108+
guard.direction = guard.direction.rotate_right();
109+
continue;
110+
}
111+
guard.pos = next_pos;
112+
}
113+
}
114+
println!("Different obstruction positions: {obstruction_positions}");
115+
}

0 commit comments

Comments
 (0)