既約分数の数を求める

例えば,1〜10までの刻み幅で,値を入力できるプログラムがあったとしよう.なんかの数値の入力でも,図形入力の座標値でもなんでもかまわない.

このとき,例えばベースとなる値を1000にすると,1/3を入力したときに端数が出るから,浮動小数点数を使おう,とか考えてはいけない.浮動小数点数にすると,値の比較とかで常に悩まなくてはならないのだから.そんなことをするよりも,0/1,1/1,1/2,...,9/10の値しか入力として受理されないことがわかっているのだから,それに最も近い値に丸めてしまうのが正解である.0,100,...,900の値をソートして通し番号を振って,二つの整数の組で,値を表現すれば良い*1.こうすれば,値の差を求める場合など,多少ややこしい場合は残るが,比較に関しては常に整数の比較ですむから,話は楽である*2

ありがちなパターンとしては,図形入力で入力した点がすでに入力された点の集合に含まれるかを判別したりってのが,ぱっと思いつく(というか,この問題を考えてたんだけど).この場合は浮動小数点で点の座標を考えるとすると,点の近傍に入力があった場合はその入力が集合に含まれるとするのが妥当な実装だろうけれども,その場合は入力された点と集合に含まれた点のどっちを集合に含まれているとするのか悩んだりすることになる.すでに集合に含まれた点を生かすという実装にするならば,入力の順で微妙に集合が変わることになって,なんか上手くない気がする.それなら,入力を全て受け取って近傍に含まれる点の平均をその点群の座標とするのがよさそうな気がするが,システムの性質によってはそういう実装にできない場合もある.まあ,とにかく頭がこんがらがってくるのだ.

んで,考えててふと思った.もし,刻み幅が1〜10ならば,既約の分数は,

0
1
1/2
1/3 2/3
1/4 3/4
1/5 2/5 3/5 4/5
1/6 5/6
1/7 2/7 3/7 4/7 5/7 6/7
1/8 3/8 5/8 7/8
1/9 2/9 4/9 5/9 7/9 8/9
1/10 3/10 7/10 9/10

の,33個であるが,これが1〜nの場合だったら,いったいいくつになるんだろうか.

どっかの入試の問題にありそうだが,ぱっと考えただけでは思いつかない.こういう問題苦手なんだよなー

*1:別に,分数でそのまま管理してもいいんだけど,既約分数の扱いとかで,ややこしくなりそうでいま一つ面白くない

*2:って,これウソかも.誤差が積み重なって,最終的にえらいことになるかもしれない・・・入出力に関しては,こうするのが正解だと思うけれども.