initial
This commit is contained in:
commit
aed21bb06a
5 changed files with 307 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/target
|
||||
148
Cargo.lock
generated
Normal file
148
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "bit-art"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasip2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.178"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.103"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.42"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.9.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||
dependencies = [
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.9.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.111"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "wasip2"
|
||||
version = "1.0.1+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7"
|
||||
dependencies = [
|
||||
"wit-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.46.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
[package]
|
||||
name = "bit-art"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
rand = "0.9.2"
|
||||
3
README.md
Normal file
3
README.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
generate images from random bitwise expressions forever. idea taken from <https://freeradical.zone/@bitartbot>
|
||||
|
||||
`Ctrl`+`c` to stop
|
||||
148
src/main.rs
Normal file
148
src/main.rs
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
use std::{fmt, iter, ops, thread, time::Duration};
|
||||
|
||||
use rand::{
|
||||
Rng,
|
||||
distr::{Distribution, StandardUniform},
|
||||
rng,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let mut rng = rng();
|
||||
|
||||
loop {
|
||||
let expr: Expr = rng.random();
|
||||
for y in 0..=255 {
|
||||
for x in 0..=255 {
|
||||
let n = expr.run(x, y);
|
||||
print!("\x1b[48;2;{n};{n};{n}m ");
|
||||
}
|
||||
println!();
|
||||
}
|
||||
println!("\x1b[0m{expr}");
|
||||
thread::sleep(Duration::from_secs(3));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
enum Inst {
|
||||
X,
|
||||
Y,
|
||||
Const(u8),
|
||||
|
||||
Or,
|
||||
And,
|
||||
Xor,
|
||||
Mod,
|
||||
Mul,
|
||||
Div,
|
||||
Add,
|
||||
|
||||
Not,
|
||||
Neg,
|
||||
}
|
||||
|
||||
impl Distribution<Inst> for StandardUniform {
|
||||
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Inst {
|
||||
#[allow(clippy::enum_glob_use)]
|
||||
use Inst::*;
|
||||
|
||||
match rng.random_range(0..12) {
|
||||
0 => X,
|
||||
1 => Y,
|
||||
2 => Const(rng.random()),
|
||||
|
||||
3 => Or,
|
||||
4 => And,
|
||||
5 => Xor,
|
||||
6 => Mod,
|
||||
7 => Mul,
|
||||
8 => Div,
|
||||
9 => Add,
|
||||
|
||||
10 => Not,
|
||||
11 => Neg,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Inst {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Inst::X => write!(f, "x"),
|
||||
Inst::Y => write!(f, "y"),
|
||||
Inst::Const(n) => write!(f, "{n}"),
|
||||
Inst::Or => write!(f, "|"),
|
||||
Inst::And => write!(f, "&"),
|
||||
Inst::Xor => write!(f, "^"),
|
||||
Inst::Mod => write!(f, "%"),
|
||||
Inst::Mul => write!(f, "*"),
|
||||
Inst::Div => write!(f, "/"),
|
||||
Inst::Add => write!(f, "+"),
|
||||
Inst::Not => write!(f, "~"),
|
||||
Inst::Neg => write!(f, "-"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Expr {
|
||||
insts: Vec<Inst>,
|
||||
}
|
||||
|
||||
impl fmt::Display for Expr {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for inst in &self.insts {
|
||||
write!(f, "{inst} ")?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn monad(stack: &mut Vec<u8>, op: impl FnOnce(u8) -> u8) {
|
||||
let x = stack.pop().unwrap_or_default();
|
||||
stack.push(op(x));
|
||||
}
|
||||
|
||||
fn dyad(stack: &mut Vec<u8>, op: impl FnOnce(u8, u8) -> u8) {
|
||||
let first = stack.pop().unwrap_or_default();
|
||||
let second = stack.pop().unwrap_or_default();
|
||||
stack.push(op(first, second));
|
||||
}
|
||||
|
||||
impl Expr {
|
||||
fn run(&self, x: u8, y: u8) -> u8 {
|
||||
let mut stack = Vec::new();
|
||||
|
||||
for inst in &self.insts {
|
||||
match inst {
|
||||
Inst::X => stack.push(x),
|
||||
Inst::Y => stack.push(y),
|
||||
Inst::Const(n) => stack.push(*n),
|
||||
|
||||
Inst::Or => dyad(&mut stack, ops::BitOr::bitor),
|
||||
Inst::And => dyad(&mut stack, ops::BitAnd::bitand),
|
||||
Inst::Xor => dyad(&mut stack, ops::BitXor::bitxor),
|
||||
Inst::Mul => dyad(&mut stack, u8::wrapping_mul),
|
||||
Inst::Add => dyad(&mut stack, u8::wrapping_add),
|
||||
Inst::Mod => dyad(&mut stack, |a, b| u8::checked_rem(a, b).unwrap_or_default()),
|
||||
Inst::Div => dyad(&mut stack, |a, b| u8::checked_div(a, b).unwrap_or_default()),
|
||||
|
||||
Inst::Not => monad(&mut stack, ops::Not::not),
|
||||
#[allow(clippy::cast_sign_loss, clippy::cast_possible_wrap)]
|
||||
Inst::Neg => monad(&mut stack, |x| -(x as i8) as u8),
|
||||
}
|
||||
}
|
||||
|
||||
stack.pop().unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
impl Distribution<Expr> for StandardUniform {
|
||||
fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> Expr {
|
||||
let inst_count = rng.random_range(5..40);
|
||||
let insts = iter::repeat_with(|| rng.random())
|
||||
.take(inst_count)
|
||||
.collect();
|
||||
Expr { insts }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue