简体   繁体   English

打印复杂的菱形图案

[英]Print a Complex Diamond Pattern

I am trying to build a diamond pattern of diamond pattern.我正在尝试构建菱形图案的菱形图案。 Let me break it down for you.让我为你分解一下。 Currently I have a function that prints a diamond pattern with input as size.目前我有一个功能可以打印一个输入为大小的菱形图案。

def diamond(n,space=' '): 

    for i in range(n):
        print(space*(n-1-i) + "* "*(i+1))            
    for l in range(n-1,0,-1):   
        print(space*(n-l) + "* "*(l))

diamond(2)

My output will be a diamond of size 2我的输出将是大小为 2 的钻石

 * 
* * 
 * 

Now what i really want is replace each star with this diamond pattern itself.现在我真正想要的是用这种菱形图案本身替换每颗星星。 Desired output to look like.所需的输出看起来像。

在此处输入图片说明

Should be able to do this for all sizes, where each star of that pattern is replaced by the whole pattern.应该能够对所有尺寸执行此操作,其中该图案的每个星号都被整个图案替换。

Thank you.谢谢你。

You cannot go to a previous line once your cursor has advanced.一旦光标前进,您就无法转到上一行。 Instead you can approach the problem differently.相反,您可以以不同的方式处理问题。 If you have a set of words you want to print such as如果您有一组要打印的单词,例如

words = ['Hello', 'World']

You can print each of them n times as follows:您可以按如下方式将它们中的每一个打印n次:

for word in words:
    print(word * n)

For n = 2 , this gives对于n = 2 ,这给出

HelloHello
WorldWorld

You can use np.array as a grid and put '*' with position [i][j].您可以使用 np.array 作为网格并将 '*' 放在位置 [i][j]。 In this code, empty array is made, then check the position of * and finally set outer diamond position.在这段代码中,创建空数组,然后检查 * 的位置,最后设置外菱形位置。 There might be better code but this still works.可能有更好的代码,但这仍然有效。

import numpy as np

n = 2

k = (2*n - 1)

# make empty array, set
# a is used for single diamond. Not necessary.
a = np.array([[' ']*k for t in range(k)])
# set of * position in array
b = set()
c = np.array([[' ']*k**2 for t in range(k**2)])

# check positions in array of single diamond 
for i in range(n**2):
    for i in range(n):
        i_reverce = k - i -1
        for j in range(i+1):
            y = n-i-1+2*j
            a[i][y] = '*'
            a[i_reverce][y] = '*'
            b.add((i,y))
            b.add((i_reverce,y))

# print(a) # use if you want to check a

positions = list(b)

# positions of * in diamond of diamond
for pos1 in positions:
    for pos2 in positions:
        x = pos1[0] * k + pos2[0]
        y = pos1[1] * k + pos2[1]
        c[x][y] = '*'

for row in c:
    print(''.join(row))

For n=2对于 n=2

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

For n=3对于 n=3

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

With this recursive function you can print a complex diamond on any position of the screen.使用此递归函数,您可以在屏幕的任何位置打印复杂的菱形。

import sys

def draw_diamond(x, y, diamond_size):
    # x and y represent the upper-left corner of the diamond to be drawn
    # diamond_size must be a power of 3
    if diamond_size == 1:
        sys.stdout.write("\x1b7\x1b[%d;%df%s\x1b8" % (x, y, "*"))
        sys.stdout.flush()
        return
    subdiamond_size = diamond_size / 3
    draw_diamond(x + subdiamond_size, y, subdiamond_size)
    draw_diamond(x, y + subdiamond_size, subdiamond_size)
    draw_diamond(x + 2*subdiamond_size, y + subdiamond_size, subdiamond_size)
    draw_diamond(x + subdiamond_size, y + 2*subdiamond_size, subdiamond_size)

For example, draw_diamond(5, 100, 27) prints a diamond with dimension 27 whose upper-left corner is 5 characters from the top of the terminal and 100 characters from the left of the terminal:例如, draw_diamond(5, 100, 27)打印尺寸为 27 的菱形,其左上角距终端顶部 5 个字符,距终端左侧 100 个字符:

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

You can get your desired output by using diamond_size=9 .您可以使用diamond_size=9获得所需的输出。 Possible sizes are 1, 3, 9, 27, 81, 243, etc.可能的大小为 1、3、9、27、81、243 等。

Your desired output can be obtained with diamond_size=3**2 :您可以使用diamond_size=3**2获得所需的输出:

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

Take them in strings:把它们放在字符串中:

>>> s1, s2 = '', ''
>>> for i in range(2):
...     s1 += 'Hello'
...     s2 += 'World'
... 
>>> print(s1); print(s2)
HelloHello
WorldWorld

As you want all in one line, you can try:如果您想在一行中完成所有操作,您可以尝试:

>>> print(*(l*2 for l in ['Hello','World']),sep='\n')

HelloHello
WorldWorld

If you want to keep using range:如果您想继续使用范围:

print(*(''.join((['Hello','World']*2)[i::2]) for i in range(2)), sep='\n')

