AlgoVerse

ماشین حالت متناهی (تشخیص دنباله)

یک ماشین سه‌حالته رشته‌ی دودویی را بیت به بیت می‌خواند و تشخیص می‌دهد عددش بر ۳ بخش‌پذیر است یا نه؛ بدون نگه داشتن خود عدد.

ماشین حالت متناهی فقط تعداد محدودی حالت دارد و با هر نماد ورودی، طبق جدول انتقال δ، از یک حالت به حالت دیگر می‌رود. اگر در پایان در یکی از حالت‌های پذیرش باشد، رشته پذیرفته می‌شود.

ادامه‌ی توضیح ↓
ورودی:
s="10010"خروجی PDF

۱۰۰۱۰ = ۱۸ بر ۳ بخش‌پذیر است؛ ماشین در حالت ۰ تمام می‌کند.

  1. def multiple_of_three(s):
  2. # A machine with three states: the value read so far, mod 3. Reading bit b turns value v into 2v + b.
  3. delta = {0: {"0": 0, "1": 1}, 1: {"0": 2, "1": 0}, 2: {"0": 1, "1": 2}}
  4. table = [[q, delta[q]["0"], delta[q]["1"]] for q in range(3)] # rows: state, after 0, after 1
  5. state = 0
  6. for i in range(len(s)):
  7. state = delta[state][s[i]]
  8. accepted = state == 0
  9. return accepted

ناوردا: بعد از خواندن s[0..i]، حالت برابر مقدار دودویی s[0..i] به پیمانه‌ی ۳ است.

شروع اجرا

01234
10010
state—

جدول هنوز خالی است.

متغیرهای محلی

s'10010'

نارنجی = در همین گام عوض شد

Call stack

  1. multiple_of_three()خط 1
گام ۱ از ۱۷
خط سیاه = read · خط نارنجی = گام کلیدیread: 0/5 · verdict: 0/1
    توضیح

    ایده

    ماشین حالت متناهی فقط تعداد محدودی حالت دارد و با هر نماد ورودی، طبق جدول انتقال δ، از یک حالت به حالت دیگر می‌رود. اگر در پایان در یکی از حالت‌های پذیرش باشد، رشته پذیرفته می‌شود.

    سه حالت کافی است

    اگر مقدار بیت‌های خوانده‌شده v باشد، خواندن بیت b آن را 2v + b می‌کند. برای بخش‌پذیری بر ۳ فقط v mod 3 مهم است:

    v mod 3 = r  ⇒  (2v + b) mod 3 = (2r + b) mod 3
    

    پس سه حالت 0، 1 و 2 بس است، هر قدر هم عدد بزرگ باشد. حالت 0 هم شروع است و هم پذیرش.

    در trace به چه چیزی نگاه کنی

    • جدول انتقال‌های ماشین است (هر سطر یک حالت)؛ کارت state حالت فعلی را با خواندن هر بیت نشان می‌دهد.