Add cyclic optimization
This commit is contained in:
parent
e6cceca88c
commit
be3697a749
6 changed files with 144 additions and 82 deletions
|
|
@ -1,10 +1,8 @@
|
|||
use stamp_folding::stamp_folding;
|
||||
|
||||
fn main() {
|
||||
for length in 2.. {
|
||||
let mut count = 0;
|
||||
let mut state = vec![0, 1];
|
||||
stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {});
|
||||
stamp_folding::cyclic::stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {});
|
||||
println!("{length:02}: {count} {}", count * 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,6 @@
|
|||
use stamp_folding::stamp_folding;
|
||||
|
||||
fn main() {
|
||||
let length = 4;
|
||||
let length = 21;
|
||||
let mut count = 0;
|
||||
let mut state = vec![0, 1];
|
||||
stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {});
|
||||
stamp_folding::cyclic::stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use image::{GenericImage, GrayImage};
|
||||
use stamp_folding::{
|
||||
image::{draw_image, image_dimensions},
|
||||
stamp_folding,
|
||||
naive::stamp_folding,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
|
|
@ -11,7 +11,6 @@ fn main() {
|
|||
stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {});
|
||||
|
||||
let (width, height) = image_dimensions(length as usize);
|
||||
dbg!(width, height);
|
||||
let columns = count.isqrt() as u32;
|
||||
|
||||
let mut image = GrayImage::new(
|
||||
|
|
|
|||
72
src/cyclic.rs
Normal file
72
src/cyclic.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
pub fn stamp_folding(
|
||||
current: &mut Vec<u8>,
|
||||
last_inserted_index: usize,
|
||||
remaining: u8,
|
||||
count: &mut u128,
|
||||
callback: &mut impl FnMut(u128, &[u8]),
|
||||
) {
|
||||
let depth = current.len() as u8;
|
||||
// dbg!(¤t, depth, last_inserted_index);
|
||||
if remaining == 0 {
|
||||
callback(*count, current);
|
||||
*count = count.checked_add(1).unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
let last_inserted_value = current[last_inserted_index];
|
||||
|
||||
let mut last = None;
|
||||
for i in (0..last_inserted_index).rev() {
|
||||
// dbg!(&last, ¤t, i);
|
||||
if let Some(l) = last {
|
||||
let next = if l % 2 == last_inserted_value % 2 {
|
||||
l + 1
|
||||
} else {
|
||||
l - 1
|
||||
};
|
||||
if current[i] == next {
|
||||
last = None;
|
||||
}
|
||||
} else {
|
||||
current.insert(i + 1, depth);
|
||||
stamp_folding(current, i + 1, remaining - 1, count, callback);
|
||||
current.remove(i + 1);
|
||||
if current[i] != 0 || last_inserted_value % 2 == 0 {
|
||||
last = Some(current[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if last.is_none() {
|
||||
current.insert(0, depth);
|
||||
stamp_folding(current, 0, remaining - 1, count, callback);
|
||||
current.remove(0);
|
||||
}
|
||||
|
||||
let mut last = None;
|
||||
for i in (last_inserted_index + 1)..current.len() {
|
||||
if let Some(l) = last {
|
||||
let next = if l % 2 == last_inserted_value % 2 {
|
||||
l + 1
|
||||
} else {
|
||||
l - 1
|
||||
};
|
||||
if current[i] == next {
|
||||
last = None;
|
||||
}
|
||||
} else {
|
||||
current.insert(i, depth);
|
||||
stamp_folding(current, i, remaining - 1, count, callback);
|
||||
current.remove(i);
|
||||
if current[i] != 0 || last_inserted_value % 2 == 0 {
|
||||
last = Some(current[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if last.is_none() {
|
||||
current.push(depth);
|
||||
stamp_folding(current, current.len() - 1, remaining - 1, count, callback);
|
||||
current.pop();
|
||||
}
|
||||
}
|
||||
75
src/lib.rs
75
src/lib.rs
|
|
@ -1,74 +1,3 @@
|
|||
pub mod cyclic;
|
||||
pub mod image;
|
||||
|
||||
pub fn stamp_folding(
|
||||
current: &mut Vec<u8>,
|
||||
last_inserted_index: usize,
|
||||
remaining: u8,
|
||||
count: &mut u128,
|
||||
callback: &mut impl FnMut(u128, &[u8]),
|
||||
) {
|
||||
let depth = current.len() as u8;
|
||||
// dbg!(¤t, depth, last_inserted_index);
|
||||
if remaining == 0 {
|
||||
callback(*count, current);
|
||||
*count = count.checked_add(1).unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
let last_inserted_value = current[last_inserted_index];
|
||||
|
||||
let mut last = None;
|
||||
for i in (0..last_inserted_index).rev() {
|
||||
// dbg!(&last, ¤t, i);
|
||||
if let Some(l) = last {
|
||||
let next = if l % 2 == last_inserted_value % 2 {
|
||||
l + 1
|
||||
} else {
|
||||
l - 1
|
||||
};
|
||||
if current[i] == next {
|
||||
last = None;
|
||||
}
|
||||
} else {
|
||||
current.insert(i + 1, depth);
|
||||
stamp_folding(current, i + 1, remaining - 1, count, callback);
|
||||
current.remove(i + 1);
|
||||
if current[i] != 0 || last_inserted_value % 2 == 0 {
|
||||
last = Some(current[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if last.is_none() {
|
||||
current.insert(0, depth);
|
||||
stamp_folding(current, 0, remaining - 1, count, callback);
|
||||
current.remove(0);
|
||||
}
|
||||
|
||||
let mut last = None;
|
||||
for i in (last_inserted_index + 1)..current.len() {
|
||||
if let Some(l) = last {
|
||||
let next = if l % 2 == last_inserted_value % 2 {
|
||||
l + 1
|
||||
} else {
|
||||
l - 1
|
||||
};
|
||||
if current[i] == next {
|
||||
last = None;
|
||||
}
|
||||
} else {
|
||||
current.insert(i, depth);
|
||||
stamp_folding(current, i, remaining - 1, count, callback);
|
||||
current.remove(i);
|
||||
if current[i] != 0 || last_inserted_value % 2 == 0 {
|
||||
last = Some(current[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if last.is_none() {
|
||||
current.push(depth);
|
||||
stamp_folding(current, current.len() - 1, remaining - 1, count, callback);
|
||||
current.pop();
|
||||
}
|
||||
}
|
||||
pub mod naive;
|
||||
|
|
|
|||
66
src/naive.rs
Normal file
66
src/naive.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
pub fn stamp_folding(
|
||||
current: &mut Vec<u8>,
|
||||
last_inserted_index: usize,
|
||||
remaining: u8,
|
||||
count: &mut u128,
|
||||
callback: &mut impl FnMut(u128, &[u8]),
|
||||
) {
|
||||
let depth = current.len() as u8;
|
||||
// dbg!(¤t, depth, last_inserted_index);
|
||||
if remaining == 0 {
|
||||
callback(*count, current);
|
||||
*count = count.checked_add(depth as u128).unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
let last_inserted_value = current[last_inserted_index];
|
||||
|
||||
let mut last = None;
|
||||
for i in (0..last_inserted_index).rev() {
|
||||
// dbg!(&last, ¤t, i);
|
||||
if let Some(l) = last {
|
||||
let next = if l % 2 == last_inserted_value % 2 {
|
||||
l + 1
|
||||
} else {
|
||||
l - 1
|
||||
};
|
||||
if current[i] == next {
|
||||
last = None;
|
||||
}
|
||||
} else {
|
||||
current.insert(i + 1, depth);
|
||||
stamp_folding(current, i + 1, remaining - 1, count, callback);
|
||||
current.remove(i + 1);
|
||||
if current[i] != 0 || last_inserted_value % 2 == 0 {
|
||||
last = Some(current[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut last = None;
|
||||
for i in (last_inserted_index + 1)..current.len() {
|
||||
if let Some(l) = last {
|
||||
let next = if l % 2 == last_inserted_value % 2 {
|
||||
l + 1
|
||||
} else {
|
||||
l - 1
|
||||
};
|
||||
if current[i] == next {
|
||||
last = None;
|
||||
}
|
||||
} else {
|
||||
current.insert(i, depth);
|
||||
stamp_folding(current, i, remaining - 1, count, callback);
|
||||
current.remove(i);
|
||||
if current[i] != 0 || last_inserted_value % 2 == 0 {
|
||||
last = Some(current[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if last.is_none() {
|
||||
current.push(depth);
|
||||
stamp_folding(current, current.len() - 1, remaining - 1, count, callback);
|
||||
current.pop();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue