Top / Docs / 練習問題 / 解答例 / シェルピンスキーのギャスレット / Python

問題文

1次元セルオートマトンのルール60と同等実装。ルール90だと左右に広がる。

SZ = 33
s = [ [ 0 for _ in range(SZ) ] for _ in range(SZ) ]
s[0][1] = 1
for r in range(SZ-1):
  for c in range(1, SZ):
    s[r+1][c] = s[r][c] ^ s[r][c-1]
print('\n'.join(''.join('*' if s[r][c] else ' ' for c in range(1, SZ)) for r in range(SZ-1)))

無限に流しておく実装。停止はCtrl+Cで。

import time

Width = 76
cells = [0] * Width
cells_next = cells.copy()
cells[1] = 1

while True:
    print(''.join('*' if cells[c] else ' ' for c in range(1, Width)))
    for c in range(1, Width):
        cells_next[c] = cells[c] ^ cells[c-1]
    cells, cells_next = cells_next, cells
    time.sleep(0.05)

ギャス「ケ」ットだった。死にたい。

import turtle
import math

turtle.speed(6)

# 最初の三角形の各座標を決めます。
# 下記実装は正三角形ですが形は自由です。
A = (0, 270)
B = (- 270 * math.sqrt(3)/2, -270 * 1/2)
C = (270 * math.sqrt(3)/2, -270 * 1/2)

first_tri = [A,B,C]  # 最初の三角形の各座標をリストに格納します。

def draw_triangle(tri_points):  # 3座標のリストを受け取り、三角を描く関数を定義します。
    a, b, c = tri_points
    turtle.penup()
    turtle.goto(a)
    turtle.pendown()
    turtle.begin_fill()
    turtle.goto(b)
    turtle.goto(c)
    turtle.goto(a)
    turtle.end_fill()  # 塗りつぶします。

draw_triangle(first_tri)  # 最初の三角を描きます。

turtle.fillcolor('white')  # 穴を白く塗りつぶして表現するため、fillcolorを白色にします。

# 描画の順番待ちリストを作ります。
# (このような「後ろに追加・前から取り出し」の構造をキューと呼ぶ。
# 実は以下のようにリストでやるのは非効率。なので collections.deque 使え。)
tri_queue = []
tri_queue.append(first_tri)  # 最初の三角を先頭に据えます。

def mid_points(tri_points):  # 三角の中点3つを求める関数を定義します。
    a, b, c = tri_points
    m_ab = ((a[0] + b[0]) / 2, (a[1] + b[1]) / 2)
    m_bc = ((b[0] + c[0]) / 2, (b[1] + c[1]) / 2)
    m_ca = ((c[0] + a[0]) / 2, (c[1] + a[1]) / 2)
    return [m_ab, m_bc, m_ca]

def draw_gasket(level):  # シェルピンスキーのギャスケットを描く関数です。
    n_iter = (3**level - 1)//2  # 描画回数は 1 + 3 + 3^2 + ... の等比級数の和として事前にわかります。

    for _ in range(n_iter):
        tri = tri_queue.pop(0)  # 先頭を取り出します。
        m_ab, m_bc, m_ca = mid_points(tri)
        draw_triangle([m_ab, m_bc, m_ca])  # 穴部分を描きます。

        # 穴により3つの黒三角に分割されるので、それぞれを順番待ちに入れます。
        a, b, c = tri
        tri_queue.append([   a, m_ab, m_ca])
        tri_queue.append([m_ab,    b, m_bc])
        tri_queue.append([m_ca, m_bc,    c])

draw_gasket(4)
turtle.done()
📝 このページに誤りを見つけたら…  GitHubで報告(エンジニア向け)  ・  フォームで報告