#include <iostream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <set>
#include <map>
#include <ranges>

// this is a demonstration of the algorithms from the standard library

int main() {
    // TODO: read a sequence of integers from stdin and store them in a vector
    //   there is a twist: use std::copy, std::istream_iterator and std::back_inserter
    //   <https://en.cppreference.com/w/cpp/iterator/istream_iterator>
    //   <https://en.cppreference.com/w/cpp/iterator/back_insert_iterator>

    // TODO: print the numbers in the vector using std::copy, std::ostream_iterator and std::cout; separate the numbers with a newline
    //   <https://en.cppreference.com/w/cpp/iterator/ostream_iterator>

    // TODO: sort the vector using std::sort; compare the numbers using std::greater<int> (reverse order)

    // TODO: print the squares of the numbers in the vector using std::transform, std::ostream_iterator and std::cout; separate the numbers with a newline
    //   use a lambda expression to square the numbers

    // TODO: remove all the numbers that are divisible by 3 using std::remove_if and a subsequent std::vector::erase
    //   you can write both algorithms as a single statement

    // TODO: insert the numbers into a set using std::copy and std::inserter, you have to pass some iterator to the inserter (begin or end) as well

    // TODO: create a map that maps the numbers to their order in the set using std::transform, std::views::iota (creates a pseudo-container with a range of numbers), std::inserter and std::make_pair<const int&, const int&>
    //   <https://en.cppreference.com/w/cpp/algorithm/transform>
    auto order = std::views::iota(1); // contains 1, 2, ...; use order.begin() as the second begin to std::transform

    // TODO: print the pairs in the map using std::for_each and a lambda expression (it can take an `auto` parameter; use .first and .second to access the members)
}