Java, 625 605
Golfed code:
import static java.math.BigInteger.*;
String f(BigInteger a, BigInteger b){BigInteger[]r=a.divideAndRemainder(b);String s=r[0].toString();if(r[1].signum()<0)s="-"+s;if(!ZERO.equals(r[1])){s+='.';List<BigInteger>x=new ArrayList();List<BigInteger>y=new ArrayList();for(BigInteger d=TEN.multiply(r[1].abs());;){BigInteger[]z=d.divideAndRemainder(b.abs());int i=y.indexOf(z[1]);if(i>-1&&i==x.indexOf(z[0])){for(int j=0;j<i;++j)s+=x.get(j);s+='(';for(int j=i;j<x.size();++j)s+=x.get(j);s+=')';break;}x.add(z[0]);y.add(z[1]);if(ZERO.equals(z[1])){for(BigInteger j:x)s+=j;break;}d=TEN.multiply(z[1]);}}return s;}
Note: I count the static import as part of the function for golfing purposes.
This function starts out by getting the division result. It adds the integral portion and sign, if necessary. Then if there is a remainder, it performs base 10 long division. At each step, perform the division. Store the calculated digit and the remainder in two lists. If we encounter the same digit and remainder again, there is a repeated portion and we know what index it starts at. The code either adds the digits (no repeat) or the pre-repeat digits, then the repeated digits enclosed in parentheses.
This is a bit big mostly because of BigInteger. If the inputs did not overflow even a long then it could be a bit shorter. Still, I expect there are ways to improve this entry.
Ungolfed code with main method for testing:
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import static java.math.BigInteger.*;
public class FractionToExactDecimal {
public static void main(String[] args) {
// @formatter:off
String[][] testData = new String[][] {
{ "123562375921304812375087183597", "2777", "44494913907563850333124661" },
{ "81", "3", "27" },
{ "-6", "2", "-3" },
{ "1", "2", "0.5" },
{ "3289323463", "-250000000", "-13.157293852" },
{ "-1", "3", "-0.(3)" },
{ "235", "14", "16.7(857142)" },
{ "123", "321", "0.(38317757009345794392523364485981308411214953271028037)" },
{ "355", "113", "3.(1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168)" }
};
// @formatter:on
for (String[] data : testData) {
System.out.println(data[0] + " / " + data[1]);
System.out.println(" Expected -> " + data[2]);
System.out.print(" Actual -> ");
System.out.println(new FractionToExactDecimal().f(new BigInteger(data[0]), new BigInteger(data[1])));
System.out.println();
}
}
// Begin golf
String f(BigInteger a, BigInteger b) {
BigInteger[] r = a.divideAndRemainder(b);
String s = r[0].toString();
if (r[1].signum() < 0) s = "-" + s;
if (!ZERO.equals(r[1])) {
s += '.';
List<BigInteger> x = new ArrayList();
List<BigInteger> y = new ArrayList();
for (BigInteger d = TEN.multiply(r[1].abs());;) {
BigInteger[] z = d.divideAndRemainder(b.abs());
int i = y.indexOf(z[1]);
if (i > -1 && i == x.indexOf(z[0])) {
for (int j = 0; j < i; ++j)
s += x.get(j);
s += '(';
for (int j = i; j < x.size(); ++j)
s += x.get(j);
s += ')';
break;
}
x.add(z[0]);
y.add(z[1]);
if (ZERO.equals(z[1])) {
for (BigInteger j : x)
s += j;
break;
}
d = TEN.multiply(z[1]);
}
}
return s;
}
// End golf
}
Program output:
123562375921304812375087183597 / 2777
Expected -> 44494913907563850333124661
Actual -> 44494913907563850333124661
81 / 3
Expected -> 27
Actual -> 27
-6 / 2
Expected -> -3
Actual -> -3
1 / 2
Expected -> 0.5
Actual -> 0.5
3289323463 / -250000000
Expected -> -13.157293852
Actual -> -13.157293852
-1 / 3
Expected -> -0.(3)
Actual -> -0.(3)
235 / 14
Expected -> 16.7(857142)
Actual -> 16.7(857142)
123 / 321
Expected -> 0.(38317757009345794392523364485981308411214953271028037)
Actual -> 0.(38317757009345794392523364485981308411214953271028037)
355 / 113
Expected -> 3.(1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168)
Actual -> 3.(1415929203539823008849557522123893805309734513274336283185840707964601769911504424778761061946902654867256637168)
@DestructibleWatermelon This is possible in pretty much all languages, including Turing tarpits. (Those might struggle with the time limit though.) – Dennis – 9 years ago
@DestructibleWatermelon I was under the impression that most languages are turing complete. – orlp – 9 years ago
Can we safely assume the fraction won't be something like: 0.33333333333336333...? – brianush1 – 9 years ago
@brianush1 Of course not. There is only one exact answer for a fraction, and your answer must correctly determine that one answer. – orlp – 9 years ago
Is this possible on real tangible computers (limited memory)? – Destructible Lemon – 9 years ago
2
This seems like a long-winded way of asking for solutions to PE26 ;)
– Conor O'Brien – 9 years ago@ConorO'Brien The general case is a tad more complicated than the reciprocal case. To emphasize, there was one incorrect example in my initial post due to this, and I still haven't found the bug in my test program... – orlp – 9 years ago
@DestructibleWatermelon It is possible with limited memory. You would only need memory up to the point where the decimal starts repeating. So assuming you do the worst and store a binary digit per byte, you'd still only use max 1KB – brianush1 – 9 years ago
Can b be negative? (Edit: Never mind, just saw the test case where it is) – xnor – 9 years ago
1
Generalisation of this question; also related.
– Peter Taylor – 9 years agoIs the input format literally a pair of integers, or is it already in the form "a / b" with the "/" included? – Greg Martin – 9 years ago
@GregMartin Whatever you prefer. – orlp – 9 years ago
Also very similar to this: http://codegolf.stackexchange.com/questions/22146/implement-arbitrary-precision-division
– durron597 – 9 years agoI recall this exact question from USACO's site (same output format as well) – Moira – 8 years ago