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

#define MAX_ITER 1000
#define MAX_SIZE 4000

/* How many steps until the point (cr, ci) escapes, up to MAX_ITER? */
int escape_time(double cr, double ci) {
    double x = 0.0;
    double y = 0.0;
    int iter = 0;

    while (iter < MAX_ITER && x * x + y * y <= 4.0) {
        double next_x = x * x - y * y + cr;
        y = 2.0 * x * y + ci;
        x = next_x;
        iter++;
    }
    return iter;
}

/* Fill image, stored one row after another, with an escape time per pixel. */
void compute_row(int image[], int row, int width, int height) {
    double ci = -1.25 + (row + 0.5) * 2.5 / height;
    for (int col = 0; col < width; col++) {
        double cr = -2.25 + (col + 0.5) * 3.0 / width;
        image[row * width + col] = escape_time(cr, ci);
    }
}

/* Draw a small image as text. A '#' is a point that never escaped. */
void print_picture(const int image[], int width, int height) {
    for (int row = 0; row < height; row++) {
        for (int col = 0; col < width; col++) {
            int iter = image[row * width + col];
            char mark = ' ';
            if (iter == MAX_ITER) {
                mark = '#';
            } else if (iter >= 10) {
                mark = '+';
            } else if (iter >= 5) {
                mark = '.';
            }
            putchar(mark);
        }
        putchar('\n');
    }
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Usage: %s <width> <height>\n", argv[0]);
        return 1;
    }
    int width = (int)strtol(argv[1], NULL, 10);
    int height = (int)strtol(argv[2], NULL, 10);
    if (width < 1 || width > MAX_SIZE || height < 1 || height > MAX_SIZE) {
        fprintf(stderr, "Width and height must be from 1 through %d.\n", MAX_SIZE);
        return 1;
    }

    int *image = malloc(width * height * sizeof(int));

    clock_t start = clock();
    for (int row = 0; row < height; row++) {
        compute_row(image, row, width, height);
    }
    double elapsed = (double)(clock() - start) / CLOCKS_PER_SEC;

    long long total_iters = 0;
    int in_set = 0;
    for (int i = 0; i < width * height; i++) {
        total_iters += image[i];
        if (image[i] == MAX_ITER) {
            in_set++;
        }
    }

    if (width <= 100 && height <= 60) {
        print_picture(image, width, height);
    }
    printf("Image: %d x %d\n", width, height);
    printf("Total iterations: %lld\n", total_iters);
    printf("Pixels that never escaped: %d\n", in_set);
    printf("Serial time: %.3f seconds\n", elapsed);
    free(image);
    return 0;
}
