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

int main(int argc, char *argv[]) {
    int pid, nprocs;
    int N;  // Size of the array
    int *tableau = NULL;  // Pointer to hold the user-entered array
    int taille_par_process, somme_locale = 0, somme_totale = 0;

    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &pid);
    MPI_Comm_size(MPI_COMM_WORLD, &nprocs);

    if (pid == 0) {
        // Process 0 asks the user for the size of the array
        printf("Enter the size of the array (divisible by %d): ", nprocs);
        scanf("%d", &N);

        // Allocate memory for the array
        tableau = (int *)malloc(N * sizeof(int));

        // Get the elements from the user
        printf("Enter %d integers:\n", N);
        for (int i = 0; i < N; i++) {
            scanf("%d", &tableau[i]);
        }
    }

    // Broadcast the size of the array to all processes
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);

    // Check if the size is divisible by the number of processes
    if (N % nprocs != 0) {
        if (pid == 0) {
            printf("Error: Array size must be divisible by the number of processes.\n");
        }
        MPI_Finalize();
        return -1;
    }

    // Calculate the size of each process's portion
    taille_par_process = N / nprocs;
    int sous_tableau[taille_par_process];  // Local array for each process

    // Scatter the array to all processes
    MPI_Scatter(tableau, taille_par_process, MPI_INT,
                sous_tableau, taille_par_process, MPI_INT,
                0, MPI_COMM_WORLD);

    // Each process calculates the sum of its portion
    for (int i = 0; i < taille_par_process; i++) {
        somme_locale += sous_tableau[i];
    }
    printf("Process %d: Local sum = %d\n", pid, somme_locale);

    // Reduce the local sums into the total sum at process 0
    MPI_Reduce(&somme_locale, &somme_totale, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);

    // Process 0 prints the total sum
    if (pid == 0) {
        printf("Total sum of the array elements = %d\n", somme_totale);
        free(tableau);  // Free the allocated memory
    }

    MPI_Finalize();
    return 0;
}
