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

#define EPSILON 1e-5 
#define MAX_ITER 100

double f1(double x, double y) { return x * x + y * y - 4; }
double f2(double x, double y) { return pow(x, 4) + x - y * y + 1; }

double df1_dx(double x, double y) { return 2 * x; }
double df1_dy(double x, double y) { return 2 * y; }
double df2_dx(double x, double y) { return 4 * x * x * x + 1; }
double df2_dy(double x, double y) { return -2 * y; }

void solve(int attempt, double x0, double y0) {
    double x = x0, y = y0;
    int iter = 0;

    printf("\n--- Guess #%d: (x0=%.2f, y0=%.2f) ---\n", attempt, x0, y0);
    printf("%-5s %-15s %-15s\n", "Iter", "x", "y");

    while (iter <= MAX_ITER) {
        double F1 = f1(x, y);
        double F2 = f2(x, y);

        // Print current state (Iter, x, y)
        printf("%-5d %-15.10f %-15.10f\n", iter, x, y);

        // Slide requirement: |f1| < 10^-5 AND |f2| < 10^-5
        if (fabs(F1) < EPSILON && fabs(F2) < EPSILON) {
            printf(">> Result: Converged to root (%.5f, %.5f) at iter %d\n", x, y, iter);
            return;
        }

        double J11 = df1_dx(x, y);
        double J12 = df1_dy(x, y);
        double J21 = df2_dx(x, y);
        double J22 = df2_dy(x, y);

        double det = J11 * J22 - J12 * J21;
        if (fabs(det) < 1e-12) {
            printf(">> Result: Failed (Jacobian determinant too small).\n");
            return;
        }

        x += (-F1 * J22 + F2 * J12) / det;
        y += (-J11 * F2 + J21 * F1) / det;
        iter++;
    }
    printf(">> Result: Failed (Reached Max Iterations).\n");
}

int main() {
    // 3 Different Initial Values as required by the assignment
    double initial_x[] = {1.2, -1.0, 0.5};
    double initial_y[] = {1.5, 1.0, -1.8};

    for (int i = 0; i < 3; i++) {
        solve(i + 1, initial_x[i], initial_y[i]);
    }

    return 0;
}