aboutsummaryrefslogtreecommitdiff
path: root/entries/lilylin/fractran/src/engines/register.rs
diff options
context:
space:
mode:
Diffstat (limited to 'entries/lilylin/fractran/src/engines/register.rs')
-rw-r--r--entries/lilylin/fractran/src/engines/register.rs164
1 files changed, 0 insertions, 164 deletions
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);
- }
- }
- }
-}