Skip to content

Commit 9785c3e

Browse files
committed
refactor(06/2015): remove duplication and simplify using enum for instruction type instead of traits
1 parent 169142c commit 9785c3e

File tree

1 file changed

+59
-83
lines changed

1 file changed

+59
-83
lines changed

src/solutions/year2015/day06.rs

Lines changed: 59 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::solutions::year2015::day06::InstructionType::{Toggle, TurnOff, TurnOn};
12
use crate::solutions::Solution;
23
use crate::utils::point::Point;
34
use crate::utils::surface_range::SurfaceRange;
@@ -9,34 +10,41 @@ pub struct Day06;
910
impl Solution for Day06 {
1011
fn part_one(&self, input: &str) -> String {
1112
let apply =
12-
|instruction: &dyn Instruction, grid: &mut LightGrid| instruction.apply_part_one(grid);
13-
let grid = self.apply_instructions(input, apply);
13+
|instruction: &Instruction, grid: &mut LightGrid| instruction.apply_part_one(grid);
1414

15-
grid.grid.values().filter(|v| **v == 1).count().to_string()
15+
self.apply_instructions(input, apply)
16+
.grid
17+
.values()
18+
.filter(|v| **v == 1)
19+
.count()
20+
.to_string()
1621
}
1722

1823
fn part_two(&self, input: &str) -> String {
1924
let apply =
20-
|instruction: &dyn Instruction, grid: &mut LightGrid| instruction.apply_part_two(grid);
21-
let grid = self.apply_instructions(input, apply);
25+
|instruction: &Instruction, grid: &mut LightGrid| instruction.apply_part_two(grid);
2226

23-
grid.grid.values().sum::<u64>().to_string()
27+
self.apply_instructions(input, apply)
28+
.grid
29+
.values()
30+
.sum::<u64>()
31+
.to_string()
2432
}
2533
}
2634

2735
impl Day06 {
28-
fn parse(&self, input: &str) -> Vec<Box<dyn Instruction>> {
36+
fn parse(&self, input: &str) -> Vec<Instruction> {
2937
input
3038
.lines()
31-
.map(|line| -> Box<dyn Instruction> {
39+
.map(|line| {
3240
let parts = line.split_whitespace().collect::<Vec<_>>();
3341

3442
if parts[0] == "turn" && parts[1] == "on" {
35-
Box::new(TurnOn::from(self.parse_points(parts[2], parts[4])))
43+
Instruction::new(TurnOn, self.parse_points(parts[2], parts[4]))
3644
} else if parts[0] == "turn" && parts[1] == "off" {
37-
Box::new(TurnOff::from(self.parse_points(parts[2], parts[4])))
45+
Instruction::new(TurnOff, self.parse_points(parts[2], parts[4]))
3846
} else if parts[0] == "toggle" {
39-
Box::new(Toggle::from(self.parse_points(parts[1], parts[3])))
47+
Instruction::new(Toggle, self.parse_points(parts[1], parts[3]))
4048
} else {
4149
unreachable!()
4250
}
@@ -50,12 +58,12 @@ impl Day06 {
5058

5159
fn apply_instructions<F>(&self, input: &str, mut func: F) -> LightGrid
5260
where
53-
F: FnMut(&dyn Instruction, &mut LightGrid),
61+
F: FnMut(&Instruction, &mut LightGrid),
5462
{
5563
let mut grid = LightGrid::default();
5664

5765
for instruction in self.parse(input) {
58-
func(instruction.as_ref(), &mut grid);
66+
func(&instruction, &mut grid);
5967
}
6068

6169
grid
@@ -67,94 +75,62 @@ struct LightGrid {
6775
grid: HashMap<Point, u64>,
6876
}
6977

70-
trait Instruction: Debug {
71-
fn apply_part_one(&self, grid: &mut LightGrid);
72-
fn apply_part_two(&self, grid: &mut LightGrid);
73-
}
74-
7578
#[derive(Debug)]
76-
struct TurnOn {
77-
surface_range: SurfaceRange,
78-
}
79-
80-
impl From<(Point, Point)> for TurnOn {
81-
fn from(value: (Point, Point)) -> Self {
82-
Self {
83-
surface_range: SurfaceRange::from(value),
84-
}
85-
}
86-
}
87-
88-
impl Instruction for TurnOn {
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-
}
93-
}
94-
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-
}
99-
}
100-
}
101-
102-
#[derive(Debug)]
103-
struct TurnOff {
104-
surface_range: SurfaceRange,
105-
}
106-
107-
impl From<(Point, Point)> for TurnOff {
108-
fn from(value: (Point, Point)) -> Self {
109-
Self {
110-
surface_range: SurfaceRange::from(value),
111-
}
112-
}
113-
}
114-
115-
impl Instruction for TurnOff {
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-
}
120-
}
121-
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-
}
129-
}
79+
enum InstructionType {
80+
TurnOn,
81+
TurnOff,
82+
Toggle,
13083
}
13184

13285
#[derive(Debug)]
133-
struct Toggle {
86+
struct Instruction {
87+
instruction_type: InstructionType,
13488
surface_range: SurfaceRange,
13589
}
13690

137-
impl From<(Point, Point)> for Toggle {
138-
fn from(value: (Point, Point)) -> Self {
91+
impl Instruction {
92+
fn new(instruction_type: InstructionType, points: (Point, Point)) -> Self {
13993
Self {
140-
surface_range: SurfaceRange::from(value),
94+
instruction_type,
95+
surface_range: SurfaceRange::from(points),
14196
}
14297
}
143-
}
14498

145-
impl Instruction for Toggle {
14699
fn apply_part_one(&self, grid: &mut LightGrid) {
147100
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);
101+
match self.instruction_type {
102+
TurnOn => {
103+
*grid.grid.entry(point).or_default() = 1;
104+
}
105+
TurnOff => {
106+
*grid.grid.entry(point).or_default() = 0;
107+
}
108+
Toggle => {
109+
grid.grid
110+
.entry(point)
111+
.and_modify(|v| *v = if *v == 0 { 1 } else { 0 })
112+
.or_insert(1);
113+
}
114+
}
152115
}
153116
}
154117

155118
fn apply_part_two(&self, grid: &mut LightGrid) {
156119
for point in self.surface_range.points() {
157-
*grid.grid.entry(point).or_default() += 2;
120+
match self.instruction_type {
121+
TurnOn => {
122+
*grid.grid.entry(point).or_default() += 1;
123+
}
124+
TurnOff => {
125+
grid.grid
126+
.entry(point)
127+
.and_modify(|v| *v = v.saturating_sub(1))
128+
.or_default();
129+
}
130+
Toggle => {
131+
*grid.grid.entry(point).or_default() += 2;
132+
}
133+
}
158134
}
159135
}
160136
}

0 commit comments

Comments
 (0)