Skip to content

Instantly share code, notes, and snippets.

@DutchGhost
Created February 21, 2020 21:25
Show Gist options
  • Select an option

  • Save DutchGhost/d638688dfdfa7f8c722dfbcfb18cd340 to your computer and use it in GitHub Desktop.

Select an option

Save DutchGhost/d638688dfdfa7f8c722dfbcfb18cd340 to your computer and use it in GitHub Desktop.
Const collatz using traits!
#![feature(const_trait_bound_opt_out)]
#![feature(const_fn)]
#![feature(const_trait_impl)]
#![feature(const_if_match)]
#![feature(const_loop)]
#![feature(const_mut_refs)]
trait CollatzTransform: Sized {
fn transform(self) -> Option<Self>;
}
impl const CollatzTransform for usize {
fn transform(self) -> Option<Self> {
match self {
1 => None,
n if n & 1 == 0 => Some(n / 2),
n => Some(n * 3 + 1),
}
}
}
trait Collatz<T = Self> {
fn collatz(self) -> CollatzIterator<T>;
}
impl const Collatz for usize {
fn collatz(self) -> CollatzIterator<Self> {
CollatzIterator { current: Some(self) }
}
}
struct CollatzIterator<T> {
current: Option<T>,
}
impl const Iterator for CollatzIterator<usize> {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
match self.current {
None => None,
Some(n) => {
self.current = CollatzTransform::transform(n);
Some(n)
}
}
}
fn count(mut self) -> usize {
let mut count = 0;
while let Some(_) = self.next() {
count += 1;
}
count
}
}
const fn collatzy(n: usize) -> (usize, usize) {
(n, n.collatz().count())
}
const C: (usize, usize) = collatzy(9);
fn main() {
dbg!(C);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment