Initial commit
This commit is contained in:
commit
e6cceca88c
10 changed files with 1234 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
/target
|
||||
*.png
|
||||
1007
Cargo.lock
generated
Normal file
1007
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "stamp-folding"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
image = "0.25.5"
|
||||
13
src/bin/image.rs
Normal file
13
src/bin/image.rs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
use image::GrayImage;
|
||||
use stamp_folding::image::{draw_image, image_dimensions};
|
||||
|
||||
fn main() {
|
||||
let data = [0, 1, 2, 3];
|
||||
let (width, height) = image_dimensions(data.len());
|
||||
|
||||
let mut img = GrayImage::new(width, height);
|
||||
|
||||
draw_image(&mut img, &data);
|
||||
|
||||
img.save("img.png").unwrap();
|
||||
}
|
||||
10
src/bin/overflow_check.rs
Normal file
10
src/bin/overflow_check.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
fn main() {
|
||||
let mut i = 1;
|
||||
let mut f = 1u128;
|
||||
while let Some(nf) = f.checked_mul(i) {
|
||||
f = nf;
|
||||
i += 1;
|
||||
}
|
||||
|
||||
println!("{}: {f}", i - 1);
|
||||
}
|
||||
10
src/bin/series.rs
Normal file
10
src/bin/series.rs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
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 |_, _| {});
|
||||
println!("{length:02}: {count} {}", count * 2);
|
||||
}
|
||||
}
|
||||
8
src/bin/single_stamp.rs
Normal file
8
src/bin/single_stamp.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
use stamp_folding::stamp_folding;
|
||||
|
||||
fn main() {
|
||||
let length = 4;
|
||||
let mut count = 0;
|
||||
let mut state = vec![0, 1];
|
||||
stamp_folding(&mut state, 1, length - 2, &mut count, &mut |_, _| {});
|
||||
}
|
||||
37
src/bin/stamp_folding_images.rs
Normal file
37
src/bin/stamp_folding_images.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use image::{GenericImage, GrayImage};
|
||||
use stamp_folding::{
|
||||
image::{draw_image, image_dimensions},
|
||||
stamp_folding,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
for length in 2..12 {
|
||||
let mut count = 0;
|
||||
let mut state = vec![0, 1];
|
||||
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(
|
||||
width * columns,
|
||||
height * count.div_ceil(columns as u128) as u32,
|
||||
);
|
||||
|
||||
let mut count = 0;
|
||||
let mut state = vec![0, 1];
|
||||
stamp_folding(&mut state, 1, length - 2, &mut count, &mut |i, l| {
|
||||
let mut subimage = image.sub_image(
|
||||
width * (i as u32 % columns),
|
||||
height * (i as u32 / columns),
|
||||
width,
|
||||
height,
|
||||
);
|
||||
|
||||
draw_image(&mut *subimage, l);
|
||||
});
|
||||
|
||||
image.save(format!("img{length:02}.png")).unwrap();
|
||||
}
|
||||
}
|
||||
66
src/image.rs
Normal file
66
src/image.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
use image::{GenericImage, Luma};
|
||||
|
||||
const CENTRAL_WIDTH: u32 = 5;
|
||||
|
||||
pub fn draw_image(image: &mut impl GenericImage<Pixel = Luma<u8>>, layout: &[u8]) {
|
||||
let side_width = layout.len() as u32 + 1;
|
||||
|
||||
let white = Luma::from([255]);
|
||||
let grey = Luma::from([125]);
|
||||
|
||||
for (i, &s) in layout.iter().enumerate() {
|
||||
for j in 0..CENTRAL_WIDTH {
|
||||
image.put_pixel(
|
||||
side_width + j,
|
||||
1 + i as u32 * 3,
|
||||
if s == 0 { grey } else { white },
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(j) = layout.iter().position(|&c| c == s + 1) {
|
||||
if s % 2 == 0 {
|
||||
let lower = usize::min(i, j) as u32;
|
||||
let upper = usize::max(i, j) as u32;
|
||||
|
||||
let diff = upper - lower;
|
||||
|
||||
let depth = diff;
|
||||
|
||||
for d in 0..depth {
|
||||
image.put_pixel(side_width + CENTRAL_WIDTH + d, 1 + lower * 3 + d + 1, white);
|
||||
image.put_pixel(side_width + CENTRAL_WIDTH + d, 1 + upper * 3 - d - 1, white);
|
||||
}
|
||||
|
||||
let l = 1 + lower * 3 + depth + 1;
|
||||
let u = 1 + upper * 3 - depth - 1;
|
||||
|
||||
for y in l..=u {
|
||||
image.put_pixel(side_width + CENTRAL_WIDTH + depth, y, white);
|
||||
}
|
||||
} else {
|
||||
let lower = usize::min(i, j) as u32;
|
||||
let upper = usize::max(i, j) as u32;
|
||||
|
||||
let diff = upper - lower;
|
||||
|
||||
let depth = diff;
|
||||
|
||||
for d in 0..depth {
|
||||
image.put_pixel(side_width - d - 1, 1 + lower * 3 + d + 1, white);
|
||||
image.put_pixel(side_width - d - 1, 1 + upper * 3 - d - 1, white);
|
||||
}
|
||||
|
||||
let l = 1 + lower * 3 + depth + 1;
|
||||
let u = 1 + upper * 3 - depth - 1;
|
||||
|
||||
for y in l..=u {
|
||||
image.put_pixel(side_width - depth - 1, y, white);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn image_dimensions(len: usize) -> (u32, u32) {
|
||||
(CENTRAL_WIDTH + 2 * len as u32 + 2, 3 * len as u32)
|
||||
}
|
||||
74
src/lib.rs
Normal file
74
src/lib.rs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
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();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue