add more code for 81 (WIP)
This commit is contained in:
+43
-69
@@ -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
|
#[derive(PartialEq, Eq, Hash)]
|
||||||
|
struct Node {
|
||||||
|
is_infinity: bool,
|
||||||
|
value: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate2(length: usize, mut vec: Vec<Direction>) -> Vec<Vec<Direction>> {
|
impl From<u32> for Node {
|
||||||
let orig = vec.clone();
|
fn from(value: u32) -> Self {
|
||||||
let mut result = vec![vec.clone()];
|
Node {
|
||||||
for i in 1..=length {
|
is_infinity: true,
|
||||||
// vec.remove
|
value,
|
||||||
todo!()
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Node> for Rc<RefCell<Node>> {
|
||||||
|
fn from(node: Node) -> Self {
|
||||||
|
Rc::new(RefCell::new(node))
|
||||||
}
|
}
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user