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

#define ARRAY_SIZE 12 // Size of the array

int main(int argc, char *argv[]) {
    int rank, size, i;
    int array[ARRAY_SIZE];
    int local_max, global_max = -1;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);

    // Initialize random seed based on current time and rank
    srand(time(NULL) + rank * 100); // Add rank to ensure different seeds for different processes

    // Generate random numbers for the array on process 0
    if (rank == 0) {
        printf("Array:\n");
        for (i = 0; i < ARRAY_SIZE; i++) {
            array[i] = rand() % 100;
            printf("%d ", array[i]);
        }
        printf("\n");
    }

    // Broadcast the array from process 0 to all other processes
    MPI_Bcast(array, ARRAY_SIZE, MPI_INT, 0, MPI_COMM_WORLD);

    // Calculate local maximum
    int start_index = (ARRAY_SIZE / size) * rank;
    int end_index = start_index + (ARRAY_SIZE / size);
    local_max = array[start_index];
    for (i = start_index + 1; i < end_index; i++) {
        if (array[i] > local_max) {
            local_max = array[i];
        }
    }

    if (rank != 0) {
        // Send local maximum to process 0
        MPI_Send(&local_max, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
    } else {
        // Process 0 receives local maxima from all other processes
        for (i = 1; i < size; i++) {
            int received_max;
            MPI_Recv(&received_max, 1, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
            if (received_max > global_max) {
                global_max = received_max;
            }
        }

        // Compare the local maximum of process 0 with the global maximum
        if (local_max > global_max) {
            global_max = local_max;
        }

        // Print the global maximum on process 0
        printf("Global Maximum: %d\n", global_max);
    }

    MPI_Finalize();

    return 0;
}
