Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
assert recurringDecimal(3, 8) == '0.375'
assert recurringDecimal(3, 14) == '0.2{142857}'
assert recurringDecimal(1, 3) == '0.{3}'
assert recurringDecimal(1, 7) == '0.{142857}'
assert recurringDecimal(3, 7) == '0.{428571}'
assert recurringDecimal(269, 111) == '2.{423}'
/**
* 循環小数に変換
* 例) 3/14 → 0.2{142857}
* @param numer 分子
* @param denom 分母
* @return 循環小数
*/
def recurringDecimal(int numer, int denom) {
def rslt = '' << '' // バッファ
def remainMap = [:] // 剰余:小数点第n位
def frac = [] // 小数部
// とりあえずqとrを求める
int q = numer / denom // quotient(商)
int r = numer % denom // remainder(剰余)
// 整数部を投入
rslt << q
// 剰余が0なら終了
if (r == 0) {
return rslt.toString()
}
rslt << '.'
// 剰余を保持しておく
remainMap[r] = 0
// 小数第100位まで繰り返し
for(digit in 0..<100) {
// numerをr * 10に置き換えて、q, rを求める
numer = r * 10
q = numer / denom
r = numer % denom
// 小数部分を追加
frac << q
// 剰余がremainMapに含まれている場合、循環部分を取り出して返却して終了
if (remainMap.containsKey(r)) {
def beforeRecurr = frac[0..<remainMap[r]]
def recurr = frac[remainMap[r]..-1]
rslt << beforeRecurr.join() << "{${recurr.join()}}"
return rslt.toString()
}
// 剰余が0なら終了
if (r == 0) {
rslt << frac.join()
return rslt.toString()
}
// 剰余を保持しておく
remainMap[r] = digit + 1
}
// 既定の小数点桁数を超過
rslt << frac.join() << '...'
return rslt.toString()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment