From 6cf14ebc878248978d99a6472f0174c6dc69b44c Mon Sep 17 00:00:00 2001 From: vonzhou Date: Mon, 2 May 2016 17:11:36 +0800 Subject: [PATCH 1/5] add source code of this book --- Chapter04/script.hs | 22 +++++++++++++++++ Chapter05/decimal2rome.hs | 18 ++++++++++++++ Chapter05/fibonacci.hs | 37 ++++++++++++++++++++++++++++ Chapter05/hanoi.hs | 14 +++++++++++ Chapter05/script.hs | 52 +++++++++++++++++++++++++++++++++++++++ Chapter05/search.hs | 7 ++++++ 6 files changed, 150 insertions(+) create mode 100644 Chapter04/script.hs create mode 100644 Chapter05/decimal2rome.hs create mode 100644 Chapter05/fibonacci.hs create mode 100644 Chapter05/hanoi.hs create mode 100644 Chapter05/script.hs create mode 100644 Chapter05/search.hs diff --git a/Chapter04/script.hs b/Chapter04/script.hs new file mode 100644 index 0000000..d9e240c --- /dev/null +++ b/Chapter04/script.hs @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + +reverseSentence :: String -> String +reverseSentence str = unwords (reverse (words str)) + + + diff --git a/Chapter05/decimal2rome.hs b/Chapter05/decimal2rome.hs new file mode 100644 index 0000000..d87578c --- /dev/null +++ b/Chapter05/decimal2rome.hs @@ -0,0 +1,18 @@ +romeNotation :: [String] +romeNotation = ["M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"] + +romeAmount :: [Int] +romeAmount = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] + +pair :: [(Int, String)] +pair = zip romeAmount romeNotation + +subtrahend :: Int -> (Int, String) +subtrahend n = head (dropWhile (\(a,_) -> a > n) pair) + +convert :: Int -> (Int, String) +convert 0 = (0, "") +convert n = let (i,st) = subtrahend n in + let (i',st') = convert (n-i) in (i', st ++ st') + + diff --git a/Chapter05/fibonacci.hs b/Chapter05/fibonacci.hs new file mode 100644 index 0000000..78beeda --- /dev/null +++ b/Chapter05/fibonacci.hs @@ -0,0 +1,37 @@ + +fibonacci :: Int -> Int +fibonacci 0 = 1 +fibonacci 1 = 1 +fibonacci n = fibonacci (n-1) + fibonacci (n-2) + +fibStep :: (Int, Int) -> (Int, Int) +fibStep (u,v) = (v, u+v) + +fibPair :: Int -> (Int, Int) +fibPair 0 = (0, 1) +fibPair n = fibStep (fibPair (n-1)) + +fastFib n = fst (fibPair n) + +fibs n = map fastFib [1 .. n] + +fibs' n = take n (map fst (iterate fibStep (0,1))) + +{- +golden :: Fractional a => Int -> [a] +golden n = take n (map (\(x,y) -> x/y) (iterate fibStep (0,1)) +-} + + +-- 得到连续的3项 +combine :: [(a,a)] -> [(a,a,a)] +combine ((f1,f2):(f3,f4):fs) = (f1,f2,f4) : combine ((f3,f4):fs) +combine _ = [] + +fibPairs :: Int -> [(Int, Int)] +fibPairs n = map fibPair [1 .. n] + +difference :: Int -> [Int] +difference n = map (\(f1,f2,f3) -> f1 * f3 - f2 * f2) (combine $ fibPairs n) + + diff --git a/Chapter05/hanoi.hs b/Chapter05/hanoi.hs new file mode 100644 index 0000000..b0b7c0c --- /dev/null +++ b/Chapter05/hanoi.hs @@ -0,0 +1,14 @@ + +type From = Int +type To = Int +type Via = Int + +move :: (Int, From, To, Via) -> [(From, To)] +move (1, from, to, via) = [(from, to)] +move (n, from, to, via) = move (n-1, from, via, to) ++ [(from, to)] ++ + move (n-1, via, to, from) + +hanoi n = move (n, 1, 2, 3) + + + diff --git a/Chapter05/script.hs b/Chapter05/script.hs new file mode 100644 index 0000000..d7ef3ca --- /dev/null +++ b/Chapter05/script.hs @@ -0,0 +1,52 @@ +factorial :: Integer -> Integer +factorial n = if n < 0 then error "n is less than 0" + else if n == 0 then 1 + else n * factorial (n-1) + +mygcd :: Int -> Int -> Int +mygcd x y = if y == 0 then x else mygcd y (mod x y) + +power :: Int -> Int -> Int +power _ 0 = 1 +power x n = x * power x (n-1) + +power' :: Int -> Int -> Int +power' _ 0 = 1 +power' x n + | odd n = let p = power' x ((n-1) `div` 2) in x * p * p + | otherwise = let p = power' x (n `div` 2) in p * p + + +snoc :: a -> [a] -> [a] +snoc x [] = [x] +snoc x (y:ys) = y : snoc x ys + +last' :: [a] -> a +last' [] = error "empty list" +last' [x] = x +last' (_:xs) = last' xs + +elem' :: Eq a => a -> [a] -> Bool +elem' _ [] = False +elem' a (x:xs) = if a == x then True else elem' a xs + +{- +total :: [Int] -> Int +total [] = 0 +total (x:xs) = x + total xs +-} + + +total' :: [Int] -> Int -> Int +total' [] n = n +--total'(x:xs) n = total' xs (n+x) +total'(x:xs) n = total' xs $! (n+x) + +total xs = total' xs 0 + +mc :: Int -> Int +mc n + | n > 100 = n - 10 + | otherwise = mc (mc (n+11)) + + diff --git a/Chapter05/search.hs b/Chapter05/search.hs new file mode 100644 index 0000000..f29fc64 --- /dev/null +++ b/Chapter05/search.hs @@ -0,0 +1,7 @@ +search :: (Ord a) => a -> [a] -> Bool +search a [] = False +search a xs + | a > m = search a behind + | a < m = search a front + | otherwise = True + where (front, m:behind) = splitAt (length xs `div` 2) xs From e452d89300e545202eb32a74650311f594aae201 Mon Sep 17 00:00:00 2001 From: vonzhou Date: Mon, 2 May 2016 17:16:18 +0800 Subject: [PATCH 2/5] add source code of this book --- Chapter04/script.hs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Chapter04/script.hs b/Chapter04/script.hs index d9e240c..fe10c26 100644 --- a/Chapter04/script.hs +++ b/Chapter04/script.hs @@ -1,22 +1,5 @@ - - - - - - - - - - - - - - - - reverseSentence :: String -> String reverseSentence str = unwords (reverse (words str)) - From ad038320ce34ba32aec39542c323e336255a87d1 Mon Sep 17 00:00:00 2001 From: vonzhou Date: Mon, 2 May 2016 21:29:15 +0800 Subject: [PATCH 3/5] Sort Implemetation --- Chapter05/sort.hs | 97 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 Chapter05/sort.hs diff --git a/Chapter05/sort.hs b/Chapter05/sort.hs new file mode 100644 index 0000000..e5da9fd --- /dev/null +++ b/Chapter05/sort.hs @@ -0,0 +1,97 @@ +------- +--插入排序 + +insert :: (Ord a) => a -> [a] -> [a] +insert x [] = [x] +insert x (y:ys) + | x < y = x:y:ys + | otherwise = y: insert x ys + + +-- 利用中间辅助列表,把要排序的列表元素逐渐插入到辅助list中, 尾递归 +insertionSort :: Ord a => [a] -> [a] -> [a] +insertionSort xs [] = xs +insertionSort xs (y:ys) = insertionSort (insert y xs) ys + +insertionSort' :: Ord a => [a] -> [a] +insertionSort' [] = [] +insertionSort' (x:xs) = insert x (insertionSort' xs) + +------------ +--冒泡排序-- +swaps :: Ord a => [a] -> [a] +swaps [] = [] +swaps [x] = [x] +swaps (x1:x2:xs) + | x1 > x2 = x2 : swaps (x1:xs) + | otherwise = x1 : swaps (x2:xs) + +-- 定义一个不动点函数,一致调用swaps,知道列表不发生改变 +fix :: Eq a => (a -> a) -> a -> a +fix f x = if x == x' then x else fix f x' + where x' = f x + +bubbleSort :: Ord a => [a] -> [a] +bubbleSort xs = fix swaps xs + +-- assemble fix in the bubbleSort +bubbleSort' :: Ord a => [a] -> [a] +bubbleSort' xs + | swaps xs == xs = xs + | otherwise = bubbleSort' $ swaps xs + + +----------------- +--选择排序 +delete :: Eq a => a -> [a] -> [a] +delete _ [] = [] +delete x (l:xs) | x == l = xs + | otherwise = l:delete x xs + +selectionSort :: [Int] -> [Int] +selectionSort [] = [] +selectionSort xs = mini : selectionSort xs' + where mini = minimum xs + xs' = delete mini xs + + +----------------- +--Quick Sort +quickSort :: Ord a => [a] -> [a] +quickSort [] = [] +quickSort (x:xs) = quickSort smaller ++ [x] ++ quickSort larger + where smaller = filter (= x) xs + +filterSplit :: (a -> Bool) -> [a] -> ([a],[a]) +filterSplit _ [] = ([],[]) +filterSplit f (x:xs) + | f x = ((x:l),r) + | otherwise = (l, (x:r)) + where (l,r) = filterSplit f xs + +quickSort' :: Ord a => [a] -> [a] +quickSort' [] = [] +quickSort' [x] = [x] +quickSort' (x:xs) = quickSort' l ++ [x] ++ quickSort' r + where (l,r) = filterSplit ( [a] -> [a] -> [a] +merge xs [] = xs +merge [] ys = ys +merge (x:xs) (y:ys) | x > y = y:merge (x:xs) ys + | otherwise = x:merge xs (y:ys) + +-- 注意where的各个子句要对齐,否则解析错误 +mergeSort :: Ord a => [a] -> [a] +mergeSort [] = [] +mergeSort [x] = [x] +mergeSort xs = merge (mergeSort x1) (mergeSort x2) + where (x1, x2) = halve xs + halve xs = (take l xs, drop l xs) + l = (length xs) `div` 2 + + From 9d2667a863436226f0f0443949bd754be4e13dec Mon Sep 17 00:00:00 2001 From: vonzhou Date: Tue, 3 May 2016 09:48:13 +0800 Subject: [PATCH 4/5] chapter 5 --- Chapter05/Newton.hs | 6 +++++- Chapter05/halt.hs | 6 ++++++ Chapter05/shorter.hs | 7 +++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 Chapter05/halt.hs create mode 100644 Chapter05/shorter.hs diff --git a/Chapter05/Newton.hs b/Chapter05/Newton.hs index 81bf6a0..caa8d74 100644 --- a/Chapter05/Newton.hs +++ b/Chapter05/Newton.hs @@ -1,7 +1,11 @@ +--n 控制迭代的次数 squareroot :: Int -> Double -> Double squareroot 0 x = x squareroot n x = (squareroot (n-1) x + x / squareroot (n-1) x )/2 +-- c 精度控制 +-- f x 步骤 +-- 如果精度满足条件,则得到结果;否则说明还要继续进行牛顿迭代(继续猜测的均值) fix c f x | c x (f x) = x | otherwise = fix c f (f x) @@ -10,4 +14,4 @@ newton c t = (c/t + t) /2.0 mysqrt :: Double -> Double mysqrt c = fix (\a b -> a - b < 0.000001) (newton c) c - \ No newline at end of file + diff --git a/Chapter05/halt.hs b/Chapter05/halt.hs new file mode 100644 index 0000000..530d3d6 --- /dev/null +++ b/Chapter05/halt.hs @@ -0,0 +1,6 @@ +halt :: Integral a => a -> [a] +halt 1 = [1] +halt n | even n = let n' = div n 2 in n' : halt n' + | otherwise = let n' = 3*n + 1 in n' : halt n' + + diff --git a/Chapter05/shorter.hs b/Chapter05/shorter.hs new file mode 100644 index 0000000..ed92cf5 --- /dev/null +++ b/Chapter05/shorter.hs @@ -0,0 +1,7 @@ +-- 对于无穷列表,求长度存在问题 +shorter :: [a] -> [a] -> [a] +shorter xs ys | x < y = xs + | otherwise = ys + where x = length xs + y = length ys + From 85e5fa00d594eae7bd2a21342e59f7c1d0429579 Mon Sep 17 00:00:00 2001 From: vonzhou Date: Tue, 3 May 2016 10:40:46 +0800 Subject: [PATCH 5/5] source code --- Chapter06/Pi.hs | 9 +++++++++ Chapter06/Prime.hs | 22 ++++++++++++++++++++++ README.md | 2 ++ 3 files changed, 33 insertions(+) create mode 100644 Chapter06/Pi.hs create mode 100644 Chapter06/Prime.hs diff --git a/Chapter06/Pi.hs b/Chapter06/Pi.hs new file mode 100644 index 0000000..6d32b9c --- /dev/null +++ b/Chapter06/Pi.hs @@ -0,0 +1,9 @@ + +--生成级数展开序列 +series :: Int -> [Double] +series n = [1/(2 * (fromIntegral k) + 1) * (-1) ^ k | k <- [0 .. n]] + +mypi :: Int -> Double +mypi n = 4 * (sum $ series n) + + diff --git a/Chapter06/Prime.hs b/Chapter06/Prime.hs new file mode 100644 index 0000000..a1447d1 --- /dev/null +++ b/Chapter06/Prime.hs @@ -0,0 +1,22 @@ +factors :: Integral a => a -> [a] +factors n = [x | x <- [1 .. n], mod n x == 0] + +isPrime :: Integral a => a -> Bool +isPrime n = factors n == [1,n] + +primes :: Integral a => a -> [a] +primes n = [x | x <- [1 .. n], isPrime x] + + + +halfOdd :: Integral a => a -> [a] +halfOdd p = takeWhile (\n -> n * n <= p) [3,5 ..] + + +allNotFactorOf :: Integral a => [a] -> a -> Bool +allNotFactorOf xs p = all (\n -> p `mod` n /= 0) xs + + +isPrime' :: Integral a => a -> Bool +isPrime' 2 = True +isPrime' p = p > 1 && odd p && (all (\n -> p `mod` n /= 0) $ takeWhile (\n -> n * n <= p) [3,5 ..]) diff --git a/README.md b/README.md index 5bddc5e..262f224 100644 --- a/README.md +++ b/README.md @@ -91,6 +91,8 @@ This is source code of my book. 第95页 take 5 nature的结果应该为[0,1,2,3,4]而非[1,2,3,4,5] +第100页 isPrime' 代码需要排除偶数的情况,看[Chapter06/Prime.hs](Chapter06/Prime.hs) + 第124页 第一行`某两个列表`应为`某个列表`。 **第124页 该页的最后一段:理论上。。。以及下面的图7-1应该插入在125页练习2之后。