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