見出し画像

100日アプリ開発チャレンジ Day15 - ソートアルゴリズム可視化で「見える化」の力を知った

Day15、学習ツールと向き合った日

100日チャレンジDay15。

今日作ったのは、ソートアルゴリズムの可視化ツール。

そして今日、気づきました。

「見える化が、理解を生む」

ゲームじゃない。教育ツール。でも、これが一番面白かった。


可視化できたんじゃないですか!


おぉー、すげーってなりました!


折れそうになった瞬間

今日は、最初から迷ってました。

「何を作ろう」

Day10-14:シンプルなゲーム路線

でも、そろそろ変化が欲しい。

選択肢は3つ

A. また新しいゲーム

  • 安全

  • でも、飽きてきた

B. 複雑なゲーム

  • 挑戦的

  • でも、Day9の将棋がトラウマ

C. 全く違うもの

  • 新鮮

  • でも、何作る?

朝、2時間悩んだ

「何か作りたいけど、何も思いつかない」

これが、一番辛い。

手が動かない。

コード書く気力がない。

「もう休もうかな...」

ここで、折れそうになりました。

でも、思い出しました。

Day9の将棋、何が辛かったか。

「終わりが見えない」

これが辛かった。

じゃあ、今日は:

「終わりが見えるもの」を作ろう。

迷った判断

迷い1:何を可視化するか

可視化ツール、作ることにしました。

でも、何を可視化する?

選択肢A:データ分析ツール

  • CSVを読み込んで、グラフ化

  • 実用的

  • でも、地味

選択肢B:ソートアルゴリズム

  • バブルソート、クイックソートなど

  • 動きがある

  • 学習に使える

選択肢C:物理シミュレーション

  • 重力、衝突など

  • 見た目が面白い

  • でも、複雑

判断理由

ソートアルゴリズムを選びました。

理由は3つ:

  1. 終わりが明確

    • ソートが終われば、完成

    • 無限ループにならない

  2. 4種類実装できる

    • バブル、選択、挿入、クイック

    • バリエーションがある

  3. 自分も学べる

    • アルゴリズムを理解できる

    • 作りながら勉強できる

「作りながら学ぶ」

これが、決め手でした。

迷い2:ステップ実行か、一気にソートか

選択肢A:一気にソート

def bubble_sort(array):
    for i in range(len(array)):
        for j in range(len(array) - i - 1):
            if array[j] > array[j + 1]:
                array[j], array[j + 1] = array[j + 1], array[j]
  • シンプル

  • でも、途中経過が見えない

選択肢B:ステップ実行

def bubble_sort_step():
    # 1ステップだけ実行
    # 状態を保存
    # 次回続きから
  • 複雑

  • でも、途中経過が見える

判断理由

ステップ実行を選びました。

可視化ツールなのに、途中が見えないのは意味がない。

「見える化」が目的。

ステップ実行なら、アルゴリズムの動きが見える。

どこを比較してるか。

どこがソート済みか。

これが、学習ツールの価値。

続けるために決めたこと

決断1:完璧を目指さない

4つのソートアルゴリズム。

全部完璧に実装しようとしたら、終わらない。

だから、決めました。

「動けばOK。最適化は後で」

バブルソートから始めて、1つずつ。

動いたら、次へ。

完成を優先。

決断2:「作りながら学ぶ」を受け入れる

ソートアルゴリズム、全部理解してたわけじゃない。

特に、クイックソート。

「わからないから、作らない」じゃなくて。

「作りながら、理解する」

これを受け入れました。

わからないことは、調べる。

試す。

動かす。

作ることが、学びになる。

決断3:教育ツールとしての価値を意識

ゲームじゃない。

でも、これは**「学習ツール」**として価値がある。

プログラミングを学ぶ人の役に立つかもしれない。

「誰かの役に立つかも」

この意識が、モチベーションになりました。

実装で苦労したところ

1. ステップ実行の状態管理

