/* PRESOS Y SOMBREROS
 * Los presos se representan como una tabla de enteros que podra
 * tener dos valores: 0-sombrero blanco, o 1-sombrero negro.
 * La elección de cada preso se representa como otra tabla de
 * enteros siguiendo la misma codificación.
 */

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>

int i,j,oidos,vistos;

int sombrero[31];
int eleccion[31];

int salvados;
int ejecutados;

main() {
   printf("PRESOS Y SOMBREROS\n");
   printf("Codificacion: 0-blanco 1-negro\n");

   Repartir_sombreros();
   Aplicar_estrategia();
   Mostrar_resultado();
}

Repartir_sombreros() {
   /* Aleatoriamente se asignan sobreros a cada uno de los 30 presos. */

   printf("Repartiendo sombreros...\n");

   srand(time(0));
   for (i=1; i<=30; i++) {
      sombrero[i]= rand()%2;
      printf("%i",sombrero[i]);
   }
   printf("\n");
}

Aplicar_estrategia() {
   /* Recorriendo la lista del 1 al 30, la estrategia para cada preso es:
    * - escuchar el sombrero del primer preso y decodificarlo
    *      -si dijo blanco, ha visto un n£mero par de sombreros
    *      -si dijo negro, ha visto un n£mero impar de sombreros
    * - llevar la cuenta de los sombreros negros que han ido diciendo sus
    *   compa¤eros, quitando el primero, que habr n ido acertando.
    * - si la suma de los que ha oido mas los que ve es del mismo orden
    *   (par o impar) que los que vio el primer preso, entonces
    *       elegir blanco
    * -sino
    *       elegir  negro
    */

   printf("Aplicando estrategia (relativa a sombreros negros)...\n");
   printf("Eleccion:\n");

   vistos=0;
   for (i=2; i<=30; i++) {
       vistos=vistos+sombrero[i];
   }
   eleccion[1]=vistos%2;
   printf("El preso  1 ve %2i sombreros, y elige %i.\n",
	   vistos,eleccion[1]);

   for (i=2; i<=30; i++) {
      oidos=0;
      for (j=2; j<i; j++) {
         oidos=oidos+sombrero[j];
      }
      vistos=0;
      for (j=i+1; j<=30; j++) {
         vistos=vistos+sombrero[j];
      }
      if ((oidos+vistos)%2==eleccion[1])
         eleccion[i]=0;
      else
         eleccion[i]=1;

      printf("El preso %2i lleva contados %2i sombreros y ve %2i sombreros, luego elige %i.\n",
	      i,oidos,vistos,eleccion[i]);
   }
}

Mostrar_resultado() {
   /* Se muestra el resultado comparando las respuesta de cada preso con el sombrero que
    * lleva, indicando si coincide (y se salva) o no (y le matan).
    */

   printf("Mostrando resultado...\n");

   salvados=0;
   ejecutados=0;

   for (i=1; i<=30; i++) {
      printf("El preso %2i ha elegido %i y su sombrero era %i",i,eleccion[i],sombrero[i]);
      if (eleccion[i]==sombrero[i])
      {
	 printf(", luego se salva.\n");
	 salvados++;
      }
      else
      {
	 printf(", luego le matan.\n");
	 ejecutados++;
      }
   }
   printf("Se han salvado %i y han ejecutado a %i.\n",salvados,ejecutados);
   return 0;
}
