// Cuatro experimentos con la franja del par más cercano, con fuerza bruta y un solo nivel de la división.
#include <cstdio>
#include <vector>

#include "strip.h"

static void print_step(const RootStep& step) {
    std::printf("linea x = %lld\n", step.line);
    std::printf("mejor izquierda = %lld, mejor derecha = %lld, delta^2 = %lld\n", step.left_best, step.right_best, step.delta2);
    std::printf("franja por y:");
    for (const StripPoint& p : step.strip) {
        std::printf(" (%lld,%lld)%c", p.point.x, p.point.y, p.from_left ? 'I' : 'D');
    }
    std::printf("\n");
}

int main() {
    std::printf("1. Ejemplo de los apuntes\n");
    std::vector<Point> example = {{1, 9}, {2, 3}, {3, 7}, {4, 1}, {5, 5}, {6, 4}, {7, 10}, {8, 8}, {9, 2}, {10, 6}};
    RootStep root = analyze_root(example);
    print_step(root);
    for (std::size_t i = 0; i < root.strip.size(); i++) {
        for (std::size_t j = i + 1; j < root.strip.size(); j++) {
            long long d = dist2(root.strip[i].point, root.strip[j].point);
            std::printf("  posiciones %zu y %zu: distancia^2 %lld%s\n", i, j, d, d < root.delta2 ? "  mejora" : "");
        }
    }
    std::printf("respuesta = %lld, fuerza bruta = %lld\n\n", root.best_in_strip, brute_force(example));

    std::printf("2. No basta con los puntos mas cercanos a la linea en x\n");
    std::vector<Point> near_line = {{-2, 0}, {-1, 100}, {1, -100}, {2, 0}};
    RootStep second = analyze_root(near_line);
    print_step(second);
    std::printf("distancia^2 entre los mas cercanos a la linea: %lld\n", dist2({-1, 100}, {1, -100}));
    std::printf("fuerza bruta = %lld\n\n", brute_force(near_line));

    std::printf("3. No basta con comparar con el siguiente\n");
    std::vector<Point> next_only = {{-9, 50}, {-1, 0}, {0, 2}, {8, 1}};
    RootStep third = analyze_root(next_only);
    print_step(third);
    std::printf("solo con el siguiente: %lld\n", best_with_window(third, 1));
    std::printf("con los 7 siguientes: %lld\n", best_with_window(third, 7));
    std::printf("fuerza bruta = %lld\n\n", brute_force(next_only));

    std::printf("4. La respuesta a 3 posiciones\n");
    std::vector<Point> three_apart = {{-99, 50}, {0, 0}, {1, 99}, {99, 51}};
    RootStep fourth = analyze_root(three_apart);
    print_step(fourth);
    for (std::size_t window = 1; window <= 3; window++) {
        std::printf("con los %zu siguientes: %lld\n", window, best_with_window(fourth, window));
    }
    std::printf("fuerza bruta = %lld\n", brute_force(three_apart));
}
