Skip to content

Commit 918ba5a

Browse files
committed
feat: still not done with day 15...
1 parent e2dcdcd commit 918ba5a

File tree

4 files changed

+162
-32
lines changed

4 files changed

+162
-32
lines changed

day_15/src/enums.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use Direction::{Down, Left, Right, Up};
1010

1111
impl Direction {
1212
pub fn new(input: i64) -> Direction {
13-
println!("input: {:>}", input);
1413
match input {
1514
1 => Up,
1615
2 => Down,

day_15/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ fn main() {
88
println!("{:?}", part_01(&input));
99
}
1010

11-
fn part_01(input: &Vec<i64>) {
11+
fn part_01(input: &Vec<i64>) -> usize {
1212
let (b_sender, a_receiver) = channel();
1313
let (a_sender, b_receiver) = channel();
1414

day_15/src/paths.rs

Lines changed: 97 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,60 @@ fn is_between(a: &Point, c: &Point, b: &Point) -> bool {
1616
)
1717
}
1818

19+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
20+
struct State {
21+
cost: isize,
22+
point: Point,
23+
}
24+
1925
type Map = HashMap<Point, Tile>;
2026

2127
pub fn best_match(input: &Map, position: &Point, visited: &Vec<Point>) -> Option<Vec<Point>> {
22-
let available = input
23-
.clone()
24-
.iter()
25-
.filter(|(pos, tile)| {
26-
(tile == &&Tile::Unknown || tile == &&Tile::Visited) && !visited.contains(pos)
27-
})
28-
.map(|(pos, _tile)| pos.to_owned())
29-
.collect::<Vec<Point>>();
30-
31-
if available.len() <= 0 {
32-
return None;
33-
}
28+
let within_range = || -> Option<Vec<Point>> {
29+
let get_closest = |range: usize| -> Option<Vec<Point>> {
30+
let input = input
31+
.clone()
32+
.iter()
33+
.filter(|(pos, tile)| {
34+
(tile == &&Tile::Unknown || tile == &&Tile::Visited) && !visited.contains(pos)
35+
})
36+
.filter(|(pos, _title)| {
37+
let x = ((position.0 as f64) - (pos.0 as f64)).abs() as usize;
38+
let y = ((position.1 as f64) - (pos.1 as f64)).abs() as usize;
39+
40+
x <= range && y <= range
41+
})
42+
.map(|(pos, _tile)| pos.to_owned())
43+
.collect::<Vec<Point>>();
44+
45+
if input.len() <= 0 {
46+
None
47+
} else {
48+
Some(input.to_owned())
49+
}
50+
};
51+
52+
let mut range = 0;
53+
let mut result = None;
54+
55+
loop {
56+
if let Some(res) = get_closest(range) {
57+
result = Some(res);
58+
break;
59+
}
60+
range += 1;
61+
if range >= input.len() {
62+
break;
63+
}
64+
}
65+
66+
result
67+
};
68+
69+
let available = match within_range() {
70+
Some(res) => res.to_owned(),
71+
None => return None,
72+
};
3473

3574
let mut steps = vec![];
3675

@@ -40,7 +79,7 @@ pub fn best_match(input: &Map, position: &Point, visited: &Vec<Point>) -> Option
4079
None => continue,
4180
};
4281

43-
if path.len() < steps.len() {
82+
if steps.len() == 0 || path.len() < steps.len() {
4483
steps = path.to_owned();
4584
}
4685
}
@@ -52,12 +91,6 @@ pub fn best_match(input: &Map, position: &Point, visited: &Vec<Point>) -> Option
5291
}
5392
}
5493

55-
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
56-
struct State {
57-
cost: isize,
58-
point: Point,
59-
}
60-
6194
pub fn find_path(map: &Map, start: Point, goal: Point) -> Option<Vec<Point>> {
6295
let adjacent = |point: &Point| -> Vec<Point> {
6396
let mut vec = Vec::new();
@@ -124,3 +157,48 @@ pub fn find_path(map: &Map, start: Point, goal: Point) -> Option<Vec<Point>> {
124157

125158
Some(path)
126159
}
160+
161+
#[cfg(test)]
162+
mod tests {
163+
use super::*;
164+
165+
#[test]
166+
fn it_goes_around_the_maze() {
167+
let mut map = HashMap::new();
168+
169+
let c = Tile::Current;
170+
let v = Tile::Visited;
171+
let w = Tile::Wall;
172+
173+
let positions = vec![
174+
vec![w, w, w, w, w], // [(0,0), (1,0), (2,0), (3,0), (4,0)]
175+
vec![w, v, v, v, w], // [(0,1), (1,1), (2,1), (3,1), (4,1)]
176+
vec![w, v, w, c, w], // [(0,2), (1,2), (2,2), (3,2), (4,2)]
177+
vec![w, v, w, w, w], // [(0,3), (1,3), (2,3), (3,3), (4,3)]
178+
vec![w, v, v, v, w], // [(0,4), (1,4), (2,4), (3,4), (4,4)]
179+
vec![w, w, w, w, w], // [(0,5), (1,5), (2,5), (3,5), (4,5)]
180+
];
181+
182+
for (y, row) in positions.iter().enumerate() {
183+
for (x, tile) in row.iter().enumerate() {
184+
let (x, y) = (x.to_owned() as i64, y.to_owned() as i64);
185+
map.insert((x, y), tile.to_owned());
186+
}
187+
}
188+
189+
assert_eq!(
190+
find_path(&map, (3, 2), (3, 4)),
191+
Some(vec![
192+
(3, 4),
193+
(2, 4),
194+
(1, 4),
195+
(1, 3),
196+
(1, 2),
197+
(1, 1),
198+
(2, 1),
199+
(3, 1),
200+
(3, 2)
201+
])
202+
);
203+
}
204+
}

day_15/src/repair_droid.rs

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub struct RepairDroid {
2222
input: Receiver<i64>,
2323
output: Sender<i64>,
2424
grid: HashMap<Point, Tile>,
25+
end: Option<Point>,
26+
end_route: Option<Vec<Point>>,
2527
position: Point,
2628
direction: Direction,
2729
iterations: u64,
@@ -49,6 +51,8 @@ impl RepairDroid {
4951
visited: vec![(0, -1)],
5052
direction: Up,
5153
iterations: 0,
54+
end: None,
55+
end_route: None,
5256
}
5357
}
5458

@@ -102,19 +106,48 @@ impl RepairDroid {
102106
continue;
103107
}
104108

109+
let start = x == 0 && y == 0;
110+
let end = !self.end.is_none() && self.end.unwrap() == (x, y);
111+
105112
let x = (x + x_padding) as usize;
106113
let y = (y + y_padding) as usize;
107114

108115
if let Some(elem) = grid.get_mut(y) {
109-
elem[x] = match tile {
110-
Tile::Current => 'D',
111-
Tile::Wall => '#',
112-
Tile::Visited => '.',
113-
_ => ' ',
116+
elem[x] = if start {
117+
'☆'
118+
} else if end {
119+
'★'
120+
} else {
121+
match tile {
122+
Tile::Current => 'D',
123+
Tile::Wall => '#',
124+
Tile::Visited => '.',
125+
_ => ' ',
126+
}
114127
};
115128
}
116129
}
117130

131+
if let Some(vec) = &self.end_route {
132+
for (x, y) in vec {
133+
let (x, y) = (x.to_owned(), y.to_owned());
134+
let start = x == 0 && y == 0;
135+
let end = self.end.unwrap() == (x, y);
136+
let x = (x + x_padding) as usize;
137+
let y = (y + y_padding) as usize;
138+
139+
if let Some(elem) = grid.get_mut(y) {
140+
elem[x] = if start {
141+
'☆'
142+
} else if end {
143+
'★'
144+
} else {
145+
'x'
146+
};
147+
}
148+
}
149+
}
150+
118151
for row in grid {
119152
println!("{}", row.clone().iter().collect::<String>());
120153
}
@@ -129,6 +162,7 @@ impl RepairDroid {
129162
if x == &self.position.0 && y == &self.position.1 {
130163
continue;
131164
}
165+
132166
let direction = if x == &prev.0 {
133167
if y < &prev.1 {
134168
Up
@@ -190,7 +224,7 @@ impl RepairDroid {
190224
Direction::dir(self.direction)
191225
}
192226

193-
fn move_droid(&mut self) -> Status {
227+
fn move_droid(&mut self) -> bool {
194228
let next_direction = self.next_direction();
195229

196230
self.output.send(next_direction.to_owned()).unwrap();
@@ -200,6 +234,10 @@ impl RepairDroid {
200234
Err(error) => panic!("error: {}", error),
201235
};
202236

237+
if status == MovedAndOnOxygen {
238+
self.end = Some(self.position.clone());
239+
}
240+
203241
match status {
204242
Wall => {
205243
let wall_position = self.get_position(self.direction);
@@ -210,7 +248,6 @@ impl RepairDroid {
210248
self.grid.insert(self.position.clone(), Tile::Visited);
211249
self.position = self.get_position(self.direction);
212250
self.grid.insert(self.position.clone(), Tile::Current);
213-
214251
vec![(0, 1), (1, 0), (-1, 0), (0, -1)]
215252
.iter()
216253
.for_each(|(x, y)| {
@@ -228,14 +265,30 @@ impl RepairDroid {
228265
}
229266
};
230267

231-
status
268+
let unknown_left = self.grid.iter().fold(0, |acc, curr| {
269+
if curr.1 == &Tile::Unknown {
270+
acc + 1
271+
} else {
272+
acc
273+
}
274+
});
275+
276+
unknown_left == 0
232277
}
233278

234-
pub fn run(&mut self) {
235-
while self.move_droid() != MovedAndOnOxygen {
236-
sleep(Duration::from_millis(60));
279+
pub fn run(&mut self) -> usize {
280+
while !self.move_droid() {
281+
sleep(Duration::from_millis(10));
237282
self.iterations += 1;
238283
self.print();
239284
}
285+
286+
if let Some(result) = paths::find_path(&self.grid.to_owned(), (0, 0), self.end.unwrap()) {
287+
self.end_route = Some(result.to_owned());
288+
self.print();
289+
result.len()
290+
} else {
291+
0
292+
}
240293
}
241294
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy