Skip to content

Commit 2f1175c

Browse files
committed
[2025] Solution for Day 7
1 parent 56384bf commit 2f1175c

File tree

5 files changed

+194
-1
lines changed

5 files changed

+194
-1
lines changed

2025/src/bin/day07.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use aoc2025::days::day06::{part1, part2};
2+
use std::env;
3+
use std::fs;
4+
use std::process;
5+
6+
fn main() {
7+
let args: Vec<String> = env::args().collect();
8+
if args.len() < 2 {
9+
println!("Missing required arguments");
10+
process::exit(1);
11+
}
12+
13+
let contents = fs::read_to_string(&args[1]).expect("Something went wrong");
14+
println!("Part 1: {}", part1(&contents));
15+
println!("Part 2: {}", part2(&contents));
16+
}

2025/src/days.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ pub mod day03;
44
pub mod day04;
55
pub mod day05;
66
pub mod day06;
7+
pub mod day07;

2025/src/days/day07.rs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
use std::collections::{HashMap, HashSet, VecDeque};
2+
3+
pub fn part1(contents: &str) -> i64 {
4+
let grid = parse_grid(contents);
5+
let start = grid[0]
6+
.iter()
7+
.enumerate()
8+
.filter(|(_, c)| *c == &'S')
9+
.next()
10+
.unwrap();
11+
let mut count = 0;
12+
let mut queue = VecDeque::new();
13+
let mut visited = HashSet::new();
14+
15+
let start = (0 as usize, start.0);
16+
queue.push_back(start);
17+
visited.insert(start);
18+
19+
while !queue.is_empty() {
20+
let (y, x) = queue.pop_front().unwrap();
21+
if y == grid.len() - 1 {
22+
break;
23+
}
24+
25+
match grid[y + 1][x] {
26+
'.' => {
27+
let next = (y + 1, x);
28+
if !visited.contains(&next) {
29+
queue.push_back(next);
30+
visited.insert(next);
31+
}
32+
}
33+
'^' => {
34+
let left = (y + 1, x - 1);
35+
if !visited.contains(&left) {
36+
queue.push_back(left);
37+
visited.insert(left);
38+
}
39+
let right = (y + 1, x + 1);
40+
if !visited.contains(&right) {
41+
queue.push_back(right);
42+
visited.insert(right);
43+
}
44+
count += 1;
45+
}
46+
_ => {
47+
panic!("Unexpected character")
48+
}
49+
}
50+
}
51+
count
52+
}
53+
54+
pub fn part2(contents: &str) -> i64 {
55+
let grid = parse_grid(contents);
56+
let start = grid[0]
57+
.iter()
58+
.enumerate()
59+
.filter(|(_, c)| *c == &'S')
60+
.map(|(i, _)| (0 as usize, i))
61+
.next()
62+
.unwrap();
63+
let mut memo = HashMap::new();
64+
count_recursive(&grid, start, &mut memo)
65+
}
66+
67+
fn parse_grid(contents: &str) -> Vec<Vec<char>> {
68+
contents
69+
.lines()
70+
.map(|line| line.chars().collect())
71+
.collect()
72+
}
73+
74+
fn count_recursive(
75+
grid: &Vec<Vec<char>>,
76+
next: (usize, usize),
77+
memo: &mut HashMap<(usize, usize), i64>,
78+
) -> i64 {
79+
if memo.contains_key(&next) {
80+
return memo.get(&next).unwrap().clone();
81+
}
82+
83+
if next.0 == grid.len() - 1 {
84+
return 1;
85+
}
86+
87+
let mut count = 0;
88+
match grid[next.0][next.1] {
89+
'S' => {
90+
let next = (next.0 + 1, next.1);
91+
count += count_recursive(grid, next, memo);
92+
}
93+
'^' => {
94+
let left = (next.0 + 1, next.1 - 1);
95+
let right = (next.0 + 1, next.1 + 1);
96+
count += count_recursive(grid, left, memo);
97+
count += count_recursive(grid, right, memo);
98+
}
99+
'.' => {
100+
let next = (next.0 + 1, next.1);
101+
count += count_recursive(grid, next, memo);
102+
}
103+
_ => {
104+
panic!("Unexpected character");
105+
}
106+
}
107+
108+
memo.insert(next, count);
109+
count
110+
}
111+
112+
#[cfg(test)]
113+
mod tests {
114+
use super::*;
115+
116+
#[test]
117+
fn test_part1() {
118+
let input = vec![
119+
".......S.......",
120+
"...............",
121+
".......^.......",
122+
"...............",
123+
"......^.^......",
124+
"...............",
125+
".....^.^.^.....",
126+
"...............",
127+
"....^.^...^....",
128+
"...............",
129+
"...^.^...^.^...",
130+
"...............",
131+
"..^...^.....^..",
132+
"...............",
133+
".^.^.^.^.^...^.",
134+
"...............",
135+
];
136+
137+
assert_eq!(part1(&input.join("\n")), 21);
138+
}
139+
140+
#[test]
141+
fn test_part2() {
142+
let input = vec![
143+
".......S.......",
144+
"...............",
145+
".......^.......",
146+
"...............",
147+
"......^.^......",
148+
"...............",
149+
".....^.^.^.....",
150+
"...............",
151+
"....^.^...^....",
152+
"...............",
153+
"...^.^...^.^...",
154+
"...............",
155+
"..^...^.....^..",
156+
"...............",
157+
".^.^.^.^.^...^.",
158+
"...............",
159+
];
160+
161+
assert_eq!(part2(&input.join("\n")), 40);
162+
}
163+
}

2025/tests/day07.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use aoc2025::days::day07::{part1, part2};
2+
3+
#[test]
4+
fn test_part1() {
5+
let content = std::include_str!("../../private/inputs/2025/day07.txt");
6+
assert_eq!(part1(&content), 1626);
7+
}
8+
9+
#[test]
10+
fn test_part2() {
11+
let content = std::include_str!("../../private/inputs/2025/day07.txt");
12+
assert_eq!(part2(&content), 48989920237096);
13+
}

private

0 commit comments

Comments
 (0)