refactor 81 and dijkstra
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
use dijkstra::{Matrix as MatrixTrait, Node as NodeTrait};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
type Coordinate = (usize, usize);
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Matrix {
|
||||
data: Vec<Vec<Node>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Node {
|
||||
value: usize,
|
||||
distance: Option<usize>,
|
||||
previous: Option<Coordinate>,
|
||||
}
|
||||
|
||||
impl NodeTrait<usize> for Node {
|
||||
fn get_value(&self) -> &usize {
|
||||
&self.value
|
||||
}
|
||||
|
||||
fn get_distance(&self) -> Option<&usize> {
|
||||
self.distance.as_ref()
|
||||
}
|
||||
|
||||
fn get_previous(&self) -> Option<Coordinate> {
|
||||
self.previous
|
||||
}
|
||||
|
||||
fn set_distance(&mut self, distance: usize) {
|
||||
self.distance = Some(distance);
|
||||
}
|
||||
|
||||
fn set_previous(&mut self, coord: Coordinate) {
|
||||
self.previous = Some(coord)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Node {
|
||||
fn from(value: usize) -> Self {
|
||||
Self {
|
||||
value,
|
||||
distance: None,
|
||||
previous: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MatrixTrait<usize> for Matrix {
|
||||
fn height(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
self.data[0].len()
|
||||
}
|
||||
|
||||
fn get(&self, (x, y): Coordinate) -> Option<&dyn NodeTrait<usize>> {
|
||||
if x < self.width() && y < self.height() {
|
||||
Some(&self.data[y][x])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, (x, y): Coordinate) -> Option<&mut dyn NodeTrait<usize>> {
|
||||
if x < self.width() && y < self.height() {
|
||||
Some(self.data.get_mut(y).unwrap().get_mut(x).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Matrix {
|
||||
pub fn load(f: &Path) -> Self {
|
||||
let mut data: Vec<Vec<_>> = fs::read_to_string(f)
|
||||
.unwrap()
|
||||
.split_whitespace()
|
||||
.map(|line| {
|
||||
line.split(',')
|
||||
.into_iter()
|
||||
.map(|number| number.parse::<usize>().unwrap())
|
||||
.map(Node::from)
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
let mut start = &mut data[0][0];
|
||||
start.distance = Some(start.value);
|
||||
Self { data }
|
||||
}
|
||||
}
|
||||
+3
-96
@@ -1,6 +1,6 @@
|
||||
use dijkstra::Dijkstra;
|
||||
use dijkstra::Matrix as MatrixTrait;
|
||||
use std::fs;
|
||||
use dijkstra::{AllowedMovements, Dijkstra};
|
||||
use euler81::Matrix;
|
||||
use std::path::Path;
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
@@ -15,102 +15,9 @@ const FILENAME: &str = "p081_test.txt";
|
||||
#[cfg(not(debug_assertions))]
|
||||
const FILENAME: &str = "p081_matrix.txt";
|
||||
|
||||
type Coordinate = (usize, usize);
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Matrix {
|
||||
data: Vec<Vec<Node>>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Node {
|
||||
value: usize,
|
||||
distance: Option<usize>,
|
||||
previous: Option<Coordinate>,
|
||||
}
|
||||
|
||||
impl dijkstra::Node<usize> for Node {
|
||||
fn get_value(&self) -> &usize {
|
||||
&self.value
|
||||
}
|
||||
|
||||
fn get_distance(&self) -> Option<&usize> {
|
||||
self.distance.as_ref()
|
||||
}
|
||||
|
||||
fn get_previous(&self) -> Option<Coordinate> {
|
||||
self.previous
|
||||
}
|
||||
|
||||
fn set_distance(&mut self, distance: usize) {
|
||||
self.distance = Some(distance);
|
||||
}
|
||||
|
||||
fn set_previous(&mut self, coord: Coordinate) {
|
||||
self.previous = Some(coord)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Node {
|
||||
fn from(value: usize) -> Self {
|
||||
Self {
|
||||
value,
|
||||
distance: None,
|
||||
previous: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MatrixTrait<usize> for Matrix {
|
||||
fn height(&self) -> usize {
|
||||
self.data.len()
|
||||
}
|
||||
|
||||
fn width(&self) -> usize {
|
||||
self.data[0].len()
|
||||
}
|
||||
|
||||
fn get(&self, (x, y): Coordinate) -> Option<&dyn dijkstra::Node<usize>> {
|
||||
if x < self.width() && y < self.height() {
|
||||
Some(&self.data[y][x])
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mut(&mut self, (x, y): Coordinate) -> Option<&mut dyn dijkstra::Node<usize>> {
|
||||
if x < self.width() && y < self.height() {
|
||||
Some(self.data.get_mut(y).unwrap().get_mut(x).unwrap())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Matrix {
|
||||
fn load(f: &Path) -> Self {
|
||||
let mut data: Vec<Vec<_>> = fs::read_to_string(f)
|
||||
.unwrap()
|
||||
.split_whitespace()
|
||||
.map(|line| {
|
||||
line.split(',')
|
||||
.into_iter()
|
||||
.map(|number| number.parse::<usize>().unwrap())
|
||||
.map(Node::from)
|
||||
.collect()
|
||||
})
|
||||
.collect();
|
||||
let mut start = &mut data[0][0];
|
||||
start.distance = Some(start.value);
|
||||
assert_eq!(data.len(), LENGTH);
|
||||
assert!(data.iter().all(|subvec| subvec.len() == LENGTH));
|
||||
Self { data }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut matrix = Matrix::load(Path::new(FILENAME));
|
||||
let mut dijkstra = Dijkstra::new(&mut matrix);
|
||||
let mut dijkstra = Dijkstra::new(&mut matrix, AllowedMovements::DownRight);
|
||||
dijkstra.solve();
|
||||
let result = matrix
|
||||
.get((LENGTH - 1, LENGTH - 1))
|
||||
|
||||
Reference in New Issue
Block a user