2進数文字列のうち3の倍数のものを受理するオートマトン
Pythonのautomata-libを使いました。
pypi.org
オートマトンの説明
状態q0:3で割ったあまりが0である状態
状態q1:3で割ったあまりが1である状態
状態q2:3で割ったあまりが2である状態
初期状態:q0
受理状態:q0
入力文字:{'0', '1'}
<状態遷移>
2進数を表す文字列を上の位から順に読む
'101'を読む場合、読み終えた文字列は
'1' -> '10' -> '101' と変化する。
10進数としては、1 -> 2 -> 5 と変化している。
ある状態から'0'を読むと元の数を2倍した数に変化する。
ある状態から'1'を読むと元の数を2倍して1を足した数に変化する。
3の倍数を2倍すると、3の倍数になる。
3の倍数を2倍して1を足すと、3の倍数+1になる。
3の倍数+1を2倍すると、3の倍数+2になる。
3の倍数+1を2倍して1を足すと、3の倍数になる。
3の倍数+2を2倍すると、3の倍数+1になる。
3の倍数+2を2倍して1を足すと、3の倍数+2になる。
初期状態は'0'を読み終えている状態とみなせるので、
初期状態からの遷移も他の遷移と区別する必要がない。
from automata.fa.dfa import DFA dfa = DFA( states = {'q0', 'q1', 'q2'}, input_symbols = {'0', '1'}, transitions = { 'q0': {'0': 'q0', '1': 'q1'}, 'q1': {'0': 'q2', '1': 'q0'}, 'q2': {'0': 'q1', '1': 'q2'} }, initial_state = 'q0', final_states ={'q0'} ) for i in range(10): print(i, dfa.accepts_input(bin(i)[2:]))
実行結果
0 True 1 False 2 False 3 True 4 False 5 False 6 True 7 False 8 False 9 True