For your second requirement, without changing your code much:对于您的第二个要求,无需太多更改代码:

n=2
for i in range(n):
    s = ' '*(n-1-i) + "* "*(i+1);print(s+' '*(n-1-i)+s)
for l in range(n-1,0,-1):   
    s = ' '*(n-l) + "* "*(l);print(s+' '*(n-l)+s)

I think convert basic star sign to a retangle shaped string like this我认为将基本的星座转换为像这样的 retangle 形状的字符串


basic = ''' * 
* *
 * '''
print(basic)
>>> * 
>>>* *
>>> *

tolist = basic.split('\n')
x = len(tolist[0])
y = len(tolist)
'''This x, y might be the arguments you need
 to write a generator function base on size'''

If you want to change the pattern to repeat, modify the str_ variable.如果要将模式更改为重复,请修改 str_ 变量。

str_ = " * \n* *\n * "
str_splited = str_.split("\n")

for i in str_splited:
    for j in range(0, 3):
        print(i*j, end="")
    print("")

I like the idea of putting one one diamond at each star(*) of the single diamond to create the full pattern.我喜欢在单颗钻石的每个星形 (*) 上放一颗一颗钻石来创建完整图案的想法。 You could do it but you will have to recompute the spacing between them.您可以这样做,但您必须重新计算它们之间的间距。 My solution is based on your idea.我的解决方案是基于你的想法。

What I did is created a function that creates a single diamond but accepts two additional parameters X_Offset and Y_Offset.我所做的是创建了一个创建单个菱形但接受两个附加参数 X_Offset 和 Y_Offset 的函数。 Once the star was created, all I had to do is compute the X_Offset and Y_Offset for each of the possible star and pass the previous function to this zipped list of X_Offset and Y_Offset.创建星星后,我所要做的就是为每个可能的星星计算 X_Offset 和 Y_Offset,并将前一个函数传递给这个 X_Offset 和 Y_Offset 的压缩列表。 Finally I created a reporter function that prints the star.最后我创建了一个打印星星的记者功能。

This program has a lot of room for improvement since it is slow and based on for loop.这个程序有很大的改进空间,因为它很慢并且基于 for 循环。 Some math experts could make it fast.一些数学专家可以让它很快。 I am not sure if this is what you wanted.我不确定这是否是您想要的。 Nevertheless here it is.尽管如此,它还是在这里。

import numpy as np
import math
np.set_printoptions(linewidth=100)


def MakeADiamond(n, X_Offset, Y_Offset, Array):
    NumDrawn = 0
    StartPos_Y, StartPos_X = Y_Offset, X_Offset

    while(NumDrawn < n):
        ## Move to left edge of the diamond and start filling digonally upwards.
        ## Then move down and repeat the process until bottom of the star is reached
        for x in range(n):
            Array[StartPos_Y - x + (n-1), StartPos_X + x -n +1] = 1
        StartPos_Y += 1
        StartPos_X += 1
        NumDrawn += 1        
    return Array


def PrintFullPattern(Array):
    ## replace 1 with '*' and 0 with ' '
    ## Needed for final printing
    NewArray = np.where(Array==1, "*"," ")
    for i in NewArray:
        for j in i:
            print(j,sep="",end="")
        print()


def MakeADiamondOfDiamonds(n):
    Array = np.zeros(shape=((2*n-1)**2,(2*n-1)**2)) ## I create a placeholder for the numbers/stars
    NumDiamonds = [x for x in range(1,n,1)]+[n]+[y for y in range(n-1,0,-1)] ## Calculate the number of diamonds in each layer
    X_Offset_List = [] ## Create an empty X_Offset
    Y_Offset_List = [] ## Create an empty Y_Offset
    Y_Offset_Start = 0 ## Y_Offset for the first star must be zero  
    for eachNumDiamonds in NumDiamonds:
        X_Offset_Start = math.floor(((2*n-1)**2)/2) - (eachNumDiamonds-1) * (2*n -1)  ## Calculate the starting X_Offset for every layer                  
        for eachDiamond in range(eachNumDiamonds): ## Process each diamond of a particular layer
            X_Offset_List.append(X_Offset_Start) ## Add to X_Offset
            Y_Offset_List.append(Y_Offset_Start) ## Add to Y_Offset
            X_Offset_Start += 2*(2*n -1) ## Increment X_Offset for the next star in the same layer
        Y_Offset_Start += (2*n -1) ## Increment Y_Offset for the star in the next layer
    Offset_List = list(zip(X_Offset_List, Y_Offset_List)) ## Bring together X_Offset and Y_Offset so that they could be passed to the function

    for (eachOffset_X, eachOffset_Y) in Offset_List: ## For every X and Y offset for stars, compute a single diamond position
        Array = MakeADiamond(n, eachOffset_X, eachOffset_Y, Array)

    PrintFullPattern(Array)

MakeADiamondOfDiamonds(2)
MakeADiamondOfDiamonds(3)
MakeADiamondOfDiamonds(4)

The outputs respectively for 2, 3 and 4 stars are as below.分别为 2、3 和 4 星的输出如下。

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

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM