Задание 12
Исполнение алгоритма для исполнителя
Как понять, что делает машина по таблице команд, и ответить на вопрос о её результате или входе — вручную и программой.
6 подтем · 38 задач + 5 дополнительных · повышенный · ≈ 6 мин
Подтема 1 из 6
Лента, команда и такт
Что такое лента, головка и команда машины и как выполнять таблицу такт за тактом — вручную и программой.
Как устроена тема
В задании 12 дана машина, которая по таблице команд переписывает символы на ленте. Нужно понять, что она делает со строкой, и ответить на вопрос о результате — или о том, какой могла быть исходная строка. Вот задача, которую мы будем решать всю тему:
«На ленте исполнителя МТ в соседних ячейках записана последовательность из 12 символов, каждый из которых 0 или 1; остальные ячейки содержат пустой символ λ. В начальный момент головка находится в ближайшей справа от последовательности ячейке в состоянии q0. Программа работы исполнителя задана таблицей. После выполнения программы в последовательности оказалось ровно 5 нулей. Какое наибольшее количество нулей могло быть в исходной последовательности?»
| Состояние | λ | 0 | 1 |
|---|---|---|---|
q0 | λ, L, q1 | — | — |
q1 | λ, S, q1 | 1, L, q1 | 0, S, q1 |
Прогонять машину по всей ленте не нужно: достаточно выполнить несколько тактов, понять, что таблица делает с любой строкой, — и ответ получится рассуждением. Сначала разберём, что сказано в условии:
| В условии | Что это значит |
|---|---|
| 12 символов 0 или 1, остальные ячейки — λ | на ленте строка из 12 цифр, вокруг пустые ячейки |
| головка справа от последовательности, в состоянии q0 | машина начинает сразу за последней цифрой |
| программа задана таблицей | в каждой клетке: что записать, куда сдвинуться, в какое состояние перейти |
| после выполнения ровно 5 нулей | так стало в конце |
| наибольшее количество нулей в исходной | вопрос обратный: каким мог быть вход |
Тема состоит из шести подтем — у каждой своя страница. Идём по ним по порядку:
- Лента, команда и такт — ты сейчас здесь.
- Однократный проход и количества — таблицы, которые меняют каждый символ один раз.
- Двоичное число на ленте — что таблица задачи темы делает с числом.
- Хвост и обратная задача — ответ задачи темы: 11.
- Состояния и фазы — таблицы из нескольких состояний.
- Сумма, простота и ограничения на количества — дополнительный урок для редких вопросов.
Таблицу можно выполнить и вручную, и программой — выбирай вкладку «Вручную» или «Python». Программа помогает проверить ответ на коротких строках, но экзаменационную ленту из сотен символов перебором не решить: сначала нужно понять, что делает таблица.
Лента и головка
Что видит машина в начале работы?
Лента — ряд ячеек, в каждой ровно один символ; λ — пустой символ, а не цифра 0. Головка читает одну ячейку и находится в одном состоянии. Возьмём короткое слово 10100. Пронумеруем ячейки с цифрами от 0 до 4 — это наши метки для решения. Головка стоит в ближайшей пустой ячейке справа, на ячейке 5, в состоянии q0.
Состояние — режим работы, а не номер шага: q0 — состояние, в котором машина начинает, а дальше она может много тактов подряд оставаться в одном состоянии.
Тонкости:бесконечная лента
За записанными символами в обе стороны всегда есть пустые ячейки, поэтому машина может писать левее ячейки 0 — у неё будут отрицательные номера. Запись λ стирает символ, но ячейка остаётся на месте, соседние не сдвигаются.
Команда
Что означает команда 0, L, q3?
Команда — тройка: что записать в текущую ячейку, куда сдвинуться и в какое состояние перейти. Запись всегда идёт до сдвига. 0, L, q3: записать 0 в ту ячейку, где головка стоит сейчас, сдвинуться на одну ячейку влево, перейти в q3.
| Обозначение | Действие |
|---|---|
L | сдвиг на ячейку влево |
R | сдвиг на ячейку вправо |
N | остаться на месте |
S | записать символ и остановиться |
Команду выбирают по паре «состояние, прочитанный символ»: строка таблицы — состояние, столбец — символ. Команда 1, S, q2 сначала запишет единицу и только потом остановит машину: остановочный такт тоже меняет ленту и тоже считается.
Прочерк в таблице — пара, которая при правильном запуске не встретится. Это не команда остановки: если ты в неё попал, проверь начальное положение и предыдущие такты.
Трасса
Что таблица задачи темы сделает со словом 10100?
За один такт машина выполняет одну клетку таблицы — ту, что стоит на пересечении текущего состояния и символа под головкой.
- Начало: q0, головка в клетке 5. Перед тактом 1: q0 читает λ в клетке 5 → записать λ, влево, q1.
- Перед тактом 2: q1 читает 0 в клетке 4 → записать 1, влево, q1.
- Перед тактом 3: q1 читает 0 в клетке 3 → записать 1, влево, q1.
- Перед тактом 4: q1 читает 1 в клетке 2 → записать 0, стоп, q1.
- Остановка: на ленте 10011, тактов 4, головка на 2.
| Такт | Состояние, ячейка, символ | Команда | Слово после |
|---|---|---|---|
| 1 | q0, 5, λ | λ, L, q1 | 10100 |
| 2 | q1, 4, 0 | 1, L, q1 | 10101 |
| 3 | q1, 3, 0 | 1, L, q1 | 10111 |
| 4 | q1, 2, 1 | 0, S, q1 | 10011 |
Получилось 10011, головка остановилась на ячейке 2, тактов четыре — остановочный тоже считается. Нули справа стали единицами, встреченная единица — нулём, левее ничего не изменилось.
Таблицу удобно хранить : ключ — пара «состояние, символ» (), значение — тройка команды. Ленту — тоже словарём «номер ячейки → символ»; возвращает λ для ячейки, которой нет в словаре. Каждый проход — один такт:
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])Чтобы запускать любую таблицу на любом слове, оформим то же функцией 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, stepsrules = { ('q0', 'λ'): ('λ', 'L', 'q1'), ('q1', 'λ'): ('λ', 'S', 'q1'), ('q1', '0'): ('1', 'L', 'q1'), ('q1', '1'): ('0', 'S', 'q1'),}print(run_tm('10100', rules, 5))Головка шла справа налево, но результат читают как обычно — слева направо. Строка не переворачивается.
Тонкости:начальная ячейка и цикл
Начальное положение берут буквально: «в ближайшей пустой ячейке справа» и «на последней цифре» — разные запуски. Запуск этой таблицы в q0 на последней цифре сразу приводит к прочерку, а run_tm сообщит об ошибке KeyError.
Несколько тактов подряд в q1 — не цикл: головка каждый раз в новой ячейке. Если же в таблице нет пути к S, программа будет работать бесконечно — на проверке ограничь число тактов.
Итого
- Лентав ячейке один символ, λ — не 0
- Состояниережим работы; q0 — начало, не остановка
- Командазаписать → сдвинуться → состояние
- Sзаписать и остановиться; такт считается
- Прочеркпри правильном запуске не встретится
- Python
run_tm(word, rules, pos)
Проверьте себя
Ответь сначала сам, потом открой ответ.
0, головка на ней в состоянии q1, выбрана команда 1, L, q2. Что будет в ячейке 5, где окажется головка и в каком состоянии?ОтветСкрыть ответ
q2: запись идёт до сдвига.1, S, q2. Что изменится на ленте?ОтветСкрыть ответ
S запись тоже выполняется.1000. Какое слово получится и сколько будет тактов?ОтветСкрыть ответ
0111, пять тактов: вход, три нуля стали единицами, единица стала нулём с остановкой.q0 с головкой на последней цифре слова 10100?ОтветСкрыть ответ
q0, 0) команды нет: такой запуск условием не предусмотрен, головка должна начинать в пустой ячейке.tape.get(7, 'λ'), если tape = {0: '1'}?ОтветСкрыть ответ
'λ': ячейки 7 в словаре нет, значит, она пустая.Практика
Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.
Слово 10100
На ленте исполнителя МТ записано слово 10100, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:
| Состояние | λ | 0 | 1 |
|---|---|---|---|
| q0 | λ, L, q1 | — | — |
| q1 | λ, S, q1 | 1, L, q1 | 0, S, q1 |
Какое слово окажется на ленте после остановки?
Введите слово — цифры подряд, без пробелов.
Подсказка
Нули справа становятся единицами, пока не встретится единица.
Решение
Такт 1 — вход на последнюю цифру. Такты 2 и 3: два нуля справа стали единицами. Такт 4: единица стала нулём, и машина остановилась. На ленте 10011.
Ответ: 10011
Такты на слове 1000
На ленте исполнителя МТ записано слово 1000, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:
| Состояние | λ | 0 | 1 |
|---|---|---|---|
| q0 | λ, L, q1 | — | — |
| q1 | λ, S, q1 | 1, L, q1 | 0, S, q1 |
Сколько тактов выполнит исполнитель, включая такт с остановкой?
Введите число.
Подсказка
Остановочный такт тоже считается.
Решение
Вход на последнюю цифру — один такт, три нуля стали единицами — ещё три, единица стала нулём с остановкой — пятый. На ленте 0111.
Ответ: 5
Число 37
На ленте исполнителя МТ в соседних ячейках записано двоичное представление числа 37 без ведущих нулей, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:
| Состояние | λ | 0 | 1 |
|---|---|---|---|
| q0 | λ, L, q1 | — | — |
| q1 | λ, S, q1 | 1, L, q1 | 0, S, q1 |
Определи результат выполнения программы. В ответе запиши получившееся число в десятичной системе счисления.
Введите число.
Подсказка
Переведи 37 в двоичную запись: 100101.
Решение
37 = 100101. Справа сразу единица: она становится нулём, и машина останавливается. Получается 100100 = 36.
Ответ: 36
Такты для числа 40
На ленте исполнителя МТ в соседних ячейках записано двоичное представление числа 40 без ведущих нулей, остальные ячейки пустые (λ). Головка — в ближайшей пустой ячейке справа от строки, состояние q0. Программа:
| Состояние | λ | 0 | 1 |
|---|---|---|---|
| q0 | λ, L, q1 | — | — |
| q1 | λ, S, q1 | 1, L, q1 | 0, S, q1 |
Сколько тактов выполнит исполнитель, включая такт с остановкой?
Введите число.
Подсказка
Вход, нули справа, остановка.
Решение
40 = 101000: вход — один такт, три нуля справа — три такта, замена единицы с остановкой — пятый.
Ответ: 5