How can I use function in C++ to create a sequence? - c++

My goal is to create an immutable function (functional programming) using "accumulate" in C++. I created a dummy list that generates 1's based on the position I send, which will be 6. So the list at the start contains {1,1,1,1,1,1}. I tried using accumulate to somehow use the information on this list and make the fibonacci sequence into a new list. The result has to be {1,1,2,3,5,8}
Here is what I have.
list<int> immutableFibonacci(int position)
{
const size_t fixedListSize(position);
list<int> newList(position, int(1));
list<int> copyList;
list<int>::iterator it = newList.begin();
if (position <=2)
{
return newList; //returns {1,1} or {1}
}
while (position>0)
{
advance(it, 1);
sum = accumulate(newList.begin(),it, 0);
copyList.push_back(sum);
position--;
}
return copyList;
}
What I have so far will return copyList as {1,2,3,4,5,6}. Can someone please push me in the right direction on what to do? I tried researching quite a bit.

this method creates a 'container-like' object which exposes iterators via begin() and end()
#include <iterator>
#include <iostream>
struct fib_iterator : std::iterator<std::forward_iterator_tag, long long>
{
fib_iterator(std::size_t torun = 0) : to_run(torun) {}
value_type operator*() const {
return value();
}
fib_iterator& operator++()
{
--to_run;
switch(preamble)
{
case 2:
--preamble;
return *this;
case 1:
--preamble;
return *this;
}
auto next = value();
x = y;
y = next;
return *this;
}
value_type value() const
{
switch(preamble)
{
case 2:
return 0;
case 1:
return 1;
}
return x + y;
}
bool operator==(const fib_iterator& r) const {
return to_run == r.to_run;
}
bool operator!=(const fib_iterator& r) const {
return to_run != r.to_run;
}
long long x = 0;
long long y = 1;
std::size_t preamble = 2;
std::size_t to_run;
};
struct fibonacci_sequence
{
fibonacci_sequence(std::size_t length) : length_(length) {}
fib_iterator begin() const { return { length_ }; }
fib_iterator end() const { return { }; }
std::size_t length_;
};
int main()
{
for (auto i : fibonacci_sequence(50))
std::cout << i << ", ";
std::cout << '\n';
}
sample output:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987,
1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368, 75025, 121393,
196418, 317811, 514229, 832040, 1346269, 2178309, 3524578, 5702887,
9227465, 14930352, 24157817, 39088169, 63245986, 102334155, 165580141,
267914296, 433494437, 701408733, 1134903170, 1836311903, 2971215073,
4807526976, 7778742049,

