5

ダイヤモンド出力を再帰的に生成するHaskellプログラムを作成する必要があります。これが与えられた入力のためのいくつかのサンプル出力です

入力:1
出力:

 *
* *
 *

入力:2
出力:

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

入力:3
出力:

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

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

私は次の関数を書きました:

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

これにより、次の出力が得られます。

かなり1

 *
*
 *

かなり2

    *
   *
    *
 *
*
 *
    *
   *
    *

誰かが残りの半分で私を助けることができますか?前もって感謝します。

4

3 に答える 3

5

私はその仕事が好きだったので、別の解決策を書きました。

きれいなプリンターを作るのと同じように、それを組み立てることができます。これらのアイデアを取り入れて適切に使用するには、きれいなパッケージを調べてください[String]

まず、空白のグリッドを作成しましょう

blank :: Int -> [String]
blank n = replicate (3^n) $ replicate (3^n) ' '

次に、ダイヤモンドを定義しましょう。

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]]

しかし、どうすればこの行列を[String]一緒に結合できるでしょうか? 最初に、Stringを使用して相互の下ではなく隣同士に連結する必要があるすべての を取得しtranspose、次にconcatそれらすべてを取得します。

joinLine :: [[String]] -> [String]
joinLine = map concat.transpose

行列全体に対してこれを行うには、各行の行を結合し、すべての行を 1 つの行のリストに連結する必要があります。

joinMatrix :: [[[String]]] -> [String]
joinMatrix = concat.map joinLine

印刷用のヘルパー関数:

put = mapM_ putStrLn
d n = put $ diamond n

数値解法の方が効率的であると主張することもできますが、実際にd 4はそうですが、私の画面に収まる最大のものであり、遅くはありません。この解決策はより明確であると主張することもできます。

*Main> d 0
*
*Main> d 1
 * 
* *
 * 
*Main>  d 2
    *    
   * *   
    *    
 *     * 
* *   * *
 *     * 
    *    
   * *   
    *    

(これはより高い n でも機能しますが、ページ上でこの投稿が不必要に長くなります。)

于 2012-12-08T16:05:31.340 に答える
4

についてn==0は、next 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

次に、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'

1 行に適用され、diffs各星の前に配置する必要があるスペースの数のリストを返し、lpadそこから画像を生成します。前と同じように印刷します。

pretty :: Int -> IO ()
pretty n = putStrLn $ unlines $ lpad n
于 2012-12-08T15:48:22.923 に答える
1

これは、AndrewC のソリューションから派生したものです。スペース ブロックは再帰的に生成され、コードをわかりやすくするために演算子を使用することを好みます。

diamond
    = putStr
    . unlines
    . fst
    . (iterate f (["*"], [" "]) !!)
  where
    f (d, e)
        = (  e + d + e
         ++  d + e + d
         ++  e + d + e
          ,  e + e + e
         ++  e + e + e
         ++  e + e + e
          )

    (+) = zipWith (++)

一般化。これが必要な場合:

             +             
            - -            
             +             
          -     -          
         + +   + +         
          -     -          
             +             
            - -            
             +             
    -                 -    
   + +               + +   
    -                 -    
 +     +           +     + 
- -   - -         - -   - -
 +     +           +     + 
    -                 -    
   + +               + +   
    -                 -    
             +             
            - -            
             +             
          -     -          
         + +   + +         
          -     -          
             +             
            - -            
             +             

解決策はstar 3どこにありますか

star
    = putStr
    . unlines
    . (\(d, p, e) -> d)
    . (iterate f (["-"], ["+"], [" "]) !!)
  where
    f (d, p, e)
        = (  e + p + e
         ++  d + e + d
         ++  e + p + e
          ,  e + d + e
         ++  p + e + p
         ++  e + d + e
          ,  e + e + e
         ++  e + e + e
         ++  e + e + e
          )

    (+) = zipWith (++)
于 2013-01-12T11:24:32.473 に答える