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 – 2016-08-09T05:46:32.543
@DestructibleWatermelon I was under the impression that most languages are turing complete. – orlp – 2016-08-09T05:46:38.073
Can we safely assume the fraction won't be something like: 0.33333333333336333...? – brianush1 – 2016-08-09T05:50:26.023
@brianush1 Of course not. There is only one exact answer for a fraction, and your answer must correctly determine that one answer. – orlp – 2016-08-09T05:52:56.057
Is this possible on real tangible computers (limited memory)? – Destructible Lemon – 2016-08-09T06:17:44.400
2
This seems like a long-winded way of asking for solutions to PE26 ;)
– Conor O'Brien – 2016-08-09T06:24:00.510@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 – 2016-08-09T06:26:30.523
@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 – 2016-08-09T06:34:59.463
Can b be negative? (Edit: Never mind, just saw the test case where it is) – xnor – 2016-08-09T07:15:38.757
1
Generalisation of this question; also related.
– Peter Taylor – 2016-08-09T07:52:52.553Is the input format literally a pair of integers, or is it already in the form "a / b" with the "/" included? – Greg Martin – 2016-08-09T17:13:33.437
@GregMartin Whatever you prefer. – orlp – 2016-08-09T17:23:37.493
Also very similar to this: http://codegolf.stackexchange.com/questions/22146/implement-arbitrary-precision-division
– durron597 – 2016-08-11T23:10:21.083I recall this exact question from USACO's site (same output format as well) – Moira – 2017-07-11T10:43:17.400