feat: implemented file to graph parsing and dijkstra
This commit is contained in:
parent
fbcdc63d64
commit
0f479302dd
|
@ -2,6 +2,245 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstream"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"anstyle-parse",
|
||||||
|
"anstyle-query",
|
||||||
|
"anstyle-wincon",
|
||||||
|
"colorchoice",
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
|
||||||
|
dependencies = [
|
||||||
|
"utf8parse",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-query"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anstyle-wincon"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
|
||||||
|
dependencies = [
|
||||||
|
"anstyle",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.75"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap"
|
||||||
|
version = "4.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "84ed82781cea27b43c9b106a979fe450a13a31aab0500595fb3fc06616de08e6"
|
||||||
|
dependencies = [
|
||||||
|
"clap_builder",
|
||||||
|
"clap_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_builder"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08"
|
||||||
|
dependencies = [
|
||||||
|
"anstream",
|
||||||
|
"anstyle",
|
||||||
|
"clap_lex",
|
||||||
|
"strsim",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_derive"
|
||||||
|
version = "4.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "clap_lex"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorchoice"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.66"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.32"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8parse"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-sys"
|
||||||
|
version = "0.48.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||||
|
dependencies = [
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||||
|
dependencies = [
|
||||||
|
"windows_aarch64_gnullvm",
|
||||||
|
"windows_aarch64_msvc",
|
||||||
|
"windows_i686_gnu",
|
||||||
|
"windows_i686_msvc",
|
||||||
|
"windows_x86_64_gnu",
|
||||||
|
"windows_x86_64_gnullvm",
|
||||||
|
"windows_x86_64_msvc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.48.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zauberschule"
|
name = "zauberschule"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"clap",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
|
@ -6,3 +6,6 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
|
clap = { version = "4.4.2", features = ["derive"] }
|
||||||
|
slab = "0.4.9"
|
||||||
|
|
|
@ -0,0 +1,207 @@
|
||||||
|
use anyhow::{Error, Result};
|
||||||
|
use slab::Slab;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Edge {
|
||||||
|
node: usize,
|
||||||
|
gravity: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Node {
|
||||||
|
edges: Slab<Edge>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Graph {
|
||||||
|
nodes: Slab<Node>,
|
||||||
|
start: usize,
|
||||||
|
end: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum MapNode {
|
||||||
|
Wall,
|
||||||
|
Floor(usize),
|
||||||
|
Unknown(char),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
struct DijkstraNode {
|
||||||
|
parent: usize,
|
||||||
|
distance: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Edge {
|
||||||
|
fn new(id: usize, gravity: usize) -> Self {
|
||||||
|
Self { node: id, gravity }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Node {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self { edges: Slab::new() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DijkstraNode {
|
||||||
|
fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
parent: 0,
|
||||||
|
distance: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Graph {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
nodes: Slab::new(),
|
||||||
|
start: 0,
|
||||||
|
end: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new(path: &Path) -> Result<Self> {
|
||||||
|
let mut graph = Self::default();
|
||||||
|
|
||||||
|
let file_content = std::fs::read_to_string(path)?;
|
||||||
|
|
||||||
|
// Split the raw content into two vectors of vectors of MapNodes
|
||||||
|
// Each vector represents a map layer that's split into rows.
|
||||||
|
let maps = file_content
|
||||||
|
.split_once('\n')
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.split("\n\n")
|
||||||
|
.map(|block| {
|
||||||
|
block
|
||||||
|
.lines()
|
||||||
|
.map(|line| {
|
||||||
|
line.chars()
|
||||||
|
.map(|c| match c {
|
||||||
|
'#' => MapNode::Wall,
|
||||||
|
'.' | 'A' | 'B' => {
|
||||||
|
let id = graph.nodes.insert(Node::new());
|
||||||
|
|
||||||
|
if c == 'A' {
|
||||||
|
graph.start = id;
|
||||||
|
}
|
||||||
|
if c == 'B' {
|
||||||
|
graph.end = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
MapNode::Floor(id)
|
||||||
|
}
|
||||||
|
c => MapNode::Unknown(c),
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
})
|
||||||
|
.collect::<Vec<Vec<Vec<MapNode>>>>();
|
||||||
|
|
||||||
|
// connect nodes
|
||||||
|
for (z, map) in maps.iter().enumerate() {
|
||||||
|
print!("\n");
|
||||||
|
for (y, row) in map.iter().enumerate() {
|
||||||
|
print!("\n");
|
||||||
|
for (x, map_node) in row.iter().enumerate() {
|
||||||
|
match map_node {
|
||||||
|
MapNode::Wall => print!("--- "),
|
||||||
|
MapNode::Floor(id) => {
|
||||||
|
let node = graph.nodes.get_mut(id.to_owned()).unwrap();
|
||||||
|
|
||||||
|
print!("{:03} ", id);
|
||||||
|
|
||||||
|
if let MapNode::Floor(i) = row[x - 1] {
|
||||||
|
node.edges.insert(Edge::new(i, 1));
|
||||||
|
}
|
||||||
|
if let MapNode::Floor(i) = row[x + 1] {
|
||||||
|
node.edges.insert(Edge::new(i, 1));
|
||||||
|
}
|
||||||
|
if let MapNode::Floor(i) = maps[z][y - 1][x] {
|
||||||
|
node.edges.insert(Edge::new(i, 1));
|
||||||
|
}
|
||||||
|
if let MapNode::Floor(i) = maps[z][y + 1][x] {
|
||||||
|
node.edges.insert(Edge::new(i, 1));
|
||||||
|
}
|
||||||
|
if let MapNode::Floor(i) = maps[(z + 1) % 2][y][x] {
|
||||||
|
node.edges.insert(Edge::new(i, 3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MapNode::Unknown(c) => {
|
||||||
|
return Err(Error::msg(format!("Unknown character: '{c}'")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print!("\n");
|
||||||
|
|
||||||
|
Ok(graph)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn dijkstra(&self) -> Result<Vec<usize>> {
|
||||||
|
let mut visited = Vec::new();
|
||||||
|
let mut distances = vec![DijkstraNode::new(); self.nodes.len()];
|
||||||
|
let mut queue = Vec::new();
|
||||||
|
|
||||||
|
queue.push(self.start);
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let id = queue.pop().unwrap();
|
||||||
|
// println!("{id}");
|
||||||
|
if id == self.end {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
let node = self.nodes.get(id).unwrap();
|
||||||
|
visited.push(id);
|
||||||
|
|
||||||
|
for (_, edge) in node.edges.iter() {
|
||||||
|
if visited.contains(&edge.node) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if distances[edge.node].distance == 0
|
||||||
|
|| distances[id].distance + edge.gravity < distances[edge.node].distance
|
||||||
|
{
|
||||||
|
if distances[edge.node].distance == 0 {
|
||||||
|
queue.push(edge.node);
|
||||||
|
}
|
||||||
|
|
||||||
|
distances[edge.node].parent = id;
|
||||||
|
distances[edge.node].distance = distances[id].distance + edge.gravity;
|
||||||
|
|
||||||
|
// println!(" {}: {}", edge.node, distances[edge.node].distance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.sort_unstable_by(|a, b| {
|
||||||
|
distances[b.to_owned()]
|
||||||
|
.distance
|
||||||
|
.cmp(&distances[a.to_owned()].distance)
|
||||||
|
});
|
||||||
|
// println!(
|
||||||
|
// " {:?}",
|
||||||
|
// queue
|
||||||
|
// .iter()
|
||||||
|
// .map(|id| (id, distances[id.to_owned()].distance))
|
||||||
|
// .collect::<Vec<(&usize, usize)>>()
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut id = self.end;
|
||||||
|
let mut path = Vec::new();
|
||||||
|
|
||||||
|
while id != self.start {
|
||||||
|
path.push(id);
|
||||||
|
id = distances[id].parent;
|
||||||
|
}
|
||||||
|
path.push(self.start);
|
||||||
|
path.reverse();
|
||||||
|
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,27 @@
|
||||||
fn main() {
|
mod graph;
|
||||||
println!("Hello, world!");
|
|
||||||
|
use anyhow::Result;
|
||||||
|
use clap::Parser;
|
||||||
|
use graph::Graph;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
/// BWINF 42.1
|
||||||
|
/// <Name Censored>
|
||||||
|
/// Aufgabe 3: Zauberschule
|
||||||
|
#[derive(Parser, Debug)]
|
||||||
|
#[command(author, version, about, long_about = None)]
|
||||||
|
struct Args {
|
||||||
|
/// The file containing the two maps
|
||||||
|
file: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
println!("BWINF 42.1 - <Name Censored> - Aufgabe 3: Zauberschule");
|
||||||
|
let args = Args::parse();
|
||||||
|
|
||||||
|
let graph = Graph::new(Path::new(&args.file))?;
|
||||||
|
let path = graph.dijkstra()?;
|
||||||
|
println!("Path: {:?}", path);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue