-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtriangular.cpp
193 lines (154 loc) · 4.23 KB
/
triangular.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include <vector>
#include <iostream>
#include <stdexcept>
class iterator_overflow{
public:
iterator_overflow(int index, int max)
:_index(index), _max(max) {}
int index() {return _index;}
int max() {return _max;}
void what_happened(std::ostream& os = std::cerr){
os << "Internal error: current index " << _index << " exceeds maximum bound: " << _max;
}
private:
int _index;
int _max;
};
class Triangular_iterator
{
public:
friend class Triangular;
Triangular_iterator(int index) : _index(index - 1) {}
bool operator==(const Triangular_iterator&) const;
bool operator!=(const Triangular_iterator&) const;
int operator* () const;
Triangular_iterator& operator++();
Triangular_iterator operator++(int);
private:
void check_integrity() const;
int _index;
};
class Triangular
{
public:
friend class Triangular_iterator;
typedef Triangular_iterator iterator;
Triangular_iterator begin() const {return Triangular_iterator(_beg_pos);}
Triangular_iterator end() const {return Triangular_iterator(_beg_pos + _length);}
friend int Triangular_iterator::operator*() const;
friend void Triangular_iterator::check_integrity() const;
Triangular(){
_length = 1;
_beg_pos = 1;
_next = 0;
};
Triangular(int len)
{
_length = len;
_beg_pos = 1;
_next = 0;
}
Triangular(int len, int beg_pos)
{
_length = len > 0 ? len : 1;
_beg_pos = beg_pos > 0 ? beg_pos : 1;
_next = _beg_pos - 1;
}
int length() const {return _length;}
int beg_pos() const {return _beg_pos;}
int elem(int pos) const;
bool next(int& value);
void next_reset(){_next = _beg_pos - 1;}
static int gen_element(int index)
{
return _elems[index];
}
private:
int _length;
int _beg_pos;
int _next;
static int _max_elements;
static std::vector<int> _elems;
};
int Triangular::_max_elements = 1024; //
inline bool Triangular_iterator::operator==(const Triangular_iterator& rhs) const
{
return _index == rhs._index;
}
inline bool Triangular_iterator::operator!=(const Triangular_iterator& rhs) const
{
return !(*this == rhs);
}
inline int Triangular_iterator::operator* () const
{
check_integrity();
return Triangular::_elems[_index];
}
inline void Triangular_iterator::check_integrity () const
{
if(_index >= Triangular::_max_elements)
throw iterator_overflow(_index, Triangular::_max_elements);
if(_index >= Triangular::_elems.size())
{
Triangular::gen_element(_index + 1);
}
}
inline Triangular_iterator& Triangular_iterator::operator++ ()
{
++_index;
check_integrity();
return *this;
}
inline Triangular_iterator Triangular_iterator::operator++ (int)
{
Triangular_iterator tmp = *this;
++_index;
check_integrity();
return tmp;
}
std::vector<int> Triangular::_elems = {1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 66, 78, 91, 105, 120, 136, 153, 171, 190, 210};
bool Triangular::next(int& value){
if(_next < _beg_pos + _length - 1)
{
value = _elems[_next++];
return true;
}
else{
return false;
}
}
int sum(Triangular& trian)
{
if(!trian.length())
return 0;
int val, sum = 0;
trian.next_reset();
while(trian.next(val))
{
std::cout << val << " ";
sum += val;
}
return sum;
}
std::ostream& operator<<(std::ostream& os, const Triangular &tri)
{
os << "(" << tri.beg_pos() << ", " << tri.length() << ")";
return os;
}
int main()
{
Triangular tri(4, 1);
std::cout << tri << " -- sum of elements: " << sum(tri) << std::endl;
Triangular tri2(4, 3);
std::cout << tri2 << " -- sum of elements: " << sum(tri2) << std::endl;
Triangular tri3(7, 8);
std::cout << tri3 << " -- sum of elements: " << sum(tri3) << std::endl;
Triangular::iterator it = tri3.begin();
Triangular::iterator end = tri3.end();
while(it != end)
{
std::cout << *it << ' ';
++it;
}
return 0;
}