17

私はPythonにかなり慣れていないので、趣味の興味として取り上げました。検索を行ったところ、「コンピューティングの実践」の演習がたくさんありました。そのうちの1人が、以下に示すようなASCII図の作成について質問しました。

アスキークロス

とても簡単な練習のように思えますが、数字を使ってこれを描くことに頭を悩ませているようには見えません。この練習では、上の絵は数字「1」を使って描かれたと述べています。

また、0未満または100を超える数値を使用して、ASCII図面を作成することはできません。

別の例を次に示します。

ここでの入力は数字「2」でした。

より大きなASCIIクロス

最初の画像を表示する方法を見つけましたが、指定された数値を使用することなく、whileループ内の単純な「else」を使用して、0以下の数値を除外できるようにしました。 100以上。

行き止まりになりました。

最初の図面を作成するために変数番号を使用しない上記の私のコード:

while True:
s = input("Give me a number to make a drawing with that is between 0 and 100: ")


if not s.isdigit():
    print ("Error, only numbers will make this program run.")
    continue #Try Again but with a number this time

if int(s) >= 100:
    print ("The number is bigger than or equal to 100 and won't work. \nDo try again.")
    continue #try again

if int(s) <= 0:
    print ("The number is smaller than or equal to 0 and won't work. \nDo try again.")
    continue #try again

else:
    print ("%5s" %("*" *3),"\n"'%5s' %("* *"),"\n" '%7s' %("*** ***"),"\n" '%7s' %("*     *"),"\n" '%7s' %("*** ***"),"\n" '%5s' %("* *"),"\n" '%5s' %("*" *3))


    print ('Want to make another drawing ?')
    continue #make another drawing

演習では、次のように述べています。

サイズが$n$のASCII図形は、1行または複数行で構成されています。各行ではスペースと星(*)のみが許可されます。行の各星の後にスペースは許可されないため、「\n」または改行で終了する必要があります。そして、上記の例が続きます。

変数入力に依存する新しいコード例: また、このコード例では、入力が1のときにトリガーするように設定されていますが、入力数を増やすと、図面全体を「拡大」する際に問題が発生します。

    while True:

 A = input("Give me a number to make a drawing with that is between 0 and 100: ")
 b = "***"
 c = "*"
 d = " "


 if not A.isdigit():
        print ("Error, only numbers will make this program run.")
        continue #Try Again but with a number this time

 if int(A) >= 100:
        print ("The number is bigger than or equal to 100 and won't work. \nDo try again.")
        continue #try again

 if int(A) <= 0:
        print ("The number is smaller than or equal to 0 and won't work. \nDo try again.")
        continue #try again


 else :
  range(1,99)
 if int(A) == (1) :
  print ((d *((int(A))*2)) + b,)
  print ((d *((int(A))*2))+ c + d + c,)
  print ((d *((int(A))*0))+ b + d + b,)
  print ((d *((int(A))*0))+ c + d*5 + c,)
  print ((d *((int(A))*0))+ b + d + b,)
  print ((d *((int(A))*2))+ c + d + c,)
  print ((d *((int(A))*2)) + b,)

  continue #try again

しかし、ASCII数値内のスペースの数が1から2に増加するとともに、スペースの数が「増加」するという問題がまだあります。

3行目も問題があるので、コンソールの側面に沿って表示する必要があるため、側面から0の間隔にする必要がありますが、2の間隔で2に増やす必要があります。 。

4

3 に答える 3

14

1 と 2 の違いを考えてみてください。シーケンスを機能させるには、3 と 4 がどのように見えるべきかを手で描いてみてください。シーケンスの開始が与えられ、残りを処理する必要がある問題の 1 つと考えてください。

お気に入り:

0 1 1 2 3 5 8 13

すぐにわからない場合は、フィボナッチ数列です。パターンを理解したら、値の任意の長いシーケンスを書き込むことができます。

そして、この単純な ASCII シーケンスについて考えてみましょう:

1)

#

2)

##
#

3)

###
##
#

4) はどのように見えますか?

または別の ASCII シーケンス:

1)

#

2)

 #
# #
 #

3)

  #
 # #
#   #
 # #
  #

(4)とは?

それでも意味が分からない場合は、理解しようとしているものに少し似ている、独自の再帰的な形状をいくつか設計してみてください (おそらく、私の 2 番目の例に沿ったものです)。今のところ、コーディング方法について心配する必要はありません。出力がどうあるべきかだけを考えてください。次に、パターンを見て、アルゴリズムを考え出します。

于 2012-10-25T20:05:03.087 に答える
3

First, analyze the figure line-by-line to identify the different types of patterns.

  • The cap, which appears only on the top and bottom lines. It is any number of spaces, followed by three stars.
  • The wall, which forms vertical sections of the figure. It is any number of spaces, followed by one star, followed by any number of spaces, followed by a star.
  • The floor, which forms horizontal sections of the figure. It is any number of spaces, followed by three stars, followed by any number of spaces, followed by three stars.

We can write a function that prints each of these patterns.

def cap(spacesBefore):
    print " " * spacesBefore + "***"

def wall(spacesBefore, spacesBetween):
    print " " * spacesBefore + "*" + " " * spacesBetween + "*"

def floor(spacesBefore, spacesBetween):
    print " " * spacesBefore + "***" + " " * spacesBetween + "***"

Next, write code that will display a figure of size, 0, 1, and 2. This should give you insight on how to display a figure of any size.

#size 0
cap(0)
wall(0,1)
cap(0)

print "\n"

#size 1
cap(2)
wall(2, 1)
floor(0, 1)
wall(0, 5)
floor(0, 1)
wall(2, 1)
cap(2)

print "\n"

