From be3697a7497616aa0686e50ec0db25f6055c0bc0 Mon Sep 17 00:00:00 2001 From: hal8174 Date: Tue, 10 Dec 2024 23:49:47 +0100 Subject: [PATCH] Add cyclic optimization --- src/bin/series.rs | 4 +- src/bin/single_stamp.rs | 6 +-- src/bin/stamp_folding_images.rs | 3 +- src/cyclic.rs | 72 +++++++++++++++++++++++++++++++ src/lib.rs | 75 +-------------------------------- src/naive.rs | 66 +++++++++++++++++++++++++++++ 6 files changed, 144 insertions(+), 82 deletions(-) create mode 100644 src/cyclic.rs create mode 100644 src/naive.rs diff --git a/src/bin/series.rs b/src/bin/series.rs index 86ec57a..da7434b 100644 --- a/src/bin/series.rs +++ b/src/bin/series.rs @@ -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); } } diff --git a/src/bin/single_stamp.rs b/src/bin/single_stamp.rs index 16a2ae3..d7e20f3 100644 --- a/src/bin/single_stamp.rs +++ b/src/bin/single_stamp.rs @@ -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 |_, _| {}); } diff --git a/src/bin/stamp_folding_images.rs b/src/bin/stamp_folding_images.rs index 22ce5c2..a2eb4a2 100644 --- a/src/bin/stamp_folding_images.rs +++ b/src/bin/stamp_folding_images.rs @@ -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( diff --git a/src/cyclic.rs b/src/cyclic.rs new file mode 100644 index 0000000..19f76e6 --- /dev/null +++ b/src/cyclic.rs @@ -0,0 +1,72 @@ +pub fn stamp_folding( + current: &mut Vec, + 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(); + } +} diff --git a/src/lib.rs b/src/lib.rs index 2a848c2..6907447 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,74 +1,3 @@ +pub mod cyclic; pub mod image; - -pub fn stamp_folding( - current: &mut Vec, - 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; diff --git a/src/naive.rs b/src/naive.rs new file mode 100644 index 0000000..350c198 --- /dev/null +++ b/src/naive.rs @@ -0,0 +1,66 @@ +pub fn stamp_folding( + current: &mut Vec, + 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(); + } +}