一番難しかったのは、これ。

def bubble_sort_step():
    global sort_state
    
    if 'current_index' not in sort_state:
        sort_state = {'current_index': 0, 'compare_index': 0, 'swapped': False}
    
    ci = sort_state['current_index']
    coi = sort_state['compare_index']
    
    # 1ステップだけ実行
    if coi < len(array) - ci - 1:
        if array[coi] > array[coi + 1]:
            array[coi], array[coi + 1] = array[coi + 1], array[coi]
            sort_state['swapped'] = True
        
        sort_state['compare_index'] += 1
        return [coi, coi + 1], list(range(len(array) - ci, len(array)))

状態を保存しないと、続きができない。

どこまで比較したか。

どこまでソート済みか。

これを sort_state に保存。

次回呼ばれたとき、続きから再開。

これが、ステップ実行の本質。

2. クイックソートのスタック管理

クイックソートは、再帰アルゴリズム。

でも、ステップ実行には再帰が使えない。

だから、スタックで管理。

def quick_sort_step():
    if 'stack' not in sort_state:
        sort_state = {
            'stack': [(0, len(array) - 1)],
            'current_partition': None,
            'pivot_index': None,
            'i': None,
            'j': None,
            'sorted_indices': set()
        }
    
    stack = sort_state['stack']
    
    if not stack:
        # 全部ソート完了
        sorting = False
        return
    
    # スタックから次のパーティションを取り出す
    low, high = stack.pop()

再帰をスタックで模倣。

これ、理解するのに1時間かかりました。

でも、理解できたとき、「あ、そういうことか!」って。

作りながら、学びました。

3. 色分けの設計

どこを比較してるか、一目でわかるように。

def draw_array(highlight_indices=None, sorted_indices=None, pivot_index=None):
    for i, value in enumerate(array):
        # 色を決定
        if i == pivot_index:
            color = PURPLE  # ピボット(クイックソート用)
        elif i in sorted_indices:
            color = GREEN  # ソート済み
        elif i in highlight_indices:
            color = RED  # 比較中
        else:
            color = BLUE  # 未ソート

色で、状態を伝える。

  • 青:未ソート

  • 赤:比較中

  • 緑:ソート済み

  • 紫:ピボット(クイックソート)

視覚的にわかる。

これが、可視化ツールの価値。

4. 4つのアルゴリズムの統一

def sort_step():
    """現在のアルゴリズムに応じてソートステップを実行"""
    algo = ALGORITHMS[current_algorithm]
    
    if algo == "Bubble Sort":
        return bubble_sort_step()
    elif algo == "Selection Sort":
        return selection_sort_step()
    elif algo == "Insertion Sort":
        return insertion_sort_step()
    elif algo == "Quick Sort":
        return quick_sort_step()

4つのアルゴリズム、同じインターフェース。

どれも sort_step() で呼べる。

統一されたAPI。

これで、メインループがシンプルになりました。

開発者視点の裏話

なぜ4つのアルゴリズムを選んだのか

バブルソート:基本中の基本 選択ソート:シンプルでわかりやすい 挿入ソート:実用的 クイックソート:高速、でも複雑

段階的に難易度が上がる。

初心者は、バブルソートから理解できる。

上級者は、クイックソートの美しさがわかる。

幅広い層に対応。

なぜFPS 60にしたのか

FPS = 60
clock.tick(FPS)

60フレーム/秒。

これより速いと、見えない。

これより遅いと、待てない。

60FPSが、ちょうどいい。

なぜ棒グラフで表現したのか

ソートアルゴリズム、数値の並び替え。

高さで大小を表現。

視覚的に、一瞬でわかる。

数字で「45, 32, 78...」って見るより、

棒グラフの方が、圧倒的にわかりやすい。

「見える化」の力。

なぜ凡例を入れたのか

