7
\$\begingroup\$

Write a program that converts a decimal to a mixed, simplified fraction.

Sample input:

5.2

Sample output:

5 + (1/5)

The code with the shortest length in bytes wins.

\$\endgroup\$
  • 5
    \$\begingroup\$ Easy: 1.2345 = 12345/10000. You give me the precision & I'll give you the fraction! \$\endgroup\$ – recursion.ninja Jan 2 '14 at 21:52
  • \$\begingroup\$ Do you mean simplified fractions? \$\endgroup\$ – hkk Jan 2 '14 at 21:53
  • \$\begingroup\$ i meant mixed fractions \$\endgroup\$ – belvi Jan 2 '14 at 21:58
  • \$\begingroup\$ basically: find how many spaces the decimal goes beyond the decimal point (e.g. 2.357 is 3 digits after decimal), then turn it into improper, unsimplified: 2357/1000 and then, have a list of primes, starting at lowest, try to divide both numbers by it without remainder, then try it on that until at least one of the numbers is a prime and the other is not divisible by that number, and you're done \$\endgroup\$ – markasoftware Jan 2 '14 at 22:04
  • 2
    \$\begingroup\$ 5.2 != 5+1/2... \$\endgroup\$ – Kevin Jan 2 '14 at 22:28

11 Answers 11

4
\$\begingroup\$

Ruby, 43

y=gets.to_r;puts"#{y.to_i} + (#{y-y.to_i})"

Pretty straightforward.

\$\endgroup\$
  • \$\begingroup\$ Interesting solution. I'm honestly surprised you can make such short program with correct output format. \$\endgroup\$ – Konrad Borowski Jan 3 '14 at 17:47
  • \$\begingroup\$ Ruby has a lot of Lispy features and the Rational class is probably one of the lesser-known ones. However, if the input is a float you're liable to get something like "2 + (1499999999999999/5000000000000000)" \$\endgroup\$ – Ibrahim Tencer Jan 4 '14 at 4:01
2
\$\begingroup\$

GolfScript, 40

'.'/~'+'\.~.@,10\?.@{.@\%.}do;:d/\d/'/'@

Requires no line terminator in the input. Can probably be golfed further.

\$\endgroup\$
1
\$\begingroup\$

Golf-Basic 84, 32 characters

Executed from a TI-84 calculator

i`A:floor(A)→B:A-B→A:d`Bd`A►Frac
\$\endgroup\$
1
\$\begingroup\$

Mathematica 73

No cigar this time. Numerator, Denominator and Rationalize are big words.

f@x_:=(Row@{⌊#⌋,"+",Numerator@#~Mod~(d=Denominator@#)/d})&[Rationalize@x]

Example

f[23.872]

mixed

\$\endgroup\$
1
\$\begingroup\$

GTB, 28

`A:floor(A)→B:A-B→A~B~A►Frac
\$\endgroup\$
  • \$\begingroup\$ The source code for your compiler cannot be run since iX2Web is not available. The link in your site is bad as well. \$\endgroup\$ – mbomb007 Apr 13 '15 at 20:58
1
\$\begingroup\$

OK, this isn't the shortest. But the proper way to convert decimals to fractions is to use continued fractions.

#include <stdio.h>
#include <string.h>
#include <math.h>

int main(int argc, char **argv) {
  double f = 152/147.;
  int temp, i, cf[50], n=0, d=1;
  double prec = 1e-6;

  memset(cf,0,sizeof(memset));

  for (i=0;i<50 && prec<1;i++) {
    cf[i] = f;
/* Next line assumes division by zero evaluates to inf */
    f = 1/(f-cf[i]);
    prec*=f;
  }

  for (;i>=0;i--) {
    temp = n;
    n = n*cf[i] + d;
    d = temp;
  }
  if (cf[0] == 0)
    printf("%d/%d\n",d,n);
  else
    printf("%d %d/%d\n",cf[0],d,n);

}
\$\endgroup\$
1
\$\begingroup\$

Perl 6 (53 bytes)

Does the output in right, expected format. Would be way shorter if output in invalid format would be allowed. This gets a number, converts it to rational. nude method returns denominator and numerator (there are separate denominator and numerator methods, but they are crazily long.

[] is a reduce operator which takes operator between square brackets, and in this case, I use it to shorten the code (so I wouldn't have to specify both array elements, because they are already in correct order (but if they wouldn't, there are R operators (like R/, R%, Rdiv, and Rmod) that reverse the order of arguments for operator)). {} in double quotes puts the result of code in string (like #{} in Ruby).

my \ is declaration of sigilless variable. In this case it doesn't save characters, but it doesn't waste them either, so why not use it. I could have used my@, and it would use identical number of characters.

my \n=get.Rat.nude;say "{[div] n} + ({[%] n}/{n[1]})"

Sample output (just to show the correct format):

~ $ perl6 -e 'my \n=get.Rat.nude;say "{[div] n} + ({[%] n}/{n[1]})"'
42.42
42 + (21/50)

If negative number support is needed, this would work (2 bytes more).

~ $ perl6 -e 'my \n=get.Rat.nude;say "{[div] n} + ({[mod] n}/{n[1]})"'
-42.42
-42 + (-21/50)
\$\endgroup\$
1
\$\begingroup\$

python 3, 84

from fractions import*
a,b=input().split(".")
print("%s + (%s)"%(a,Fraction("."+b)))
\$\endgroup\$
  • \$\begingroup\$ Doesn't return the output in correct format. + should be returned (but otherwise, it's close to expected format). \$\endgroup\$ – Konrad Borowski Jan 3 '14 at 7:03
  • \$\begingroup\$ @GlitchMr Edited the format. \$\endgroup\$ – Wasi Jan 3 '14 at 7:52
  • \$\begingroup\$ Also, there are parens. Dunno why, but the OP put them. \$\endgroup\$ – Konrad Borowski Jan 3 '14 at 12:42
  • \$\begingroup\$ @GlitchMr Added those creepy parens. Now the code size raised to 84 :-( \$\endgroup\$ – Wasi Jan 3 '14 at 12:58
1
\$\begingroup\$

R, several lines

How about the way they tought us at grammar school?

f=function(s){
  gcd=function(a,b)if(!b)a else gcd(b,a%%b)
  a=strsplit(s,'\\.')[[1]]
  p=10^nchar(a[2])
  x=strtoi(a[2])
  d=gcd(x,p);
  cat(a[1]," + (",x/d,"/",p/d,")",sep="");
}

Vaguely: works for positive decimals with finite decimal fraction.

> f("23.872")
23 + (109/125)

Input must be a string matching "[0-9]+\.[0-9]+" regular expression.

\$\endgroup\$
1
\$\begingroup\$

Haskell

Isn't pretty, but whatever

import Data.Ratio
main=let r '%'='/';r c=c in interact$(\(x,y)->show x++" + "++map r(show$approxRational y 1e-9)).properFraction.read
\$\endgroup\$
0
\$\begingroup\$

kind of cheating, but pressing these characters in a mathematica notebook looks it up in wolfram alpha, which gives the mixed fraction form among other information

==5.2
==1.234
etc...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.