/**********************************************************************

Exemplo simples para structs.  

Este programa pede inteiros nao-negativos n e s como entrada; ele gera
n numeros complexos usando a funcao rand() do stdlib.h e entao soma
todos e calcula a media.  Os numeros gerados tem parte real e
imaginaria no intervalo [-1,1].  O inteiro s 'e usado como a semente
do gerador de numeros aleatorios.  Se o gerador 'e bom e n 'e grande,
espera-se algo como 0 na saida.

Usamos vetores de numeros complexos.  Naturalmente, este programa pode 
ser feito sem vetores, mas a ideia 'e termos um exemplo simples de
uso de vetores de estruturas.  Voce pode calcular o desvio padrao dos
complexos gerados, como exercicio.  Para isto, voce vai precisar usar 
o vetor usado aqui.

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

#define N 10000
#define DEBUG 0

typedef struct {
  double Re;
  double Im;
} Complexo;

void imprima_complexo(Complexo z)
{
  printf("Parte real = %.5lf\n", z.Re);
  printf("Parte imaginaria = %.5lf\n", z.Im);
}

Complexo soma(Complexo z1, Complexo z2)
{
  Complexo z;

  z.Re=z1.Re+z2.Re;
  z.Im=z1.Im+z2.Im;

  return z;
}  

Complexo complexo_aleatorio()
{
  Complexo z;

  z.Re=(double)rand()/RAND_MAX; 
  z.Im=(double)rand()/RAND_MAX; 
  /* RAND_MAX e o maior valor que rand() */
  /* pode devolver. */

  if (rand()%2) z.Re=-z.Re;
  if (rand()%2) z.Im=-z.Im;

  return z;
}

void leia_entrada(int *n, unsigned int *s)
{
  printf("Entre o numero de complexos a serem gerados (<= %d): ", N);
  scanf("%d", n);
  printf("Entre uma semente (um inteiro nao-negativo): ");
  scanf("%ud", s);
}
     
main()
{
  int k, n;
  unsigned int s;
  Complexo z[N], z_total;

  leia_entrada(&n, &s);
  srand(s); /* Inicializa o gerador de numeros aleatorios */

  for (k=0; k<n; ++k) {
    z[k]=complexo_aleatorio();
    if (DEBUG) {
      printf("z[%d].Re=%.3f\n", k, z[k].Re);
      printf("z[%d].Im=%.3f\n\n", k, z[k].Im);
    }
  }

  z_total.Re=0.0;
  z_total.Im=0.0;

  for (k=0; k<n; ++k) {
    z_total.Re+=z[k].Re;
    z_total.Im+=z[k].Im;
  }

  z_total.Re=z_total.Re/n;
  z_total.Im=z_total.Im/n;;
  
  imprima_complexo(z_total);

  return 0;
}
