Skip to content

Commit aebebeb

Browse files
committed
feat(06/2015): solve first part
1 parent d3f8d54 commit aebebeb

File tree

4 files changed

+132
-6
lines changed

4 files changed

+132
-6
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) | | - | - |
95+
| [Day 6: Probably a Fire Hazard](src/solutions/year2015/day06.rs) | | 1227.077 | - |
9696

9797
# TODO
9898

src/solutions/year2015/day06.rs

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,130 @@
11
use crate::solutions::Solution;
2+
use crate::utils::grid::Grid;
3+
use crate::utils::point::Point;
4+
use crate::utils::surface_range::SurfaceRange;
5+
use std::fmt::Debug;
26

37
pub struct Day06;
48

59
impl Solution for Day06 {
6-
fn part_one(&self, _input: &str) -> String {
7-
String::from("0")
10+
fn part_one(&self, input: &str) -> String {
11+
let mut grid = Grid::filled(
12+
SurfaceRange::from((Point::new(0, 0), Point::new(999, 999))),
13+
false,
14+
);
15+
let instructions = self.parse(input);
16+
17+
for instruction in instructions {
18+
instruction.apply(&mut grid);
19+
}
20+
21+
grid.get_all_positions(&true).len().to_string()
822
}
923

1024
fn part_two(&self, _input: &str) -> String {
1125
String::from("0")
1226
}
1327
}
1428

29+
impl Day06 {
30+
fn parse(&self, input: &str) -> Vec<Box<dyn Instruction>> {
31+
input
32+
.lines()
33+
.map(|line| -> Box<dyn Instruction> {
34+
if line.starts_with("turn on ") {
35+
let trimmed = line.trim_start_matches("turn on ");
36+
37+
Box::new(TurnOn::from(self.parse_points(trimmed)))
38+
} else if line.starts_with("turn off ") {
39+
let trimmed = line.trim_start_matches("turn off ");
40+
41+
Box::new(TurnOff::from(self.parse_points(trimmed)))
42+
} else if line.starts_with("toggle ") {
43+
let trimmed = line.trim_start_matches("toggle ");
44+
45+
Box::new(Toggle::from(self.parse_points(trimmed)))
46+
} else {
47+
unreachable!()
48+
}
49+
})
50+
.collect()
51+
}
52+
53+
fn parse_points(&self, points_str: &str) -> (Point, Point) {
54+
let p = points_str.split_once(" through ").unwrap();
55+
56+
(p.0.parse().unwrap(), p.1.parse().unwrap())
57+
}
58+
}
59+
60+
trait Instruction: Debug {
61+
fn apply(&self, grid: &mut Grid<bool>);
62+
}
63+
64+
#[derive(Debug)]
65+
struct TurnOn {
66+
surface_range: SurfaceRange,
67+
}
68+
69+
impl From<(Point, Point)> for TurnOn {
70+
fn from(value: (Point, Point)) -> Self {
71+
Self {
72+
surface_range: SurfaceRange::from(value),
73+
}
74+
}
75+
}
76+
77+
impl Instruction for TurnOn {
78+
fn apply(&self, grid: &mut Grid<bool>) {
79+
grid.modify_many(self.surface_range.points(), true)
80+
}
81+
}
82+
83+
#[derive(Debug)]
84+
struct TurnOff {
85+
surface_range: SurfaceRange,
86+
}
87+
88+
impl From<(Point, Point)> for TurnOff {
89+
fn from(value: (Point, Point)) -> Self {
90+
Self {
91+
surface_range: SurfaceRange::from(value),
92+
}
93+
}
94+
}
95+
96+
impl Instruction for TurnOff {
97+
fn apply(&self, grid: &mut Grid<bool>) {
98+
grid.modify_many(self.surface_range.points(), false)
99+
}
100+
}
101+
102+
#[derive(Debug)]
103+
struct Toggle {
104+
surface_range: SurfaceRange,
105+
}
106+
107+
impl From<(Point, Point)> for Toggle {
108+
fn from(value: (Point, Point)) -> Self {
109+
Self {
110+
surface_range: SurfaceRange::from(value),
111+
}
112+
}
113+
}
114+
115+
impl Instruction for Toggle {
116+
fn apply(&self, grid: &mut Grid<bool>) {
117+
grid.modify_many_with(self.surface_range.points(), |b| *b = !*b)
118+
}
119+
}
120+
15121
#[cfg(test)]
16122
mod tests {
17123
use super::*;
18124

19125
#[test]
20126
fn part_one_example_test() {
21-
assert_eq!("0", Day06.part_one(""));
127+
assert_eq!("1000000", Day06.part_one("turn on 0,0 through 999,999"));
128+
assert_eq!("1000", Day06.part_one("toggle 0,0 through 999,0"));
22129
}
23130
}

src/utils/grid.rs

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

49-
#[allow(dead_code)]
5049
pub fn filled(surface_range: SurfaceRange, element: T) -> Self
5150
where
5251
T: Clone,
@@ -178,7 +177,6 @@ where
178177
*self.cells.get_mut(&point).unwrap() = new_value;
179178
}
180179

181-
#[allow(dead_code)]
182180
pub fn modify_many(&mut self, points: Vec<Point>, new_value: T)
183181
where
184182
T: Clone,
@@ -188,6 +186,15 @@ where
188186
}
189187
}
190188

189+
pub fn modify_many_with<F>(&mut self, points: Vec<Point>, mut func: F)
190+
where
191+
F: FnMut(&mut T),
192+
{
193+
for point in points {
194+
self.cells.entry(point).and_modify(&mut func);
195+
}
196+
}
197+
191198
fn move_rows_to_south_from(&mut self, from: isize) {
192199
for y in self
193200
.rows_range

src/utils/surface_range.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ impl SurfaceRange {
8585
y_range: self.y_range._shrink(by).unwrap(),
8686
}
8787
}
88+
89+
pub fn points(&self) -> Vec<Point> {
90+
let mut points: Vec<Point> = Vec::with_capacity(self.area());
91+
92+
for x in self.columns().iter() {
93+
for y in self.rows().iter() {
94+
points.push(Point::new(x, y));
95+
}
96+
}
97+
98+
points
99+
}
88100
}
89101

90102
impl From<(Point, Point)> for SurfaceRange {

0 commit comments

Comments
 (0)