Hatena::ブログ(Diary)

pon_zhanの日記

2009-09-02

Problem 5

問題文(Project Euler - PukiWikiより)

2520 は 1 から 10 の数字の全ての整数で割り切れる数字であり、そのような数字の中では最小の値である。

では、1 から 20 までの整数全てで割り切れる数字の中で最小の値はいくらになるか。


自分が書いた答え
answer5 = f [1..20]

f :: [Int] -> Int
f [x]		= x
f (x:xs)	= lcm x (f xs)

最初、Intリストの最小公倍数を返す関数を自分で実装しようとして四苦八苦した。lcmで簡単に書けることに気づいてこうなった。しかし、foldl1を使えばもっと簡潔に書けると知り勉強中。

それにしても、ふつけるで紹介されていない関数を使えないのは良くない。次の本を読みたいところ……

Problem 4

問題文(Project Euler - PukiWikiより)

左右どちらから読んでも同じ値になる数を回文数という。 2桁の数の積で表される回文数のうち、最大のものは 9009 = 91 × 99 である。

では、3桁の数の積で表される回文数のうち最大のものはいくらになるか。


自分が書いた答え
answer4 = maximum $ filter (\x -> show x == (reverse $ show x)) ns
ns = [x * y | x <- [100..999], y <-[100..999]]

ns の部分をリスト内包表記でこんなに綺麗にかけるとは思わなかった。内部的にはリストモナドらしい。リストモナドの動作原理を考える - あどけない話 で分かりやすく解説されている。


改善できそうな点

回文数のうち最大の数のものを答えれば良いので、ns を大きい順に回文数判定して最初に当たったものが答え。でもやり方が分からない…orz

全部ソートしてからfind を使うのは効率が悪い気がするが、遅延評価だから気にしなくて良いのかな? 誰か教えてください><

2009-08-31

哲学者RPGを作ろう企画 後編

哲学者RPGを作ろう企画」に対して予想以上に反応があったので軽く補足。


  • 友人との馬鹿話のときに偶然生まれたネタなので、僕一人の創作ではありません!
  • 哲学者の役回りはほぼ言葉の響きから決まりました。
  • ニーチェを含むいくつかの設定がまだ残っていたので後で追加します。
  • 作ろう企画となっていますが、もともと仲間内での冗談なので今すぐに自分達がRPGを作るということは無いです。
  • FragileOnline というサークルの方がこのアイデアを使いたいと言って下さいました。もちろん大歓迎なのですが、少しお聞きしたいことがあるので後で直接ご連絡いたします。
  • 他にも、このネタを使いたい(大したアイデアでもありませんが……)という方がいらっしゃったらご自由にどうぞ。その時に一声かけてくれると非常に嬉しいです。

Project Eulerを解き始めた

Haskellの復習を始めてしまったので、その流れでProject Eulerの問題を解く。

Problem 1

リスト内包表記で一発。

answer1 = sum [x | x <- [1..999], (x `mod` 3 == 0) || (x `mod` 5 == 0)]

Problem 2

フィボナッチ数列の問題。解答時のコードは汚くて恥ずかしい。

最初、filter関数で400万以下の数を集めようとしたが、無限リストに適用しても意味が無いことに気づきtakeWhile関数を使う。

-- 解答時のコード

answer2 = 2 + sum [x | x <- takeWhile (<= 4000000) (mkFibs 1 2), even x]

mkFibs :: Integer -> Integer -> [Integer]
mkFibs n1 n2 = [n1 + n2] ++ mkFib n2 (n1 + n2)

フィボナッチ数列のきれいな書き方を教わったのでちょっと改善。

answer2 = sum [x | x <- takeWhile (<= 4000000) fibs, even x]
fibs = 1:2:zipWith (+) fibs (tail fibs)

Problem 3

基本的に素因数分解するだけ。素因数分解の部分をもうちょっと綺麗にかけないかなあ。

answer3 = maximum $ factorize 600851475143

factorize :: Integer -> [Integer]
factorize 1 = [1]
factorize n = factorize' n (2:[3,5..])

factorize' n (x:xs)
	| n < x * x		= [n]
	| n `mod` x == 0	= x : factorize' (n `div` x) (x:xs)
	| otherwise		= factorize' n xs

哲学者RPGを作ろう企画

一番強そうな名前の哲学者は何か、という話から気づいたらRPGを作ろうということになってた。

登場人物

  • カント : 主人公。必殺技は「純粋理性批判」で、レベルが上がると最強の技「永久平和のために」を覚える。
  • キルケゴール : ラスボス。必殺技は「死に至る病」。過去に辛い経験をして絶望して以来変わってしまったらしい。
  • ハイデガー : ラスボス前哨戦。鉄壁のハイデガーの異名をもつ。「存在と時間」を使われると通常攻撃が効かない。
  • フーコー : 序盤に出てくるザコ敵。3、4体でまとまって現れることが多いがギラ系魔法で一撃。まれに「狂気」の状態異常攻撃を使ってくる。
  • ルソー : 夜の街に出てくる変態、害は無い。
  • コーシー/モーシー/カンピーシー : 100種類いるといわれている謎のモンスター。アンノーン的な。

その他

  • 著作を集めると何らかの効果が出るようにしたい。
  • これで倫理の勉強が楽しくなりますね。僕は政経選択ですが。