49/98は面白い分数である。経験の足りない数学家が間違ったやり方で簡約しよ うとして9を取り除いたとき、49/98=4/8となりこれは正しい。
30/50=3/5のようなものは自明な場合とする。
分子と分母が2桁で値が1より小さい分数で、自明ではないこのタイプの分数が ちょうど4つ存在する。
これらの4つの分数の積が規約分数で与えられたときの分母を求めよ。
Haskellには有理数が用意されているのでこれを用いることにする。import Ratioで使用可能になる。リストの内包表記で対象となる分数のリストを生成し、 productで積を求め、denominatorで分母が求まる。値は自動的に既約分数となる。 分数の値は%で生成できる。
ソースコード的な美しさは全くないが、分子の10の位をa、1の位をb、分母の 10の位をc、1の位をdとして、問題の条件を以下のようなコードにする。2桁の 数なので10の位に0はこない。また自明な場合は対象にならないので1の位も0は 含まない。ある数字を取り除く操作があるので、10の位と1の位は同じ値になら ない。分数の値は1より小さい。自明な場合意外ということで、分数の値をxと したときa==dでb/c=xの場合とb==cでa/d=xの場合がありえる。この条件で生成 された分数を最初に書いた処理をすれば答えが求まる。
euler033 = denominator $ product [(a * 10 + b) % (c * 10 + d)
| a <- [1..9], b <- [1..9],
c <- [1..9], d <- [1..9],
curious a b c d]
where curious a b c d = a /= b && c /= d && x < 1
&& ((a == d && b % c == x)
|| (b == c && a % d == x))
where x = (a * 10 + b) % (c * 10 + d)
