使用Haskell打印菱形图案

con*_*00b 5 io recursion haskell

我需要编写一个Haskell程序,它将以递归方式生成菱形输出.以下是给定输入的一些示例输出

输入:1
输出:

 *
* *
 *
Run Code Online (Sandbox Code Playgroud)

输入:2
输出:

    *
   * *
    *
 *     *
* *   * *
 *     *
    *
   * *
    *
Run Code Online (Sandbox Code Playgroud)

输入:3
输出:

             *             
            * *             
             *              
          *     *           
         * *   * *          
          *     *           
             *              
            * *             
             *              

    *                 *    
   * *               * *   
    *                 *    
 *     *           *     * 
* *   * *         * *   * *
 *     *           *     * 
    *                 *    
   * *               * *   
    *                 *    
             *             
            * *             
             *              
          *     *           
         * *   * *          
          *     *           
             *              
            * *             
             *     
Run Code Online (Sandbox Code Playgroud)

我写了以下功能:

next 0 = [1,0,1]
next n = map (+3^n) (next (n-1)) ++ next (n-1) ++ map (+3^n) (next (n-1))
lpad n = map (++"*") (zipWith ($) (map (take)(next (n-1))) ((repeat(repeat ' '))))
pretty n = putStrLn $ intercalate "\n" $ lpad n
Run Code Online (Sandbox Code Playgroud)

它给出了以下输出:

漂亮1

 *
*
 *
Run Code Online (Sandbox Code Playgroud)

漂亮2

    *
   *
    *
 *
*
 *
    *
   *
    *
Run Code Online (Sandbox Code Playgroud)

任何人都能帮助我剩下的一半吗?提前致谢.

And*_*ewC 5

我喜欢这个任务,所以我写了一个替代解决方案.

我们可以建立它,有点像你用漂亮的打印机.查看漂亮的包装以获取这些想法并正确使用它们,但是[String]为了这个,我们坚持使用它们.

首先让我们做一个空格

blank :: Int -> [String]
blank n = replicate (3^n) $ replicate (3^n) ' '
Run Code Online (Sandbox Code Playgroud)

然后让我们定义一颗钻石.

diamond :: Int -> [String]
diamond 0 = ["*"]
diamond n = let 
        o = diamond (n-1) 
        x = blank (n-1) in
    joinMatrix [[x,o,x]
               ,[o,x,o]
               ,[x,o,x]]
Run Code Online (Sandbox Code Playgroud)

但是我们怎样才能加入这个矩阵[String]呢?首先得到所有String应该连接在一起的s而不是彼此在一起使用transpose,然后concat全部:

joinLine :: [[String]] -> [String]
joinLine = map concat.transpose
Run Code Online (Sandbox Code Playgroud)

要对整个矩阵执行此操作,我们需要连接每行上的行,然后将所有行连接成一个行列表:

joinMatrix :: [[[String]]] -> [String]
joinMatrix = concat.map joinLine
Run Code Online (Sandbox Code Playgroud)

用于打印的辅助函数:

put = mapM_ putStrLn
d n = put $ diamond n
Run Code Online (Sandbox Code Playgroud)

您可能会认为数值解决方案更有效,而且它是d 4最大的,适合我的屏幕而且速度不慢.你也可以说这个解决方案更清晰.

*Main> d 0
*
*Main> d 1
 * 
* *
 * 
*Main>  d 2
    *    
   * *   
    *    
 *     * 
* *   * *
 *     * 
    *    
   * *   
    *    
Run Code Online (Sandbox Code Playgroud)

(它也适用于更高的n,但它们会使页面上的帖子不必要地长.)


Lar*_*ski 4

对于n==0next n描述了直到镜像为止的整个画面。对于更大的情况来说,情况已不再如此n。因此,第一步,我们更改函数next以输出对称图片:

mmap = map . map

next :: Int -> [[Int]]
next 0 = [[1],[0,2],[1]]
next n = sn ++ map (\a -> a ++ map (+2*3^n) a) nn ++ sn
  where
    nn = next (n - 1)
    sn = mmap (+3^n) nn
Run Code Online (Sandbox Code Playgroud)

现在,next n描述一下所有星星的位置。为了打印它们,我们首先计算相对距离。

diffs :: [Int] -> [Int]
diffs (x:xs) = x: diffs' x (xs)
  where
    diffs' x (y:ys) = y - x - 1 : diffs' y ys
    diffs' _ [] = []
diffs [] = []

lpad :: Int -> [[Char]]
lpad = map (concatMap $ \n -> replicate n ' ' ++ "*") . map diffs . next'
Run Code Online (Sandbox Code Playgroud)

应用于一行,diffs返回我们需要在每个星星之前放置的空格数的列表,并lpad从中生成图片。像以前一样打印它:

pretty :: Int -> IO ()
pretty n = putStrLn $ unlines $ lpad n
Run Code Online (Sandbox Code Playgroud)