蛇形填充
【题目】用自然数蛇形填充一个 N 阶的方阵。当N=5时,形如:
这个问题用 haskell 解决时与【题目13】差别甚微。
实际上,从函数式的思考习惯看,只要让有些行作成后反转一下就可以了。
上代码:
ju n = [ f x | x<-[0..n-1] ] where
f row | even row = take n [row*n+1..]
| odd row = reverse . take n $ [row*n+1..]
bu :: Int -> String -> String
bu n s = let x = length (show (n*n))
y = length s
in replicate (x-y) ' ' ++ s
ok :: Int -> [String]
ok n = map (unwords . map (bu n . show)) (ju n)
main = putStrLn $ unlines (ok 5)
$ 在 haskell 中的定义很有意思。
f $ x = f x
这有用?? 是的,虽然还是调用函数,但 $ 的优先级最低。可以避免我们用太多的括号,使人眼花。
reverse . take n $ [row*n+1..]
的意思是:
(reverse . take n) [row*n+1..]
再结合 (.)的定义,上式等价于:
reverse (take n [row*n+1..])
函数的定义后用竖线,表示后面要跟一个限定条件,满足后才匹配。
一般是多个条件,最好能全覆盖,所以,最后一个条件一般都是 otherwise,实际上就是true
因而,也可以这么写:
f row | even row = take n [row*n+1..]
| otherwise = reverse . take n $ [row*n+1..]
或者:
f row | even row = take n [row*n+1..]
| True = reverse . take n $ [row*n+1..]