Commit 2ab99fa4 authored by Marcel Behrmann's avatar Marcel Behrmann

new algo

parent 091477d8
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "autocfg"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "day_20"
version = "0.1.0"
dependencies = [
"pathfinding 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "fixedbitset"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "indexmap"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itertools"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "pathfinding"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3"
"checksum fixedbitset 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
"checksum itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f56a2d0bc861f9165be4eb3442afd3c236d8a98afd426f65d92324ae1091a484"
"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
"checksum pathfinding 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7c84b3f8a97e544e03c0b8865ddff93de5d8c3c96962b51bfc9639e5dddf299b"
......@@ -7,3 +7,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
pathfinding = "2.0.1"
\ No newline at end of file
......@@ -5,14 +5,35 @@ mod map;
use std::fs;
use std::collections::HashMap;
use map::Pos;
use pathfinding::directed::astar;
const INPUT_FILE: &str = "input.txt";
type Map = HashMap<Pos, char>;
type JumpTable = HashMap<Pos, char>;
type JumpTable = HashMap<Pos, Pos>;
fn main() {
let input = fs::read_to_string(INPUT_FILE).expect("Error reading input");
let input =
" A
A
#######.#########
#######.........#
#######.#######.#
#######.#######.#
#######.#######.#
##### B ###.#
BC...## C ###.#
##.## ###.#
##...DE F ###.#
##### G ###.#
#########.#####.#
DE..#######...###.#
#.#########.###.#
FG..#########.....#
###########.#####
Z
Z ";
let input = input.lines();
let input: Vec<&str> = input.collect::<Vec<&str>>();
......@@ -23,11 +44,42 @@ fn main() {
#[allow(unused_variables)]
fn part_01(input: Vec<&str>) {
let (map, dimensions) = build_map(input);
println!("Map dimensions: {:?}", dimensions);
let ( start, goal, network ) = analyze_network(&map, &dimensions);
println!("Map dimensions: {:?}", dimensions);
println!("Found start at: {:?}", start);
println!("Found goal at: {:?}", goal);
println!("Found {} jumps", network.len());
println!("Jumps: {:#?}", network);
let successors = |p: &Pos| {
p.successors(&network)
.iter()
.filter(|f| {
let pp = map.get(&f.0);
match pp {
Some(x) => {
match x {
'.' => true,
_ => false,
}
},
None => {
false
}
}
})
.map(|pp| pp.clone())
.collect::<Vec<(Pos, u32)>>()
};
let result = astar::astar(
&start,
successors,
|p| p.distance(&goal),
|p| *p == goal
);
println!("Path: {:?}", result);
}
fn build_map(input: Vec<&str>) -> (Map, (i32, i32)) {
......@@ -44,7 +96,10 @@ fn build_map(input: Vec<&str>) -> (Map, (i32, i32)) {
// Save map to our dict
for line in input {
for c in line.chars() {
map.insert(Pos{x, y}, c);
if c != ' ' {
map.insert(Pos{x, y}, c);
}
x += 1;
if x > dimensions.0 {
......@@ -60,9 +115,11 @@ fn build_map(input: Vec<&str>) -> (Map, (i32, i32)) {
}
fn analyze_network(map: &Map, dimensions: &(i32, i32)) -> (Pos, Pos, JumpTable) {
let table: JumpTable = JumpTable::new();
let start = Pos{x: 0, y: 0};
let goal = Pos{x: 0, y: 0};
let mut table: JumpTable = JumpTable::new();
let mut start = Pos{x: 0, y: 0};
let mut goal = Pos{x: 0, y: 0};
let mut cache: HashMap<String, Pos> = HashMap::new();
let neighbours = vec![
Pos{x: 0, y: -1},
......@@ -71,23 +128,59 @@ fn analyze_network(map: &Map, dimensions: &(i32, i32)) -> (Pos, Pos, JumpTable)
Pos{x: 1, y: 0},
];
for x in 0..dimensions.0 {
for y in 0..dimensions.1 {
if let Some(c) = map.get(&Pos{x, y}) {
'column: for x in 0..dimensions.0 {
'row: for y in 0..dimensions.1 {
let p = Pos{x, y};
if let Some(c) = map.get(&p) {
match c {
'A' ..= 'Z' => (),
_ => continue,
}
for neighbour in &neighbours {
let t = p.clone() + neighbour.clone();
if let Some(cc) = map.get(&t) {
if cc == c {
let tt = p.clone() + neighbour.clone() + neighbour.clone();
// we need that check here so we can use the right portal stuff
if let Some(ccc) = map.get(&tt) {
if *ccc == '.' && *c == 'A' {
start = tt.clone();
continue 'row;
}
if *ccc == '.' && *c == 'Z' {
goal = tt.clone();
continue 'row;
}
}
} else if *cc >= 'A' && *cc <= 'Z' {
let mut key = String::new();
key.push(*c);
key.push(*cc);
if let Some(ca) = cache.get(&key) {
let org = Pos{x, y};
table.insert(org.clone(), ca.clone());
table.insert(ca.clone(), org.clone());
continue 'row;
} else {
let org = Pos{x, y};
cache.insert(key, org);
continue 'row;
}
}
}
}
panic!("Found a portal that does not make any sense");
}
}
}
println!("Jump table contains {} jumps", table.len());
(start, goal, table)
}
......
use std::ops::{Add, AddAssign, Sub, SubAssign};
use std::collections::HashMap;
#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct Pos {
......@@ -7,6 +7,23 @@ pub struct Pos {
pub y: i32,
}
impl Pos {
pub fn distance(&self, other: &Self) -> u32 {
((self.x - other.x).abs() + (self.y - other.y).abs()) as u32
}
pub fn successors(&self, network: &HashMap<Pos, Pos>) -> Vec<(Pos, u32)> {
let &Pos{x, y} = self;
let mut succs = vec![Pos{x: x+1, y}, Pos{x: x-1,y}, Pos{x,y: y+1}, Pos{x,y: y-1}];
if let Some(t) = network.get(self) {
succs.push(t.clone());
}
succs.into_iter().map(|p| (p, 1)).collect()
}
}
impl Add for Pos {
type Output = Pos;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment