К содержанию

Задание 12

Исполнение алгоритма для исполнителя

Как понять, что делает машина по таблице команд, и ответить на вопрос о её результате или входе — вручную и программой.

6 подтем · 38 задач + 5 дополнительных · повышенный · ≈ 6 мин

Подтема 1 из 6

Лента, команда и такт

Что такое лента, головка и команда машины и как выполнять таблицу такт за тактом — вручную и программой.

Как устроена тема

В задании 12 дана машина, которая по таблице команд переписывает символы на ленте. Нужно понять, что она делает со строкой, и ответить на вопрос о результате — или о том, какой могла быть исходная строка. Вот задача, которую мы будем решать всю тему:

«На ленте исполнителя МТ в соседних ячейках записана последовательность из 12 символов, каждый из которых 0 или 1; остальные ячейки содержат пустой символ λ. В начальный момент головка находится в ближайшей справа от последовательности ячейке в состоянии q0. Программа работы исполнителя задана таблицей. После выполнения программы в последовательности оказалось ровно 5 нулей. Какое наибольшее количество нулей могло быть в исходной последовательности?»

Состояниеλ01
q0λ, L, q1——
q1λ, S, q11, L, q10, S, q1

Прогонять машину по всей ленте не нужно: достаточно выполнить несколько тактов, понять, что таблица делает с любой строкой, — и ответ получится рассуждением. Сначала разберём, что сказано в условии:

В условииЧто это значит
12 символов 0 или 1, остальные ячейки — λна ленте строка из 12 цифр, вокруг пустые ячейки
головка справа от последовательности, в состоянии q0машина начинает сразу за последней цифрой
программа задана таблицейв каждой клетке: что записать, куда сдвинуться, в какое состояние перейти
после выполнения ровно 5 нулейтак стало в конце
наибольшее количество нулей в исходнойвопрос обратный: каким мог быть вход

Тема состоит из шести подтем — у каждой своя страница. Идём по ним по порядку:

  1. Лента, команда и такт — ты сейчас здесь.
  2. Однократный проход и количества — таблицы, которые меняют каждый символ один раз.
  3. Двоичное число на ленте — что таблица задачи темы делает с числом.
  4. Хвост и обратная задача — ответ задачи темы: 11.
  5. Состояния и фазы — таблицы из нескольких состояний.
  6. Сумма, простота и ограничения на количества — дополнительный урок для редких вопросов.

Таблицу можно выполнить и вручную, и программой — выбирай вкладку «Вручную» или «Python». Программа помогает проверить ответ на коротких строках, но экзаменационную ленту из сотен символов перебором не решить: сначала нужно понять, что делает таблица.

Лента и головка

Что видит машина в начале работы?

Лента — ряд ячеек, в каждой ровно один символ; λ — пустой символ, а не цифра 0. Головка читает одну ячейку и находится в одном состоянии. Возьмём короткое слово 10100. Пронумеруем ячейки с цифрами от 0 до 4 — это наши метки для решения. Головка стоит в ближайшей пустой ячейке справа, на ячейке 5, в состоянии q0.

Слово 10100 в ячейках 0–4, вокруг — пустые ячейки λ. Головка над ячейкой 5, состояние q0.

Состояние — режим работы, а не номер шага: q0 — состояние, в котором машина начинает, а дальше она может много тактов подряд оставаться в одном состоянии.

Тонкости:бесконечная лента

За записанными символами в обе стороны всегда есть пустые ячейки, поэтому машина может писать левее ячейки 0 — у неё будут отрицательные номера. Запись λ стирает символ, но ячейка остаётся на месте, соседние не сдвигаются.

Команда

Что означает команда 0, L, q3?

Команда — тройка: что записать в текущую ячейку, куда сдвинуться и в какое состояние перейти. Запись всегда идёт до сдвига. 0, L, q3: записать 0 в ту ячейку, где головка стоит сейчас, сдвинуться на одну ячейку влево, перейти в q3.

ОбозначениеДействие
Lсдвиг на ячейку влево
Rсдвиг на ячейку вправо
Nостаться на месте
Sзаписать символ и остановиться

Команду выбирают по паре «состояние, прочитанный символ»: строка таблицы — состояние, столбец — символ. Команда 1, S, q2 сначала запишет единицу и только потом остановит машину: остановочный такт тоже меняет ленту и тоже считается.

Прочерк в таблице — пара, которая при правильном запуске не встретится. Это не команда остановки: если ты в неё попал, проверь начальное положение и предыдущие такты.

Трасса

Что таблица задачи темы сделает со словом 10100?

За один такт машина выполняет одну клетку таблицы — ту, что стоит на пересечении текущего состояния и символа под головкой.

Вручную
  1. Начало: q0, головка в клетке 5. Перед тактом 1: q0 читает λ в клетке 5 → записать λ, влево, q1.
  2. Перед тактом 2: q1 читает 0 в клетке 4 → записать 1, влево, q1.
  3. Перед тактом 3: q1 читает 0 в клетке 3 → записать 1, влево, q1.
  4. Перед тактом 4: q1 читает 1 в клетке 2 → записать 0, стоп, q1.
  5. Остановка: на ленте 10011, тактов 4, головка на 2.
ТактСостояние, ячейка, символКомандаСлово после
1q0, 5, λλ, L, q110100
2q1, 4, 01, L, q110101
3q1, 3, 01, L, q110111
4q1, 2, 10, S, q110011

Получилось 10011, головка остановилась на ячейке 2, тактов четыре — остановочный тоже считается. Нули справа стали единицами, встреченная единица — нулём, левее ничего не изменилось.

Python

Таблицу удобно хранить : ключ — пара «состояние, символ» (), значение — тройка команды. Ленту — тоже словарём «номер ячейки → символ»; возвращает λ для ячейки, которой нет в словаре. Каждый проход — один такт:

rules = {    ('q0', 'λ'): ('λ', 'L', 'q1'),    ('q1', 'λ'): ('λ', 'S', 'q1'),    ('q1', '0'): ('1', 'L', 'q1'),    ('q1', '1'): ('0', 'S', 'q1'),}tape = {0: '1', 1: '0', 2: '1', 3: '0', 4: '0'}pos, state = 5, 'q0'while True:    write, move, state = rules[(state, tape.get(pos, 'λ'))]    tape[pos] = write    if move == 'S':        break    pos += -1 if move == 'L' else 1print(tape[0] + tape[1] + tape[2] + tape[3] + tape[4])
10011

Чтобы запускать любую таблицу на любом слове, оформим то же функцией run_tm. Она возвращает итоговое слово без пустых краёв, ячейку остановки и число тактов и пригодится до конца темы:

def run_tm(word, rules, pos, state='q0'):    tape = {}    for i in range(len(word)):        tape[i] = word[i]    steps = 0    while True:        symbol = tape.get(pos, 'λ')        write, move, state = rules[(state, symbol)]        tape[pos] = write        steps += 1        if move == 'S':            break        if move == 'L':            pos -= 1        if move == 'R':            pos += 1    result = ''    for i in range(min(tape), max(tape) + 1):        result += tape.get(i, 'λ')    return result.strip('λ'), pos, steps
rules = {    ('q0', 'λ'): ('λ', 'L', 'q1'),    ('q1', 'λ'): ('λ', 'S', 'q1'),    ('q1', '0'): ('1', 'L', 'q1'),    ('q1', '1'): ('0', 'S', 'q1'),}print(run_tm('10100', rules, 5))
('10011', 2, 4)

Головка шла справа налево, но результат читают как обычно — слева направо. Строка не переворачивается.

Тонкости:начальная ячейка и цикл

Начальное положение берут буквально: «в ближайшей пустой ячейке справа» и «на последней цифре» — разные запуски. Запуск этой таблицы в q0 на последней цифре сразу приводит к прочерку, а run_tm сообщит об ошибке KeyError.

Несколько тактов подряд в q1 — не цикл: головка каждый раз в новой ячейке. Если же в таблице нет пути к S, программа будет работать бесконечно — на проверке ограничь число тактов.

Итого

  • Лентав ячейке один символ, λ — не 0
  • Состояниережим работы; q0 — начало, не остановка
  • Командазаписать → сдвинуться → состояние
  • Sзаписать и остановиться; такт считается
  • Прочеркпри правильном запуске не встретится
  • Pythonrun_tm(word, rules, pos)

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
В ячейке 5 записан 0, головка на ней в состоянии q1, выбрана команда 1, L, q2. Что будет в ячейке 5, где окажется головка и в каком состоянии?
ОтветСкрыть ответ
Ответ
В ячейке 5 — единица, головка на ячейке 4, состояние q2: запись идёт до сдвига.
Вопрос 2
Та же ситуация, команда 1, S, q2. Что изменится на ленте?
ОтветСкрыть ответ
Ответ
В ячейке 5 появится единица, головка останется на ней, и машина остановится: при S запись тоже выполняется.
Вопрос 3
Таблица задачи темы получает слово 1000. Какое слово получится и сколько будет тактов?
ОтветСкрыть ответ
Ответ
0111, пять тактов: вход, три нуля стали единицами, единица стала нулём с остановкой.
Вопрос 4
Что будет, если таблицу задачи темы запустить в q0 с головкой на последней цифре слова 10100?
ОтветСкрыть ответ
Ответ
Для пары (q0, 0) команды нет: такой запуск условием не предусмотрен, головка должна начинать в пустой ячейке.
Вопрос 5
Что вернёт tape.get(7, 'λ'), если tape = {0: '1'}?
ОтветСкрыть ответ
Ответ
'λ': ячейки 7 в словаре нет, значит, она пустая.

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Слово 10100

На ленте исполнителя МТ записано слово 10100, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:

Состояниеλ01
q0λ, L, q1——
q1λ, S, q11, L, q10, S, q1

Какое слово окажется на ленте после остановки?

Введите слово — цифры подряд, без пробелов.

Такты на слове 1000

На ленте исполнителя МТ записано слово 1000, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:

Состояниеλ01
q0λ, L, q1——
q1λ, S, q11, L, q10, S, q1

Сколько тактов выполнит исполнитель, включая такт с остановкой?

Введите число.

Число 37

На ленте исполнителя МТ в соседних ячейках записано двоичное представление числа 37 без ведущих нулей, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:

Состояниеλ01
q0λ, L, q1——
q1λ, S, q11, L, q10, S, q1

Определи результат выполнения программы. В ответе запиши получившееся число в десятичной системе счисления.

Введите число.

Такты для числа 40

На ленте исполнителя МТ в соседних ячейках записано двоичное представление числа 40 без ведущих нулей, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:

Состояниеλ01
q0λ, L, q1——
q1λ, S, q11, L, q10, S, q1

Сколько тактов выполнит исполнитель, включая такт с остановкой?

Введите число.