Time Limit Exceeded. Грустный вердикт проверяющей системы, который часто
означает, что задача решается принципиально неверным способом.
Наверняка каждый игрок ACM сталкивался с таким вердиктом. И конечно же
в такие моменты очень хочется, чтобы компьютеры умели исполнять
программы чуть быстрее. Ведь алгоритм должен быть правильным
(разве может быть иначе?), и лишь по причине того, что жюри для проверки
использует слабые машины и неэффективные компиляторы, правильное решение
никак не засчитывают...
Но в этот раз у вас есть возможность доказать, что вы умеете писать
действительно быстрый код, позволяющий исполнять чужие программы.
Исходные данные
Вход содержит программу в следующем формате. Каждая непустая строка выглядит так:
<label>: <command>
,
так:
<label>:
или так:
<command>
Здесь <label>
- это метка строки в программе (она уникальна в пределах программы, состоит из латинских символов, регистр не важен), а <command>
- одна из описанных ниже доступных команд рассматриваемого языка (регистр символов, используемых в составе идентификаторов команд, так же не важен).
Для описания форматов команд нам потребуются следующие обозначения:
<variable>
- имя переменной (состоит из латинских букв, регистр важен);
<number>
- целое число (все числа лежат в диапазоне от -109 до 109;
<varnum>
- либо имя переменной, либо целое число.
В программе могут встречаться лишь следующие команды:
end
print <varnum>
<variable> = <varnum>
<variable> = <varnum> + <varnum>
<variable> = <varnum> - <varnum>
<variable> = <varnum> * <varnum>
<variable> = <varnum> / <varnum>
<variable> = <varnum> % <varnum>
<variable> = <varnum> or <varnum>
<variable> = <varnum> and <varnum>
<variable> = <varnum> xor <varnum>
<variable> = not <varnum>
goto <label>
if <varnum> == <varnum> goto <label>
if <varnum> != <varnum> goto <label>
if <varnum> >= <varnum> goto <label>
if <varnum> > <varnum> goto <label>
if <varnum> <= <varnum> goto <label>
if <varnum> < <varnum> goto <label>
Команды выполняются последовательно. Исключение составляют команды goto
и if... goto
, описание которых приводится ниже и
команда end
, которая приводит к завершению программы.
Работают команды следующим образом. Команда print
выводит очередную строку со значением аргумента команды. Команды присваивания работают привычным образом (переменной присваивается результат вычисления выражения). Операции в выражениях имеют следующий смысл: сложение (+
), вычитание (-
), умножение (*
), целочисленное деление (/
), взятие остатка (%
), побитовое логическое 'или' (or
), побитовое логическое 'и' (and
), побитовое 'исключающее или' (xor
) и побитовое отрицание (not
). Предполагается, что в процессе вычислений все значения хранятся в виде 4--байтовых целых чисел, отрицательные числа кодируются в дополнительном коде. Команда goto
приводит к тому, что следующей будет выполняться команда, находящаяся в строке с указанной меткой. Команда if ... goto
работает аналогично команде goto
, если условие, указанное после if
является истинным, в противном случае управление передается на следующую за обрабатываемой команду.
После выполнения десяти миллионов команд программа должна быть принудительно
остановлена с выдачей диагностической информации (бывают же ошибки,
приводящие к бесконечным циклам!).
Можно предполагать, что программа синтаксически корректна, что операнды всегда разделяются хотя бы одним пробелом, что перед использованием переменная всегда получает значение, что длина имен переменных и меток не превышает 50, и что в процессе
вычислений не возникает переполнений и делений на ноль. Также можно
предполагать, что программа содержит не более 2000 строк,
и что в процессе работы операция print
выполняется не более 100 раз. Любое количество пробелов может встречаться в любом месте программы: в начале строк, в конце строк, в пустых строках, но не между именем метки и ':'.
Результат
Выход должен содержать результат работы программы (вывод команды print
). Если программа была остановлена принудительно,
то после вывода команд print
следует выдать диагностическую информацию в следующем формате. Сначала следует выдать сообщение "Program terminated. Variables state:"
. Затем следует выдать список проинициализированных на данный момент переменных и их значения в формате: <имя переменной>: <значение>
.
Список переменных должен быть упорядочен лексикографически по имени переменной.
Примеры
исходные данные | результат |
---|
X = 5
Y = 1
loop: Y = Y * X
X = X - 1
if X >= 1 goto LOOP
Print Y
y = Y - 5
Print y
end
| 120
115
|
value = 15
value = not value
value = value or 4
print value
value = 0
loop:
value = value - 1
Value = value % 6
ValueA = value % -6
goto loop
| -12
Program terminated. Variables state:
Value: 3
ValueA: 3
value: -2499999
|
Автор задачи: Александр Клепинин
Источник задачи: Седьмое открытое личное первенство УрГУ по спортивному программированию - 25 февраля 2006 года