Skip to content

Commit 124972e

Browse files
committed
feat: trying to solve part 1
1 parent df4c97c commit 124972e

File tree

6 files changed

+494
-0
lines changed

6 files changed

+494
-0
lines changed

day_15/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[package]
2+
name = "day_15"
3+
version = "0.1.0"
4+
authors = ["Dennis Pettersson <mail@dennispettersson.se>"]
5+
edition = "2018"
6+
7+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+
[dependencies]
10+
day_09 = { path = "../day_09" }
11+
termion = "1.5.4"
12+
float-cmp = "0.6.0"
13+
rand = "0.7.2"

day_15/src/enums.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
2+
pub enum Direction {
3+
Up = 1,
4+
Down = 2,
5+
Left = 3,
6+
Right = 4,
7+
}
8+
9+
use Direction::{Down, Left, Right, Up};
10+
11+
impl Direction {
12+
pub fn new(input: i64) -> Direction {
13+
println!("input: {:>}", input);
14+
match input {
15+
1 => Up,
16+
2 => Down,
17+
3 => Left,
18+
_ => Right,
19+
}
20+
}
21+
22+
pub fn dir(input: Direction) -> i64 {
23+
match input {
24+
Up => 1,
25+
Down => 2,
26+
Left => 3,
27+
Right => 4,
28+
}
29+
}
30+
31+
pub fn turn(self) -> Direction {
32+
match self {
33+
Up => Right,
34+
Right => Down,
35+
Down => Left,
36+
Left => Up,
37+
}
38+
}
39+
}
40+
41+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
42+
pub enum Status {
43+
Wall = 0,
44+
Moved = 1,
45+
MovedAndOnOxygen = 2,
46+
}
47+
48+
use Status::{Moved, MovedAndOnOxygen, Wall};
49+
50+
impl Status {
51+
pub fn new(input: i64) -> Status {
52+
match input {
53+
0 => Wall,
54+
1 => Moved,
55+
2 => MovedAndOnOxygen,
56+
_ => panic!("{} not known", input),
57+
}
58+
}
59+
}
60+
61+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug)]
62+
pub enum Tile {
63+
Current,
64+
Unknown,
65+
Wall,
66+
Visited,
67+
}

day_15/src/lib.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#[macro_use]
2+
extern crate float_cmp;
3+
4+
extern crate day_09;
5+
extern crate rand;
6+
extern crate termion;
7+
8+
pub type Point = (i64, i64);
9+
10+
pub mod enums;
11+
pub mod paths;
12+
pub mod repair_droid;
13+
14+
pub fn parse_input(input: &str) -> Vec<i64> {
15+
input
16+
.lines()
17+
.map(|string| string.trim())
18+
.filter(|string| !string.is_empty())
19+
.next()
20+
.unwrap()
21+
.split(',')
22+
.map(|part| part.parse::<i64>().unwrap())
23+
.collect::<Vec<i64>>()
24+
}

day_15/src/main.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use ::day_15::{parse_input, repair_droid::RepairDroid};
2+
use day_09::program::Program;
3+
use std::{sync::mpsc::channel, thread::spawn};
4+
5+
fn main() {
6+
let input = parse_input(&include_str!("../../input/day_15"));
7+
8+
println!("{:?}", part_01(&input));
9+
}
10+
11+
fn part_01(input: &Vec<i64>) {
12+
let (b_sender, a_receiver) = channel();
13+
let (a_sender, b_receiver) = channel();
14+
15+
let mut program = Program::new(&input);
16+
17+
program.new_input(b_receiver);
18+
program.new_output(b_sender);
19+
20+
spawn(move || program.run());
21+
spawn(move || RepairDroid::new(a_receiver, a_sender).run())
22+
.join()
23+
.unwrap()
24+
}

day_15/src/paths.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
use crate::enums::Tile;
2+
use crate::Point;
3+
use std::collections::{BinaryHeap, HashMap};
4+
5+
fn distance(p1: &Point, p2: &Point) -> f64 {
6+
((p2.0 as f64 - p1.0 as f64).powf(2f64) + (p2.1 as f64 - p1.1 as f64).powf(2f64)).sqrt()
7+
}
8+
9+
#[allow(dead_code)]
10+
fn is_between(a: &Point, c: &Point, b: &Point) -> bool {
11+
approx_eq!(
12+
f64,
13+
distance(&a, &c) + distance(&c, &b),
14+
distance(&a, &b),
15+
ulps = 2
16+
)
17+
}
18+
19+
type Map = HashMap<Point, Tile>;
20+
21+
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+
}
34+
35+
let mut steps = vec![];
36+
37+
for current in available.clone() {
38+
let path = match find_path(&input, position.to_owned(), current.to_owned()) {
39+
Some(path) => path.to_owned(),
40+
None => continue,
41+
};
42+
if path.len() > steps.len() {
43+
steps = path.to_owned();
44+
}
45+
}
46+
47+
if steps.len() == 0 {
48+
None
49+
} else {
50+
Some(steps.to_owned())
51+
}
52+
}
53+
54+
#[derive(Clone, Copy, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
55+
struct State {
56+
cost: isize,
57+
point: Point,
58+
}
59+
60+
pub fn find_path(map: &Map, start: Point, goal: Point) -> Option<Vec<Point>> {
61+
let adjacent = |point: &Point| -> Vec<Point> {
62+
let mut vec = Vec::new();
63+
64+
for (x, y) in vec![(0, 1), (1, 0), (-1, 0), (0, -1)] {
65+
let new_pos = (point.0 + x, point.1 + y);
66+
if let Some(tile) = map.get(&new_pos) {
67+
if tile != &Tile::Wall {
68+
vec.push(new_pos.to_owned());
69+
}
70+
};
71+
}
72+
73+
vec
74+
};
75+
76+
let can_move = |point: &Point| -> bool {
77+
match map.get(&point) {
78+
Some(tile) => tile != &Tile::Wall,
79+
None => false,
80+
}
81+
};
82+
83+
let mut frontier = BinaryHeap::new();
84+
frontier.push(State {
85+
cost: 0,
86+
point: start,
87+
});
88+
89+
let mut came_from = HashMap::new();
90+
came_from.insert(start, None);
91+
92+
while frontier.len() != 0 {
93+
let current = frontier.pop();
94+
if current.unwrap().point == goal {
95+
break;
96+
}
97+
for next_point in adjacent(&current.unwrap().point) {
98+
if !came_from.contains_key(&next_point) && can_move(&next_point) {
99+
frontier.push(State {
100+
point: next_point,
101+
cost: distance(&goal, &next_point) as isize,
102+
});
103+
came_from.insert(next_point, current.map(|a| a.point));
104+
}
105+
}
106+
}
107+
108+
let mut current = goal;
109+
let mut path = vec![current];
110+
111+
while current != start {
112+
if let Some(c) = came_from.get(&current) {
113+
if let Some(c) = *c {
114+
current = c;
115+
path.push(current);
116+
} else {
117+
return None;
118+
}
119+
} else {
120+
return None;
121+
}
122+
}
123+
124+
Some(path)
125+
}

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