打印大X
【题目】在控制台上输出一个由星号组成的“大X”,要求可以改变笔宽和高度。
当笔宽=3,高度=10的时候,输出如图:
这类的问题,按haskell 的函数组合思路,一般都是先构造一部分,再通过旋转、镜像等变换、组给得出最终的结果。当然,图形有对称性才可以这样。
如果图形没有任何规律呢?。。。。那是个美术问题。。不要编程了吧
---打印大X
big_x :: Int -> Int -> [String]
big_x pen_width height =
[ zipWith f x (reverse x) | x <- half_x ]
where
half_x =
[ replicate i ' '
++ replicate pen_width '*'
++ replicate (height-1-i) ' '
| i<-[0..height-1] ]
f '*' _ = '*'
f _ '*' = '*'
f _ _ = ' '
main = putStrLn . unlines $ big_x 3 10
half_x 是先画出X的一笔。另一笔和它是镜像对称关系。
把这两者用 zipWith 合在一处就是了。
如果对 height-1 啊,height-1-i 等精细计算深恶痛绝(我亦如是,设计若比需求更不自然,纵有一百个理由,也。。。。),也可以换如下方案。不过是多变换几步。
big_x w h =
[ zipWith f x (reverse x) | x <- half_x ]
where
half_x = let sp = [replicate i ' ' | i<-[0..] ]
base = replicate h $ replicate w '*'
t1 = zipWith (++) sp base
t2 = reverse t1
in zipWith (++) t2 sp
f c1 c2 = if c1=='*' || c2=='*' then '*' else ' '