/* Problem 1--Double Trouble Trial and error would take too long for this problem. What you needed to observe--mathematically--was that this problem REALLY involved repeating decimals. The correct answer was a multiple of 1/(2b-1). The double trouble number in base 10 is, for example, 1/19. */ #include #include FILE *in, *out; int b; int main (int argc, char **argv); void Process (void); void MakeString (char **n, int *l, int i); int main (int argc, char **argv) { in = fopen ("prob1.in","r"); out = fopen ("prob1.out","w"); /* Process case */ while (fscanf (in,"%d",&b),b > 0) Process (); fclose (in); fclose (out); return EXIT_SUCCESS; } /* Process processes a single test case. */ void Process (void) { char *f, *n; int fl, nl, i; MakeString (&f,&fl,1); /* generate repeating decimals */ for (i = 2; i < b; i++) { /* the one with the smallest length */ MakeString (&n,&nl,i); /* is the double trouble number */ if (nl < fl) { free (f); f = n; fl = nl; } else { free (n); } } /* Print out the number */ fprintf (out,"For base %d the double-trouble number is\n",b); for (i=0; i < fl;i++) fprintf (out,"%d ",(int)(unsigned char)f[i]); fprintf (out,"\n\n"); } /* MakeString accepts a string variable and an integer i, and builds */ /* the repeating decimal string i/(2b-1) in base b. It is put into */ /* string n, and the length is put into l */ void MakeString (char **n, int *l, int i) { int j = i; *l = 0; *n = malloc (2*b-1); do { /* get the next digit */ (*n)[(*l)++] = j*b/(2*b-1); j = j*b % (2*b-1); /* get the next remainder */ } while (j!=i); }