fork download
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int euclid_gcd(int a, int b) {
  6. if (b == 0) return a;
  7. return euclid_gcd(b, a % b);
  8. }
  9.  
  10. void reducesimple(char *buf,
  11. int integer,
  12. const char *floating)
  13. {
  14. int flen = strlen(floating);
  15. int scale = 1;
  16. int gcd;
  17. int decimal;
  18. while (flen--) scale *= 10;
  19. decimal = atoi(floating);
  20. gcd = euclid_gcd(decimal, scale);
  21. sprintf(buf, "%d + %d/%d", integer, decimal / gcd, scale / gcd);
  22. }
  23.  
  24. void reducerational(char *buf,
  25. int numerator,
  26. int denominator)
  27. {
  28. int whole = numerator / denominator;
  29. int rest = numerator % denominator;
  30. int gcd = euclid_gcd(rest, denominator);
  31. if (!whole) {
  32. sprintf(buf, "%d/%d", rest / gcd, denominator / gcd);
  33. } else {
  34. sprintf(buf, "%d + %d/%d", whole, rest / gcd, denominator / gcd);
  35. }
  36. }
  37.  
  38. void reducerepeating(char *buf,
  39. int integer,
  40. const char *floating,
  41. const char *repeating)
  42. {
  43. int flen, rlen;
  44. int num = 1, den = 1;
  45. int gcd;
  46. int fscale = 1, rscale = 9;
  47. int part1, part2;
  48.  
  49. part1 = atoi(floating);
  50. part2 = atoi(repeating);
  51.  
  52. rlen = strlen(repeating);
  53. while (--rlen) { rscale *= 10; rscale += 9; }
  54. flen = strlen(floating);
  55. while (flen--) rscale *= 10;
  56. flen = strlen(floating);
  57. while (flen--) fscale *= 10;
  58.  
  59. num = part1 * rscale + fscale * part2;
  60. den = fscale * rscale;
  61. gcd = euclid_gcd(num, den);
  62. sprintf(buf, "%d + %d / %d", integer, num / gcd, den / gcd);
  63. }
  64.  
  65. void reduce(char *buf, const char *expression) {
  66. int chk1, chk2, chk3, chk4;
  67. int integer, numerator, denominator;
  68. char floating[11], repeating[11];
  69.  
  70. chk1 = sscanf(expression, "%d.%10[0123456789]", &integer, floating);
  71. chk2 = sscanf(expression, "%d/%d", &numerator, &denominator);
  72. chk3 = sscanf(expression, "%d.%10[0123456789](%10[0123456789])", &integer, floating, repeating);
  73. chk4 = sscanf(expression, "%d.(%10[0123456789])", &integer, repeating);
  74. if ((chk3 == 3) || (chk4 == 2)) {
  75. if (chk4 == 2) *floating = 0;
  76. reducerepeating(buf, integer, floating, repeating);
  77. } else {
  78. if (chk2 == 2) {
  79. reducerational(buf, numerator, denominator);
  80. } else {
  81. if (chk1 == 2) {
  82. reducesimple(buf, integer, floating);
  83. } else {
  84. strcpy(buf, "invalid expression");
  85. }
  86. }
  87. }
  88. }
  89.  
  90. int main(void) {
  91. char buf[1000], src[1000];
  92. while (fgets(src, sizeof src, stdin)) {
  93. src[strlen(src) - 1] = 0;
  94. reduce(buf, src);
  95. printf("%s ==> %s\n", src, buf);
  96. }
  97. return 0;
  98. }
Success #stdin #stdout 0.01s 1724KB
stdin
0.333333333
0.333
0.(3)
0.1(6)
10/8
3.(012)
3.4(042)
3.00(4)
3.00(42)
stdout
0.333333333 ==> 0 + 333333333/1000000000
0.333 ==> 0 + 333/1000
0.(3) ==> 0 + 1 / 3
0.1(6) ==> 0 + 1 / 6
10/8 ==> 1 + 1/4
3.(012) ==> 3 + 4 / 333
3.4(042) ==> 3 + 673 / 1665
3.00(4) ==> 3 + 1 / 225
3.00(42) ==> 3 + 7 / 1650