add more code for 81 (WIP)

This commit is contained in:
Dr. Matthias Ratajczak
2022-09-22 16:08:18 +02:00
parent 972294470c
commit 6944016d73
+45 -71
View File
@@ -1,108 +1,82 @@
use std::cell::RefCell;
use std::collections::HashSet;
use std::fs; use std::fs;
use std::iter::Cycle;
use std::path::Path; use std::path::Path;
use std::rc::Rc;
const LENGTH: usize = 80; const LENGTH: usize = 80;
struct Matrix { type Coordinate = (usize, usize);
data: Vec<Vec<u32>>,
}
#[derive(Clone, Eq, PartialEq, Hash)] struct Matrix {
enum Direction { data: Vec<Vec<Node>>,
Down,
Right,
} }
impl Matrix { impl Matrix {
fn load(f: &Path) -> Self { fn load(f: &Path) -> Self {
let data: Vec<Vec<u32>> = fs::read_to_string(f) let mut data: Vec<Vec<_>> = fs::read_to_string(f)
.unwrap() .unwrap()
.split_whitespace() .split_whitespace()
.map(|line| { .map(|line| {
line.split(',') line.split(',')
.into_iter() .into_iter()
.map(|number| number.parse::<u32>().unwrap()) .map(|number| number.parse::<u32>().unwrap())
.map(Node::from)
.collect() .collect()
}) })
.collect(); .collect();
data[0][0].is_infinity = false;
assert_eq!(data.len(), LENGTH); assert_eq!(data.len(), LENGTH);
assert!(data.iter().all(|subvec| subvec.len() == LENGTH)); assert!(data.iter().all(|subvec| subvec.len() == LENGTH));
Self { data } Self { data }
} }
fn calculate_sum_along_route(&self, route: &[Direction]) -> u32 {
assert_eq!(route.len() / 2, LENGTH - 1);
let mut i = 0;
let mut j = 0;
let mut sum = self.data[i][j];
for step in route {
match step {
Direction::Down => {
i += 1;
}
Direction::Right => {
j += 1;
}
}
sum += self.data[i][j];
}
sum
}
} }
fn main() { fn main() {
let matrix = Matrix::load(Path::new("p081_matrix.txt")); let matrix = Matrix::load(Path::new("p081_matrix.txt"));
let permutations = calculate_permutations(LENGTH - 1); let dijkstra = Dijkstra::new(matrix);
assert_eq!(permutations.len(), (LENGTH - 1).pow(2));
let mut sums = vec![];
for route in permutations.into_iter() {
let sum = matrix.calculate_sum_along_route(&route);
sums.push(sum);
}
sums.sort_unstable();
println!("{}", sums.last().unwrap());
} }
fn calculate_permutations(length: usize) -> Vec<Vec<Direction>> { struct Dijkstra {
let mut base = vec![Direction::Down; length]; initial: Coordinate,
base.append(&mut vec![Direction::Right; length]); matrix: Matrix,
generate2(length, base) unvisited: Vec<Coordinate>,
} }
/// https://en.wikipedia.org/wiki/Heap%27s_algorithm impl Dijkstra {
/// produces OOM, or is otherwise too slow fn new(matrix: Matrix) -> Self {
fn generate(length: usize, mut vec: Vec<Direction>) -> Vec<Vec<Direction>> { let initial = (0, 0);
let mut result = vec![vec.clone()]; let unvisited: Vec<_> = (0..LENGTH)
let mut c = vec![0; length]; .flat_map(|x| (0..LENGTH).zip([x].into_iter().cycle()))
.filter(|value| *value != (0, 0))
let mut i = 1; .collect();
while i < length { assert_eq!(unvisited.len(), LENGTH * LENGTH - 1);
if c[i] < i { Self {
if i % 2 == 0 { initial,
vec.swap(0, i); matrix,
} else { unvisited,
vec.swap(c[i], i)
}
result.push(vec.clone());
c[i] += 1;
i = 1;
} else {
c[i] = 0;
i += 1;
} }
} }
result
} }
fn generate2(length: usize, mut vec: Vec<Direction>) -> Vec<Vec<Direction>> { #[derive(PartialEq, Eq, Hash)]
let orig = vec.clone(); struct Node {
let mut result = vec![vec.clone()]; is_infinity: bool,
for i in 1..=length { value: u32,
// vec.remove }
todo!()
impl From<u32> for Node {
fn from(value: u32) -> Self {
Node {
is_infinity: true,
value,
} }
result }
}
impl From<Node> for Rc<RefCell<Node>> {
fn from(node: Node) -> Self {
Rc::new(RefCell::new(node))
}
} }