Ява, 625 605
Код для гольфу:
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;}
Примітка: я вважаю статичний імпорт частиною функції для цілей гольфу.
Ця функція починається, отримуючи результат ділення. До нього додається цілісна частина і підписується, якщо потрібно. Потім, якщо є залишок, він виконує основу 10 довгого поділу. На кожному кроці виконайте ділення. Зберігайте обчислену цифру та залишок у двох списках. Якщо ми знову зустрінемо одну і ту ж цифру і решту, повторюється частина, і ми знаємо, з якого індексу він починається. Код або додає цифри (без повтору), або цифри, які повторюються, а потім повторні цифри, що містяться в дужках.
Це трохи більше, головним чином через BigInteger
. Якщо входи не переповнені навіть long
тоді, це може бути трохи коротше. І все-таки я сподіваюся, що є способи покращити цей запис.
Невикольований код з основним методом тестування:
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
}
Вихід програми:
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)