How about this:
#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <functional>
int main()
{
std::vector<int> v{1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
std::vector<int> s = std::accumulate(v.begin(), v.end(),std::vector<int>{},
[](const std::vector<int>& a, int b)
{
std::vector<int> d = a;
if(a.size()<2)
{
d.push_back(1);
}
else
{
auto start = d.rbegin();
auto first = *start;
start++;
auto second = *start;
d.push_back(first+second);
}
return d;
});
std::cout << "Fibo: " <<'\n';
for( auto c : s )
{
std::cout << c << "-";
}
std::cout << '\n';
}
But I also think it is a bit too much overhead, for something that simple.
EDIT: Remember to compile that with: g++ --std=c++14 fibo.cpp -o fibo.
EDIT: If you don't want to use the lambda function look here: How can I modify this Fibonacci code in C++ to use a function instead of lambda?

Related

Is there anything like C++ default object method

I have the following templated merge sort program:
#include <iostream>
#include <vector>
#include <string>
// trying to create a default method call
class CInstance {
private:
std::string str_;
public:
CInstance(const std::string& str) : str_(str) {}
bool const operator>(const CInstance& that){ return (this->str_.size() > that.str_.size());}
};
template<class T>
class CObj {
private:
T val;
public:
CObj(const T n) : val(n) {}
T Get() { return val; }
};
template<class T>
using vcobj = std::vector<CObj<T>>;
template<class T>
void display(vcobj<T>& v) {
for (auto &i : v) {
std::cout << i.Get() << " ";
}
std::cout << "\n";
}
template<class T>
vcobj<T> Merge(vcobj<T>& lv, vcobj<T>& rv) {
vcobj<T> ret;
auto lsize = lv.size();
auto rsize = rv.size();
unsigned int lpin = 0,
rpin = 0;
while(lpin < lsize && rpin < rsize) {
if(lv.at(lpin).Get() > rv.at(rpin).Get()) {
ret.emplace_back(rv.at(rpin).Get());
rpin++;
}
else {
ret.emplace_back(lv.at(lpin).Get());
lpin++;
}
}
for (auto i=lpin; i<lsize; i++) {
ret.emplace_back(lv.at(i).Get());
}
for (auto i=rpin; i<rsize; i++) {
ret.emplace_back(rv.at(i).Get());
}
return ret;
}
template<class T>
vcobj<T> Sort(const vcobj<T>& v) {
vcobj<T> ret;
auto size = v.size();
if(size == 0) {
return ret;
}
if(size > 1) {
auto mid = size / 2;
vcobj<T> l(v.begin(), v.begin()+mid);
auto lv = Sort(l);
vcobj<T> r(v.begin()+mid, v.end());
auto rv = Sort(r);
ret = Merge(lv, rv);
}
else {
ret = v;
}
return ret;
}
int main() {
{
vcobj<int> v = {4, 5, 2, 1, 9, 6, 10, 8, 15, 3, 7};
display(v);
auto sorted = Sort(v);
display(sorted);
}
{
vcobj<float> v = {0.01, 0.001, 0.002, 0.009, 0.010, 0.0003, 0.00001};
display(v);
auto sorted = Sort(v);
display(sorted);
}
{
vcobj<std::string> v = {{"pineapple"}, {"jackfruit"}, {"mango"}, {"apple"}, {"banana"}};
display(v);
auto sorted = Sort(v);
display(sorted);
}
// causing problem
{
vcobj<CInstance> v = {{"pineapple"}, {"jackfruit"}, {"mango"}, {"apple"}, {"banana"}};
display(v);
auto sorted = Sort(v);
display(sorted);
}
return 0;
}
In all of the above types, I can simply call the object and it extracts the data which looks like calling a default get() method. Is there a way to make objects of class CInstance trigger a methos, when used just alone.
example:
I could do something like
CInstance obj;
std::cout << obj;
And that will call a default method in CInstance what every it may be.
As already mentioned in the other answer you can create your own operator<< function:
std::ostream & operator<<(std::ostream &stream, const CInstance &obj) {
// stream << whatever you want to output
return stream;
}
You could also define a conversion operator. But you should think twice before you use them. They can lead to problems that are not easy to debug, especially when explicit is omitted. You generally should not use those for logging/debugging purposes. If your type represents a string and you use it to allow an easy conversion to an std::string then it might be fine.
#include <iostream>
#include <string>
class CInstance {
std::string str_ = "test";
public:
explicit operator const std::string () const { return str_; }
};
int main() {
CInstance obj;
std::cout << (std::string)obj << std::endl;
return 0;
}
If you can guarantee that the lifetime of the returned const char * is still valid after the call you could also do something like (but I would avoid that solution):
#include <iostream>
#include <string>
class CInstance {
std::string str_ = "test";
public:
operator const char *() const { return str_.c_str(); }
};
int main() {
CInstance t;
std::cout << t << std::endl;
return 0;
}
Personally, I would go with the first solution. But that really depends if you actually have a string representation of CInstance or if you want to display something for debugging purposes in a different format. I however would avoid the last non-explicit version with the const char * conversion operator.
In this exact case, you define an operator<< method like so:
std::ostream & operator<<(std::ostream &stream, const CInstance &obj) {
... output obj however you want to the stream. For instance:
stream << obj.getAge();
return stream;
}

Overwriting first element of a vector changes contents of last element of vector

When writing my code, I noticed that running the code returns incorrect results, it turns out something in my code is changing the vector of handles for my coroutines and narrowed it down to one line of code where I overwrite an existing element of the handle vector with a new element.
Doing that also changes the content of the last element of the vector (more specifically, the bool from the myTask header) but not the elements in between.
Does anyone know what causes this? Any help appreciated.
Full implementation code:
#include <concepts>
#include <coroutine>
#include <exception>
#include <iostream>
#include <myTask.h>
#include <vector>
myTask<int> getVectorInt(std::vector<int>& array, int key, bool interleave)
{
std::cout << "started lookup of key: " << key << std::endl;
int result = array.at(key);
if (interleave == true)
{
std::cout << "about to suspend task with key: " << key << std::endl;
co_await std::suspend_always{};
std::cout << "resumed task with key: " << key << std::endl;
}
co_return result;
}
void interleavedExecution(std::vector<int>& lookup, std::vector<int>& keys, std::vector<int>& results)
{
// group size = number of concurrent instruction streams
int groupsize = 3;
// initialization of handle vector
std::vector<std::coroutine_handle<myTask<int>::promise_type>> handles;
// initialization of promise vector
std::vector<myTask<int>::promise_type> promises;
// creating/initializing first handles
for (int i = 0; i < groupsize; ++i)
{
handles.push_back(getVectorInt(lookup, keys.at(i), true));
}
int notDone = groupsize;
int i = groupsize;
// interleaved execution starts here
while (notDone > 0)
{
for (int handleIndex = 0; handleIndex < handles.size(); ++handleIndex)
{
if (!handles.at(handleIndex).promise().isDone())
{
handles.at(handleIndex).resume();
handles.at(handleIndex).promise().boolIsDone = true;
}
else
{
// pushing value back directly into results
results.push_back(handles.at(handleIndex).promise().value_);
if (i < keys.size())
{
// bug here, changes the last boolIsDone also to false (or messes with the last vector element)
handles.at(handleIndex) = getVectorInt(lookup, keys.at(i), true);
handles.at(handleIndex).promise().boolIsDone = false;
++i;
}
else { --notDone; }
}
}
}
}
template <typename T>
void outputVector(std::vector<T> toOutput)
{
std::cout << "Results: ";
for (int i = 0; i < toOutput.size(); ++i)
{
std::cout << toOutput.at(i) << ' ';
}
}
int main()
{
std::vector<int> lookup = {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
std::vector<int> keys = {4, 2, 0, 6, 9, 0};
std::vector<int> results;
// correct output: 50, 30, 10, 70, 100, 10
// given output: 50, 30, 70, 10, 100, 10
interleavedExecution(lookup, keys, results);
outputVector(results);
}
myTask header carrying a bool:
#include <concepts>
#include <coroutine>
#include <exception>
#include <iostream>
template <typename T>
struct myTask {
struct promise_type {
unsigned value_;
~promise_type() {
//std::cout << "promise_type destroyed" << std::endl;
}
myTask<T> get_return_object() {
return myTask<T> {
.h_ = std::coroutine_handle<promise_type>::from_promise(*this)
};
}
std::suspend_never initial_suspend() { return {}; }
std::suspend_never final_suspend() { return {}; }
void unhandled_exception() { std::terminate(); }
std::suspend_always return_value(unsigned value) {
value_ = value;
return {};
}
bool boolIsDone = false;
auto isDone() { return boolIsDone; }
};
std::coroutine_handle<promise_type> h_;
operator std::coroutine_handle<promise_type>() const {
//std::cout << "called handle" << std::endl;
return h_; }
};
It turned out that changing the return type of final_suspend() from std::suspend_never to std::suspend_always fixed the issue.

Find max value in a vector recursively in C++

i am trying to wirte a function to find a the max value in a vector recursively. To do that i want to test in the findMax function if it can return the last value in the list right. But at the end, when the list has just one element, it returns me the adress of variable and not the value. Why is it?
/// finding max value in a list recursively
template <typename T>
int findMax(std::vector<T> arrayVector)
{
if(arrayVector.size()==1)
{
return arrayVector[0];
}
int op1= arrayVector[0];
std::vector<T> newVector (arrayVector.cbegin() + 1, arrayVector.cend());
disPlay(newVector);
int op2= findMax(newVector);
}
/// print vector
template <typename T>
void disPlay(std::vector<T> vectorArray)
{
for (int i=0; i< vectorArray.size(); i++)
{
std::cout << vectorArray[i] << "\t";
}
std::cout << "\n";
}
main()
{
std::vector<int> arrayVector = {6, 8, 19, 20, 23, 41, 49, 53, 56};
std::cout << findMax(arrayVector) << endl;
return 0;
}
I ran you program and it triggered several warnings, the one that probably justifies the unwanted behaviour is the lack of return value in int findMax(std::vector<T> arrayVector).
template <typename T>
int findMax(std::vector<T> arrayVector)
{
if(arrayVector.size()==1)
{
return arrayVector[0];
}
int op1= arrayVector[0];
std::vector<T> newVector (arrayVector.cbegin() + 1, arrayVector.cend());
disPlay(newVector);
int op2= findMax(newVector);
return op2; //<-- added return
}
I corrected the problems in https://wandbox.org/permlink/Kts9qs7MooG4dEQL
It seems ok now.
Use compiler warnings, it can save you a lot of time an headaches.
Now, this solves the issues with your code, but I would advise the use of std::max_element to get max values in a C++ data structure.
Here is a test sample of a function to get the max value recursively in an unordered vector witch loses the last element in each iteration:
template <typename T>
void findMax(std::vector<T>& arrayVector)
{
if(arrayVector.size() == 0) //stop condition
return;
int max = *std::max_element(arrayVector.begin(), arrayVector.end());
std::cout << "Max value: "<< max << std::endl;
arrayVector.erase(arrayVector.end() - 1); //last element being deleted in every recursion
findMax(arrayVector);
}
Check it in https://wandbox.org/permlink/0oyGnXoQdwhl3kUJ
template<typename T>
T findMax(const std::vector<T> vec, size_t index=0){
if(index==vec.size()-1) return vec[vec.size()-1];
return ( vec[index] > findMax(vec,index+1))?vec[index]:findMax(vec,index+1) ;
}
Your code is convoluted:
it's not actually computing the max of the vector
not all paths return a value
you are copying std::vector objects around with no real purpose
STL has the advantage of abstracting iterators, which make your attempt rather trivial:
template<typename T, typename C>
T findMax(C begin, C end)
{
if (begin+1 == end)
return *begin;
else
return std::max(*begin, findMax<T,C>(begin+1, end));
}
Mind: the code is not checking for correctness of input.
Can't be a recursive solution without ol' std::accumulate:
#include <iostream>
#include <vector>
#include <numeric>
#include <limits>
int main(int argc, char *argv[])
{
std::vector<int> arrayVector = {6, 8, 19, 20, 23, 41, 49, 53, 56};
const int max = std::accumulate(
arrayVector.cbegin(),
arrayVector.cend(),
std::numeric_limits<int>::min(),
[](int x, int y) { return x > y ? x : y; }
);
std::cout << max << '\n';
return 0;
}
Earlier solution by Rietty to similar question and solutions in this thread follow vector from 0 to end. Next follows vector from end to 0 to simplify recursive function:
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
template<typename T>
T findMax (vector<T> values, size_t end) {
if (0 == end) return values[0];
return max (findMax (values, end - 1), values[end]);
}
template<typename T>
T inline findMax (vector<T> values) {
return findMax (values, values.size() - 1);
}
int main () {
vector<int> values = { 6, 8, 19, 20, 23, 41, 49, 53, 56 };
cout << findMax (values) << endl;
return 0;
}
Simple code:
int find_max(int a[], int length){
if (length == 0) return a[length];
return std::max(a[length-1], find_max(a, length-1));
}
#include "iostream"
#include "vector"
using namespace std;
int maxre(vector<int> array);
int main()
{
vector<int> data = {210, 800, 2,150 ,19,600};
cout << maxre(data);
return 0;
}
int maxre(vector<int> array)
{
static int index = -1;
if (array.size() == index + 1)
{
return 0;
}
else
{
index++;
int current = array[index];
int back = maxre(array);
return current > back ? current : back;
}
return 0;
}

Why is trying to store a pointer to function ambiguous

Here is my code:
#include <functional>
#include <iostream>
#include<vector>
using namespace std;
// vector iterator
template <class T> class vit
{
private:
//vector<T>::iterator it;
vector<T> m_v;
function<bool (T, T)> m_fptr;
int len, pos;
public:
vit(vector<T> &v) { this->m_v = v; len = v.size(); pos = 0;};
// it= v.begin(); };
bool next(T &i) {
//if(it == m_v.end()) return false;
if(pos==len) return false;
//i = *it;
i = m_v[pos];
//if(idle) { idle = false ; return true; }
//it++;
pos++;
return true;};
//bool idle = true;
void set_same(function<bool (T,T)> fptr) { m_fptr = fptr ;};
//void set_same(function<bool(int, int)> fun) { return ; }
bool grp_begin() {
return pos == 0 || ! m_fptr(m_v[pos], m_v[pos-1]); };
bool grp_end() {
return pos == len || ! m_fptr(m_v[pos], m_v[pos+1]); };
};
bool is_same(int a, int b) { return a == b; }
main()
{
vector<int> v ={ 1, 1, 2, 2, 2, 3, 1, 1, 1 };
int total;
for(auto it = v.begin(); it != v.end(); it++) {
if(it == v.begin() || *it != *(it-1)) {
total = 0;
}
total += *it;
if(it+1 == v.end() || *it != *(it+1)) {
cout << total << endl;
}
}
cout << "let's gry a group" <<endl;
vit<int> g(v);
int i;
while(g.next(i)) { cout << i << endl; }
cout << "now let's get really fancy" << endl;
vit<int> a_vit(v);
//auto is_same = [](int a, int b) { return a == b; };
a_vit.set_same(is_same);
//int total;
while(a_vit.next(i)) {
if(a_vit.grp_begin()) total = 0;
total += i;
if(a_vit.grp_end()) cout << total << endl ;
}
}
When I compile it with g++ -std=c++11 iter.cc -o iter, I get the result:
iter.cc: In function 'int main()':
iter.cc:63:17: error: reference to 'is_same' is ambiguous
a_vit.set_same(is_same);
^
iter.cc:37:6: note: candidates are: bool is_same(int, int)
bool is_same(int a, int b) { return a == b; }
^
In file included from /usr/include/c++/5.3.0/bits/move.h:57:0,
from /usr/include/c++/5.3.0/bits/stl_pair.h:59,
from /usr/include/c++/5.3.0/utility:70,
from /usr/include/c++/5.3.0/tuple:38,
from /usr/include/c++/5.3.0/functional:55,
from iter.cc:1:
/usr/include/c++/5.3.0/type_traits:958:12: note: template<class, class> struct std::is_same
struct is_same;
^
By way of explanation, I have created a class called 'vit'. It does two things: iterate over a vector, and determine if a new group has been reached.
The class function 'set_same' is supposed to store a function provided by the calling class to determine if two adjacent elements of a vector are in the same group. However, I can't seem to store the function in the class for future use by grp_begin() and grp_end() on account of the ostensible ambiguity of is_same.
What gives?
There is an is_same function defined by you and there is a struct is_same defined by the C++ Standard Library. Since you are using namespace std, your compiler doesn't know which is_same you meant to use.
It's what the error says: it's not clear whether you mean your is_same (in the global namespace) or the class template is_same (in namespace std).
You may disambiguate as follows:
::is_same
… with the leading :: meaning "in the global namespace".
Though you should consider putting your code in a namespace of its own.
Thanks guys. This is my first time touching C++ after more than a decade. I have cleaned up the code, and used a lambda to bring the "is_same" function closer to where it is called.
Did you spot the bug in my code? 'pos' was off-by-one when calling grp_begin() and grp_end(). Here is the revised code:
#include <functional>
#include <iostream>
#include <vector>
// vector iterator
template <class T> class vit
{
private:
std::vector<T> m_v;
std::function<bool (T, T)> m_fptr;
int len, pos;
public:
vit(std::vector<T> &v) { m_v = v; len = v.size(); pos = -1;};
bool next(T &val) {
pos++;
if(pos==len) return false;
val = m_v[pos];
return true;};
void set_same(std::function<bool (T,T)> fptr) { m_fptr = fptr ;};
bool grp_begin() {
return pos == 0 || ! m_fptr(m_v[pos], m_v[pos-1]); };
bool grp_end() {
return pos+1 == len || ! m_fptr(m_v[pos], m_v[pos+1]); };
};
main()
{
std::vector<int> v ={ 1, 1, 2, 2, 2, 3, 1, 1, 1 };
vit<int> a_vit(v);
std::function<bool (int, int)> is_same = [](int a, int b) { return a == b; };
a_vit.set_same(is_same);
int i, total;
while(a_vit.next(i)) {
if(a_vit.grp_begin()) total = 0;
total += i;
if(a_vit.grp_end()) std::cout << total << std::endl ;
}
}
My class definition isn't bullet-proof and could be better: if the user forgets to 'set-same', for example, they'll be referring a random memory address as a function.
Nevertheless, I'm pretty chuffed with my solution so far. The class caller is relieved of all the bookkeeping relating iterating over the vector, and working out if a group boundary has been crossed.
The calling code looks very compact and intuitive to me.I can see C++ being my go to language.

Eigen C++ wrapping assignment

In Matlab, it is possible to do the following:
% init
a = 1:10;
b = 18:23;
% wrapping assignment
a([8:end 1:3]) = b;
Is something like this possible with Eigen? I'm hoping to make a member function for a circular buffer class that returns some reference to an Eigen type, perhaps something like:
VectorXd b(5);
b << 1,2,3,4,5 ;
CircularBuf a( 6 /*capacity*/ );
a.push(1);a.push(2);a.push(3);
// 3 elements in buf
a.pop();a.pop();
// 1 element in buf
// next line probably wraps around internal buffer, depending on impl
a.pushRef( b.size() /*number of elements in ref*/ ) = b;
I am not sure if this is what you are looking for...Following an answer I got from Jerry Coffin, I came up with this:
#include <iostream>
#include <vector>
#include <iterator>
template <class T>
class CircularVector {
typedef std::vector<T> DVector;
public:
CircularVector(const DVector& v) : v(v){}
T at(int i){return v.at(i);}
int size(){return v.size();}
class iterator :
public std::iterator < std::random_access_iterator_tag, T > {
CircularVector *vec;
int index;
public:
iterator(CircularVector &d, int index) : vec(&d), index(index) {}
iterator &operator++() { nextIndex(); return *this; }
iterator operator++(int) {
iterator tmp(*vec, index); nextIndex(); return tmp;
}
iterator operator+(int off) {
return iterator(*vec, (index + off)%vec->size());
}
iterator operator-(int off) {
return iterator(*vec, (index - off + vec->size())%vec->size());
}
T& operator*() { return (*vec).v[index]; }
bool operator!=(iterator const &other) { return index != other.index; }
//bool operator<(iterator const &other) { return index < other.index; }
private:
void nextIndex(){
++index;
if (index==vec->size()){index=0;}
}
};
iterator begin() { return iterator(*this, 0); }
//iterator end() { return iterator(*this, size()); }
private:
DVector v;
};
Your first example then can be written as:
int main() {
std::vector<int> a;
std::vector<int> b;
for(int i=1;i<11;i++){a.push_back(i);}
for(int i=18;i<24;i++){b.push_back(i);}
CircularVector<int> ca(a);
std::copy(b.begin(),b.end(),ca.begin()+7); // copy elements starting
// at index 8
for (int i=0;i<ca.size();i++){std::cout << ca.at(i) << std::endl;}
}
Actually, I was just curious to try it and I believe there are nicer ways to implement it. It is not the most efficient way to check if the index has to be wrapped each time it is increased. Obviously < and end() are not quite meaningful for a circular buffer and I decided not to implement them (e.g. for(it=begin();it<end();it++) would be an infinite loop. However, those are not needed to use it as input/output iterator.
I have another solution as described in my answer to this question. The code posted in the answer defines a custom expression for the circular shift, so you can benefit from Eigen's optimisations.
Given the circ_shift.h from the mentioned answer, you can do the following to achieve your goal: I hope this helps...
// main.cpp
#include "stdafx.h"
#include "Eigen/Core"
#include <iostream>
#include "circ_shift.h" // posted in the answer to the other quesiton.
using namespace Eigen;
int main()
{
VectorXi a(10), b(6);
a << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
b << 18, 19, 20, 21, 22, 23;
std::cout << "a = " << a.transpose() << std::endl << "b = " << b.transpose() << std::endl;
circShift(a, 3, 0).block(0, 0, b.size(), 1) = b;
std::cout << "now: a = " << a.transpose() << std::endl; // prints 21, 22, 23, 4, 5, 6, 7, 18, 19, 20
return 0;
}