diff --git a/problems/yoshi/chapter10/1.hs b/problems/yoshi/chapter10/1.hs new file mode 100644 index 0000000..8db6740 --- /dev/null +++ b/problems/yoshi/chapter10/1.hs @@ -0,0 +1,4 @@ +import Prelude hiding (putStr) + +putStr :: String -> IO () +putStr xs = sequence_ [putChar x | x <- xs] \ No newline at end of file diff --git a/problems/yoshi/chapter10/2.hs b/problems/yoshi/chapter10/2.hs new file mode 100644 index 0000000..1030cbb --- /dev/null +++ b/problems/yoshi/chapter10/2.hs @@ -0,0 +1,13 @@ +type Board = [Int] + +putRow :: Int -> Int -> IO () +putRow row num = do + putStr (show row) + putStr ": " + putStrLn (concat (replicate num "* ")) + +putBoard :: Int -> Board -> IO () +putBoard _ [] = return () +putBoard current (x : xs) = do + putRow current x + putBoard (current + 1) xs diff --git a/problems/yoshi/chapter10/3.hs b/problems/yoshi/chapter10/3.hs new file mode 100644 index 0000000..ec238fa --- /dev/null +++ b/problems/yoshi/chapter10/3.hs @@ -0,0 +1,10 @@ +type Board = [Int] + +putRow :: Int -> Int -> IO () +putRow row num = do + putStr (show row) + putStr ": " + putStrLn (concat (replicate num "* ")) + +putBoard :: Board -> IO () +putBoard xs = sequence_ [putRow row num | (row, num) <- zip [1 ..] xs] \ No newline at end of file diff --git a/problems/yoshi/chapter10/4.hs b/problems/yoshi/chapter10/4.hs new file mode 100644 index 0000000..cc568bf --- /dev/null +++ b/problems/yoshi/chapter10/4.hs @@ -0,0 +1,14 @@ +adderHelper :: Int -> Int -> IO Int +adderHelper n total + | n == 0 = do + return total + | otherwise = do + x <- getLine + adderHelper (n - 1) (total + (read x :: Int)) + +adder :: IO () +adder = do + putStr "How many numbers? " + n <- getLine + total <- adderHelper (read n :: Int) 0 + putStrLn ("The total is " ++ show total) \ No newline at end of file diff --git a/problems/yoshi/chapter10/5.hs b/problems/yoshi/chapter10/5.hs new file mode 100644 index 0000000..5d84d04 --- /dev/null +++ b/problems/yoshi/chapter10/5.hs @@ -0,0 +1,6 @@ +adder :: IO () +adder = do + putStr "How many numbers? " + n <- getLine + numbers <- sequence (replicate (read n :: Int) getLine) + putStrLn ("The total is " ++ show (sum (map read numbers :: [Int]))) diff --git a/problems/yoshi/chapter10/6.hs b/problems/yoshi/chapter10/6.hs new file mode 100644 index 0000000..f2ea383 --- /dev/null +++ b/problems/yoshi/chapter10/6.hs @@ -0,0 +1,28 @@ +import System.IO (hSetEcho, stdin) + +readLine :: IO String +readLine = do + hSetEcho stdin False + readLineHelper "" + where + readLineHelper input = do + x <- getChar + case x of + '\n' -> do + putChar '\n' + return input + '\DEL' -> + if null input + then readLineHelper input + else do + putStr "\b \b" + readLineHelper (init input) + '\b' -> + if null input + then readLineHelper input + else do + putStr "\b \b" + readLineHelper (init input) + _ -> do + putChar x + readLineHelper (input ++ [x]) \ No newline at end of file diff --git a/problems/yoshi/chapter3/1.hs b/problems/yoshi/chapter3/1.hs new file mode 100644 index 0000000..aaaf6a4 --- /dev/null +++ b/problems/yoshi/chapter3/1.hs @@ -0,0 +1,15 @@ +a::[Char] +a = ['a', 'b', 'c'] + +b::(Char, Char, Char) +b = ('a', 'b', 'c') + + +c :: [(Bool, Char)] +c = [(False, '0'), (True, '1')] + +d :: ([Bool], [Char]) +d = ([False, True], ['0', '1']) + +e :: [[a] -> [a]] +e = [tail, init, reverse] \ No newline at end of file diff --git a/problems/yoshi/chapter3/2.hs b/problems/yoshi/chapter3/2.hs new file mode 100644 index 0000000..0968606 --- /dev/null +++ b/problems/yoshi/chapter3/2.hs @@ -0,0 +1,14 @@ +bools :: [Bool] +bools = [True, False] + +nums :: [[Int]] +nums = [[1, 2], [3]] + +add :: Int -> Int -> Int -> Int +add = \x -> \y -> \z -> x + y + z + +copy :: a -> (a, a) +copy = \x -> (x, x) + +apply :: (a -> b) -> a -> b +apply = \f -> \x -> f x diff --git a/problems/yoshi/chapter3/3.hs b/problems/yoshi/chapter3/3.hs new file mode 100644 index 0000000..b3e59b1 --- /dev/null +++ b/problems/yoshi/chapter3/3.hs @@ -0,0 +1,17 @@ +second :: [a] -> a +second xs = head (tail xs) + +swap :: (a, b) -> (b, a) +swap (x, y) = (y, x) + +pair :: a -> b -> (a, b) +pair x y = (x, y) + +double :: Num a => a -> a +double x = x * 2 + +palindrome :: Eq a => [a] -> Bool +palindrome xs = reverse xs == xs + +twice :: (a -> a) -> a -> a +twice f x = f (f x) \ No newline at end of file diff --git a/problems/yoshi/chapter3/5.md b/problems/yoshi/chapter3/5.md new file mode 100644 index 0000000..bd9d82c --- /dev/null +++ b/problems/yoshi/chapter3/5.md @@ -0,0 +1,2 @@ +- 一般の関数を対象とすると、入力のパターンが無限になりうるため全ての出力の値が同一であることを式を評価することにって確認することができないため。 +- 関数が停止するかを決定することが不可能であるため。 \ No newline at end of file diff --git a/problems/yoshi/chapter4/1.hs b/problems/yoshi/chapter4/1.hs new file mode 100644 index 0000000..58dd83f --- /dev/null +++ b/problems/yoshi/chapter4/1.hs @@ -0,0 +1,3 @@ +halve :: [a] -> ([a], [a]) +halve xs = (take n xs, drop n xs) + where n = length xs `div` 2 \ No newline at end of file diff --git a/problems/yoshi/chapter4/2.hs b/problems/yoshi/chapter4/2.hs new file mode 100644 index 0000000..43d4307 --- /dev/null +++ b/problems/yoshi/chapter4/2.hs @@ -0,0 +1,9 @@ +third_1 :: [a] -> a +third_1 xs = head (tail (tail xs)) + +third_2 :: [a] -> a +third_2 xs = xs !! 2 + +third_3 :: [a] -> a +third_3 (_:_:x:_) = x + diff --git a/problems/yoshi/chapter4/3.hs b/problems/yoshi/chapter4/3.hs new file mode 100644 index 0000000..7e7a48d --- /dev/null +++ b/problems/yoshi/chapter4/3.hs @@ -0,0 +1,10 @@ +safetail_1 :: [a] -> [a] +safetail_1 xs = if null xs then [] else tail xs + +safetail_2 :: [a] -> [a] +safetail_2 xs | null xs = [] + | otherwise = tail xs + +safetail_3 :: [a] -> [a] +safetail_3 [] = [] +safetail_3 (_:xs) = xs \ No newline at end of file diff --git a/problems/yoshi/chapter4/4-1.hs b/problems/yoshi/chapter4/4-1.hs new file mode 100644 index 0000000..3bd0260 --- /dev/null +++ b/problems/yoshi/chapter4/4-1.hs @@ -0,0 +1,3 @@ +(||) :: Bool -> Bool -> Bool +True || _ = True +False || a = a \ No newline at end of file diff --git a/problems/yoshi/chapter4/4-2.hs b/problems/yoshi/chapter4/4-2.hs new file mode 100644 index 0000000..78def08 --- /dev/null +++ b/problems/yoshi/chapter4/4-2.hs @@ -0,0 +1,5 @@ +(||) :: Bool -> Bool -> Bool +True || True = True +True || False = True +False || True = True +False || False = False \ No newline at end of file diff --git a/problems/yoshi/chapter4/4-3.hs b/problems/yoshi/chapter4/4-3.hs new file mode 100644 index 0000000..4ed2ef6 --- /dev/null +++ b/problems/yoshi/chapter4/4-3.hs @@ -0,0 +1,3 @@ +(||) :: Bool -> Bool -> Bool +False || False = False +_ || _ = True \ No newline at end of file diff --git a/problems/yoshi/chapter4/4-4.hs b/problems/yoshi/chapter4/4-4.hs new file mode 100644 index 0000000..fb01a7c --- /dev/null +++ b/problems/yoshi/chapter4/4-4.hs @@ -0,0 +1,3 @@ +(||) :: Bool -> Bool -> Bool +b || c | b == c = b + | otherwise = True \ No newline at end of file diff --git a/problems/yoshi/chapter4/5.hs b/problems/yoshi/chapter4/5.hs new file mode 100644 index 0000000..33d9b6a --- /dev/null +++ b/problems/yoshi/chapter4/5.hs @@ -0,0 +1,2 @@ +(&&) :: Bool -> Bool -> Bool +b && c = if b == True then if c == True then True else False else False \ No newline at end of file diff --git a/problems/yoshi/chapter4/6.hs b/problems/yoshi/chapter4/6.hs new file mode 100644 index 0000000..0bf15f5 --- /dev/null +++ b/problems/yoshi/chapter4/6.hs @@ -0,0 +1,2 @@ +(&&) :: Bool -> Bool -> Bool +b && c = if b == True then c else False \ No newline at end of file diff --git a/problems/yoshi/chapter4/7.hs b/problems/yoshi/chapter4/7.hs new file mode 100644 index 0000000..1e0d4bb --- /dev/null +++ b/problems/yoshi/chapter4/7.hs @@ -0,0 +1,2 @@ +mult :: Int -> Int -> Int -> Int +mult = \x -> \y -> \z -> x * y * z \ No newline at end of file diff --git a/problems/yoshi/chapter4/8.hs b/problems/yoshi/chapter4/8.hs new file mode 100644 index 0000000..1de0735 --- /dev/null +++ b/problems/yoshi/chapter4/8.hs @@ -0,0 +1,6 @@ +luhnDouble :: Int -> Int +luhnDouble x | x * 2 > 9 = x * 2 - 9 + | otherwise = x * 2 + +luhn :: Int -> Int -> Int -> Int -> Bool +luhn a b c d = (luhnDouble a + b + luhnDouble c + d) `mod` 10 == 0 \ No newline at end of file diff --git a/problems/yoshi/chapter5/1.hs b/problems/yoshi/chapter5/1.hs new file mode 100644 index 0000000..7f28e23 --- /dev/null +++ b/problems/yoshi/chapter5/1.hs @@ -0,0 +1 @@ +n = sum [x^2 | x <- [1..100]] \ No newline at end of file diff --git a/problems/yoshi/chapter5/2.hs b/problems/yoshi/chapter5/2.hs new file mode 100644 index 0000000..8de9ee7 --- /dev/null +++ b/problems/yoshi/chapter5/2.hs @@ -0,0 +1,5 @@ +grid :: Int -> Int -> [(Int, Int)] +grid m n = [(x, y) | x <- [0..m], y <- [0..n]] + +square :: Int -> [(Int, Int)] +square n = [(x, y) | (x, y) <- grid n n, x /= y] \ No newline at end of file diff --git a/problems/yoshi/chapter5/3.hs b/problems/yoshi/chapter5/3.hs new file mode 100644 index 0000000..e69de29 diff --git a/problems/yoshi/chapter6/1.hs b/problems/yoshi/chapter6/1.hs new file mode 100644 index 0000000..598c8be --- /dev/null +++ b/problems/yoshi/chapter6/1.hs @@ -0,0 +1,6 @@ +-- n が負の場合, 停止しなくなるためその場合はエラーを返す. +fac :: Int -> Int +fac 0 = 1 +fac n + | n < 0 = error "fac: negative argument" + | otherwise = n * fac (n - 1) \ No newline at end of file diff --git a/problems/yoshi/chapter6/2.hs b/problems/yoshi/chapter6/2.hs new file mode 100644 index 0000000..2da52d2 --- /dev/null +++ b/problems/yoshi/chapter6/2.hs @@ -0,0 +1,3 @@ +sumdown :: Int -> Int +sumdown 0 = 0 +sumdown n = n + sumdown (n - 1) \ No newline at end of file diff --git a/problems/yoshi/chapter6/3.hs b/problems/yoshi/chapter6/3.hs new file mode 100644 index 0000000..4aa1451 --- /dev/null +++ b/problems/yoshi/chapter6/3.hs @@ -0,0 +1,5 @@ +import Prelude hiding ((^)) + +(^) :: Int -> Int -> Int +m ^ 0 = 1 +m ^ n = m * m ^ (n - 1) \ No newline at end of file diff --git a/problems/yoshi/chapter6/4.hs b/problems/yoshi/chapter6/4.hs new file mode 100644 index 0000000..b5617e1 --- /dev/null +++ b/problems/yoshi/chapter6/4.hs @@ -0,0 +1,5 @@ +euclid :: Int -> Int -> Int +euclid m n + | m == n = m + | m < n = euclid m (n - m) + | m > n = euclid (m - n) n \ No newline at end of file diff --git a/problems/yoshi/chapter6/5.hs b/problems/yoshi/chapter6/5.hs new file mode 100644 index 0000000..03c3d68 --- /dev/null +++ b/problems/yoshi/chapter6/5.hs @@ -0,0 +1,14 @@ +import Prelude hiding (drop, init, length) + +length :: [a] -> Int +length [] = 0 +length (_ : xs) = 1 + length xs + +drop :: Int -> [a] -> [a] +drop 0 xs = xs +drop _ [] = [] +drop n (_ : xs) = drop (n - 1) xs + +init :: [a] -> [a] +init [_] = [] +init (x : xs) = x : init xs \ No newline at end of file diff --git a/problems/yoshi/chapter6/6.hs b/problems/yoshi/chapter6/6.hs new file mode 100644 index 0000000..f916cc1 --- /dev/null +++ b/problems/yoshi/chapter6/6.hs @@ -0,0 +1,25 @@ +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} + +{-# HLINT ignore "Use foldr" #-} +import Prelude hiding (elem, and, concat, replicate, (!!)) + +and :: [Bool] -> Bool +and [] = True +and (x : xs) = x && and xs + +concat :: [[a]] -> [a] +concat [] = [] +concat (xs : xss) = xs ++ concat xss + +replicate :: Int -> a -> [a] +replicate 0 _ = [] +replicate n x = x : replicate (n - 1) x + +(!!) :: [a] -> Int -> a +[] !! _ = error "index too large" +(x : _) !! 0 = x +(_ : xs) !! n = xs !! (n - 1) + +elem :: Eq a => a -> [a] -> Bool +elem _ [] = False +elem y (x : xs) = x == y || elem y xs \ No newline at end of file diff --git a/problems/yoshi/chapter6/8.hs b/problems/yoshi/chapter6/8.hs new file mode 100644 index 0000000..ac40f0f --- /dev/null +++ b/problems/yoshi/chapter6/8.hs @@ -0,0 +1,11 @@ +import Merge (merge) + +halve :: [a] -> ([a], [a]) +halve xs = splitAt (length xs `div` 2) xs + +msort :: (Ord a) => [a] -> [a] +msort [] = [] +msort [x] = [x] +msort xs = merge (msort ys) (msort zs) + where + (ys, zs) = halve xs \ No newline at end of file diff --git a/problems/yoshi/chapter6/9.hs b/problems/yoshi/chapter6/9.hs new file mode 100644 index 0000000..e69de29 diff --git a/problems/yoshi/chapter6/Merge.hs b/problems/yoshi/chapter6/Merge.hs new file mode 100644 index 0000000..5e0aeea --- /dev/null +++ b/problems/yoshi/chapter6/Merge.hs @@ -0,0 +1,9 @@ +module Merge (merge) where + +merge :: (Ord a) => [a] -> [a] -> [a] +merge [] [] = [] +merge [] ys = ys +merge xs [] = xs +merge (x : xs) (y : ys) + | x <= y = x : merge xs (y : ys) + | otherwise = y : merge (x : xs) ys \ No newline at end of file diff --git a/problems/yoshi/chapter7/1.hs b/problems/yoshi/chapter7/1.hs new file mode 100644 index 0000000..ba7a878 --- /dev/null +++ b/problems/yoshi/chapter7/1.hs @@ -0,0 +1,3 @@ +listCompresion :: (a -> a) -> (a -> Bool) -> [a] -> [a] +listCompresion _ _ [] = [] +listCompresion f p xs = map f (filter p xs) \ No newline at end of file diff --git a/problems/yoshi/chapter7/2.hs b/problems/yoshi/chapter7/2.hs new file mode 100644 index 0000000..8c490c7 --- /dev/null +++ b/problems/yoshi/chapter7/2.hs @@ -0,0 +1,19 @@ +import Prelude hiding (all, any, dropWhile, takeWhile) + +all :: (a -> Bool) -> [a] -> Bool +all p = foldr (\x acc -> p x && acc) True + +any :: (a -> Bool) -> [a] -> Bool +any p = foldr (\x acc -> p x || acc) False + +takeWhile :: (a -> Bool) -> [a] -> [a] +takeWhile _ [] = [] +takeWhile p (x : xs) + | p x = x : takeWhile p xs + | otherwise = [] + +dropWhile :: (a -> Bool) -> [a] -> [a] +dropWhile _ [] = [] +dropWhile p (x : xs) + | p x = dropWhile p xs + | otherwise = x : xs \ No newline at end of file diff --git a/problems/yoshi/chapter7/3.hs b/problems/yoshi/chapter7/3.hs new file mode 100644 index 0000000..d2e319f --- /dev/null +++ b/problems/yoshi/chapter7/3.hs @@ -0,0 +1,7 @@ +map :: (a -> a) -> [a] -> [a] +map _ [] = [] +map f xs = foldr (\x acc -> f x : acc) [] xs + +filter :: (a -> Bool) -> [a] -> [a] +filter _ [] = [] +filter p xs = foldr (\x acc -> if p x then x : acc else acc) [] xs \ No newline at end of file diff --git a/problems/yoshi/chapter7/4.hs b/problems/yoshi/chapter7/4.hs new file mode 100644 index 0000000..3ca086a --- /dev/null +++ b/problems/yoshi/chapter7/4.hs @@ -0,0 +1,2 @@ +dec2int :: [Int] -> Int +dec2int = foldl (\x y -> 10 * x + y) 0 \ No newline at end of file diff --git a/problems/yoshi/chapter7/5.hs b/problems/yoshi/chapter7/5.hs new file mode 100644 index 0000000..20ac99a --- /dev/null +++ b/problems/yoshi/chapter7/5.hs @@ -0,0 +1,10 @@ +{-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} + +{-# HLINT ignore "Redundant lambda" #-} +import Prelude hiding (curry, uncurry) + +curry :: ((a, b) -> c) -> a -> b -> c +curry f = \x y -> f (x, y) + +uncurry :: (a -> b -> c) -> (a, b) -> c +uncurry f = \(x, y) -> f x y \ No newline at end of file diff --git a/problems/yoshi/chapter7/6.hs b/problems/yoshi/chapter7/6.hs new file mode 100644 index 0000000..e69de29 diff --git a/problems/yoshi/chapter7/9.hs b/problems/yoshi/chapter7/9.hs new file mode 100644 index 0000000..f54d944 --- /dev/null +++ b/problems/yoshi/chapter7/9.hs @@ -0,0 +1,3 @@ +altMap :: (a -> b) -> (a -> b) -> [a] -> [b] +altMap _ _ [] = [] +altMap f g (x : xs) = f x : altMap g f xs \ No newline at end of file diff --git a/problems/yoshi/chapter8/1.hs b/problems/yoshi/chapter8/1.hs new file mode 100644 index 0000000..e7de10f --- /dev/null +++ b/problems/yoshi/chapter8/1.hs @@ -0,0 +1,10 @@ +data Nat = Zero | Succ Nat + deriving (Show) + +add :: Nat -> Nat -> Nat +add Zero n = n +add (Succ m) n = Succ (add m n) + +mult :: Nat -> Nat -> Nat +mult m Zero = Zero +mult m (Succ n) = add m (mult m n) \ No newline at end of file diff --git a/problems/yoshi/chapter8/2.hs b/problems/yoshi/chapter8/2.hs new file mode 100644 index 0000000..e5f3aee --- /dev/null +++ b/problems/yoshi/chapter8/2.hs @@ -0,0 +1,9 @@ +data Tree a = Leaf a | Node (Tree a) a (Tree a) + deriving (Show) + +occurs :: (Ord a) => a -> Tree a -> Bool +occurs x (Leaf y) = x == y +occurs x (Node l y r) = case compare x y of + LT -> occurs x l + EQ -> True + GT -> occurs x r diff --git a/problems/yoshi/chapter8/3.hs b/problems/yoshi/chapter8/3.hs new file mode 100644 index 0000000..12cc7a4 --- /dev/null +++ b/problems/yoshi/chapter8/3.hs @@ -0,0 +1,10 @@ +data Tree a = Leaf a | Node (Tree a) (Tree a) + deriving (Show) + +leaves :: Tree a -> Int +leaves (Leaf _) = 1 +leaves (Node l r) = leaves l + leaves r + +balanced :: Tree a -> Bool +balanced (Leaf _) = True +balanced (Node l r) = abs (leaves l - leaves r) <= 1 && balanced l && balanced r \ No newline at end of file diff --git a/problems/yoshi/chapter8/4.hs b/problems/yoshi/chapter8/4.hs new file mode 100644 index 0000000..27fc9d1 --- /dev/null +++ b/problems/yoshi/chapter8/4.hs @@ -0,0 +1,11 @@ +halve :: [a] -> ([a], [a]) +halve xs = splitAt (length xs `div` 2) xs + +data Tree a = Leaf a | Node (Tree a) (Tree a) + deriving (Show) + +balance :: [a] -> Tree a +balance [x] = Leaf x +balance xs = Node (balance ys) (balance zs) + where + (ys, zs) = halve xs diff --git a/problems/yoshi/chapter8/5.hs b/problems/yoshi/chapter8/5.hs new file mode 100644 index 0000000..ef2c8ed --- /dev/null +++ b/problems/yoshi/chapter8/5.hs @@ -0,0 +1,12 @@ +data Expr = Val Int | Add Expr Expr + deriving (Show) + +folde :: (Int -> a) -> (a -> a -> a) -> Expr -> a +folde f g (Val x) = f x +folde f g (Add x y) = g (folde f g x) (folde f g y) + +eval :: Expr -> Int +eval = folde id (+) + +size :: Expr -> Int +size = folde (const 1) (+) \ No newline at end of file