1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

生成AIにPythonを書かせて、1次元セルオートマトンを動かしてみた

Posted at

私は聞こえないため、情報保障1が整っている放送大学大学院でリスキリングに取り組んでいます。その中の講義「計算と自然」で、ひさしぶりにセルオートマトン(以下、CA)に出会いました。

単純なルールから複雑なパターンが生まれ、まるで生き物のように動く様子に強く惹かれました。 特に、カオス的な振る舞いを見せるルールには、自然現象とのつながりを感じてワクワクしました。:grin:

そこで今回は、

生成AI × オートマトン × Python&EXCEL

という組み合わせで、「本当にAIにオートマトンのプログラムを書かせられるのか?」を実験してみることにしました。

どれも特別な開発環境を必要とせず、誰でもすぐに試せるようにしています。

セルオートマトンの概要

まずは、セルオートマトンについて簡単にまとめます2

  • セルオートマトンとは?
     自分自身と周囲のセルの状態、そして遷移ルールに基づいて次の状態を決定する「計算モデル」です。

  • 1次元初等セルオートマトン(ECA)とは?
     セルが1列に並び、各セルは0か1の状態を持ちます。
     自分自身と左右のセルの状態に応じて、次の状態が決まります。

  • ECAルールとは?
     ルール番号(0〜255)で定義されます。以下はECAルール16の例です。
    ECAルール16.png

 左から2番目のセルの状態は、左・中央・右のセルがそれぞれ「1・0・0(黒・白・白)」のとき、次の状態が「1(黒)」になります。 このように、遷移結果(0, 0, 0, 1, 0, 0, 0, 0)を2進数とみなして10進数に変換したものが、ルール番号16です。

利用する生成AIとプロンプト

  • 使用ツール:Microsoft Copilot (GPT-5.1)
  • プロンプト例:
     プログラムの言語、入力、処理、出力に分けて、スクリプトの仕様を明確に記述することがポイントです。
 1次元初等セルオートマトンを以下の仕様で作成してください。

# 言語  
Python 3.10 以上

# 入力  
- コマンドプロンプトで、初期状態とECAルール番号を入力する  
- 初期状態は、最大30桁の「1」と「0」からなる文字列  
- ECAルール番号は、0〜255 の10進数

# 処理  
- 1次元初等セルオートマトン(ECA)を、指定した世代数だけシミュレーションする  
- 各世代の状態を1行ずつCSVに出力する

# 出力  
- CSVファイル(カンマ区切り)  
- セルの状態は、1(黒)と空白(白)で表現する  
- ファイル名は「セルオートマトン_ECA_<ルール番号>_<yyyymmddhhmmss>.csv」とする

# 注意  
- Python初心者でも理解できるように、上から下へ流れる構成にしてください  
- 各処理にコメントを付けて、コードレビューがしやすいようにしてください

生成されたマクロと実行結果

コードの紹介

コメントと一緒にコードが生成されたので、各関数がどんな処理しているのかがわかります。

import csv
from datetime import datetime

# ----------------------------------------
# 1. ルール番号(0〜255)を2進数8ビットに変換する関数
#    例:30 → "00011110"
# ----------------------------------------
def rule_to_binary(rule_number: int) -> str:
    return f"{rule_number:08b}"


# ----------------------------------------
# 2. 3セルのパターン(111,110,...,000)に対応する次状態を返す関数
#    ルールのビット列を逆順にしてインデックス対応させる
# ----------------------------------------
def next_cell_state(left: str, center: str, right: str, rule_bits: str) -> str:
    pattern = left + center + right
    index = int(pattern, 2)  # パターンを2進数として整数に変換
    return rule_bits[::-1][index]  # ビット列を逆順にして参照


# ----------------------------------------
# 3. 1世代分の状態を計算する関数
# ----------------------------------------
def evolve(state: str, rule_bits: str) -> str:
    next_state = ""

    # 両端は0(白)とみなす
    padded = "0" + state + "0"

    # 3セルずつ取り出して次状態を計算
    for i in range(len(state)):
        left = padded[i]
        center = padded[i + 1]
        right = padded[i + 2]
        next_state += next_cell_state(left, center, right, rule_bits)

    return next_state


# ----------------------------------------
# 4. メイン処理
# ----------------------------------------
def main():
    # --- 入力 ---
    initial_state = input("初期状態(最大30桁の0/1): ").strip()
    rule_number = int(input("ECAルール番号(0〜255): ").strip())
    generations = int(input("シミュレーションする世代数: ").strip())

    # --- ルール番号を2進数8ビットに変換 ---
    rule_bits = rule_to_binary(rule_number)

    # --- 出力ファイル名を作成 ---
    timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
    filename = f"セルオートマトン_ECA_{rule_number}_{timestamp}.csv"

    # --- CSVに書き込み開始 ---
    with open(filename, "w", newline="", encoding="utf-8") as csvfile:
        writer = csv.writer(csvfile)

        # 初期状態を書き込み
        current_state = initial_state
        writer.writerow([cell if cell == "1" else "" for cell in current_state])

        # 指定世代数だけ進める
        for _ in range(generations):
            current_state = evolve(current_state, rule_bits)
            writer.writerow([cell if cell == "1" else "" for cell in current_state])

    print(f"\nCSVファイルを出力しました: {filename}")


# ----------------------------------------
# スクリプトが直接実行されたときだけ main() を動かす
# ----------------------------------------
if __name__ == "__main__":
    main()

実行結果

以下の入力値でシミュレーションを実行しました。出力されたCSVファイルをExcelに読み込み、条件付き書式を設定しました。値が 1 のセルには黒い背景色を適用し、パターンが視覚的にわかりやすくなるようにしています。
この結果は、教科書2に記載された例と一致しました。

(1)

  • 初期状態(最大30桁の0/1):011110010111001110000
  • ECAルール番号(0〜255):16
  • シミュレーションする世代数:15

ECAルール16の結果.png

(2)

  • 初期状態(最大30桁の0/1):00000000000111100101110011100000000000000
  • ECAルール番号(0〜255):30
  • シミュレーションする世代数:30

ECAルール30の結果.png

まとめ

生成AIにプログラムの仕様を与えることで、正しく動作するコードを生成できることが確認できました。
初期状態は最大30桁と指定しましたが、実際には無制限に入力可能であり、また"シミュレーションの世代数"の入力機能もAIが独断で追加していました。これは厳密には指示違反ですが、結果としてコードの完成度は高く、実用に耐えるものでした。

生成されたコードにコメントが付いていたことで、処理内容の理解が深まり、プログラム言語の学習にも役立ちました。
コードをそのまま使うのではなく、内容を読み解く姿勢が大切だと思います。

今後、生成AIの進化によってプログラム開発のあり方がどう変わっていくのかは未知数ですが、私はこの技術を積極的に学び3、より良い開発に役立てていきたいと思います。

おまけ

  • 初期状態:00000000000000000000000001111001011100111
  • ルール番号:110
  • 世代数:100

この結果から、一つの穴と大きさの異なる三角形の穴がランダムに並んでいる様子が確認できました。 なんとも魅力的な図柄で、眺めているだけでも楽しくなります。

ECAルール110の結果.png

  1. 聞こえない学生や聴講生にとって、音声で補われる情報が文面や手話で明示されていることは、理解や学習を支える大きな助けになります。

  2. 萩谷昌己『計算と自然』一般財団法人 放送大学教育振興会, pp.86–91 2

  3. とはいえ、聞こえない人にとって、情報保障が十分に整った学びの場は、まだまだ限られています。:cry:

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?