haskell 基础题解(25)

打印大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 ' '
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值