#include <iostream>
#include <vector>
#include <algorithm>
#include <numeric>
#include <string>
#include <ctime>
#include <random>

using namespace std;

// concatenate two strings with delimiter ":"
string myconcat( string a, string b)
{
    return (a.length() == 0) ? b : a + string(":") + b;
}

// concatenate a string with a number converted to a string
string numconcat( string a, int b)
{
    return a + ((a.size() == 0 ) ? "" : ", " ) + to_string(b);
}

// get a random number from 0 to 99
int genRandom() {
    return rand() % 100;
}

int main()
{
    vector<int> numbers;
    for( int i=0; i<100; i++ )
        numbers.push_back(i);

    // calculate sum by iteration
    int sum=0;
    for( auto p = numbers.begin(); p != numbers.end(); p++ )
        sum += *p;
    
    cout << "The sum from 0 to 99 is " << sum << endl;
    
    // use accumulate( start, end, initial value)
    int sum_acc = accumulate( numbers.begin(), numbers.end(), 0 );
    cout << "The sum by accumulate is " << sum_acc << endl;
    
    vector<string> words;
    words.push_back("I ");
    words.push_back("am ");
    words.push_back("a ");
    words.push_back("boy. ");
    
    // use accumulate to concatenate string vector
    string sentence = accumulate( words.begin(), words.end(), string(""), myconcat );
    cout << sentence << endl;
 
    // use accumulate to print out all the numbers of an integer vector
    cout << accumulate( numbers.begin(), numbers.end(), string(""), numconcat ) << endl;
    
    // use replace()
    replace( numbers.begin(), numbers.end(), 10, 100 );
    cout << accumulate( numbers.begin(), numbers.end(), string(""), numconcat ) << endl;
    replace( words.begin(), words.end(), string("a "), string("two ") );
    cout << accumulate( words.begin(), words.end(), string("")) << endl;
    
    // use fill()
    fill( numbers.begin(), numbers.begin()+3, 0 );
    cout << accumulate( numbers.begin(), numbers.end(), string(""), numconcat ) << endl;

    // sort
    sort( words.begin(), words.end() );
    cout << accumulate( words.begin(), words.end(), string("") ) << endl;
    
    // copy
    vector<int> newnum(10);
    fill( newnum.begin(), newnum.end(), 0 );
    copy( numbers.begin()+3, numbers.begin()+13, newnum.begin() );
    cout << accumulate( newnum.begin(), newnum.end(), string(""), numconcat ) << endl;
    
    // generate
    vector<int> randnums(10);
    srand((unsigned int)time(NULL));
    /*for( int i=0; i< randnums.size(); i++ )
     randnums[i] = rand() % 100;
     */
    generate( randnums.begin(), randnums.end(), genRandom );
    
    for( int i=0; i< randnums.size(); i++ )
        cout << randnums[i] << ",";
    cout << endl;
    
    system("pause");
}