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