#include <iostream>
#include <vector>
#include <set>
#include <string>
#include <algorithm>

using std::string;
using std::vector;
using std::set;
using std::find_if;
using std::copy_if;
using std::copy;
using std::back_inserter;

using ObjectId = int64_t;

struct GameObject {
    ObjectId id;
    string name;
    size_t x;
    size_t y;
};

bool operator>(const GameObject& lhs, const GameObject& rhs) {
    return lhs.id > rhs.id;
}

class GameDatabase {
 public:
  GameDatabase() = default;

    /// вставляет в базу объект с именем [name] и позицией [x, y]
    /// если объект с таким id в базе уже есть, заменяет его новым
  void Insert(ObjectId id, string name, size_t x, size_t y) {
    GameObject game_object({ id, name, x, y });
    if (data_base_.count(game_object) == 0) {
      data_base_.insert(game_object);
    } else {
      data_base_.erase(game_object);
      data_base_.insert(game_object);
    }
  }

    /// удаляет элемент по id
    /// если такого элемента нет, ничего не делает
  void Remove(ObjectId id) {
    const auto it_end = find_if(data_base_.begin(), data_base_.end(),
            [id](const GameObject& game_object) {
                return game_object.id == id;
            });
        if (it_end != data_base_.end()) {
            data_base_.erase(it_end);
        }
    }

    /// возвращает вектор объектов c именем [name]
    /// сортировка по убыванию id
    vector<GameObject> DataByName(string name) const {
        vector<GameObject> game_objects;
        copy_if(data_base_.begin(), data_base_.end(),
            back_inserter(game_objects),
            [name](const GameObject& game_object) {
                return game_object.name == name;
            });
    }

    /// возвращает вектор объектов, находящихся в позиции [x, y]
    /// сортировка по убыванию id
    vector<GameObject> DataByPosition(size_t x, size_t y) const {
        vector<GameObject> game_objects;
        copy_if(data_base_.begin(), data_base_.end(),
        back_inserter(game_objects),
            [x, y](const GameObject& game_object) {
                return game_object.x == x &&
                    game_object.y == y;
            });
    }

    /// возвращает вектор всех объектов из базы
    /// сортировка по убыванию id
    vector<GameObject> Data() const {
        vector<GameObject> game_objects;
        copy(data_base_.begin(), data_base_.end(), back_inserter(game_objects));
    }

 private:
    set<GameObject> data_base_;
};