// #include <stdio.h>
// #include <stdlib.h>
// #include <time.h>

// #ifndef N
// #define N 500 // 800
// #endif

// static double elapsed_seconds(clock_t start, clock_t end)
// {
//     return (double)(end - start) / CLOCKS_PER_SEC;
// }

// static void initialize_matrix(double *matrix, int n, double value)
// {
//     for (int i = 0; i < n * n; i++) {
//         matrix[i] = value;
//     }
// }

// /* Loop order: i-j-k.  B[k][j] is accessed column-wise in row-major C. */
// static void matmul_ijk(const double *a, const double *b, double *c, int n)
// {
//     for (int i = 0; i < n; i++) {
//         for (int j = 0; j < n; j++) {
//             double sum = 0.0;
//             for (int k = 0; k < n; k++) {
//                 sum += a[i * n + k] * b[k * n + j];
//             }
//             c[i * n + j] = sum;
//         }
//     }
// }

// /* Loop order: i-k-j.  B[k][j] and C[i][j] are accessed row-wise. */
// static void matmul_ikj(const double *a, const double *b, double *c, int n)
// {
//     for (int i = 0; i < n; i++) {
//         for (int k = 0; k < n; k++) {
//             double aik = a[i * n + k];
//             for (int j = 0; j < n; j++) {
//                 c[i * n + j] += aik * b[k * n + j];
//             }
//         }
//     }
// }

// static double checksum(const double *matrix, int n)
// {
//     double result = 0.0;
//     for (int i = 0; i < n * n; i++) {
//         result += matrix[i];
//     }
//     return result;
// }

// int main(void)
// {
//     const int n = N;
//     const size_t bytes = (size_t)n * n * sizeof(double);

//     double *a = malloc(bytes);
//     double *b = malloc(bytes);
//     double *c = malloc(bytes);

//     if (a == NULL || b == NULL || c == NULL) {
//         fprintf(stderr, "Memory allocation failed for N=%d\n", n);
//         free(a);
//         free(b);
//         free(c);
//         return 1;
//     }

//     initialize_matrix(a, n, 1.0);
//     initialize_matrix(b, n, 2.0);

//     initialize_matrix(c, n, 0.0);
//     clock_t start_ijk = clock();
//     matmul_ijk(a, b, c, n);
//     clock_t end_ijk = clock();
//     double time_ijk = elapsed_seconds(start_ijk, end_ijk);
//     double check_ijk = checksum(c, n);

//     initialize_matrix(c, n, 0.0);
//     clock_t start_ikj = clock();
//     matmul_ikj(a, b, c, n);
//     clock_t end_ikj = clock();
//     double time_ikj = elapsed_seconds(start_ikj, end_ikj);
//     double check_ikj = checksum(c, n);

//     printf("N = %d\n", n);
//     printf("i-j-k time = %.6f seconds, checksum = %.2f\n", time_ijk, check_ijk);
//     printf("i-k-j time = %.6f seconds, checksum = %.2f\n", time_ikj, check_ikj);

//     free(a);
//     free(b);
//     free(c);
//     return 0;
// }


#include <stdio.h>
#include <time.h>

#define N 1000000
#define PI 3.141592653589793

static double radius[N];
static double area[N];
static double diameter[N];
static double circumference[N];

int main(void)
{
    int i;
    clock_t start, end;
    double time_one_record, time_one_operation;
    double check = 0.0;

    /* Create one million records. */
    for (i = 0; i < N; i++) {
        radius[i] = (i % 100) + 1.0;
    }

    /* Method 1: process one record completely, then move to the next. */
    start = clock();

    for (i = 0; i < N; i++) {
        double r = radius[i];

        area[i] = PI * r * r;
        diameter[i] = 2.0 * r;
        circumference[i] = 2.0 * PI * r;
    }

    end = clock();
    time_one_record = (double)(end - start) / CLOCKS_PER_SEC;

    /* Method 2: make one complete pass for each operation. */
    start = clock();

    for (i = 0; i < N; i++) {
        double r = radius[i];
        area[i] = PI * r * r;
    }

    for (i = 0; i < N; i++) {
        double r = radius[i];
        diameter[i] = 2.0 * r;
    }

    for (i = 0; i < N; i++) {
        double r = radius[i];
        circumference[i] = 2.0 * PI * r;
    }

    end = clock();
    time_one_operation = (double)(end - start) / CLOCKS_PER_SEC;

    /* Use the results so the compiler cannot remove the calculations. */
    for (i = 0; i < N; i++) {
        check += area[i] + diameter[i] + circumference[i];
    }

    printf("Method 1 - one record at a time: %.6f seconds\n", time_one_record);
    printf("Method 2 - one operation at a time: %.6f seconds\n", time_one_operation);
    printf("Check = %.2f\n", check);

    return 0;
}
