設問
直方体の辺の長さ a, b, c (a ≦ b ≦ c) は整数で,a+b+c = n とする。
n を与えたとき,何通りの直方体があるかを求める関数 f(n) を書け。
f(10) = 12, f(50) = 225, f(100) = 867 である。
f(50000) を求めよ。どのような言語を使っても良いが,実行時間はおおむね 1 秒以内とする。
解答例はコメントを参照。
割り算
締め切りが 2018/01/14 10:00 AM なので,その 1 分後に投稿されるように予約
【概要】
割り算をしてください。
【入力】
入力は
1230/10
のようになっています。
除算記号は「/」です。
除数・被除数ともに、正の整数です。
【出力】
出力は、下のルールに従ってください。
除算の結果と出力形式
整数の場合 整数として出力してください。
小数点や「/1」などをつけてはいけません。
有限小数で表現できる場合
有限の小数として出力してください。
先頭は、値が1未満の場合は「0.」で、それ以外は 0 以外にしてください。
末尾は 0 以外にしてください。
上記以外の場合
既約分数として出力してください。
右の例の通り「/」の前後に空白は不要です。
【例】
入力 出力
1230/10 123
12345/10 123.45
123/45 41/15
2/5 0.4
==========================================
10 進数で有限小数として表現できるためには,既約分数にしたときの分母の素因子が 2 または 5 のみであること(分母 = 2^m * 5^n)
f = function(s) {
euclid = function(m, n) {
while ((temp <- n %% m) != 0) {
n <- m
m <- temp
}
return(m)
}
two.five = function(n) {
while(n %% 2 == 0) {
n = n/2
}
while(n %% 5 == 0) {
n = n/5
}
return(n == 1)
}
n = as.numeric(unlist(strsplit(s, "/")))
n1 = n[1]
n2 = n[2]
n0 = euclid(n1, n2)
n1 = n1/n0
n2 = n2/n0
if (two.five(n2)) {
cat(sprintf("%.16g", n1/n2))
} else{
cat(sprintf("%.16g/%.16g", n1, n2))
}
}
#f(readLines(file("stdin", "r")))
f("1230/10") # 123
f("12345/100") # 123.45
f("123/45") # 41/15
f("2/5") # 0.4
f("623329371537/799485550592") # 0.7796630859375
f("495306592950/219031126016") # 2.2613525390625
f("877176068377/716862166016") # 1.2236328125
f("96472946117/384354367") # 251
f("1/1") # 1
f("797441094684/769082312705") # 125892/121415
f("951731929962/379731426601") # 198/79
f("1000000000000/1") # 1000000000000
f("1/1000000000000") # 1e-12
f("1000000000000/999999999999") #
f("1/762939453125") # 1.31072e-12
f("541130809335/549755813888") # 0.9843112081125582