// Compara T(n), calculado con la recurrencia, con la solución que dice la teoría. Si la solución
// es correcta, la razón se acerca a una constante. Es aritmética: no corre ningún algoritmo, y por
// eso puede llegar a n = 2^1024.
#include <cmath>
#include <iomanip>
#include <iostream>

#include "recurrences.h"

int main() {
    std::cout << "log n  8T+n^2   3T+n     T+1      2T+n     2T+nlogn  2T+n/logn\n";
    std::cout << "       /n^3     /n^1,585 /log n   /nlogn   /nlog^2n  /nloglogn\n";
    std::cout << std::fixed << std::setprecision(3);
    long double log2_of_3 = std::log2(3.0L);
    for (int k = 4; k <= 1024; k *= 2) {
        long double kk = k;
        long double n = std::ldexp(1.0L, k);
        std::cout << std::left << std::setw(7) << k << std::right;
        std::cout << std::setw(5) << solve_power_of_two<long double>(8, k, f_n2) / (n * n * n) << "    ";
        std::cout << std::setw(5) << solve_power_of_two<long double>(3, k, f_n) / std::pow(n, log2_of_3) << "    ";
        std::cout << std::setw(5) << solve_power_of_two<long double>(1, k, f_one) / kk << "    ";
        std::cout << std::setw(5) << solve_power_of_two<long double>(2, k, f_n) / (n * kk) << "    ";
        std::cout << std::setw(5) << solve_power_of_two<long double>(2, k, f_n_log_n) / (n * kk * kk) << "     ";
        std::cout << std::setw(5) << solve_power_of_two<long double>(2, k, f_n_over_log_n) / (n * std::log2(kk)) << '\n';
    }
}
