のてすきあ − 完全独習非プログラマー −

Haskell で Project Euler を解く素人遊び

Problem 33

49/98はその値が1/2に等しいが、分子分母に共通する数字"9"を除いた4/8もまた1/2に等しい。このように分子分母から共通の数字を取り除いても値が変わらない(2桁)/(2桁)の分数が、自明な物(10/40 = 1/4 のように分子分母が10の倍数のもの)を除いて4つある。4つの数の積を計算し約分した時の分母の値を求める。

まず候補となる分数をどのように扱うかで少し悩む。後で「共通の数字」を削除する操作がしやすいようにということで、2桁の数字を(Int, Int)のようなタプルで表すこととした。つまり(a,b)で 10 * a + b を表す。そして分数はタプルのタプルで。つまり49/98を( (4,9) , (9,8) )と表現する。

また「値が変わらない」ということをどのように表現するかだが、数値計算で割り算を使うのは危険なので、割り算を避ける意味で

a/b = x/y ⇔ ay = bx

を利用した。


分子分母に共通する数字を持つは、( (a,b), (b,c) ) または ( (b,a), (c,b) )のいずれかの形を持つので( (a,b), (c,b) ) や ( (b,a), (b,c) )の形は考えなくて良い。なぜならこれらは a = c と同値だから)、そのような形の組を全て生成して、「値が変わらない」ことを評価してやれば答えが出る。

色々なやり方がありそう☆