<commit_before>// Implements http://rosettacode.org/wiki/Hamming_numbers
// port of one of the scala solutions
extern crate num;
use num::bigint::BigUint;
use std::cmp::min;
use std::sync::spsc_queue::Queue;
use std::iter::range_inclusive;

fn int_to_biguint(i: int) -> BigUint {
    FromPrimitive::from_int(i).unwrap()
}

#[cfg(not(test))]
fn main() {
    let mut hamming = Hamming::new(1691);

    println!("first 20 Hamming numbers")
    for _ in range_inclusive(0,19) {
        print!("{} ", hamming.next().unwrap());
    }

    println!("\n\n1691st Hamming number");
    println!("{}",hamming.nth(1691-20).unwrap())
}

struct Hamming {
    q2: Queue<BigUint>,
    q3: Queue<BigUint>,
    q5: Queue<BigUint>
}

impl Hamming {
    fn new(n: uint) -> Hamming {
        let h = Hamming {
            q2: Queue::new(n),
            q3: Queue::new(n),
            q5: Queue::new(n)
        };

        h.q2.push(int_to_biguint(1));
        h.q3.push(int_to_biguint(1));
        h.q5.push(int_to_biguint(1));

        h
    }

    fn enqueue(&self, n: BigUint) {
        self.q2.push(n * int_to_biguint(2));
        self.q3.push(n * int_to_biguint(3));
        self.q5.push(n * int_to_biguint(5));
    }

}

impl Iterator<BigUint> for Hamming {
    fn next(&mut self) -> Option<BigUint> {
        let (head2, head3, head5) =
            (   self.q2.peek().unwrap(),
                self.q3.peek().unwrap(),
                self.q5.peek().unwrap());

        let n = min(head2.clone(), min(head3.clone(), head5.clone()));

        if *head2 == n {self.q2.pop();}
        if *head3 == n {self.q3.pop();}
        if *head5 == n {self.q5.pop();}

        self.enqueue(n.clone());
        Some(n)
    }
}

#[test]
fn create() {
    let h = Hamming::new(5);
    h.q2.push(int_to_biguint(1));
    h.q2.push(int_to_biguint(2));
    h.q2.push(int_to_biguint(4));

    let _ = h.q2.peek();
    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
}

#[test]
fn try_enqueue() {
    let h = Hamming::new(5);
    h.enqueue(int_to_biguint(1));
    h.enqueue(int_to_biguint(2));
    h.enqueue(int_to_biguint(3));

    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
    assert!(h.q3.pop().unwrap() == int_to_biguint(1));
    assert!(h.q5.pop().unwrap() == int_to_biguint(1));
    assert!(h.q2.pop().unwrap() == int_to_biguint(2));
    assert!(h.q3.pop().unwrap() == int_to_biguint(3));
    assert!(h.q5.pop().unwrap() == int_to_biguint(5));
 }

#[test]
fn hamming_iter() {
    let mut hamming = Hamming::new(20);
    assert!(hamming.nth(19).unwrap() == int_to_biguint(36));
}<commit_msg>changed from range_inclusive to range to fight unused import warning<commit_after>// Implements http://rosettacode.org/wiki/Hamming_numbers
// port of one of the scala solutions
extern crate num;
use num::bigint::BigUint;
use std::cmp::min;
use std::sync::spsc_queue::Queue;

fn int_to_biguint(i: int) -> BigUint {
    FromPrimitive::from_int(i).unwrap()
}

#[cfg(not(test))]
fn main() {
    let mut hamming = Hamming::new(1691);

    println!("first 20 Hamming numbers")
    for _ in range(0,20) {
        print!("{} ", hamming.next().unwrap());
    }

    println!("\n\n1691st Hamming number");
    println!("{}",hamming.nth(1691-20).unwrap())
}

struct Hamming {
    q2: Queue<BigUint>,
    q3: Queue<BigUint>,
    q5: Queue<BigUint>
}

impl Hamming {
    fn new(n: uint) -> Hamming {
        let h = Hamming {
            q2: Queue::new(n),
            q3: Queue::new(n),
            q5: Queue::new(n)
        };

        h.q2.push(int_to_biguint(1));
        h.q3.push(int_to_biguint(1));
        h.q5.push(int_to_biguint(1));

        h
    }

    fn enqueue(&self, n: BigUint) {
        self.q2.push(n * int_to_biguint(2));
        self.q3.push(n * int_to_biguint(3));
        self.q5.push(n * int_to_biguint(5));
    }

}

impl Iterator<BigUint> for Hamming {
    fn next(&mut self) -> Option<BigUint> {
        let (head2, head3, head5) =
            (   self.q2.peek().unwrap(),
                self.q3.peek().unwrap(),
                self.q5.peek().unwrap());

        let n = min(head2.clone(), min(head3.clone(), head5.clone()));

        if *head2 == n {self.q2.pop();}
        if *head3 == n {self.q3.pop();}
        if *head5 == n {self.q5.pop();}

        self.enqueue(n.clone());
        Some(n)
    }
}

#[test]
fn create() {
    let h = Hamming::new(5);
    h.q2.push(int_to_biguint(1));
    h.q2.push(int_to_biguint(2));
    h.q2.push(int_to_biguint(4));

    let _ = h.q2.peek();
    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
}

#[test]
fn try_enqueue() {
    let h = Hamming::new(5);
    h.enqueue(int_to_biguint(1));
    h.enqueue(int_to_biguint(2));
    h.enqueue(int_to_biguint(3));

    assert!(h.q2.pop().unwrap() == int_to_biguint(1));
    assert!(h.q3.pop().unwrap() == int_to_biguint(1));
    assert!(h.q5.pop().unwrap() == int_to_biguint(1));
    assert!(h.q2.pop().unwrap() == int_to_biguint(2));
    assert!(h.q3.pop().unwrap() == int_to_biguint(3));
    assert!(h.q5.pop().unwrap() == int_to_biguint(5));
 }

#[test]
fn hamming_iter() {
    let mut hamming = Hamming::new(20);
    assert!(hamming.nth(19).unwrap() == int_to_biguint(36));
}
{'fraction_non_alphanumeric': 0.19806013579049467, 'fraction_numerical': 0.032589718719689624, 'mean_word_length': 2.796759941089838, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4589153', 'n_tokens_mistral': 2119, 'n_tokens_neox': 2097, 'n_words': 327}