C 语言版的一个问题的 Haskell 实现

发布于 2022-08-12 05:12:30 字数 3305 浏览 18 评论 8

原题在此:
http://bbs.chinaunix.net/thread-1260094-1-1.html

Haskell Code:

  1. #!/usr/bin/runhaskell
  2. import System.Environment
  3. f' 1 = [0]
  4. f' n = prefix ++ middle ++ postfix
  5.   where half = n `div` 2
  6.         (prefix, postfix) = splitAt (half) $ f' (n-1)
  7.         middle = if n `mod` 2 == 1
  8.                   then [half]
  9.                   else [half-1]
  10. f'' _ 0 = []
  11. f'' offset n = f'' (offset+1) (n-1) ++ [thisLine]
  12.   where thisLine = white ++ foldr ((++) . (++" ")) "" items
  13.         white = map (const ' ') [1..offset]
  14.         items = map (show) (f' n)
  15. f n = mapM_ (putStrLn) $ f'' 0 n
  16. main = do
  17.   [str] <- getArgs
  18.   let n = read str
  19.   f n

复制代码
打印结果:

  1. flw@debian:~/study$ ./ttt.hs 10
  2.          0
  3.         0 0
  4.        0 1 0
  5.       0 1 1 0
  6.      0 1 2 1 0
  7.     0 1 2 2 1 0
  8.    0 1 2 3 2 1 0
  9.   0 1 2 3 3 2 1 0
  10. 0 1 2 3 4 3 2 1 0
  11. 0 1 2 3 4 4 3 2 1 0
  12. flw@debian:~/study$ ./ttt.hs 20
  13.                    0
  14.                   0 0
  15.                  0 1 0
  16.                 0 1 1 0
  17.                0 1 2 1 0
  18.               0 1 2 2 1 0
  19.              0 1 2 3 2 1 0
  20.             0 1 2 3 3 2 1 0
  21.            0 1 2 3 4 3 2 1 0
  22.           0 1 2 3 4 4 3 2 1 0
  23.          0 1 2 3 4 5 4 3 2 1 0
  24.         0 1 2 3 4 5 5 4 3 2 1 0
  25.        0 1 2 3 4 5 6 5 4 3 2 1 0
  26.       0 1 2 3 4 5 6 6 5 4 3 2 1 0
  27.      0 1 2 3 4 5 6 7 6 5 4 3 2 1 0
  28.     0 1 2 3 4 5 6 7 7 6 5 4 3 2 1 0
  29.    0 1 2 3 4 5 6 7 8 7 6 5 4 3 2 1 0
  30.   0 1 2 3 4 5 6 7 8 8 7 6 5 4 3 2 1 0
  31. 0 1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1 0
  32. 0 1 2 3 4 5 6 7 8 9 9 8 7 6 5 4 3 2 1 0

复制代码

[ 本帖最后由 flw 于 2008-9-4 18:07 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

陌伤浅笑 2022-08-17 08:52:42
  1. (defun draw (n)
  2.   (let ((L (make-list (+ n 1) " ")))
  3.     (let ((f (lambda (l)
  4.                (cond ((= (% l 2) 0)
  5.                       (setq L (append (cdr L) (list (format "%d" (/ l 2))))))
  6.                      (t (setq L (append (cdr L) (list " ")))))
  7.                (mapcar 'insert L) (mapcar 'insert (cdr (reverse L)))
  8.                (newline)
  9.                (if (= l n) t
  10.                  (funcall f (+ l 1))))))
  11.       (funcall f 0))))

复制代码

何必那么矫情 2022-08-17 08:43:28

原帖由 flw 于 2008-9-4 22:30 发表
我对预定义函数的熟悉程度还不够啊。
谢谢 MMMIX 的指点。

哈哈,互相帮助吧,我写的时候也是参照了你的代码的。

最近正为 Monad transformer 头疼呢,不过这两天看 GHC 的 monad transformer 的实现还是蛮有收获的

[ 本帖最后由 MMMIX 于 2008-9-4 22:42 编辑 ]

沉溺在你眼里的海 2022-08-17 08:24:41

我对预定义函数的熟悉程度还不够啊。
谢谢 MMMIX 的指点。

绝影如岚 2022-08-17 08:15:29

原帖由 aero 于 2008-9-4 22:05 发表
还处于完全看不懂的阶段。

看看这个也许有帮助,How to read Haskell
http://www.haskell.org/haskellwiki/How_to_read_Haskell

梦醒灬来后我 2022-08-17 07:59:02

还处于完全看不懂的阶段。

肤浅与狂妄 2022-08-16 22:49:18

我的版本:

  1. module Main where
  2. import System.Environment (getArgs)
  3. import Data.List (intersperse)
  4. import Control.Monad (sequence_)
  5. -- | Digit palindrome stream
  6. digitPalindroms :: [[Int]]
  7. digitPalindroms = map digitPalindrom [1..]
  8.     where
  9.         digitPalindrom :: Int -> [Int]
  10.         digitPalindrom 1 = [0]
  11.         digitPalindrom n = [0..c] ++ (reverse [0..f])
  12.             where
  13.                 n' = fromIntegral $ n - 2
  14.                 c  = ceiling $ n' / 2
  15.                 f  = floor $ n' / 2
  16. -- | Prefix stream
  17. prefixes :: [String]
  18. prefixes = map (n -> replicate n ' ') [0..]
  19. -- | Generate a digit palindrom triangle
  20. --
  21. -- XXX: need a better genTriangle
  22. genTriangle :: Int -> [String]
  23. genTriangle n = zipWith (++) prefixes' strs
  24.     where
  25.         ints2str ns = concat . intersperse " " $ map show ns
  26.         strs = map ints2str $ take n digitPalindroms
  27.         prefixes' = reverse $ take n prefixes
  28. -- | Unlines string list, then put the result to stdout
  29. putStrs :: [String] -> IO ()
  30. putStrs = mapM_ putStrLn
  31. main = do
  32.     args <- getArgs
  33.     let ns = map read args
  34.     sequence_ $ map putStrs $ map genTriangle ns

复制代码

挽袖吟 2022-08-16 18:12:45

flw 代码改进易读性后的版本:

  1. import System.Environment
  2. import Data.List
  3. f' 1 = [0]
  4. f' n = prefix ++ middle ++ postfix
  5.     where
  6.         half = n `div` 2
  7.         (prefix, postfix) = splitAt half $ f' (n-1)
  8.         middle = if odd n then [half] else [half-1]
  9. f'' _ 0 = []
  10. f'' offset n = f'' (offset+1) (n-1) ++ [thisLine]
  11.     where
  12.         thisLine = white ++ (concat $ intersperse " " items)
  13.         white = replicate offset ' '
  14.         items = map (show) (f' n)
  15. f n = mapM_ (putStrLn) $ f'' 0 n
  16. main = do
  17.     [str] <- getArgs
  18.     let n = read str
  19.     f n

复制代码

时光清浅 2022-08-15 15:11:14

貌似Haskell的语法比较对我胃口,呵呵。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文