Add cyclic optimization

This commit is contained in:
hal8174 2024-12-10 23:49:47 +01:00
parent e6cceca88c
commit be3697a749
6 changed files with 144 additions and 82 deletions

View file

@ -1,10 +1,8 @@
use stamp_folding::stamp_folding;
fn main() { fn main() {
for length in 2.. { for length in 2.. {
let mut count = 0; let mut count = 0;
let mut state = vec![0, 1]; 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); println!("{length:02}: {count} {}", count * 2);
} }
} }

View file

@ -1,8 +1,6 @@
use stamp_folding::stamp_folding;
fn main() { fn main() {
let length = 4; let length = 21;
let mut count = 0; let mut count = 0;
let mut state = vec![0, 1]; 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 |_, _| {});
} }

View file

@ -1,7 +1,7 @@
use image::{GenericImage, GrayImage}; use image::{GenericImage, GrayImage};
use stamp_folding::{ use stamp_folding::{
image::{draw_image, image_dimensions}, image::{draw_image, image_dimensions},
stamp_folding, naive::stamp_folding,
}; };
fn main() { fn main() {
@ -11,7 +11,6 @@ fn main() {
stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {}); stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {});
let (width, height) = image_dimensions(length as usize); let (width, height) = image_dimensions(length as usize);
dbg!(width, height);
let columns = count.isqrt() as u32; let columns = count.isqrt() as u32;
let mut image = GrayImage::new( let mut image = GrayImage::new(

72
src/cyclic.rs Normal file
View 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!(&current, 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, &current, 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();
}
}

View file

@ -1,74 +1,3 @@
pub mod cyclic;
pub mod image; pub mod image;
pub mod naive;
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!(&current, 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, &current, 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();
}
}

66
src/naive.rs Normal file
View 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!(&current, 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, &current, 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();
}
}