私自身が表題の問題を解いた時のプログラムについて解説します。
問題の詳細は「割り算」(CodeIQ)を参照してください。
【概要】
割り算をしてください。
【入力】
入力は
1230/10
のようになっています。
除算記号は「/」です。
除数・被除数ともに、正の整数です。
【出力】
出力は、下表のルールに従ってください。
除算の結果 形式 例 整数の場合 整数として出力してください。
小数点や「/1」などをつけてはいけません。123 有限小数で表現できる場合 有限の小数として出力してください。
先頭は、値が1未満の場合は「0.」で、それ以外は 0 以外にしてください。
末尾は 0 以外にしてください。123.45 上記以外の場合 既約分数として出力してください。
右の例の通り「/」の前後に空白は不要です。41/15
先ほどの入力に対応する出力は
123
になります。
【例】
入力 出力 1230/10 123 12345/100 123.45 123/45 41/15 2/5 0.4
【補足】
不正な入力に対処する必要はありません。
除数・被除数 ともに 一兆 以下です。
入力は必ず「被除数/除数」の形式になっています。
余計な空白はありませんし、「100/10/3」のような割り算記号が複数現れる問題もありません。
1より大きな有理数を分数形式で出力する場合、帯分数ではなく仮分数で出力してください。
Rubyで解答しています。
#!/usr/bin/ruby require 'prime' def isRecurring(r) divs = r.denominator.prime_division for d in divs return true if (d[0] != 2) && (d[0] != 5) end return false end def solve(m, n) r = Rational(m,n) return r.to_i.to_s if r.denominator == 1 return r.to_s if isRecurring(r) return r.to_f.to_s end # main while line = gets line.strip! next if line.empty? m,n = line.split('/').map{|a| a.to_i} puts solve(m, n) end
RubyにはRationalがあるので簡単です。
有理数を扱う手段のない言語だと面倒だと思います。
入力値を分子と分母に分けてsolve()に渡し、結果を印字します。
まず、m/nをRationalにします。
Rubyは便利でこの時点で既約になります。
分母が1の時は整数なので分子を返却します。
isRecurring()は有限小数かどうかを判定する関数で、これがtrueならrを文字列にしたもの、つまり既約のm/nの文字列を返します。
それ以外はrを浮動小数点にして返します。
考え方に書いた通りですが、分母を素因数分解し、その中に2か5以外のものがあればfalseを返し、そうでなければtrueを返します。
Rubyでやったので簡単でした。
問題を解いていた時に小数で返す場合に単に浮動小数点にして大丈夫か、というのが気になりました。つまり、2/5のようなな場合に20/5=4と整数で計算して、結果の文字列を0.4のようにするような必要があるかということが気になったわけです。
面倒だったのでダメだったら対応しようと思って実行したらOKだったので単純に浮動小数点にすればよかったのですが、これは備考に書いておいて欲しかった。