// Las instancias que siguen los apuntes.
#ifndef INSTANCES_H
#define INSTANCES_H

#include "matching.h"

// El ejemplo con cuatro tesistas y cuatro asesores.
inline Preferences example_students() {
    return {{1, 0, 2, 3}, {1, 2, 0, 3}, {0, 1, 3, 2}, {0, 3, 2, 1}};
}
inline Preferences example_advisors() {
    return {{0, 3, 2, 1}, {1, 0, 2, 3}, {0, 1, 2, 3}, {3, 2, 0, 1}};
}

// Dos tesistas y dos asesores que no coinciden en nada: hay dos matchings estables.
inline Preferences crossed_students() {
    return {{0, 1}, {1, 0}};
}
inline Preferences crossed_advisors() {
    return {{1, 0}, {0, 1}};
}

// Todos los proponentes tienen la misma lista, y todos los receptores prefieren al último
// que llega. Obliga a hacer n(n + 1)/2 propuestas, cada una con una comparación cara.
inline Preferences same_list_proposers(int n) {
    std::vector<int> list(n);
    for (int i = 0; i < n; i++) list[i] = i;
    return Preferences(n, list);
}
inline Preferences latest_wins_receivers(int n) {
    std::vector<int> list(n);
    for (int i = 0; i < n; i++) list[i] = n - 1 - i;
    return Preferences(n, list);
}

// Listas al azar, con semilla fija. Usa std::mt19937 directamente: da lo mismo en toda máquina.
inline Preferences random_preferences(int n, std::mt19937& gen) {
    Preferences prefs(n, std::vector<int>(n));
    for (auto& list : prefs) {
        for (int i = 0; i < n; i++) list[i] = i;
        for (int i = n - 1; i > 0; i--) {
            int j = static_cast<int>(gen() % static_cast<unsigned>(i + 1));
            std::swap(list[i], list[j]);
        }
    }
    return prefs;
}

#endif
