Skip to content

Commit 0522564

Browse files
committed
feat: Solve day 8 (at least close enough, tests pass)
- description killed me https://i.redd.it/226byaxm6k5e1.jpeg
1 parent 71aeb03 commit 0522564

File tree

5 files changed

+215
-9
lines changed

5 files changed

+215
-9
lines changed

input/day08.txt

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
.....................U.........w..................
2+
l.................................................
3+
...........o.a................U...w...............
4+
............................................W.....
5+
..........T....................s.............7....
6+
.............................................W....
7+
.........T..............4....n.d.H.........5......
8+
......T.....oj...U.....n...w......H...........z...
9+
.G..x..........................E.....V..H.........
10+
.........a....................d....s.......7w.....
11+
...j....r.............o.............V.......d...W.
12+
.......r..J.Goa.U...............n................z
13+
.........Jj.........M..........Pv.................
14+
...J...........t..3..M..............sLV...........
15+
...................t................n.............
16+
....r...........X...........M........v............
17+
...x....t......I......a.PM...............W........
18+
...........1.Bj....I........vO.h.dL...............
19+
.........6....Rr......B...X........h..5v.L..z.....
20+
......1G...........x.....3B.......5...............
21+
.................B....0..........4..E.............
22+
.....................X.....5..h....P....f.....D...
23+
.......1........J.....eK..........................
24+
..................I....R....K...........k.........
25+
......G..................O........................
26+
...........H...9...............K8.P.4..k..E.......
27+
............1....3.............8.F.............f..
28+
.........................4........................
29+
.l...........X............9.......................
30+
....N.................R...t.e.....................
31+
...g............3..R.........e....h.........f.....
32+
...........................e......i...............
33+
................2...I.7..9..O.....s.........k.....
34+
....................6...9E.............F..O.......
35+
........................KN........................
36+
.......g......................Z.........F..f...Y..
37+
...........................A....i.................
38+
...........6g...b........8.......y.....S..........
39+
..l.....6.....m...............8...................
40+
....u..m...b...............p...A..................
41+
..............b.p........................k........
42+
....m......2...........Z..y....i..................
43+
........g2.....b.........i....D..ZF...............
44+
......2.0...........p............N..........A.....
45+
...m.............S...y........A...Z...N...........
46+
..S..l..........................................Y.
47+
........S....0u.................y......DY.........
48+
...........0.........................D............
49+
.................u...................p...Y........
50+
.......u..........................................

src/day04.rs

