add more code for 31 (WIP)

should work, but does not :(
This commit is contained in:
Dr. Matthias Ratajczak
2022-08-17 19:41:29 +02:00
parent c82db83ef9
commit 74ceec4f3d
+81 -130
View File
@@ -1,163 +1,114 @@
#![allow(dead_code)] #![allow(dead_code)]
use std::ops::Index; use std::{cmp::Reverse, collections::HashSet};
const VALUE: u8 = 200; const VALUE: u8 = 200;
type Values = Vec<u8>; type Values = Vec<u8>;
fn main() { fn main() {
// let head = Tree::new(200); let x = vec![VALUE];
let mut cases = HashSet::new();
cases.insert(x.clone());
solve(x, &mut cases, -1);
let mut cases_ordered: Vec<_> = cases.iter().collect();
cases_ordered.sort_unstable_by_key(|v| v.len());
for case in cases_ordered {
println!("{}", case.show());
}
println!("{}", cases.len());
} }
#[derive(Debug, PartialEq)] fn solve(x: Values, cases: &mut HashSet<Values>, max_depth: isize) {
struct Node { // println!("solving {}", x.show());
values: Values, if max_depth == 0 {
nodes: Vec<Node>, return;
} }
for (i, val) in x.iter().enumerate() {
impl Node { for variant in divide(*val) {
fn new(value: u8) -> Self { let mut copy = x.clone();
Self { copy.splice(i..i + 1, variant);
values: vec![value], debug_assert_eq!(copy.iter().sum::<u8>(), VALUE);
nodes: vec![], // copy.sort_unstable();
} // copy.sort_unstable_by_key(|&i| Reverse(i));
} // println!("{}", copy.show());
let mut sorted = copy.clone();
fn new_vec(values: Values) -> Self { sorted.sort_unstable();
Self { if cases.contains(&sorted) {
values, // eprintln!("already seen: {}", copy.show());
nodes: vec![], continue;
}
}
fn get_value(&self, index: usize) -> Option<&u8> {
self.values.get(index)
}
fn iter(&mut self) {
if !self.nodes.is_empty() {
self.nodes.iter_mut().for_each(|n| n.iter())
} else { } else {
let mut previous: Option<Vec<Values>> = None; cases.insert(sorted);
let mut offset = 0; solve(copy, cases, max_depth - 1)
for (i, value) in self.values.iter().enumerate() {
let divided = divide_value(*value);
let use_existing_data = previous.is_none();
println!();
println!();
println!();
for (j, combination) in divided.iter().enumerate() {
let mut new_vec;
let offset;
if use_existing_data {
println!("existing");
new_vec = self.values.clone();
offset = 0;
} else {
println!("previous");
new_vec = previous.as_ref().unwrap()[j].clone();
offset = new_vec.len() - self.values.len();
}
println!();
println!("{}", i + offset);
println!("{new_vec:#?}");
println!("{combination:#?}");
new_vec.splice(i + offset..i + offset + 1, combination.clone());
println!("{new_vec:#?}");
if previous.is_none() {
previous = Some(vec![new_vec.clone()]);
} else {
let mut new = previous.unwrap().clone();
new.push(new_vec.clone());
previous = Some(new);
}
debug_assert_eq!(new_vec.iter().sum::<u8>(), VALUE);
self.nodes.push(Node::new_vec(new_vec));
}
} }
} }
} }
} }
fn divide_value(x: u8) -> Vec<Values> { trait Display {
fn show(&self) -> String;
}
impl Display for Values {
fn show(&self) -> String {
self.iter()
.map(|i| i.to_string())
.reduce(|mut accum, elem| {
accum.push_str(", ");
accum.push_str(&elem);
accum
})
.unwrap()
}
}
fn divide(x: u8) -> Vec<Values> {
if x == 200 { if x == 200 {
vec![vec![100, 100]] vec![vec![100, 100]]
} else if x == 100 { } else if x == 100 {
vec![vec![50, 50]] vec![vec![50, 50]]
} else { } else if x == 50 {
// x == 50
vec![vec![20, 20, 10], vec![20, 10, 10, 10], vec![10; 5]] vec![vec![20, 20, 10], vec![20, 10, 10, 10], vec![10; 5]]
} } else if x == 20 {
} vec![vec![10, 10]]
} else if x == 10 {
impl Index<usize> for Node { vec![vec![5, 5]]
type Output = Node; } else if x == 5 {
vec![vec![2, 2, 1], vec![2, 1, 1, 1], vec![1; 5]]
fn index(&self, index: usize) -> &Self::Output { } else if x == 2 {
&self.nodes[index] vec![vec![1, 1]]
} else {
vec![vec![x]]
} }
} }
#[cfg(test)] #[cfg(test)]
mod test { mod test {
// use crate::Node; use crate::solve;
use crate::Node; use std::collections::HashSet;
use crate::VALUE;
#[test] #[test]
fn test_new() { fn test_1() {
let tree = Node::new(200); let x = vec![VALUE];
assert_eq!(tree.values, [200]); let mut hs = HashSet::new();
assert_eq!(tree.nodes.len(), 0); hs.insert(x.clone());
solve(x, &mut hs, 1);
assert_eq!(hs.len(), 2);
assert!(hs.contains(&vec![VALUE]));
assert!(hs.contains(&vec![100, 100]));
} }
#[test] #[test]
fn test_iter() { fn test_2() {
let mut tree = Node::new(200); let x = vec![VALUE];
tree.iter(); let mut hs = HashSet::new();
assert_eq!(tree.nodes.len(), 1); hs.insert(x.clone());
assert_eq!(tree.nodes[0].values, vec![100, 100]); solve(x, &mut hs, 3);
} assert_eq!(hs.len(), 4);
assert!(hs.contains(&vec![VALUE]));
#[test] assert!(hs.contains(&vec![100, 100]));
fn test_iter_2() { assert!(hs.contains(&vec![100, 50, 50]));
let mut tree = Node::new(200); assert!(hs.contains(&vec![50, 50, 50, 50]));
tree.iter();
tree.iter();
assert_eq!(tree.nodes[0][0].values, vec![50, 50, 100]);
assert_eq!(tree.nodes[0][1].values, vec![50; 4]);
assert!(tree.nodes[0].get_value(2).is_none());
}
#[test]
fn test_iter_3() {
let mut tree = Node::new(200);
tree.iter();
tree.iter();
tree.iter();
assert_eq!(tree.nodes[0][0][0].values, vec![20, 20, 10, 50, 100]);
assert_eq!(tree.nodes[0][0][1].values, vec![20, 10, 10, 10, 50, 100]);
assert_eq!(
tree.nodes[0][0][2].values,
vec![10, 10, 10, 10, 10, 50, 100]
);
assert_eq!(
tree.nodes[0][0][3].values,
vec![20, 20, 10, 20, 20, 10, 100]
);
assert_eq!(
tree.nodes[0][0][4].values,
vec![20, 10, 10, 10, 20, 10, 10, 10, 100]
);
assert_eq!(
tree.nodes[0][0][5].values,
vec![10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 100]
);
assert_eq!(
tree.nodes[0][0][6].values,
vec![10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 50, 50]
);
println!("{}", tree.nodes[0][0].nodes.len())
} }
} }