diff options
Diffstat (limited to 'entries/lilylin/fractran/src')
-rw-r--r-- | entries/lilylin/fractran/src/core.rs | 44 | ||||
-rw-r--r-- | entries/lilylin/fractran/src/engines/mod.rs | 2 | ||||
-rw-r--r-- | entries/lilylin/fractran/src/engines/register.rs | 164 | ||||
-rw-r--r-- | entries/lilylin/fractran/src/main.rs | 28 |
4 files changed, 0 insertions, 238 deletions
diff --git a/entries/lilylin/fractran/src/core.rs b/entries/lilylin/fractran/src/core.rs deleted file mode 100644 index 26e1a67..0000000 --- a/entries/lilylin/fractran/src/core.rs +++ /dev/null @@ -1,44 +0,0 @@ -use num_traits::Pow; - -pub type FracSize = u16; - -#[derive(Debug)] -pub struct Program { - pub fractions: Vec<(FracSize, FracSize)>, - pub initial: u64, -} - -impl Program { - // http://lomont.org/posts/2017/fractran/ - // A lesser known Conway FRACTRAN program is FIBONACCIGAME: - // `{17/65, 133/34, 17/19, 23/17, 2233/69, 23/29, 31/23, 74/341, 31/37, 41/31, 129/287, 41/43, 13/41, 1/13, 1/3}` - // Starting with `78*5^(n-1)`, it halts on `2^Fn` where Fn is the nth [Fibonacci number] - pub fn fibonacci(i: u32) -> Program { - Program { - fractions: vec![ - (17, 65), - (133, 34), - (17, 19), - (23, 17), - (2233, 69), - (23, 29), - (31, 23), - (74, 341), - (31, 37), - (41, 31), - (129, 287), - (41, 43), - (13, 41), - (1, 13), - (1, 3), - ], - initial: 78 * 5u64.pow(i), - } - } -} - -pub trait FractranEngine<Value>: IntoIterator<Item = Value> -where - Value: From<u64>, -{ -} diff --git a/entries/lilylin/fractran/src/engines/mod.rs b/entries/lilylin/fractran/src/engines/mod.rs deleted file mode 100644 index 6870b7c..0000000 --- a/entries/lilylin/fractran/src/engines/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ - -pub mod register; diff --git a/entries/lilylin/fractran/src/engines/register.rs b/entries/lilylin/fractran/src/engines/register.rs deleted file mode 100644 index c7c847b..0000000 --- a/entries/lilylin/fractran/src/engines/register.rs +++ /dev/null @@ -1,164 +0,0 @@ -use std::collections::HashMap; - -use crate::core::Program; - -#[derive(Debug)] -pub struct Register { - pub program: Program, - pub output_base: u64, // which prime factor registers should be used to determine output -} - -#[derive(Debug)] -struct Instruction { - conditions: Vec<(usize, u64)>, // index, amt pairs - increment: Vec<(usize, u64)>, -} - -impl Register { - fn prime_factorize(x: u64) -> Vec<(u64, u64)> { - let primes = primes::factors_uniq(x); - let mut prime_factorized = Vec::new(); - // println!("val: {:?}", x); - for prime in primes { - let mut amount = 1; - loop { - if x % prime.pow(amount + 1) != 0 { - break; - } - amount += 1; - } - // println!("{:?}, {:?}", prime, amount); - prime_factorized.push((prime, amount as u64)); - } - return prime_factorized; - } - fn convert(&self) -> (Vec<u64>, Vec<Instruction>, HashMap<usize, u64>) { - let mut primes = Vec::new(); - - let mut prime_to_index = |prime: u64| { - let index: usize; - if primes.contains(&prime) { - index = primes.iter().position(|&x| x == prime).unwrap(); - } else { - index = primes.len(); - primes.push(prime); - } - return index; - }; - - let mut instrs = Vec::new(); - for fraction in &self.program.fractions { - let denom_pfs = Register::prime_factorize(fraction.1 as u64); - let num_pfs = Register::prime_factorize(fraction.0 as u64); - instrs.push(Instruction { - conditions: denom_pfs - .iter() - .map(|x| (prime_to_index(x.0), x.1)) - .collect(), - increment: num_pfs.iter().map(|x| (prime_to_index(x.0), x.1)).collect(), - }) - } - - let mut initial_registers = Vec::new(); - initial_registers.resize(primes.len(), 0); - for (prime, amt) in Register::prime_factorize(self.program.initial) { - let idx = primes.iter().position(|&x| x == prime).unwrap(); - initial_registers[idx] = amt; - } - - let output_condition: HashMap<usize, u64> = Register::prime_factorize(self.output_base) - .iter() - .map(|(prime, amt)| (primes.iter().position(|&x| x == *prime).unwrap(), *amt)) - .collect(); - - // println!("Prime layout: {:?}", primes); - // println!("Output condition: {:?}", output_condition); - return (initial_registers, instrs, output_condition); - } -} - -impl IntoIterator for Register { - type Item = u64; - type IntoIter = RegisterIter; - - fn into_iter(self) -> Self::IntoIter { - let (registers, instructions, output_condition) = self.convert(); - RegisterIter { - instructions, - registers, - output_condition, - } - } -} - -pub struct RegisterIter { - instructions: Vec<Instruction>, - registers: Vec<u64>, - output_condition: HashMap<usize, u64>, -} - -// impl RegisterIter { -// fn registers_to_val(&self) -> BigUint { -// let mut val = BigUint::zero(); -// for (amt, prime) in self.registers.iter().zip(&self.prime_mapping) { -// val += prime.to_biguint().unwrap().pow(*amt); -// } -// return val; -// } -// } - -impl Iterator for RegisterIter { - type Item = u64; - - fn next(&mut self) -> Option<Self::Item> { - loop { - for instr in &self.instructions { - if instr - .conditions - .iter() - .all(|(idx, amt)| self.registers[*idx] >= *amt) - { - instr - .conditions - .iter() - .for_each(|(idx, amt)| self.registers[*idx] -= *amt); - instr - .increment - .iter() - .for_each(|(idx, amt)| self.registers[*idx] += *amt); - break; - } - } - - // Output condition checking - // Check that all other registers are 0 - if !self - .registers - .iter() - .enumerate() - .all(|(idx, val)| self.output_condition.contains_key(&idx) || *val == 0) - { - continue; - } - - // Check that the condition registers are multiples of the condition amounts - if !self - .output_condition - .iter() - .all(|(idx, cond)| self.registers[*idx] % cond == 0) - { - continue; - } - - // Check that condition registers are the _same_ multipel of the condition amounts - let mut xs = self - .output_condition - .iter() - .map(|(idx, cond)| self.registers[*idx] / cond); - let first = xs.next().unwrap(); - if xs.all(|y| y == first) { - return Some(first); - } - } - } -} diff --git a/entries/lilylin/fractran/src/main.rs b/entries/lilylin/fractran/src/main.rs deleted file mode 100644 index a874e1d..0000000 --- a/entries/lilylin/fractran/src/main.rs +++ /dev/null @@ -1,28 +0,0 @@ -#![feature(int_log)] - -use crate::core::Program; - -use anyhow::Ok; -use anyhow::Result; -use engines::register::Register; - -mod core; -mod engines; - -fn execute_fib() { - for i in 1..15 { - let engine = Register { - program: Program::fibonacci(i), - output_base: 2, - }; - let n = 1; - for val in engine.into_iter().take(n) { - print!("{:?},", val); - } - } -} - -fn main() -> Result<()> { - execute_fib(); - return Ok(()); -} |