// Copyright (C) 2026 Kiyotsugu Arai
// SPDX-License-Identifier: LGPL-3.0-or-later

// example_polynomial_factorization.cpp
// Factorization of integer polynomials: Yun squarefree factorization + rational root theorem + Kronecker's method
//
// Build: CMake target example_polynomial_factorization

#include <math/core/Polynomial.hpp>
#include <math/core/Polynomial_factorization.hpp>
#include <math/core/FactoredInteger.hpp>
#include <iostream>

namespace {

template <typename T>
void print(const sangi::Polynomial<T>& f, const sangi::FactoredInteger<sangi::Polynomial<T>>& factors) {
    std::cout << "f = " << f << "\n";
    for (std::size_t i = 0; i < factors.size(); ++i) {
        std::cout << "  (" << factors[i] << ")";
        if (factors.exponent(i) > 1)
            std::cout << "^" << factors.exponent(i);
        std::cout << "\n";
    }
    std::cout << "\n";
}

}  // namespace

int main() {
    using namespace sangi;

    // x^4 - 1 = (x-1)(x+1)(x^2+1)
    Polynomial<int> f1 = {-1, 0, 0, 0, 1};
    print(f1, factorize(f1));

    // x^5 - x^4 - x + 1 = (x-1)^2 (x+1)(x^2+1) -- repeated factor
    Polynomial<int> f2 = {1, -1, 0, 0, -1, 1};
    print(f2, factorize(f2));

    // 2x^3 - 5x^2 - 4x + 3 = (2x-1)(x-3)(x+1) -- rational roots
    Polynomial<int> f3 = {3, -4, -5, 2};
    print(f3, factorize(f3));

    // Resultant and discriminant
    Polynomial<int> f = {-2, 0, 1};  // x^2 - 2
    std::cout << "Disc(x^2 - 2) = " << discriminant(f) << "\n";  // 8
    std::cout << "Res(f, f') = " << resultant(f, f.derivative()) << "\n";
}
