Performance improvements and fix warnings
This commit is contained in:
parent
68d0f64058
commit
b5dcbccf02
6 changed files with 202 additions and 55 deletions
|
|
@ -1,34 +1,63 @@
|
||||||
use factorio_blueprint::{
|
use std::io;
|
||||||
belt_finding::{
|
|
||||||
brute_force::{Bruteforce, BruteforceBuilder, PathField},
|
use clap::{Parser, ValueEnum};
|
||||||
Direction, Position,
|
use factorio_blueprint::belt_finding::brute_force::{problems, Bruteforce};
|
||||||
},
|
|
||||||
misc::Map,
|
#[derive(ValueEnum, Clone)]
|
||||||
};
|
enum Mode {
|
||||||
|
Solutions,
|
||||||
|
Step,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(ValueEnum, Clone)]
|
||||||
|
enum Problem {
|
||||||
|
Simple,
|
||||||
|
Snake,
|
||||||
|
Weaving,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Problem {
|
||||||
|
fn get_problem(&self) -> Bruteforce {
|
||||||
|
match self {
|
||||||
|
Problem::Simple => problems::simple(),
|
||||||
|
Problem::Snake => problems::snake(),
|
||||||
|
Problem::Weaving => problems::weaving(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
struct Args {
|
||||||
|
#[arg(value_enum, default_value = "simple")]
|
||||||
|
problem: Problem,
|
||||||
|
#[arg(value_enum, default_value = "solutions")]
|
||||||
|
mode: Mode,
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut b = BruteforceBuilder::new(6, 8);
|
let args = Args::parse();
|
||||||
|
|
||||||
b.add_path(
|
let mut b = args.problem.get_problem();
|
||||||
(Position::new(1, 0), Direction::Down),
|
|
||||||
(Position::new(0, 0), Direction::Up),
|
|
||||||
);
|
|
||||||
|
|
||||||
b.add_path(
|
println!("{b}");
|
||||||
(Position::new(4, 0), Direction::Down),
|
|
||||||
(Position::new(1, 7), Direction::Up),
|
|
||||||
);
|
|
||||||
|
|
||||||
b.set_blocked_range(0, 2, 5, 5, true);
|
|
||||||
// b.set_blocked_range(2, 0, 2, 2, true);
|
|
||||||
|
|
||||||
let mut b = b.build();
|
|
||||||
|
|
||||||
|
match args.mode {
|
||||||
|
Mode::Solutions => {
|
||||||
while b.next_finish_state() {
|
while b.next_finish_state() {
|
||||||
println!("{}\n{}\n{}", b.count(), b.solution_count(), b);
|
println!("{}\n{}\n{}", b.count(), b.solution_count(), b);
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("{}\n{}", b.count(), b.solution_count());
|
println!("{}\n{}", b.count(), b.solution_count());
|
||||||
|
}
|
||||||
|
Mode::Step => {
|
||||||
|
while b.next_state() {
|
||||||
|
println!("{}", b);
|
||||||
|
let mut s = String::new();
|
||||||
|
let _ = io::stdin().read_line(&mut s);
|
||||||
|
}
|
||||||
|
println!("{}\n{}", b.count(), b.solution_count());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// println!(
|
// println!(
|
||||||
// "{}\n{}\n{}\n{}",
|
// "{}\n{}\n{}\n{}",
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,16 @@ pub enum PathField {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathField {
|
impl PathField {
|
||||||
fn pos(&self) -> &Position {
|
// fn pos(&self) -> &Position {
|
||||||
match self {
|
// match self {
|
||||||
PathField::Belt { pos, dir: _ } => pos,
|
// PathField::Belt { pos, dir: _ } => pos,
|
||||||
PathField::Underground {
|
// PathField::Underground {
|
||||||
pos,
|
// pos,
|
||||||
dir: _,
|
// dir: _,
|
||||||
len: _,
|
// len: _,
|
||||||
} => pos,
|
// } => pos,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn dir(&self) -> &Direction {
|
fn dir(&self) -> &Direction {
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -408,7 +408,11 @@ impl Bruteforce {
|
||||||
pos,
|
pos,
|
||||||
dir: second_last.dir().clockwise(),
|
dir: second_last.dir().clockwise(),
|
||||||
});
|
});
|
||||||
|
if self.is_next_free(&pos, &second_last.dir().clockwise()) {
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
return self.modify_remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if second_last.dir().clockwise() == dir {
|
if second_last.dir().clockwise() == dir {
|
||||||
|
|
@ -416,7 +420,11 @@ impl Bruteforce {
|
||||||
pos,
|
pos,
|
||||||
dir: second_last.dir().counter_clockwise(),
|
dir: second_last.dir().counter_clockwise(),
|
||||||
});
|
});
|
||||||
|
if self.is_next_free(&pos, &second_last.dir().counter_clockwise()) {
|
||||||
return true;
|
return true;
|
||||||
|
} else {
|
||||||
|
return self.modify_remove();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if second_last.dir().counter_clockwise() == dir
|
if second_last.dir().counter_clockwise() == dir
|
||||||
|
|
@ -452,6 +460,13 @@ impl Bruteforce {
|
||||||
// &mut self.problems[i].path
|
// &mut self.problems[i].path
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
fn is_next_free(&self, pos: &Position, dir: &Direction) -> bool {
|
||||||
|
let i = self.modify_pointer();
|
||||||
|
self.pos_in_direction(pos, dir, 1)
|
||||||
|
.filter(|p| !self.map.get(p.x, p.y).blocked || self.problems[i].end_pos == *p)
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
// Add an Path elemeent
|
// Add an Path elemeent
|
||||||
fn add(&mut self) -> bool {
|
fn add(&mut self) -> bool {
|
||||||
let (pos, dir) = self.path_field_end(self.add_path().last().unwrap());
|
let (pos, dir) = self.path_field_end(self.add_path().last().unwrap());
|
||||||
|
|
@ -459,7 +474,7 @@ impl Bruteforce {
|
||||||
if let Some(p) = self.pos_in_direction(&pos, &dir, 1) {
|
if let Some(p) = self.pos_in_direction(&pos, &dir, 1) {
|
||||||
if !self.map.get(p.x, p.y).blocked {
|
if !self.map.get(p.x, p.y).blocked {
|
||||||
self.apply_path_field(PathField::Belt { pos: p, dir });
|
self.apply_path_field(PathField::Belt { pos: p, dir });
|
||||||
return true;
|
return self.is_next_free(&p, &dir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -599,3 +614,114 @@ impl Display for Bruteforce {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use super::problems;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn simple() {
|
||||||
|
let mut b = problems::simple();
|
||||||
|
|
||||||
|
while b.next_finish_state() {}
|
||||||
|
|
||||||
|
assert_eq!(b.solution_count(), 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn snake() {
|
||||||
|
let mut b = problems::snake();
|
||||||
|
|
||||||
|
while b.next_finish_state() {}
|
||||||
|
|
||||||
|
assert_eq!(b.solution_count(), 5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod problems {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
pub fn simple() -> Bruteforce {
|
||||||
|
let mut b = BruteforceBuilder::new(6, 8);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(1, 0), Direction::Down),
|
||||||
|
(Position::new(0, 0), Direction::Up),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(4, 0), Direction::Down),
|
||||||
|
(Position::new(1, 7), Direction::Up),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.set_blocked_range(0, 2, 5, 5, true);
|
||||||
|
|
||||||
|
b.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn snake() -> Bruteforce {
|
||||||
|
let mut p = BruteforceBuilder::new(14, 3);
|
||||||
|
|
||||||
|
p.add_path(
|
||||||
|
(Position::new(0, 0), Direction::Right),
|
||||||
|
(Position::new(13, 0), Direction::Right),
|
||||||
|
);
|
||||||
|
p.add_path(
|
||||||
|
(Position::new(0, 1), Direction::Right),
|
||||||
|
(Position::new(13, 1), Direction::Right),
|
||||||
|
);
|
||||||
|
p.add_path(
|
||||||
|
(Position::new(0, 2), Direction::Right),
|
||||||
|
(Position::new(13, 2), Direction::Right),
|
||||||
|
);
|
||||||
|
|
||||||
|
p.set_blocked_range(3, 2, 10, 2, true);
|
||||||
|
|
||||||
|
p.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn weaving() -> Bruteforce {
|
||||||
|
let mut b = BruteforceBuilder::new(14, 6);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(0, 0), Direction::Right),
|
||||||
|
(Position::new(13, 0), Direction::Right),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(0, 1), Direction::Right),
|
||||||
|
(Position::new(13, 1), Direction::Right),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(0, 2), Direction::Right),
|
||||||
|
(Position::new(13, 2), Direction::Right),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(0, 3), Direction::Right),
|
||||||
|
(Position::new(13, 3), Direction::Right),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(0, 4), Direction::Right),
|
||||||
|
(Position::new(13, 4), Direction::Right),
|
||||||
|
);
|
||||||
|
|
||||||
|
b.add_path(
|
||||||
|
(Position::new(0, 5), Direction::Right),
|
||||||
|
(Position::new(13, 5), Direction::Right),
|
||||||
|
);
|
||||||
|
|
||||||
|
// b.set_blocked_range(7, 2, 10, 2, true);
|
||||||
|
// b.set_blocked_range(7, 3, 10, 4, true);
|
||||||
|
|
||||||
|
b.set_blocked_range(3, 2, 10, 3, true);
|
||||||
|
b.set_blocked(2, 0, true);
|
||||||
|
b.set_blocked(11, 0, true);
|
||||||
|
b.set_blocked(2, 5, true);
|
||||||
|
b.set_blocked(11, 5, true);
|
||||||
|
|
||||||
|
b.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::belt_finding::brute_force::BruteforceBuilder;
|
use crate::belt_finding::brute_force::BruteforceBuilder;
|
||||||
use crate::graph::wheighted_graph::shortest_path::dijkstra;
|
use crate::graph::wheighted_graph::shortest_path::dijkstra;
|
||||||
use crate::graph::wheighted_graph::WheightedGraph;
|
use crate::graph::wheighted_graph::WheightedGraph;
|
||||||
|
use crate::misc::Map;
|
||||||
use crate::priority_queue::BinaryHeap;
|
use crate::priority_queue::BinaryHeap;
|
||||||
use crate::{misc::Map, priority_queue::PriorityQueue};
|
|
||||||
use colored::{Color, Colorize};
|
use colored::{Color, Colorize};
|
||||||
use std::fmt::{write, Display};
|
use std::fmt::Display;
|
||||||
use std::io::Write;
|
|
||||||
|
|
||||||
pub mod brute_force;
|
pub mod brute_force;
|
||||||
|
|
||||||
|
|
@ -42,9 +41,9 @@ impl Direction {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn horizontal(&self) -> bool {
|
// fn horizontal(&self) -> bool {
|
||||||
!self.vertical()
|
// !self.vertical()
|
||||||
}
|
// }
|
||||||
|
|
||||||
fn reverse(&self) -> Self {
|
fn reverse(&self) -> Self {
|
||||||
match self {
|
match self {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
pub mod adjacency_list;
|
pub mod adjacency_list;
|
||||||
pub mod shortest_path;
|
pub mod shortest_path;
|
||||||
|
|
||||||
use clap::builder::NonEmptyStringValueParser;
|
|
||||||
|
|
||||||
pub trait WheightedGraph: Sized {
|
pub trait WheightedGraph: Sized {
|
||||||
type Node;
|
type Node;
|
||||||
fn num_edges(&self, node: &Self::Node) -> usize;
|
fn num_edges(&self, node: &Self::Node) -> usize;
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,4 @@
|
||||||
use std::{
|
use std::{collections::HashMap, fmt::Debug, hash::Hash, hash::Hasher};
|
||||||
collections::{BinaryHeap, HashMap},
|
|
||||||
fmt::Debug,
|
|
||||||
hash::Hash,
|
|
||||||
hash::Hasher,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::priority_queue::PriorityQueue;
|
use crate::priority_queue::PriorityQueue;
|
||||||
|
|
||||||
|
|
@ -87,7 +82,7 @@ where
|
||||||
if score < n.score {
|
if score < n.score {
|
||||||
n.parent = o.node.clone();
|
n.parent = o.node.clone();
|
||||||
n.score = score;
|
n.score = score;
|
||||||
q.decrease_key(&h, |i| i.score = score);
|
q.decrease_key(h, |i| i.score = score);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn decrease_key(&mut self, handle: &Self::Handle, f: impl Fn(&mut T)) {
|
fn decrease_key(&mut self, _handle: &Self::Handle, _f: impl Fn(&mut T)) {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut prev = None;
|
let mut prev = None;
|
||||||
let mut start = None;
|
// let mut start = None;
|
||||||
|
|
||||||
for h in &mut self.update_rank {
|
for h in &mut self.update_rank {
|
||||||
if let Some(h) = h.take() {
|
if let Some(h) = h.take() {
|
||||||
|
|
@ -136,7 +136,7 @@ where
|
||||||
self.arena.get_mut(&p).right = h;
|
self.arena.get_mut(&p).right = h;
|
||||||
} else {
|
} else {
|
||||||
prev = Some(h);
|
prev = Some(h);
|
||||||
start = Some(h);
|
// start = Some(h);
|
||||||
}
|
}
|
||||||
if let Some(m) = self.min {
|
if let Some(m) = self.min {
|
||||||
if self.arena.get(&h).data < self.arena.get(&m).data {
|
if self.arena.get(&h).data < self.arena.get(&m).data {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue