// Sigue los ejemplos de los apuntes: selección, aulas y una idea para las aulas que falla.
#include <iostream>
#include <vector>

#include "intervals.h"

int main() {
    const std::vector<Interval> week = {{8, 10}, {9, 11}, {10, 12}, {11, 13}, {8, 13}, {12, 14}, {13, 15}, {15, 16}};
    const auto chosen = select_by_finish(week);
    std::cout << "Selección (" << chosen.size() << " clases, óptimo " << max_compatible_brute(week) << "):";
    for (const Interval& c : chosen) std::cout << " [" << c.start << "," << c.finish << ")";
    std::cout << '\n';

    // El intercambio, a partir de una solución óptima que no se parece a la del greedy.
    std::vector<Interval> optimal = {{9, 11}, {11, 13}, {13, 15}, {15, 16}};
    std::cout << "Intercambio, empezando en:";
    for (const Interval& c : optimal) std::cout << " [" << c.start << "," << c.finish << ")";
    std::cout << '\n';
    for (std::size_t j = 0; j < chosen.size(); j++) {
        if (optimal[j] == chosen[j]) continue;
        optimal[j] = chosen[j];
        std::cout << "  posición " << j + 1 << ":";
        for (const Interval& c : optimal) std::cout << " [" << c.start << "," << c.finish << ")";
        std::cout << (is_valid(optimal) ? "  válida\n" : "  INVÁLIDA\n");
    }

    const auto room = assign_rooms(week);
    std::cout << "Aulas: " << rooms_used(room) << ", máximo simultáneo: " << max_simultaneous(week) << '\n';
    for (std::size_t i = 0; i < week.size(); i++) {
        std::cout << "  [" << week[i].start << "," << week[i].finish << ") -> aula " << room[i] << '\n';
    }

    const std::vector<Interval> tricky = {{10, 11}, {8, 12}, {11, 17}, {15, 16}};
    std::cout << "Clases [10,11) [8,12) [11,17) [15,16)\n";
    std::cout << "  llenar aula por aula con la selección: " << rooms_by_repeated_selection(tricky) << " aulas\n";
    std::cout << "  por orden de inicio: " << rooms_used(assign_rooms(tricky)) << " aulas\n";
    std::cout << "  mínimo por fuerza bruta: " << min_rooms_brute(tricky) << " aulas\n";
    std::cout << "  máximo simultáneo: " << max_simultaneous(tricky) << '\n';

    const std::vector<Interval> touching = {{8, 10}, {10, 12}};
    std::cout << "Clases [8,10) y [10,12): se cruzan = " << (overlap(touching[0], touching[1]) ? "sí" : "no")
              << ", aulas = " << rooms_used(assign_rooms(touching)) << '\n';
}
