1#[cfg_attr(not(feature = "num-traits"), no_std)]
2
3#[cfg(feature = "num-traits")]
4extern crate num;
5
6#[cfg(test)]
7mod test;
8
9pub struct Kolakoski
19{
20 run: usize,
21 run_length: u8,
22 is_one: bool,
23}
24
25#[cfg(feature = "num-traits")]
26pub struct KolakoskiNum<N>
27{
28 run: usize,
29 run_length: N,
30 is_one: bool,
31}
32
33impl Kolakoski
34{
35 pub fn new() -> Kolakoski
37 {
38 Kolakoski
39 {
40 run: 0,
41 run_length: 1,
42 is_one: true,
43 }
44 }
45}
46
47#[cfg(feature = "num-traits")]
48impl<N: Num> KolakoskiNum<N>
49{
50 pub fn new() -> KolakoskiNum<N>
52 {
53 KolakoskiNum
54 {
55 run: 0,
56 run_length: N::one(),
57 is_one: true,
58 }
59 }
60}
61
62impl Iterator for Kolakoski
63{
64 type Item = u8;
65
66 fn next(&mut self) -> Option<Self::Item>
67 {
68 if self.run_length == 0
69 {
70 self.is_one = !self.is_one;
71 self.run += 1;
72
73 if self.run == 1
74 {
75 self.run_length = 2;
76 }
77 else
78 {
79 self.run_length = Kolakoski::new().nth(self.run).unwrap();
80 }
81 }
82
83 self.run_length -= 1;
84
85 if self.is_one
86 {
87 Some(1)
88 }
89 else
90 {
91 Some(2)
92 }
93 }
94}
95
96#[cfg(feature = "num-traits")]
97use num::traits::Num;
98
99#[cfg(feature = "num-traits")]
100impl<N: Num + Clone> Iterator for KolakoskiNum<N>
101{
102 type Item = N;
103
104 fn next(&mut self) -> Option<Self::Item>
105 {
106 if self.run_length == N::zero()
107 {
108 self.is_one = !self.is_one;
109 self.run += 1;
110
111 if self.run == 1
112 {
113 self.run_length = N::one() + N::one()
114 }
115 else
116 {
117 self.run_length = KolakoskiNum::<N>::new().nth(self.run).unwrap();
118 }
119 }
120
121 self.run_length = self.run_length.clone() - N::one();
122
123 if self.is_one
124 {
125 Some(N::one())
126 }
127 else
128 {
129 Some(N::one() + N::one())
130 }
131 }
132}