#include <stdio.h>
#include <math.h>

#define EPSILON 1e-10
#define MAX_ITER 100

#define ROOT_TOL 1e-4   // tolerance for treating roots as identical

double f(double x) {
    return (((x*x*x*x) + x*x*x) - 54.0*x*x - 224.0*x - 345.0);
}

double df(double x) {
    return (4.0*x*x*x + 3.0*x*x - 108.0*x - 224.0);
}

double newton(double x0) {
    double x = x0;

    for (int i = 0; i < MAX_ITER; i++) {
        double fx = f(x);
        double dfx = df(x);

        if (fabs(dfx) < 1e-12) break;

        double dx = fx / dfx;
        x -= dx;

        if (fabs(dx) < EPSILON) return x;
    }

    return x;
}

int is_duplicate(double x, double roots[], int count) {
    for (int i = 0; i < count; i++) {
        if (fabs(x - roots[i]) < ROOT_TOL) return 1;
    }
    return 0;
}

int main() {
    double guesses[] = {10.0, 3.0, 1.0, -6.0};
    double roots[4];
    int found = 0;

    printf("=== Newton-Raphson roots (deduplicated) ===\n");

    for (int i = 0; i < 4; i++) {
        double r = newton(guesses[i]);

        if (!is_duplicate(r, roots, found)) {
            roots[found++] = r;
            printf("Root %d: %.10f\n", found, r);
        }
    }

    return 0;
}
