/*********************************************************/
/*   midsquare.c                                         */
/*    Este programa implementa o algoritmo de midsquare  */
/*    de von Neumann, para geracao de numeros aleatorios */
/*   Fernando Henrique Ferraz Pereira da Rosa            */
/*   Vagner Aparecido Pedro Junior                       */
/*   Data:  12/11/2002                                   */
/*                                                       */
/*********************************************************/


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

int conta_digitos(int num);
int midcut(int num,int nd);

int main(int argc,char **argv)
{
 int seed,nd,next,qtd,i;
 
 if (argc != 3) {
  printf("Uso: \n"
         "   %s semente num, onde semente e' um inteiro e \n"
         "   num o numero de numeros aleatorios que voce quer gerar.\n",
         argv[0]);
  return(0);
 }
 sscanf(argv[1],"%d",&seed);
 sscanf(argv[2],"%d",&qtd);
 
 nd = conta_digitos(seed);	
 printf("x[0] = %d\n",seed);
 for(i=1;i<=qtd;i++) {
  next = midcut(seed * seed,nd);
  printf("(%4d)^2 = %10d  => x[%3d] = %d\n",seed,seed*seed,i,next); 
  seed = next;
 }
 return(0);
}

/* conta_digitos: conta o numero de digitos
 * da representacao decimal de num
 */
int conta_digitos(int num)
{
 int cont;
 for(cont=1;num%10 != num;cont++)
  num /= 10;
 return(cont);
}

/* midcut: retorna o numero que esta no centro
 * de num, com nd digitos.
 * o cutpoint e' para a esquerda, quando a divisao
 * nao e' exata
 */
int midcut(int num,int nd)
{
 int i,res,volta;
 char *string,*midpoint;
 nd *= 2;
 res = nd - conta_digitos(num);
 string = malloc((nd+1) * sizeof(char));
 
 if (res >  0) {
  for(i=0;i<res;i++) {
   string[i] = '0';
   midpoint = &string[i+1];
  }
  sprintf(midpoint,"%d",num);
 }
 else
  sprintf(string,"%d",num);
 
 nd /= 2;
 if (nd % 2 == 0) {
  /*divisao exata, primeiro tiramos nd/2 elementos do comeco
   *e depois nd/2 do final*/
  for(i=0;i<nd/2;i++)
   string[i] = ' ';
  for(i=3*nd/2;i<2*nd+1;i++)
   string[i] = ' ';
 }
 else {
  /*como o corte e' a  esquerda, tiramos nd-nd/2 elementos da esquerda
   *e nd/2 elementos da direita.*/
  for(i=0;i<nd-nd/2;i++)
   string[i] = ' ';
  for(i=2*nd-nd/2;i<2*nd;i++)
   string[i] = ' ';
 }

 sscanf(string,"%d",&volta);
 return(volta);
}

