path_iter/
range.rs

1use crate::*;
2
3use std::ops::Range;
4
5/// Negation.
6#[derive(Clone)]
7pub struct Neg;
8
9impl<T> HigherIntoIterator<Item<Range<T>>> for Neg
10    where T: std::ops::Sub<Output = T> + From<u8>
11{
12    type Item = T;
13    type IntoIter = Range<T>;
14    fn hinto_iter(self, arg: Item<Range<T>>) -> Self::IntoIter {
15        let arg = arg.inner();
16        Range {start: T::from(1) - arg.end, end: T::from(1) - arg.start}
17    }
18}
19
20impl HigherIntoIterator<Item<i64>> for Neg {
21    type Item = i64;
22    type IntoIter = Range<i64>;
23    fn hinto_iter(self, arg: Item<i64>) -> Self::IntoIter {
24        let arg = arg.inner();
25        Range {start: -arg, end: 1-arg}
26    }
27}
28
29/// Identity function.
30#[derive(Clone)]
31pub struct Id;
32
33impl<T> HigherIntoIterator<Item<Range<T>>> for Id {
34    type Item = T;
35    type IntoIter = Range<T>;
36    fn hinto_iter(self, arg: Item<Range<T>>) -> Self::IntoIter {
37        arg.inner()
38    }
39}
40
41impl HigherIntoIterator<Item<i64>> for Id {
42    type Item = i64;
43    type IntoIter = Range<i64>;
44    fn hinto_iter(self, arg: Item<i64>) -> Self::IntoIter {
45        let arg = arg.inner();
46        Range {start: arg, end: arg+1}
47    }
48}
49
50/// Addition.
51#[derive(Clone)]
52pub struct Add;
53
54/// Iterates over numbers that adds up to some range.
55pub struct AddRangeIter {
56    range: Range<i64>,
57    ind: i64,
58    add: i64,
59}
60
61impl Iterator for AddRangeIter {
62    type Item = (i64, i64);
63    fn next(&mut self) -> Option<Self::Item> {
64        let res = Some((self.ind - self.add, self.add));
65        self.ind += 1;
66        if self.ind >= self.range.end {
67            self.ind = self.range.start;
68            if self.add >= 0 {
69                self.add += 1;
70            }
71            self.add = -self.add;
72        }
73        res
74    }
75}
76
77impl HigherIntoIterator<Item<Range<i64>>> for Add
78{
79    type Item = (i64, i64);
80    type IntoIter = AddRangeIter;
81    fn hinto_iter(self, arg: Item<Range<i64>>) -> Self::IntoIter {
82        let arg = arg.inner();
83        AddRangeIter {
84            ind: arg.start,
85            range: arg,
86            add: 0,
87        }
88    }
89}
90
91impl HigherIntoIterator<Item<i64>> for Add {
92    type Item = (i64, i64);
93    type IntoIter = AddRangeIter;
94    fn hinto_iter(self, arg: Item<i64>) -> Self::IntoIter {
95        let arg = arg.inner();
96        Add.hinto_iter(item(arg..arg+1))
97    }
98}
99
100/// Square.
101#[derive(Clone)]
102pub struct Square;
103
104/// Iterates over numbers that squares up to some range.
105pub struct SquareRangeIter {
106    range: Range<i64>,
107    ind: i64,
108}
109
110impl Iterator for SquareRangeIter {
111    type Item = i64;
112    fn next(&mut self) -> Option<Self::Item> {
113        loop {
114            if self.ind >= self.range.end {return None};
115
116            let arg = self.ind;
117            self.ind += 1;
118
119            let root = (arg as f64).sqrt() as i64;
120            if root * root == arg {
121                return Some(root);
122            }
123        }
124    }
125}
126
127impl HigherIntoIterator<Item<Range<i64>>> for Square {
128    type Item = i64;
129    type IntoIter = SquareRangeIter;
130    fn hinto_iter(self, arg: Item<Range<i64>>) -> Self::IntoIter {
131        let arg = arg.inner();
132        SquareRangeIter {
133            ind: arg.start,
134            range: arg,
135        }
136    }
137}
138
139impl HigherIntoIterator<Item<i64>> for Square {
140    type Item = i64;
141    type IntoIter = Range<i64>;
142    fn hinto_iter(self, arg: Item<i64>) -> Self::IntoIter {
143        let arg = arg.inner();
144        let root = (arg as f64).sqrt() as i64;
145        if root * root == arg {
146            Range {start: root, end: root+1}
147        } else {
148            Range {start: 0, end: 0}
149        }
150    }
151}