Last active
March 21, 2025 15:38
-
-
Save pgtwitter/1d66a655c3c53b021b4ccc46f3fc8cc3 to your computer and use it in GitHub Desktop.
モール信号をツリー表示(dotファイル)にするpythonスクリプトをGrok3に書かせてみた.morse.txtを読み込んでmorse_tree.dotを作成する.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# %% | |
def read_morse_file(filename): | |
"""モールス信号データをファイルから読み込む""" | |
morse_data = {} | |
with open(filename, 'r', encoding='utf-8') as f: | |
for line in f: | |
char, code = line.strip().split('\t') | |
morse_data[char] = code | |
return morse_data | |
def build_morse_graph(morse_data): | |
"""モールス信号のツリー構造を構築する""" | |
edges = [] # エッジのリスト | |
rank_groups = {} # 「-」の出現回数ごとのノードグループ | |
node_map = {'': '(start)'} # プレフィックスとノードのマッピング("START"を"(start)"に変更) | |
dummy_count = 0 # ダミーノードのカウンタ | |
# Trieの構築 | |
trie = {} | |
for char, code in morse_data.items(): | |
current = trie | |
for symbol in code: | |
if symbol not in current: | |
current[symbol] = {} | |
current = current[symbol] | |
current['char'] = char | |
# プレフィックスごとのノードを生成 | |
def generate_nodes(prefix, current_trie, parent_node): | |
nonlocal dummy_count | |
node_name = None | |
if 'char' in current_trie: | |
node_name = current_trie['char'] # 定義された文字 | |
else: | |
dummy_count += 1 | |
node_name = f'(dummy{dummy_count})' # ダミーノード | |
node_map[prefix] = node_name | |
if parent_node != '(start)' or prefix: | |
last_symbol = prefix[-1] | |
edges.append((parent_node, node_name, last_symbol)) | |
dot_count = prefix.count('.') | |
if dot_count not in rank_groups: | |
rank_groups[dot_count] = set() | |
rank_groups[dot_count].add(node_name) | |
for symbol in ['.', '-']: | |
if symbol in current_trie: | |
next_prefix = prefix + symbol | |
generate_nodes(next_prefix, current_trie[symbol], node_name) | |
for symbol in ['.', '-']: | |
if symbol in trie: | |
generate_nodes(symbol, trie[symbol], '(start)') | |
if 0 not in rank_groups: | |
rank_groups[0] = set() | |
rank_groups[0].add('(start)') | |
return edges, rank_groups, node_map | |
def generate_dot_code(edges, rank_groups, node_map, morse_data): | |
"""GraphvizのDOTコードを生成する""" | |
dot_lines = [ | |
'digraph MorseTree {', | |
' rankdir=TB;', | |
' bgcolor="white";', | |
' nodesep=0.5;', | |
' pad=0.2;', | |
'' | |
] | |
# ノード定義 | |
dot_lines.append(' "(start)" [shape=diamond, label="(start)"];') # "(start)"を菱形に | |
for prefix, node in node_map.items(): | |
if node == '(start)': | |
continue | |
if '(dummy' in node: | |
last_symbol = prefix[-1] | |
shape = 'circle' if last_symbol == '.' else 'rectangle' | |
dot_lines.append(f' "{node}" [shape={shape}, label="(N/A)", margin=0];') | |
else: | |
code = morse_data.get(node, '') | |
if code: | |
last_symbol = code[-1] | |
shape = 'circle' if last_symbol == '.' else 'rectangle' | |
else: | |
shape = 'rectangle' # デフォルト | |
dot_lines.append(f' "{node}" [shape={shape}];') | |
# エッジ定義 | |
dot_lines.append('') | |
for src, dst, symbol in edges: | |
if symbol == '.': | |
dot_lines.append(f' "{src}" -> "{dst}" [penwidth=2, weight=2000, style=dashed];') | |
elif symbol == '-': | |
dot_lines.append(f' "{src}" -> "{dst}" [penwidth=2];') | |
# rank指定 | |
dot_lines.append('') | |
for bar_count in sorted(rank_groups.keys()): | |
nodes = ' '.join(f'"{node}"' for node in sorted(rank_groups[bar_count])) | |
dot_lines.append(f' {{rank=same; {nodes}}}') | |
dot_lines.append('}') | |
return '\n'.join(dot_lines) | |
# メイン処理(morse.txtを読み込む関数は省略されていると仮定) | |
morse_data = read_morse_file('morse.txt') | |
edges, rank_groups, node_map = build_morse_graph(morse_data) | |
dot_code = generate_dot_code(edges, rank_groups, node_map, morse_data) | |
with open('morse_tree.dot', 'w', encoding='utf-8') as f: | |
f.write(dot_code) | |
print("Generated morse_tree.dot") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
A .- | |
B -... | |
C -.-. | |
D -.. | |
E . | |
F ..-. | |
G --. | |
H .... | |
I .. | |
J .--- | |
K -.- | |
L .-.. | |
M -- | |
N -. | |
O --- | |
P .--. | |
Q --.- | |
R .-. | |
S ... | |
T - | |
U ..- | |
V ...- | |
W .-- | |
X -..- | |
Y -.-- | |
Z --.. | |
5 ..... | |
4 ....- | |
3 ...-- | |
2 ..--- | |
1 .---- | |
6 -.... | |
7 --... | |
8 ---.. | |
9 ----. | |
0 ----- | |
訂正 ........ | |
ピリオド .-.-.- |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
digraph MorseTree { | |
rankdir=TB; | |
bgcolor="white"; | |
nodesep=0.5; | |
pad=0.2; | |
"(start)" [shape=diamond, label="(start)"]; | |
"E" [shape=circle]; | |
"I" [shape=circle]; | |
"S" [shape=circle]; | |
"H" [shape=circle]; | |
"5" [shape=circle]; | |
"(dummy1)" [shape=circle, label="(N/A)", margin=0]; | |
"(dummy2)" [shape=circle, label="(N/A)", margin=0]; | |
"訂正" [shape=circle]; | |
"4" [shape=rectangle]; | |
"V" [shape=rectangle]; | |
"3" [shape=rectangle]; | |
"U" [shape=rectangle]; | |
"F" [shape=circle]; | |
"(dummy3)" [shape=rectangle, label="(N/A)", margin=0]; | |
"2" [shape=rectangle]; | |
"A" [shape=rectangle]; | |
"R" [shape=circle]; | |
"L" [shape=circle]; | |
"(dummy4)" [shape=rectangle, label="(N/A)", margin=0]; | |
"(dummy5)" [shape=circle, label="(N/A)", margin=0]; | |
"ピリオド" [shape=rectangle]; | |
"W" [shape=rectangle]; | |
"P" [shape=circle]; | |
"J" [shape=rectangle]; | |
"1" [shape=rectangle]; | |
"T" [shape=rectangle]; | |
"N" [shape=circle]; | |
"D" [shape=circle]; | |
"B" [shape=circle]; | |
"6" [shape=circle]; | |
"X" [shape=rectangle]; | |
"K" [shape=rectangle]; | |
"C" [shape=circle]; | |
"Y" [shape=rectangle]; | |
"M" [shape=rectangle]; | |
"G" [shape=circle]; | |
"Z" [shape=circle]; | |
"7" [shape=circle]; | |
"Q" [shape=rectangle]; | |
"O" [shape=rectangle]; | |
"(dummy6)" [shape=circle, label="(N/A)", margin=0]; | |
"8" [shape=circle]; | |
"(dummy7)" [shape=rectangle, label="(N/A)", margin=0]; | |
"9" [shape=circle]; | |
"0" [shape=rectangle]; | |
"(start)" -> "E" [penwidth=2, weight=2000, style=dashed]; | |
"E" -> "I" [penwidth=2, weight=2000, style=dashed]; | |
"I" -> "S" [penwidth=2, weight=2000, style=dashed]; | |
"S" -> "H" [penwidth=2, weight=2000, style=dashed]; | |
"H" -> "5" [penwidth=2, weight=2000, style=dashed]; | |
"5" -> "(dummy1)" [penwidth=2, weight=2000, style=dashed]; | |
"(dummy1)" -> "(dummy2)" [penwidth=2, weight=2000, style=dashed]; | |
"(dummy2)" -> "訂正" [penwidth=2, weight=2000, style=dashed]; | |
"H" -> "4" [penwidth=2]; | |
"S" -> "V" [penwidth=2]; | |
"V" -> "3" [penwidth=2]; | |
"I" -> "U" [penwidth=2]; | |
"U" -> "F" [penwidth=2, weight=2000, style=dashed]; | |
"U" -> "(dummy3)" [penwidth=2]; | |
"(dummy3)" -> "2" [penwidth=2]; | |
"E" -> "A" [penwidth=2]; | |
"A" -> "R" [penwidth=2, weight=2000, style=dashed]; | |
"R" -> "L" [penwidth=2, weight=2000, style=dashed]; | |
"R" -> "(dummy4)" [penwidth=2]; | |
"(dummy4)" -> "(dummy5)" [penwidth=2, weight=2000, style=dashed]; | |
"(dummy5)" -> "ピリオド" [penwidth=2]; | |
"A" -> "W" [penwidth=2]; | |
"W" -> "P" [penwidth=2, weight=2000, style=dashed]; | |
"W" -> "J" [penwidth=2]; | |
"J" -> "1" [penwidth=2]; | |
"(start)" -> "T" [penwidth=2]; | |
"T" -> "N" [penwidth=2, weight=2000, style=dashed]; | |
"N" -> "D" [penwidth=2, weight=2000, style=dashed]; | |
"D" -> "B" [penwidth=2, weight=2000, style=dashed]; | |
"B" -> "6" [penwidth=2, weight=2000, style=dashed]; | |
"D" -> "X" [penwidth=2]; | |
"N" -> "K" [penwidth=2]; | |
"K" -> "C" [penwidth=2, weight=2000, style=dashed]; | |
"K" -> "Y" [penwidth=2]; | |
"T" -> "M" [penwidth=2]; | |
"M" -> "G" [penwidth=2, weight=2000, style=dashed]; | |
"G" -> "Z" [penwidth=2, weight=2000, style=dashed]; | |
"Z" -> "7" [penwidth=2, weight=2000, style=dashed]; | |
"G" -> "Q" [penwidth=2]; | |
"M" -> "O" [penwidth=2]; | |
"O" -> "(dummy6)" [penwidth=2, weight=2000, style=dashed]; | |
"(dummy6)" -> "8" [penwidth=2, weight=2000, style=dashed]; | |
"O" -> "(dummy7)" [penwidth=2]; | |
"(dummy7)" -> "9" [penwidth=2, weight=2000, style=dashed]; | |
"(dummy7)" -> "0" [penwidth=2]; | |
{rank=same; "(dummy7)" "(start)" "0" "M" "O" "T"} | |
{rank=same; "(dummy6)" "1" "9" "A" "E" "G" "J" "K" "N" "Q" "W" "Y"} | |
{rank=same; "(dummy3)" "(dummy4)" "2" "8" "C" "D" "I" "P" "R" "U" "X" "Z"} | |
{rank=same; "(dummy5)" "3" "7" "B" "F" "L" "S" "V" "ピリオド"} | |
{rank=same; "4" "6" "H"} | |
{rank=same; "5"} | |
{rank=same; "(dummy1)"} | |
{rank=same; "(dummy2)"} | |
{rank=same; "訂正"} | |
} |
Author
pgtwitter
commented
Mar 21, 2025
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment