#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--- 試行 #%d: (初期値 x0=%.2f, y0=%.2f) ---\n", attempt, x0, y0);
    printf("%-5s %-15s %-15s\n", "反復", "x", "y");

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

        // 各反復のx, yを表示
        printf("%-5d %-15.10f %-15.10f\n", iter, x, y);

        // 収束判定: |f1| < 10^-5 かつ |f2| < 10^-5
        if (fabs(F1) < EPSILON && fabs(F2) < EPSILON) {
            printf(">> 結果: 反復回数 %d 回で収束しました。\n", iter);
            printf(">> 解: (x = %.5f, y = %.5f)\n", x, y);
            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(">> 結果: 失敗 (ヤコビ行列の行列式が小さすぎます)。\n");
            return;
        }

        x += (-F1 * J22 + F2 * J12) / det;
        y += (-J11 * F2 + J21 * F1) / det;
        iter++;
    }
    printf(">> 結果: 失敗 (%d 回の反復内に収束しませんでした)。\n", MAX_ITER);
}

int main() {
    // 異なる3組の初期値(x0, y0)で計算すること
    double initial_x[] = {2.0, -1.0, 0.5};
    double initial_y[] = {-3.0, 1.0, -2.0};

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

    return 0;
}