#size 2
cap(4)
wall(4, 1)
floor(2, 1)
wall(2, 5)
floor(0, 5)
wall(0, 9)
floor(0, 5)
wall(2, 5)
floor(2, 1)
wall(4, 1)
cap(4)

Output:

***
* *
***


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


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

Analyzing the code used to make these figures, some patterns become apparent. For a figure of size N:

  • Both end caps have N*2 preceding spaces.
  • There are 2*N+1 wall lines.
  • There are 2*N floor lines.
  • The first and second halves of the figure are mirror images.
  • The number of preceding spaces for each wall line begins at N*2, then shrinks by two until it reaches zero; then it grows by two again until it reaches N*2 once more.
  • The number of spaces between walls begins at 1, and increases by 4 until it reaches 4*N+1; then it shrinks by four again until it reaches 1 once more.
  • The number of preceding spaces for each floor begins at 2N-2, then shrinks by two until it reaches zero; then it grows by two again until it reaches 2N-2 once more.
  • The number of spaces between floors begins at 1, and increases by 4 until it reaches 4*N-3; then it shrinks by four again until it reaches 1 once more.

The patterns all grow and shrink at a linear rate, and then shrink and grow at a linear rate. This implies that we should use two for loops with opposite conditions, with a little extra code for the caps and central wall.

def draw(N):
    cap(2*N)
    for i in range(N):              #loop from 0 to N-1
        wall(2*(N-i), 1+(4*i))
        floor(2*(N-i-1), 1+(4*i))
    wall(0, 4*N+1)
    for i in range(N-1, -1, -1):    #loop from N-1 to 0
        floor(2*(N-i-1), 1+(4*i))
        wall(2*(N-i), 1+(4*i))
    cap(2*N)

Now test the code.

for i in range(7,10):
    draw(i)
    print "\n"

Output:

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


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


                  ***
                  * *
                *** ***
                *     *
              ***     ***
              *         *
            ***         ***
            *             *
          ***             ***
          *                 *
        ***                 ***
        *                     *
      ***                     ***
      *                         *
    ***                         ***
    *                             *
  ***                             ***
  *                                 *
***                                 ***
*                                     *
***                                 ***
  *                                 *
  ***                             ***
    *                             *
    ***                         ***
      *                         *
      ***                     ***
        *                     *
        ***                 ***
          *                 *
          ***             ***
            *             *
            ***         ***
              *         *
              ***     ***
                *     *
                *** ***
                  * *
                  ***
于 2012-10-26T12:16:14.880 に答える
2

パターンを見つけるには、カメがどのように描くかを想像できます。たとえば、次のように描画します。

***
* *
***

タートルは次の指示に従うことができます:

  • 右折、前進
  • 右折、前進
  • 右折、前進
  • 右折、前進

Python プログラムとして:

import turtle

turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.right(90); turtle.forward(50)
turtle.exitonclick() # leave GUI open until a click

'r'「右に曲がる」を「進む」と略すと"f"、次のようになります。

'rfrfrfrf'

であることが容易にわかる'rf' * 4.以下についても同じ手順に従います。

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

指示は'rflfrfrflfrfrflfrfrflfrf'または'rflfrf' * 4で、'l'「左折」を表します。

nequal to0およびequal toの両方のケースを説明するルール1は次のとおりです。

("rf" + "lfrf" * n) * 4

つまり、n = 0それが'rf' * 4である場合、n = 1それが である場合('rf' + 'lfrf') * 4。式を確認するには、それを描いてn = 2既知の答えと比較します。

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

Python プログラムとして:

from turtle import Turtle

def get_romb_program(n):
    assert n >= 0
    side = "rf" + "lfrf" * n
    program = side * 4  # romb has 4 sides
    return program


def draw(turtle, n):
    assert 0 <= n < 101
    commands = {'r': lambda t: t.right(90),  # turn right
       'l': lambda t: t.left(90),  # turn left
       'f': lambda t: t.forward(2)
    }
    run(get_romb_program(n), turtle, commands)

def run(program, t, commands):
    for c in program:
        commands[c](t)

n = 2
t = Turtle()
scr = t.getscreen()
scr.xscale, scr.yscale = [101 // (n + 1)] * 2
draw(t, n)
scr.exitonclick()

アスキーアートとして印刷するには、AsciiTurtle代わりにturtle.Turtle次を使用できます。

class AsciiTurtle(object):
    def __init__(self):
        self.path = [(0, 0)]
        self.direction = (1, 0)

    def forward(self, distance):
        x, y = self.path[-1]
        for i in range(1, distance + 1):
            self.path.append((x + self.direction[0] * i,
                              y + self.direction[1] * i))

    def right(self, angle_ignored):  # 90 degree turn right
        self.direction = self.direction[1], -self.direction[0]

    def left(self, angle_ignored):  # 90 degree turn left
        self.direction = -self.direction[1], self.direction[0]

    def show(self):
        minx, maxx, maxy, miny = [f(xy[i] for xy in self.path)
                                  for i in [0, 1] for f in [min, max]]
        miny, maxy = -miny, -maxy  # upside-down
        board = [[' '] * (maxx - minx + 1) for _ in range(maxy - miny + 1)]
        for x, y in self.path:
            board[-y - miny][x - minx] = '*'
        print('\n'.join(''.join(row) for row in board))

n = 5
t = AsciiTurtle()
draw(t, n) # defined above
t.show()

出力

          ***          
          * *          
        *** ***        
        *     *        
      ***     ***      
      *         *      
    ***         ***    
    *             *    
  ***             ***  
  *                 *  
***                 ***
*                     *
***                 ***
  *                 *  
  ***             ***  
    *             *    
    ***         ***    
      *         *      
      ***     ***      
        *     *        
        *** ***        
          * *          
          ***          
于 2012-10-27T19:05:27.453 に答える