+4-9
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
use crate::utils;
2+
13
pub fn solve_part1(input: &str) -> i32 {
24
let mut xmas_count = 0;
35

4-
let word_search_matrix = parse_string_to_2d_vector(input);
6+
let word_search_matrix = utils::parse_string_to_2d_vector(input);
57

68
let diagonals = collect_diagonals(&word_search_matrix);
79
diagonals.iter().for_each(|diagonal| {
@@ -30,7 +32,7 @@ pub fn solve_part1(input: &str) -> i32 {
3032
}
3133

3234
pub fn solve_part2(input: &str) -> i32 {
33-
let m = parse_string_to_2d_vector(input);
35+
let m = utils::parse_string_to_2d_vector(input);
3436

3537
let mut x_mas_count = 0;
3638
for (i, row) in m.iter().enumerate() {
@@ -142,13 +144,6 @@ fn mirror_matrix(matrix: &[Vec<char>]) -> Vec<Vec<char>> {
142144
mirrored_matrix
143145
}
144146

145-
fn parse_string_to_2d_vector(input: &str) -> Vec<Vec<char>> {
146-
input
147-
.lines() // Create an iterator over the lines of the string
148-
.map(|line| line.chars().collect()) // Map each line to a vector of chars
149-
.collect() // Collect the results into a 2D vector
150-
}
151-
152147
#[cfg(test)]
153148
mod tests {
154149
use super::*;

src/day08.rs

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
use std::collections::HashSet;
2+
3+
use crate::utils;
4+
5+
pub fn solve_part1(input: &str) -> i32 {
6+
solve(input, false)
7+
}
8+
9+
pub fn solve_part2(input: &str) -> i32 {
10+
solve(input, true)
11+
}
12+
13+
fn solve(input: &str, part2: bool) -> i32 {
14+
let map = utils::parse_string_to_2d_vector(input);
15+
let mut locations: HashSet<(usize, usize)> = HashSet::new();
16+
for (y, row) in map.iter().enumerate() {
17+
for (x, c) in row.iter().enumerate() {
18+
if is_antenna(*c) {
19+
locations = locations
20+
.union(&get_antidode_locations(&map, *c, (x, y), part2))
21+
.cloned()
22+
.collect();
23+
}
24+
}
25+
}
26+
27+
locations.len().try_into().unwrap()
28+
}
29+
30+
fn get_antidode_locations(
31+
map: &[Vec<char>],
32+
c: char,
33+
start_pos: (usize, usize),
34+
many_antidodes: bool,
35+
) -> HashSet<(usize, usize)> {
36+
let (x, y) = start_pos;
37+
let ry = get_radius_per_dimension(map.len(), y);
38+
let rx = get_radius_per_dimension(map.first().unwrap().len(), x);
39+
40+
let mut locations: HashSet<(usize, usize)> = HashSet::new();
41+
for y_prime in y - ry..=y + ry {
42+
for x_prime in x - rx..=x + rx {
43+
if *map.get(y_prime).unwrap().get(x_prime).unwrap() == c && y_prime != y && x_prime != x
44+
{
45+
let antidode = mirror_point_through((x_prime, y_prime), start_pos);
46+
locations.insert(antidode);
47+
if many_antidodes {
48+
locations.insert(start_pos);
49+
locations.insert((x_prime, y_prime));
50+
51+
let (vec_x, vec_y) =
52+
(antidode.0 as i32 - x as i32, antidode.1 as i32 - y as i32);
53+
let mut i = 1;
54+
loop {
55+
let y_prime_prime = (antidode.1 as i32 + i * vec_y) as usize;
56+
let x_prime_prime = (antidode.0 as i32 + i * vec_x) as usize;
57+
58+
if map
59+
.get(y_prime_prime)
60+
.and_then(|row| row.get(x_prime_prime))
61+
.is_none()
62+
{
63+
break;
64+
}
65+
66+
locations.insert((x_prime_prime, y_prime_prime));
67+
i += 1;
68+
}
69+
}
70+
}
71+
}
72+
}
73+
74+
locations
75+
}
76+
77+
fn mirror_point_through(point: (usize, usize), through: (usize, usize)) -> (usize, usize) {
78+
let (x1, y1) = through;
79+
let (x2, y2) = point;
80+
81+
let mirrored_x = 2 * x1 - x2;
82+
let mirrored_y = 2 * y1 - y2;
83+
84+
(mirrored_x, mirrored_y)
85+
}
86+
87+
fn get_radius_per_dimension(length: usize, coordinate: usize) -> usize {
88+
if coordinate >= (length / 2) {
89+
return length - coordinate - 1;
90+
}
91+
92+
coordinate
93+
}
94+
95+
fn is_antenna(c: char) -> bool {
96+
c != '.'
97+
}
98+
99+
#[cfg(test)]
100+
mod tests {
101+
use super::*;
102+
103+
#[test]
104+
fn test_solve_part1() {
105+
let input = "............
106+
........0...
107+
.....0......
108+
.......0....
109+
....0.......
110+
......A.....
111+
............
112+
............
113+
........A...
114+
.........A..
115+
............
116+
............";
117+
assert_eq!(solve_part1(input), 14);
118+
}
119+
120+
#[test]
121+
fn test_solve_part2() {
122+
let input_1 = "............
123+
........0...
124+
.....0......
125+
.......0....
126+
....0.......
127+
......A.....
128+
............
129+
............
130+
........A...
131+
.........A..
132+
............
133+
............";
134+
assert_eq!(solve_part2(input_1), 34);
135+
136+
let input_2 = "T.........
137+
...T......
138+
.T........
139+
..........
140+
..........
141+
..........
142+
..........
143+
..........
144+
..........
145+
..........";
146+
assert_eq!(solve_part2(input_2), 9);
147+
}
148+
}

src/main.rs

+6
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod day04;
77
mod day05;
88
mod day06;
99
mod day07;
10+
mod day08;
1011
mod utils;
1112

1213
fn main() {
@@ -59,6 +60,11 @@ fn main() {
5960
println!("Day 7 - Part 1: {}", day07::solve_part1(&input));
6061
println!("Day 7 - Part 2: {}", day07::solve_part2(&input));
6162
}
63+
"8" => {
64+
let input = utils::read_file_to_string("input/day08.txt").unwrap();
65+
println!("Day 8 - Part 1: {}", day08::solve_part1(&input));
66+
println!("Day 8 - Part 2: {}", day08::solve_part2(&input));
67+
}
6268
_ => {
6369
eprintln!("Invalid day: {}. Please enter a valid day number.", day);
6470
}

src/utils.rs

+7
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,10 @@ where
1212
File::open(filename)?.read_to_string(&mut contents)?;
1313
Ok(contents)
1414
}
15+
16+
pub fn parse_string_to_2d_vector(input: &str) -> Vec<Vec<char>> {
17+
input
18+
.lines() // Create an iterator over the lines of the string
19+
.map(|line| line.chars().collect()) // Map each line to a vector of chars
20+
.collect() // Collect the results into a 2D vector
21+
}

0 commit comments

Comments
 (0)