#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
typedef unsigned char chiffre;
typedef chiffre *nombre;
int taille = 0;
int base = 10;

nombre init(void)
{
    return (nombre) calloc(taille, sizeof(chiffre));
}

nombre strton(char *s)
// calcule le nombre correspondant 
// a la chaine de caracteres s
{
    nombre res;
    int i = 0;
    char *ptr;
    res = init();
    ptr = s + strlen(s);
    do {
	ptr--;
	if (!isdigit(*ptr)) {
	    printf("\nErreur!\n");
	    exit(2);
	}
	// ici, il manque une 
	// ou deux instructions
    } while (ptr != s);
    return res;
}

nombre test(void)
// calcule un nombre compris entre
// base^(taille/2-1) et base^(taille/2)
{
    nombre res;
    int i;
    res = init();
    for (i = 0; i < taille / 2; i++)
	res[i] = 1;
    return res;
}

void print(nombre z)
{
    int i;
    i = taille - 1;
    while (z[i] == 0 && i > 0)
	i--;
    printf("\nnombre :");
    while (i >= 0) {
	printf("%d", z[i]);
	i = i - 1;
    }
}

void copier(nombre d, nombre s)
{
    int i;
    for (i = 0; i < taille; i++)
	d[i] = s[i];
}

void dicho(nombre z)
{
    int i;
    chiffre w = 0;
    for (i = taille - 1; i >= 0; i--) {
	w = base * w + z[i];
	z[i] = w / 2;
	w = w % 2;
    }
}

void carre(nombre r, nombre z)
{
    int i, j;
    int ret = 0;
    for (i = 0; i < taille; i++)
	r[i] = 0;
    for (i = 0; i < taille; i++)
	for (j = 0; j < taille; j++)
	    if (i + j < taille)
		r[i + j] += z[i] * z[j];
    for (i = 0; i < taille; i++) {
	ret = ret + r[i];
	r[i] = ret % base;
	ret = ret / base;
    }
}

void somme(nombre d, nombre x, nombre y)
{
    int ret = 0;
    int i;
    // completer pour coder 
    // le calcul x + y dans d
    // cf question somme.
}

int cmp(nombre x, nombre y)
{
    int i;
    i = taille - 1;
    while (i >= 0 && x[i] == y[i])
	i--;
    if (i < 0)
	return 0;
    if (x[i] < y[i])
	return -1;
    return +1;
}

int succes(nombre x, nombre y)
{
    int i = 0;
    while (i < taille && x[i] == base - 1 && y[i] == 0)
	i++;
    if (x[i] + 1 != y[i])
	return 0;
    i++;
    while (i < taille) {
	if (x[i] != y[i])
	    return 0;
	i++;
    }
    return 1;
}

void racine(nombre z)
{
    nombre a, b, c, t;
    a = init();
    b = init();
    copier(b, z);
    t = init();
    c = init();
    while (!succes(a, b)) {
	somme(t, a, b);		//    
	dicho(t);		//  bloc
	carre(c, t);		//  instructions
	if (cmp(c, z) > 0)	//     cf
	    copier(b, t);	//  question :  
	else			//  algorithmie
	    copier(a, t);	//
    }
    copier(z, a);
}

int main(int argc, char *argv[])
{
    int opt;
    nombre z;
    while ((opt = getopt(argc, argv, "hn:t:")) >= 0) {
	switch (opt) {
	case 'h':
	    printf("usage : -n{nombre} -t{taille} -h\n");
	    exit(1);
	case 'n':
	    taille = strlen(optarg) * 2;
	    z = strton(optarg);
	    break;
	case 't':
	    taille = atoi(optarg);
	    z = test();
	    break;
	default:;
	}
    }
    print(z);
    racine(z);
    print(z);
    printf("\n");
    return 0;
}
