1use crate::*;
2
3use std::ops::Range;
4
5#[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#[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#[derive(Clone)]
52pub struct Add;
53
54pub 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#[derive(Clone)]
102pub struct Square;
103
104pub 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}