Last active
February 9, 2024 05:29
-
-
Save Mroik/28adfff5fdcebdb050dea06a8bc09da1 to your computer and use it in GitHub Desktop.
Seq generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{env::args, fmt::Debug}; | |
struct Seq<'a, T> { | |
items: Vec<T>, | |
func: &'a dyn Fn(T) -> Option<T>, | |
place: usize, | |
} | |
impl<'a, T> Debug for Seq<'a, T> where T: Debug { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
f.debug_struct("Seq").field("items", &self.items).field("place", &self.place).finish() | |
} | |
} | |
impl<'a, T> Seq<'a, T> { | |
fn new(f: &'a dyn Fn(T) -> Option<T>, init: T) -> Self where T: Copy { | |
Seq { | |
items: vec![init], | |
func: f, | |
place: 0, | |
} | |
} | |
fn iter(&'a mut self) -> Iter<'a, T> { | |
Iter::new(self) | |
} | |
} | |
struct Iter<'a, T> { | |
items: &'a mut Vec<T>, | |
func: &'a dyn Fn(T) -> Option<T>, | |
place: usize, | |
} | |
// Unsafe might be required to resolve borrow checks | |
impl<'a, 'b, T> Iter<'a, T> { | |
fn new(seq: &'a mut Seq<'b, T>) -> Self { | |
Self { | |
items: &mut seq.items, | |
func: seq.func, | |
place: 0, | |
} | |
} | |
} | |
impl<'a, T> Iterator for Iter<'a, T> where T: Copy { | |
type Item = T; | |
fn next(&mut self) -> Option<Self::Item> { | |
self.place += 1; | |
let ris = match self.items.get(self.place - 1).copied() { | |
Some(x) => Some(x), | |
None => { | |
let last = self.items.last().copied().unwrap(); | |
match (self.func)(last) { | |
None => { | |
self.place = 0; | |
None | |
}, | |
Some(y) => { | |
self.items.push(y); | |
Some(y) | |
}, | |
} | |
}, | |
}; | |
ris | |
} | |
} | |
fn collatz(n: u64) -> Option<u64> { | |
if n == 1 { | |
return None; | |
} | |
let ris = if n % 2 == 1 { | |
3 * n + 1 | |
} else { | |
n / 2 | |
}; | |
Some(ris) | |
} | |
fn main() { | |
if args().len() <= 1 { | |
return; | |
} | |
let args: Vec<String> = args().collect(); | |
let mut s = Seq::new(&collatz, args[1].parse().unwrap()); | |
// TODO properly impleemnt iter() | |
// Vec implements it using unsafe... | |
for x in s.iter() { | |
println!("{}", x); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment