import Control.Applicative main :: IO () main = do s <- getLine putStrLn $ solve $ quicksort' s solve :: [a] -> [a] solve [] = [] solve (x:xs) = solve xs ++ [x] {-- 1回だけ関数を使用するときに使う無名関数。 通常、ラムダ式は高階関数に渡す関数を作るためだけに使用される。 宣言は(\)を書いて、それから関数の引数をスペース区切りで書く。 ラムダ式を使ってコラッタ列の(\xs -> length xs > 15)が使用例である。 --} -- ラムダ式 flip' :: (a -> b -> c) -> b -> a -> c flip' f = \x y -> f y x -- ラムダ式を使ってコラッタ列 numLongChain' :: Int numLongChain' = length (filter (\xs -> length xs > 15) (map chain [1..100])) -- コラッツ列 chain :: Integer -> [Integer] chain 1 = [1] chain x | even x = x : chain (x `div` 2) | odd x = x : chain (x * 3 + 1) numLongChain :: Int numLongChain = length (filter isLong (map chain [1..100])) where isLong xs = length xs > 15 -- リスト内包表記10000より小さいすべての奇数の平方数の和 squareRoot' :: Integral a => a squareRoot' = sum (takeWhile (<10000) [m | m <- [n^2 | n <- [1..]], odd m]) -- 10000より小さいすべての奇数の平方数の和 squareRoot :: Integral a => a squareRoot = sum (takeWhile (<10000) (filter odd (map (^2) [1..]))) -- mapとfilterの実装例 largestDivisible :: Integer largestDivisible = head (filter p [100000,99999..]) where p x = x `mod` 3829 == 0 -- filter'を使ってquicksort'を実装 quicksort' :: (Ord a) => [a] -> [a] quicksort' [] = [] quicksort' (x:xs) = quicksort' small ++ [x] ++ quicksort' larger where small = filter' (<= x) xs larger = filter' (> x) xs -- filter関数を実装 filter' :: (a -> Bool) -> [a] -> [a] filter' _ [] = [] filter' p (x:xs) | p x = x : filter' p xs | otherwise = filter' p xs --map関数を実装 map' :: (a -> b) -> [a] -> [b] map' _ [] = [] map' f (x:xs) = f x : map' f xs -- flipを実装 --flip' :: (a -> b -> c) -> b -> a -> c --flip' f x y = f y x --zipWithを実装 zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c] zipWith' _ [] _ = [] zipWith' _ _ [] = [] zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys -- 高階実演 applyTwice :: (a -> a) -> a -> a applyTwice f x = f (f x) -- セクション(という名のセクション) divideByTen :: (Floating a) => a -> a divideByTen = (/10) isUpperAlpahnum :: Char -> Bool isUpperAlpahnum = (`elem` ['A'..'Z']) -- 高階関数 (関数を戻り値にすることができる) twoadd :: Int -> Int -> Int twoadd x y = x + y adad :: Int -> Int adad = twoadd 10 --} -- quicksortを実装 quicksort :: (Ord a) => [a] -> [a] quicksort [] = [] quicksort (x:xs) = quicksort smaller ++ [x] ++ quicksort larger where smaller = [a | a <- xs, a <= x] larger = [a | a <- xs, a > x] -- elemを実装 elem' :: (Eq a) => a -> [a] -> Bool elem' a [] = False elem' a (x:xs) | x == a = True | otherwise = a `elem'` xs -- zipを実装 zip' :: [a] -> [b] -> [(a,b)] zip' [] _ = [] zip' _ [] = [] zip' (x:xs) (y:ys) = (x,y) : zip' xs ys -- repeatを実装 repeat' :: a -> [a] repeat' x = x : repeat' x -- reverseを実装 reverse' :: [a] -> [a] reverse' [] = [] reverse' (x:xs) = reverse' xs ++ [x] -- takeを実装 take' :: Int -> [a] -> [a] take' n _ | n <= 0 = [] take' _ [] = [] take' n (x:xs) = x : take' (n-1) xs replicate' :: Int -> a -> [a] replicate' n x | n <= 0 = [] | otherwise = x : replicate' (n-1) x -- リストの中に格納されている値の合計を計算する sum' :: (Num a) => [a] -> a sum' [] = error "empty list!" sum' [x] = x sum' (x:xs) = x + (sum' xs) -- リストの中に格納されている最大の値を探す maximum' :: (Ord a) => [a] -> a maximum' [] = error "maximum of empty list!" maximum' [x] = x maximum' (x:xs) = max x (maximum' xs) -- http://abc001.contest.atcoder.jp/tasks/abc001_ calc i | i < 100 = "00" | i < 1000 = "0" ++ (show $ i `div` 100) | i <= 5000 = show $ i `div` 100 | (6000 <= i && i <= 30000) = show $ 50 + i `div` 1000 | (35000 <= i && i <= 70000) = show $ (i `div` 1000 - 30) `div` 5 + 80 | otherwise = "89" -- let cylinder :: Double -> Double -> Double cylinder r h = let sideArea = 2 * pi * r * h topArea = pi * r ^ 2 in sideArea + 2 * topArea calcBmis :: [(Double,Double)] -> [Double] calcBmis xs = [bmi w h | (w, h) <- xs] where bmi weight height = weight / height ^ 2 initials :: String -> String -> String initials firstname lastname = [f] ++ ". " ++ [l] ++ "." where (f:_) = firstname (l:_) = lastname -- パターンマッチとwhere bmiTell :: Double -> Double -> String bmiTell weight height | bmi <= skynny = "You're underweight, you emo, you!" | bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!" | bmi <= fat = "You're fat! Lose some weight, fatty!" | otherwise = "You're a whale, congratulations!" where bmi = weight / height ^ 2 (skynny,normal,fat) = (18.5,25.0,30.0) -- whereのスコープ -- いいパターン badGreeting :: String badGreeting = "Oh! Pfft. It's you." niceGreeting :: String niceGreeting = "Hello! So very nice to see you," greet :: String -> String greet "Juan" = niceGreeting ++ " Juan!" greet "Fernando" = niceGreeting ++ " Fernando!" greet name = badGreeting ++ " " ++ name myCompare :: (Ord a) => a -> a -> Ordering a `myCompare` b | a == b = EQ | a <= b = LT | otherwise = GT max' :: (Ord a) => a -> a -> a max' a b | a < b = b | otherwise = a -- asパターン firstLetter :: String -> String firstLetter "" = "Empty string, whoops!" firstLetter all@(x:xs) = "The first letter of " ++ all ++ " is " ++ [x] tell :: (Show a) => [a] -> String tell [] = "The list is empty." tell (x:[]) = "The list has one element: " ++ (show x) tell (x:y:[]) = "The list has two element: " ++ (show x) ++ " and " ++ (show y) tell (x:y:_) = "The list is long. The first two elements are: " ++ (show x) ++ " and " ++ (show y) head' :: [a] -> a head' [] = error "Can't call head on an empty list, dummy!" head' (x:_) = x