aboutsummaryrefslogtreecommitdiff
path: root/entries/lilylin/fractran/src
diff options
context:
space:
mode:
authorLily Lin2022-10-25 07:09:05 +0000
committerLily Lin2022-10-25 07:09:05 +0000
commit7509f7f46d0511454dccce2d52545c045cb67e57 (patch)
tree70ab3d3e447e265bf22145a4bc847c9f6f4b5f73 /entries/lilylin/fractran/src
parentbea8092ecca8f4bf61a4df88c06f4eeb61ab3a56 (diff)
Much simpler fractran program
Why did I commit the complex one in the first place...
Diffstat (limited to 'entries/lilylin/fractran/src')
-rw-r--r--entries/lilylin/fractran/src/core.rs44
-rw-r--r--entries/lilylin/fractran/src/engines/mod.rs2
-rw-r--r--entries/lilylin/fractran/src/engines/register.rs164
-rw-r--r--entries/lilylin/fractran/src/main.rs28
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(());
-}