Skip to content

Instantly share code, notes, and snippets.

@hitsumabushi
Created November 11, 2012 07:43
Show Gist options
  • Save hitsumabushi/4054092 to your computer and use it in GitHub Desktop.
Save hitsumabushi/4054092 to your computer and use it in GitHub Desktop.
すごいH本読書会 in 大阪 #1 問題
-- ガードを使わないことにしてみる。
-- map, filter,fold も使わない.
-- いくつかの関数の実装
-- null, sum, product, elem
null' :: [a] -> Bool
null' [] = True
null' _ = False
-- sum と product 書くのめんどくさいので。
-- foldも使わないと言ったけど、実装しないとは言ってないっ!
-- 型もfold{l|r}と違うし。
reduce :: (a -> a -> a) -> a -> [a] -> a
reduce _ x [] = x
reduce f x (y:ys) = reduce f (f x y) ys
sum' :: (Num a) => [a] -> a
sum' = reduce (+) 0
product' :: (Num a) => [a] -> a
product' = reduce (*) 1
elem' :: (Eq a) => a -> [a] -> Bool
elem' a = any ( == a)
-- Python の slice の実装
slice :: Int -> Int -> [b] -> [b]
slice n m xs = take (m - n) $ drop n xs
-- fibo : Fibonacci 数列 の n 番目を返す関数
-- まず、 fibon を定義する
fibon :: (Integral a) => a -> a -> a -> a
fibon a _ 0 = a
fibon _ b 1 = b
fibon a b n = fibon b (a + b) (n - 1)
fibo = fibon 0 1
-- sliceFizzBuzz : FizzBuzz の n ~ m 番目
-- まず、FizzBuzz の無限リストを返す関数 fizzBuzz を作る
divisable :: (Integral a) => (a,a) -> (b,b) -> b
divisable (m,n) (s,t) = if m `mod` n == 0 then s else t
fizzBuzz :: [String]
fizzBuzz = [ x ++ y | n <- [1..], let x = divisable (n,3) ("Fizz",""), let y = divisable (n,5) ("Buzz","")]
sliceFizzBuzz n m = slice n m fizzBuzz
-- 問題:
-- 3けたの整数のうち、次の条件を満たすものを「良い整数」とよぶことにします。
-- 条件: 3けたの整数を2つの整数に分けてその和を考えると、常にもとの整数の約数になっている。
-- 例1 : 330は3と30に分けても、33と0に分けても和が330の約数になっています。このため、330は「良い整数」となります。
-- 例2 : 702は7と02に分けた場合は約数になりますが、70と2に分けてしまうと約数になりません。よって、702は「良い整数」ではありません。
-- 一の位が0でない「良い整数」を4個求めなさい。
-- 解答:
spanList :: [a] -> [([a],[a])]
spanList xs = takeWhile (not . null . snd) [splitAt n xs | n <- [1..]]
-- Integral に対してgoodかどうかを判定
isGoodNum :: (Read a,Show a, Integral a) => a -> Bool
isGoodNum n =
let xs = spanList $ show n
nums = [ (read $ (fst x)) + (read $ (snd x))| x <- xs ]
in and [ n `mod` sum == 0 | sum <- nums ]
goodAnswer = [ n | n <- [100..999], n `mod` 10 /= 0, isGoodNum n]
-- 終わり.
-- 以下、一般化して解いて、その部分列を取ろうと思ったけど、停止しない…
-- どうしてすぐ終わらないのかわからない。教えていただけるとありがたい。
goodNumsWithDigitCondition :: (Read a,Show a,Integral a) => [a]
goodNumsWithDigitCondition = [ n | n <- [1..], n `mod` 10 /= 0, isGoodNum n]
-- そこから 3桁の数の部分リストを取る
answerNums :: (Read a,Show a,Integral a) => (a,a) -> [a]
answerNums (n,m) = dropWhile (< n) $ takeWhile (< m) goodNumsWithDigitCondition
answer = answerNums (100,1000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment