// Prueba todos los órdenes de inserción de n claves, y anota lo peor que pasó en una inserción.
#include <algorithm>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <vector>

#include "avl_set.h"

int main() {
    std::cout << std::setw(3) << "n" << std::setw(8) << "ordenes" << std::setw(7) << "h.min" << std::setw(7) << "h.max"
              << std::setw(18) << "max.reparaciones" << std::setw(16) << "max.rotaciones" << "\n";
    for (int n = 1; n <= 9; n++) {
        std::vector<int> keys(n);
        std::iota(keys.begin(), keys.end(), 1);
        long orders = 0;
        int min_height = n;
        int max_height = -1;
        std::size_t max_repairs = 0;
        long max_rotations = 0;
        do {
            AvlSet<int> tree;
            for (int key : keys) {
                long before = tree.rotations();
                tree.insert(key);
                max_repairs = std::max(max_repairs, tree.last_repairs().size());
                max_rotations = std::max(max_rotations, tree.rotations() - before);
            }
            min_height = std::min(min_height, tree.height());
            max_height = std::max(max_height, tree.height());
            orders++;
        } while (std::next_permutation(keys.begin(), keys.end()));
        std::cout << std::setw(3) << n << std::setw(8) << orders << std::setw(7) << min_height << std::setw(7) << max_height
                  << std::setw(18) << max_repairs << std::setw(16) << max_rotations << "\n";
    }
    return 0;
}
