406893: GYM102599 L Стековая машина
Description
Дано $$$0 \le N \le 100$$$ целых неотрицательных чисел, выведите их сумму.
Эх, как было бы хорошо, если бы вам нужно было написать программу для решения такой задачи на C++ или Python...
У вас есть машина, память которой — это стек, элементы которого являются целыми числами. Количество элементов стека в данный момент мы будем обозначать как $$$sz$$$.
Напомним, что стек — это абстрактная структура данных, хранящая коллекцию элементов, и работающая по принципу LIFO (последним пришёл — первым вышел). Стек поддерживает две базовые операции: положить элемент на вершину стека, взять элемент с вершины стека. В качестве аналогии можно представить стопку тарелок: вы не можете оперировать с тарелками не на вершине стопки.
Список доступных инструкций приведен ниже. RTE (Run-Time Error) обозначает, что выполнение программы завершилось с ошибкой, вам следует избегать таких ситуаций.
- PUSHZ — положить на стек 0;
- POP — взять со стека $$$x$$$ (если $$$sz < 1$$$, то RTE);
- SWAP2 — взять со стека $$$x$$$, взять со стека $$$y$$$, положить на стек $$$x$$$, положить на стек $$$y$$$ (если $$$sz < 2$$$, то RTE);
- SWAP3 — взять со стека $$$x$$$, взять со стека $$$y$$$, взять со стека $$$z$$$, положить на стек $$$y$$$, положить на стек $$$x$$$, положить на стек $$$z$$$ (если $$$sz < 3$$$, то RTE);
- COPY — взять со стека $$$x$$$, положить на стек $$$x$$$, положить на стек $$$x$$$ (если $$$sz < 1$$$, то RTE);
- INC — взять со стека $$$x$$$, положить на стек $$$x+1$$$ (если $$$sz < 1$$$, то RTE);
- DEC — взять со стека $$$x$$$, положить на стек $$$x-1$$$ (если $$$sz < 1$$$, то RTE);
- ADD — взять со стека $$$x$$$, взять со стека $$$y$$$, положить на стек $$$x+y$$$ (если $$$sz < 2$$$, то RTE);
- SUB — взять со стека $$$x$$$, взять со стека $$$y$$$, положить на стек $$$x-y$$$ (если $$$sz < 2$$$, то RTE);
Также доступны условный оператор и цикл while. Чтобы их использовать, сначала нужно научиться задавать какие-то условия:
- EZ — TRUE если на вершине стека 0 (если $$$sz < 1$$$, то RTE);
- GZ — TRUE если на вершине стека положительное число (если $$$sz < 1$$$, то RTE);
- HAVE1, HAVE2 — TRUE если $$$sz \ge k$$$ (обратите внимание, что $$$k \in \{ 1, 2 \}$$$, HAVE3 не является условием)
К любому условию можно добавить NOT в начале, например NOT GZ (обратите внимание на пробел) TRUE если на вершине стека 0 или отрицательное число.
Условный оператор:
IF cond THEN
BEGIN
body
END
Цикл while:
WHILE cond DO
BEGIN
body
END
В обоих случаях cond — одно из условий, описанных выше, body — тело условного оператора или цикла — последовательность команд, которые будут выполнены, если cond=TRUE (один раз в случае условного оператора, или много раз в случае цикла). Циклы и условные операторы могут быть вложенными.
Вы должны написать программу для этой машины, котора решает следующую задачу:
Изначально стек был пуст. Числа $$$N, a_{1}, a_{2}, \ldots, a_{N}$$$ положили на стек в таком порядке (наверху стека лежит $$$a_{N}$$$, $$$N$$$ лежит в самом низу). После выполнения программы на вершине стека должно лежать число $$$a_{1} + a_{2} + \ldots + a_{N}$$$ (также в стеке могут лежать другие числа).
Гарантируется, что $$$0 \le N \le 100$$$, $$$0 \le a_{i}$$$. Каждая инструкция (а также проверки условия для условного оператора и цикла) выполняется 1 такт. Выполнение программы должно занимать не более $$$(N+22)^{2}$$$ тактов. В процессе выполнения программы не должно происходить RTE.
Входные данныеВ этой задаче нет входных данных.
Выходные данныеВыведите программу для стековой машины, решающую описанную задачу.
Вы не обязаны использовать отступы. Любой пробельный символ может быть заменён на любое ненулевое количество пробельных символов, вставлять пробельные символы внутрь инструкций нельзя.
Все инструкции должны быть записаны именно так, как они записаны в тексте условия.
ПримерВходные данныеВыходные данные
PUSHZ SWAP2 WHILE NOT EZ DO BEGIN COPY SWAP3 ADD SWAP2 DEC END POP WHILE NOT EZ DO BEGIN COPY DEC END WHILE HAVE2 DO BEGIN ADD ENDПримечание
Ответ на пример из условия содержит две программы, которые вычисляют сумму чисел от 1 до $$$N$$$ для $$$N \ge 0$$$.
В стеке могут храниться числа произвольного размера. И ваша программа должна работать для $$$a_{i}$$$ произвольного размера.
Намеренные попытки дестабилизировать работу проверяющей системы могут повлечь дисквалификацию команды. Жюри оставляет за собой право решать, что является невинной ошибкой, а что — намеренной попыткой дестабилизировать работу проверяющей системы.