「プロジェクトオイラー問33」の編集履歴(バックアップ)一覧はこちら

プロジェクトオイラー問33」(2014/02/14 (金) 13:31:32) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2033 *Problem 33 「桁消去分数」 † 49/98は面白い分数である.「分子と分母からそれぞれ9を取り除くと, 49/98 = 4/8 となり, 簡単な形にすることができる」と経験の浅い数学者が誤って思い込んでしまうかもしれないからである. (方法は正しくないが,49/98の場合にはたまたま正しい約分になってしまう.) 我々は 30/50 = 3/5 のようなタイプは自明な例だとする. このような分数のうち, 1より小さく分子・分母がともに2桁の数になるような自明でないものは, 4個ある. その4個の分数の積が約分された形で与えられたとき, 分母の値を答えよ. 解法 ルールが恣意的だということはその恣意性をコードに記述しなくていけないということです。 もしかしたら深い理由があるのかもしれませんが私にはルールを見つけられませんでした。 というわけで愚直にそのまま実装します。 幸いPrologは恣意的で不合理なルールを記述するのに向いた言語です。 素直にかけます。 最後に出てきた答えを手計算で既約分数に直せば答えです。 gcd(0, B, B). gcd(A, B, G) :- A > 0, R is B mod A, gcd(R, A, G). permAB([A1,A2]):- X =[1,2,3,4,5,6,7,8,9], member(A1,X), member(A2,X). toNum([A1,A2],X):- X is A1*10+A2. dellNum([X,A],[X,B],A,B). dellNum([X,A],[B,X],A,B). dellNum([A,X],[X,B],A,B). dellNum([A,X],[B,X],A,B). search([NumA3,NumB3]):- permAB(A), permAB(B), toNum(A,NumA), toNum(B,NumB), NumA<NumB, dellNum(A,B,NumA2,NumB2), gcd(NumA,NumB,G), NumA1 is NumA//G, NumB1 is NumB//G, gcd(NumA2,NumB2,G1), NumA3 is NumA2//G1, NumB3 is NumB2//G1, NumA1=:=NumA3, NumB1=:=NumB3. mults([],[1,1]):-!. mults([[A,B]|Xs],[ReA1,ReB1]):- mults(Xs,[ReA,ReB]), ReA1 is ReA*A, ReB1 is ReB*B. main33:- findall(N,search(N),AnsList), write(AnsList), mults(AnsList,Ans), write(Ans).
http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%2033 *Problem 33 「桁消去分数」 † 49/98は面白い分数である.「分子と分母からそれぞれ9を取り除くと, 49/98 = 4/8 となり, 簡単な形にすることができる」と経験の浅い数学者が誤って思い込んでしまうかもしれないからである. (方法は正しくないが,49/98の場合にはたまたま正しい約分になってしまう.) 我々は 30/50 = 3/5 のようなタイプは自明な例だとする. このような分数のうち, 1より小さく分子・分母がともに2桁の数になるような自明でないものは, 4個ある. その4個の分数の積が約分された形で与えられたとき, 分母の値を答えよ. 解法 ルールが恣意的だということはその恣意性をコードに記述しなくていけないということです。 もしかしたらこの問題には深い意味があるのかもしれませんが私にはルールを見つけられませんでした。 というわけで愚直にそのまま実装します。 幸いPrologは恣意的で不合理なルールを記述するのに向いた言語です。 素直にかけます。 最後に出てきた答えを手計算で既約分数に直せば答えです。 gcd(0, B, B). gcd(A, B, G) :- A > 0, R is B mod A, gcd(R, A, G). permAB([A1,A2]):- X =[1,2,3,4,5,6,7,8,9], member(A1,X), member(A2,X). toNum([A1,A2],X):- X is A1*10+A2. dellNum([X,A],[X,B],A,B). dellNum([X,A],[B,X],A,B). dellNum([A,X],[X,B],A,B). dellNum([A,X],[B,X],A,B). search([NumA3,NumB3]):- permAB(A), permAB(B), toNum(A,NumA), toNum(B,NumB), NumA<NumB, dellNum(A,B,NumA2,NumB2), gcd(NumA,NumB,G), NumA1 is NumA//G, NumB1 is NumB//G, gcd(NumA2,NumB2,G1), NumA3 is NumA2//G1, NumB3 is NumB2//G1, NumA1=:=NumA3, NumB1=:=NumB3. mults([],[1,1]):-!. mults([[A,B]|Xs],[ReA1,ReB1]):- mults(Xs,[ReA,ReB]), ReA1 is ReA*A, ReB1 is ReB*B. main33:- findall(N,search(N),AnsList), write(AnsList), mults(AnsList,Ans), write(Ans).

表示オプション

横に並べて表示:
変化行の前後のみ表示: