Skip to content

Commit 29e881b

Browse files
committed
Day 8
1 parent 5f2a778 commit 29e881b

File tree

3 files changed

+120
-2
lines changed

3 files changed

+120
-2
lines changed

README.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
2828
| [Day 4](./src/bin/04.rs) | `560.8µs` | `161.9µs` |
2929
| [Day 5](./src/bin/05.rs) | `344.6µs` | `323.6µs` |
3030
| [Day 6](./src/bin/06.rs) | `488.0µs` | `119.9ms` |
31-
| [Day 7](./src/bin/07.rs) | `64.9µs` | `84.1µs` |
31+
| [Day 7](./src/bin/07.rs) | `80.3µs` | `113.7µs` |
32+
| [Day 8](./src/bin/08.rs) | `9.9µs` | `12.2µs` |
3233

33-
**Total: 123.85ms**
34+
**Total: 123.92ms**
3435
<!--- benchmarking table --->
3536

3637
---

data/examples/08.txt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
............
2+
........0...
3+
.....0......
4+
.......0....
5+
....0.......
6+
......A.....
7+
............
8+
............
9+
........A...
10+
.........A..
11+
............
12+
............

src/bin/08.rs

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
use std::collections::HashMap;
2+
3+
advent_of_code::solution!(8);
4+
5+
#[derive(Debug)]
6+
struct Grid {
7+
width: usize,
8+
height: usize,
9+
antennas: HashMap<char, Vec<(usize, usize)>>
10+
}
11+
12+
impl Grid {
13+
fn parse(input: &str) -> Grid {
14+
let mut antennas: HashMap<_, Vec<_>> = HashMap::new();
15+
let height = input.lines().enumerate().map(|(y, line)| {
16+
line.chars().enumerate().for_each(|(x, char)| {
17+
if char.is_ascii_alphanumeric() {
18+
antennas.entry(char).or_default().push((x, y));
19+
}
20+
});
21+
y
22+
}).max().unwrap_or_default() + 1;
23+
let width = input.lines().next().unwrap_or_default().len();
24+
Grid {
25+
width,
26+
height,
27+
antennas,
28+
}
29+
}
30+
31+
fn find_antinodes(&self) -> Vec<bool> {
32+
let mut antinodes = vec![false; self.width * self.height];
33+
self.antennas.iter().for_each(|(_, positions)| positions.iter().enumerate().for_each(|(index, pos1)| positions.iter().skip(index + 1).for_each(|pos2| {
34+
let dx= (pos2.0 as isize - pos1.0 as isize) * 2;
35+
let dy= (pos2.1 as isize - pos1.1 as isize) * 2;
36+
37+
if let (Some(x), Some(y)) = (pos1.0.checked_add_signed(dx), pos1.1.checked_add_signed(dy)) {
38+
if let Some(index) = self.xy_to_index((x, y)) { antinodes[index] = true; }
39+
};
40+
41+
if let (Some(x), Some(y)) = (pos2.0.checked_add_signed(-dx), pos2.1.checked_add_signed(-dy)) {
42+
if let Some(index) = self.xy_to_index((x, y)) { antinodes[index] = true; }
43+
}
44+
})));
45+
antinodes
46+
}
47+
48+
fn find_antinodes_with_resonance(&self) -> Vec<bool> {
49+
let mut antinodes = vec![false; self.width * self.height];
50+
self.antennas.iter().for_each(|(_, positions)| positions.iter().enumerate().for_each(|(index, pos1)| positions.iter().skip(index + 1).for_each(|pos2| {
51+
let dx = pos2.0 as isize - pos1.0 as isize;
52+
let dy = pos2.1 as isize - pos1.1 as isize;
53+
54+
let mut count = 0;
55+
while let (Some(x), Some(y)) = (pos1.0.checked_add_signed(-dx * count), pos1.1.checked_add_signed(-dy * count)) {
56+
if let Some(index) = self.xy_to_index((x, y)) { antinodes[index] = true; }
57+
else { break };
58+
count += 1;
59+
};
60+
61+
count = 0;
62+
while let (Some(x), Some(y)) = (pos2.0.checked_add_signed(dx * count), pos2.1.checked_add_signed(dy * count)) {
63+
if let Some(index) = self.xy_to_index((x, y)) { antinodes[index] = true; }
64+
else { break };
65+
count += 1;
66+
};
67+
})));
68+
antinodes
69+
}
70+
71+
fn xy_to_index(&self, pos: (usize, usize)) -> Option<usize> {
72+
if (0..self.width).contains(&pos.0) && (0..self.height).contains(&pos.1) {
73+
Some(pos.1 * self.width + pos.0)
74+
} else {
75+
None
76+
}
77+
}
78+
}
79+
80+
pub fn part_one(input: &str) -> Option<u32> {
81+
let grid = Grid::parse(input);
82+
Some(grid.find_antinodes().iter().filter(|x| **x).count() as u32)
83+
}
84+
85+
pub fn part_two(input: &str) -> Option<u32> {
86+
let grid = Grid::parse(input);
87+
Some(grid.find_antinodes_with_resonance().iter().filter(|x| **x).count() as u32)
88+
}
89+
90+
#[cfg(test)]
91+
mod tests {
92+
use super::*;
93+
94+
#[test]
95+
fn test_part_one() {
96+
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
97+
assert_eq!(result, Some(14));
98+
}
99+
100+
#[test]
101+
fn test_part_two() {
102+
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
103+
assert_eq!(result, Some(34));
104+
}
105+
}

0 commit comments

Comments
 (0)