Skip to content

Commit 169142c

Browse files
committed
perf(06/2015): optimize by using hashmap and don't fill it with default state on init
1 parent b6fd8bf commit 169142c

File tree

3 files changed

+71
-34
lines changed

3 files changed

+71
-34
lines changed

readme.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
| [Day 3: Perfectly Spherical Houses in a Vacuum](src/solutions/year2015/day03.rs) | ⭐⭐ | 0.358 | 0.373 |
9393
| [Day 4: The Ideal Stocking Stuffer](src/solutions/year2015/day04.rs) | ⭐⭐ | 66.769 | 1931.428 |
9494
| [Day 5: Doesn't He Have Intern-Elves For This?](src/solutions/year2015/day05.rs) | ⭐⭐ | 0.261 | 0.987 |
95-
| [Day 6: Probably a Fire Hazard](src/solutions/year2015/day06.rs) | ⭐⭐ | 1227.077 | 1580.565 |
95+
| [Day 6: Probably a Fire Hazard](src/solutions/year2015/day06.rs) | ⭐⭐ | 871.538 | 817.533 |
9696

9797
# TODO
9898

src/solutions/year2015/day06.rs

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
use crate::solutions::Solution;
2-
use crate::utils::grid::Grid;
32
use crate::utils::point::Point;
43
use crate::utils::surface_range::SurfaceRange;
4+
use std::collections::HashMap;
55
use std::fmt::Debug;
66

77
pub struct Day06;
88

99
impl Solution for Day06 {
1010
fn part_one(&self, input: &str) -> String {
1111
let apply =
12-
|instruction: &dyn Instruction, grid: &mut Grid<u64>| instruction.apply_part_one(grid);
12+
|instruction: &dyn Instruction, grid: &mut LightGrid| instruction.apply_part_one(grid);
1313
let grid = self.apply_instructions(input, apply);
1414

15-
grid.get_all_positions(&1).len().to_string()
15+
grid.grid.values().filter(|v| **v == 1).count().to_string()
1616
}
1717

1818
fn part_two(&self, input: &str) -> String {
1919
let apply =
20-
|instruction: &dyn Instruction, grid: &mut Grid<u64>| instruction.apply_part_two(grid);
20+
|instruction: &dyn Instruction, grid: &mut LightGrid| instruction.apply_part_two(grid);
2121
let grid = self.apply_instructions(input, apply);
2222

23-
grid.all().values().sum::<u64>().to_string()
23+
grid.grid.values().sum::<u64>().to_string()
2424
}
2525
}
2626

@@ -48,14 +48,11 @@ impl Day06 {
4848
(from_str.parse().unwrap(), to_str.parse().unwrap())
4949
}
5050

51-
fn apply_instructions<F>(&self, input: &str, mut func: F) -> Grid<u64>
51+
fn apply_instructions<F>(&self, input: &str, mut func: F) -> LightGrid
5252
where
53-
F: FnMut(&dyn Instruction, &mut Grid<u64>),
53+
F: FnMut(&dyn Instruction, &mut LightGrid),
5454
{
55-
let mut grid = Grid::filled(
56-
SurfaceRange::from((Point::new(0, 0), Point::new(999, 999))),
57-
0,
58-
);
55+
let mut grid = LightGrid::default();
5956

6057
for instruction in self.parse(input) {
6158
func(instruction.as_ref(), &mut grid);
@@ -65,9 +62,14 @@ impl Day06 {
6562
}
6663
}
6764

65+
#[derive(Default)]
66+
struct LightGrid {
67+
grid: HashMap<Point, u64>,
68+
}
69+
6870
trait Instruction: Debug {
69-
fn apply_part_one(&self, grid: &mut Grid<u64>);
70-
fn apply_part_two(&self, grid: &mut Grid<u64>);
71+
fn apply_part_one(&self, grid: &mut LightGrid);
72+
fn apply_part_two(&self, grid: &mut LightGrid);
7173
}
7274

7375
#[derive(Debug)]
@@ -84,12 +86,16 @@ impl From<(Point, Point)> for TurnOn {
8486
}
8587

8688
impl Instruction for TurnOn {
87-
fn apply_part_one(&self, grid: &mut Grid<u64>) {
88-
grid.modify_many(self.surface_range.points(), 1)
89+
fn apply_part_one(&self, grid: &mut LightGrid) {
90+
for point in self.surface_range.points() {
91+
*grid.grid.entry(point).or_default() = 1;
92+
}
8993
}
9094

91-
fn apply_part_two(&self, grid: &mut Grid<u64>) {
92-
grid.modify_many_with(self.surface_range.points(), |b| *b += 1)
95+
fn apply_part_two(&self, grid: &mut LightGrid) {
96+
for point in self.surface_range.points() {
97+
*grid.grid.entry(point).or_default() += 1;
98+
}
9399
}
94100
}
95101

@@ -107,12 +113,19 @@ impl From<(Point, Point)> for TurnOff {
107113
}
108114

109115
impl Instruction for TurnOff {
110-
fn apply_part_one(&self, grid: &mut Grid<u64>) {
111-
grid.modify_many(self.surface_range.points(), 0)
116+
fn apply_part_one(&self, grid: &mut LightGrid) {
117+
for point in self.surface_range.points() {
118+
*grid.grid.entry(point).or_default() = 0;
119+
}
112120
}
113121

114-
fn apply_part_two(&self, grid: &mut Grid<u64>) {
115-
grid.modify_many_with(self.surface_range.points(), |b| *b = if *b == 0 { 0 } else { *b - 1})
122+
fn apply_part_two(&self, grid: &mut LightGrid) {
123+
for point in self.surface_range.points() {
124+
grid.grid
125+
.entry(point)
126+
.and_modify(|v| *v = if *v == 0 { 0 } else { *v - 1 })
127+
.or_default();
128+
}
116129
}
117130
}
118131

@@ -130,14 +143,19 @@ impl From<(Point, Point)> for Toggle {
130143
}
131144

132145
impl Instruction for Toggle {
133-
fn apply_part_one(&self, grid: &mut Grid<u64>) {
134-
grid.modify_many_with(self.surface_range.points(), |b| {
135-
*b = if *b == 0 { 1 } else { 0 }
136-
})
146+
fn apply_part_one(&self, grid: &mut LightGrid) {
147+
for point in self.surface_range.points() {
148+
grid.grid
149+
.entry(point)
150+
.and_modify(|v| *v = if *v == 0 { 1 } else { 0 })
151+
.or_insert(1);
152+
}
137153
}
138154

139-
fn apply_part_two(&self, grid: &mut Grid<u64>) {
140-
grid.modify_many_with(self.surface_range.points(), |b| *b += 2)
155+
fn apply_part_two(&self, grid: &mut LightGrid) {
156+
for point in self.surface_range.points() {
157+
*grid.grid.entry(point).or_default() += 2;
158+
}
141159
}
142160
}
143161

@@ -155,14 +173,29 @@ mod tests {
155173
fn part_two_example_test() {
156174
assert_eq!("1", Day06.part_two("turn on 0,0 through 0,0"));
157175
assert_eq!("2000000", Day06.part_two("toggle 0,0 through 999,999"));
158-
assert_eq!("7", Day06.part_two(r#"toggle 0,0 through 0,3
159-
turn off 0,0 through 0,0"#));
160-
assert_eq!("6", Day06.part_two(r#"toggle 0,0 through 0,3
176+
assert_eq!(
177+
"7",
178+
Day06.part_two(
179+
r#"toggle 0,0 through 0,3
180+
turn off 0,0 through 0,0"#
181+
)
182+
);
183+
assert_eq!(
184+
"6",
185+
Day06.part_two(
186+
r#"toggle 0,0 through 0,3
161187
turn off 0,0 through 0,0
162-
turn off 0,0 through 0,0"#));
163-
assert_eq!("6", Day06.part_two(r#"toggle 0,0 through 0,3
188+
turn off 0,0 through 0,0"#
189+
)
190+
);
191+
assert_eq!(
192+
"6",
193+
Day06.part_two(
194+
r#"toggle 0,0 through 0,3
164195
turn off 0,0 through 0,0
165196
turn off 0,0 through 0,0
166-
turn off 0,0 through 0,0"#));
197+
turn off 0,0 through 0,0"#
198+
)
199+
);
167200
}
168201
}

src/utils/grid.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ where
4646
Self::new(cells)
4747
}
4848

49+
#[allow(dead_code)]
4950
pub fn filled(surface_range: SurfaceRange, element: T) -> Self
5051
where
5152
T: Clone,
@@ -177,6 +178,7 @@ where
177178
*self.cells.get_mut(&point).unwrap() = new_value;
178179
}
179180

181+
#[allow(dead_code)]
180182
pub fn modify_many(&mut self, points: Vec<Point>, new_value: T)
181183
where
182184
T: Clone,
@@ -186,6 +188,7 @@ where
186188
}
187189
}
188190

191+
#[allow(dead_code)]
189192
pub fn modify_many_with<F>(&mut self, points: Vec<Point>, mut func: F)
190193
where
191194
F: FnMut(&mut T),
@@ -377,6 +380,7 @@ where
377380
printable.print(self)
378381
}
379382

383+
#[allow(dead_code)]
380384
pub fn all(&self) -> HashMap<Point, T>
381385
where
382386
T: Clone,

0 commit comments

Comments
 (0)