# カラー凡例
pygame.draw.rect(screen, BLUE, (20, legend_y, 15, 15))
screen.blit(tiny_font.render("Unsorted", True, BLACK), (40, legend_y))

pygame.draw.rect(screen, RED, (130, legend_y, 15, 15))
screen.blit(tiny_font.render("Comparing", True, BLACK), (150, legend_y))

色の意味、わからないと混乱する。

凡例があれば、誰でもわかる。

教育ツールだから、親切設計。

開発時間:約5時間

  • アルゴリズム設計:1.5時間

  • ステップ実行実装:2時間

  • 可視化・UI:1時間

  • デバッグ:0.5時間

クイックソートが一番時間かかりました。

でも、理解できたとき、達成感がすごかった。

今日の学び

技術面

  • ステップ実行の状態管理

  • 再帰をスタックで模倣

  • グローバル状態の活用

  • 色分けによる視覚化

  • 統一されたAPI設計

アルゴリズム面

  • バブルソートの仕組み

  • 選択ソートの効率

  • 挿入ソートの実用性

  • クイックソートの美しさ

設計面

  • 教育ツールの設計思想

  • 親切なUI(凡例、操作説明)

  • 段階的な難易度設計

  • 視覚的フィードバック

メンタル面

  • 「作りながら学ぶ」を受け入れる

  • 終わりが見えるものを選ぶ

  • 完璧を目指さない

  • 教育ツールとしての価値

Day15を終えて

今日、気づきました。

「見える化が、理解を生む」

ソートアルゴリズム、教科書で読んでもピンと来なかった。

でも、動いてるのを見たら、わかった。

「ああ、こうやって並び替えてるのか」

これが、可視化の力。

そして、気づいたこと。

ゲームじゃなくても、面白い。

今日作ったのは、ゲームじゃない。

教育ツール。

でも、これが一番面白かった。

アルゴリズムが、動いてる。

クイックソートのピボットが、左右に振り分けていく。

バブルソートの大きい値が、右に浮いていく。

美しい。

これまで、「ゲーム」ばかり作ってました。

でも、今日気づきました。

「ツール」も、面白い。

誰かの学びに、役立つかもしれない。

自分も、作りながら学べる。

作ることが、学びになる。

Day15、新しい扉が開きました。

ゲームだけじゃない。

ツール、可視化、教育。

作れるものは、無限にある。


今日のコード行数: 320行
開発時間: 約5時間
実装したアルゴリズム: 4種類
学んだこと: クイックソートの美しさ
達成感: ★★★★★
「作りながら学ぶ」実感: ★★★★★
「見える化の力」実感: ★★★★★

100日チャレンジ、Day16に続く。

(見える化が、理解を生む。作ることが、学びになる。)


完全版コード

引き続き、最初の30日間はコードを直接貼り付けていきます。

import pygame
import random

# 初期化
pygame.init()

# 画面設定
WIDTH = 900
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("Sorting Algorithm Visualization")

# 色定義
BLUE = (100, 150, 255)   # 未ソート
RED = (255, 100, 100)     # 比較中
GREEN = (100, 255, 100)   # ソート済み
PURPLE = (200, 100, 255)  # ピボット

# ソートアルゴリズム
ALGORITHMS = ["Bubble Sort", "Selection Sort", "Insertion Sort", "Quick Sort"]

def bubble_sort_step():
    """バブルソートの1ステップ"""
    # 状態を保存して、次回続きから
    
def selection_sort_step():
    """選択ソートの1ステップ"""
    
def insertion_sort_step():
    """挿入ソートの1ステップ"""
    
def quick_sort_step():
    """クイックソートの1ステップ"""
    # 再帰をスタックで模倣

# ... 以下省略(全320行)
# 完全版が見たい方はコメントでリクエストください!

#100日チャレンジ #プログラミング #アルゴリズム #Python #Pygame #ソートアルゴリズム #可視化 #教育ツール #初心者エンジニア

いいなと思ったら応援しよう!