/*
Napisz klasę, która umożliwia dodawanie liczb całkowitych (metoda "add").
Klasa musi zawierać metodę, która zwraca medianę liczb przechowywanych w klasie.
Liczenie mediany uznajemy za czasochłonne i chcemy uniknąć przeliczania jej na
nowo za każdym razem, kiedy ktoś poprosi o zwrócenie mediany lub gdy zostanie
dodana nowa liczba do obiektu, w związku z czym należy zadbać o odpowiedni
moment policzenia mediany.
Zwróć uwagę na constowość oraz optymalne czasowo przekazywanie danych do funkcji.
Podpowiedź: jeżeli chodzi o stan wewnętrzny klasy - mediana może być policzona lub nie (optional).
Uwaga: Sytuacją szczególną jest to, gdy w kolekcji nie ma żadnych wartości.

rozwiązanie:
*/

#include <algorithm>
#include <optional>
#include <vector>

class Collection {
public:
  void add(int value) { m_data.push_back(value); m_median = std::nullopt; }
  std::optional<int> median() const {
    if (!m_median && !m_data.empty()) {
      auto copy = m_data;
      std::nth_element(copy.begin(), copy.begin()+copy.size()/2, copy.end());
      m_median = copy[copy.size()/2];
    }
    return m_median;
  }
private:
  std::vector<int> m_data;
  mutable std::optional<int> m_median;
};

#include <cassert>

int main() {
  Collection collection;
  assert(!collection.median().has_value());
  collection.add(1);
  collection.add(2);
  collection.add(0);
  assert(collection.median() && *collection.median() == 1);
}

