Первым языком программирования, с которым я столкнулся, был Sinclair BASIC . Как и многие другие диалекты BASIC, он требует нумерации всех строк исходного кода .
В результате использование GO TO
команды было идиоматичным и переходит к выполнению на заданный номер строки (без меток).
Также есть связанная GO SUB
команда, которая может использоваться как элементарный вызов функции. Опять же, выполнение переходит к заданному номеру строки, но когда RETURN
команда достигнута, выполнение переходит обратно к следующей инструкции после GO SUB
.
Аналогично, RUN
команда перезапустит выполнение программы с заданной строки.
Любой, кто провел какое-то время в переводчике с базовым номером BASIC, научится использовать схему нумерации с пробелами в ней. Это так, чтобы легче было вставлять новые строки кода. Однако даже в этом случае вам может понадобиться вставить новые строки между последовательно пронумерованными строками.
Если в качестве входных данных указан список BASIC с номерами строк, выведите ту же программу, но перенумеруйте ее так, чтобы номера строк начинались с 10 и увеличивались с шагом 10. Список ввода может содержать команды GO TO
или GO SUB
команды, поэтому числа, связанные с ними, также должны быть скорректированы.
GO TO
иGO SUB
команды находятся либо в своих собственных строках, либо в концеIF
THEN
строк. Можно с уверенностью сказать,^(\d+) .*GO (TO|SUB) (\d+)$
чтобы соответствовать таким линиям. Эти команды в кавычках следует игнорировать.RUN
Команды всегда будут на своих линиях. В этом случае номер строки не является обязательным. Если он отсутствует, то интерпретатор просто запускается в начале программы.Если через
GO TO
,GO SUB
илиRUN
ссылку команды несуществующей строку, то вместо этого перейти к следующей определенной линии. Ваша запись должна иметь дело с этим и убедиться, что любые такие ссылки на строки исправлены, поэтому они указывают на правильную строку. Поведение может быть неопределенным, если в одной из этих команд указан номер строки после завершения программы.Номера строк всегда будут положительными целыми числами от 1 до 9999 (согласно инструкции). Это означает, что входные программы никогда не будут иметь более 999 строк.
Входные строки всегда будут пронумерованы в порядке возрастания номеров.
Для целей этой задачи входные списки будут содержать только печатный ASCII. Вам не нужно беспокоиться о наборе символов ZX. Сказав , что, если ваша запись на самом деле написано в ZX BASIC или соответствующие z80 сборки / машинный код (и есть эмуляторы из там ), то вы можете выбрать для вашего ввода , чтобы быть закодировано в наборе символов ZX вместо.
Вы не имеете права использовать библиотеки или утилиты перенумерации, специально предназначенные для этой цели.
Пример ввода:
1 REM "A rearranged guessing game"
2 INPUT A: CLS
3 INPUT "Guess the number ", B
10 IF A=B THEN PRINT "Correct": STOP
100 IF A<B THEN GO SUB 125
120 IF A>B THEN GO SUB 122
121 GO TO 3
125 PRINT "Try again"
126 RETURN
127 REM "An example of GO TO 7 and GO SUB 13 in quotes"
Пример вывода:
10 REM "A rearranged guessing game"
20 INPUT A: CLS
30 INPUT "Guess the number ", B
40 IF A=B THEN PRINT "Correct": STOP
50 IF A<B THEN GO SUB 80
60 IF A>B THEN GO SUB 80
70 GO TO 30
80 PRINT "Try again"
90 RETURN
100 REM "An example of GO TO 7 and GO SUB 13 in quotes"
Я хотел дать ссылку на руководство по ZX BASIC. Лучшее, что я смог найти, - это http://www.worldofspectrum.org/ZXBasicManual/index.html, но, похоже, это мертвая ссылка. У машины обратного хода есть копия, хотя .
GOTO 100 + A*10
и Приложении C из ZX Spectrum Manual списковGO TO
как принимать числовое выражение (без ограничения на константы). Вот обсуждение достоинств вычисленийGOTO
на ZX80 и ZX81. Кстати, я понятия не имею, почему место было добавлено в версии Spectrum.Ответы:
JavaScript (ES6) 177
Редактировать Добавлено (дорогое) сканирование для поиска следующего номера строки
ТЕСТОВОЕ ЗАДАНИЕ
источник
Perl 6,
147,145,144,142 байтаЭто, вероятно, может быть в гольфе немного больше.
расширенный
источник
.min
. используйте{min %line-map.keys».Num.grep:*>=$1
вместо этогоVisual Basic для приложений, 288 байт
Я не мог удержаться, давая решение на бейсикском диалекте. Вероятно, работает с Visual Basic 6 / .NET или другими современными вариантами с небольшими изменениями.
Я использовал много однобуквенных переменных для краткости. Кроме того, я подавил все ненужные пробелы (VBE расширяет их автоматически при импорте). Число байт для окончательного файла .BAS с CHR (10) в качестве новой строки.
Подпрограмма, которая может быть вызвана из непосредственного окна VBE, открывает программу BASIC Sinclair (первым параметром является путь к файлу ASCII - с CHR (10) в качестве новой строки - содержащей программу), перенумеровывает строки и записывает результаты в переменную Variant (второй параметр).
Идея заключается в том , чтобы итерация по всем возможным номерам источник линии, порядок возрастания, и для каждого из них, заменить сразу все номера согласование линии, а также
GO TO
,GO SUB
иRUN
ссылки с следующим доступным номером целевой линии. Используя этот подход, нам не нужны никакие таблицы перевода. Номер целевой строки увеличивается каждый раз, когда найдено совпадение с номером исходной строки, поэтому «неправильные» ссылки на строки автоматически подстраиваются под следующий допустимый номер. Символы новой строки используются в качестве маркеров начала и конца строки, а символ CHR (0), который никогда не использовался в программе, поскольку он не предназначен для печати, используется в качестве временного маркера, чтобы избежать перенумерации одной и той же строки несколько раз.Некоторые замечания:
Для краткости мы используем меньшую возможную строку для совпадения с операторами прыжка. Используя конец строки в наших строках поиска, мы не рискуем включить в кавычки вхождения или пользовательские функции (которые всегда используют круглые скобки в Sinclair).
GO TO
требует большую строку из-заFOR ... TO
конструкции (например, сравнить50 FOR X=AGO TO 100
и50 GO TO 100
)Код не поддерживает операторы в форме
GO TO200
(без пробелов), хотя руководство ZX подразумевает, что он является допустимым кодом в нескольких примерах (для его обработки потребуется десяток байт).Код добавляет новую строку в начале и другую в конце программы. В конце концов, я мог бы это исправить (еще дюжину байтов), но подумал, что ZX, вероятно, будет игнорировать пустые строки.
Ниже более читаемая версия:
источник
Пип
-rn
, 63 байтаПопробуйте онлайн!
объяснение
Настроить
-r
Флаг читает все и стандартного ввода сохраняет его в виде списка строк в локальной переменнойg
. Глобальная переменнаяt
предварительно инициализирована до 10, а глобальная переменная предварительноs
инициализирована до" "
.Объединяет список строк
g
в глобальную переменнуюy
, чтобы он был доступен внутри функции, которую мы собираемся определить.Функция перевода номера строки
Мы строим функцию, которая сопоставляет любой номер строки в исходной схеме нумерации (включая несуществующую) с соответствующим номером строки в новой схеме нумерации.
Предположим, у нас есть эти строки:
Мы хотим отобразить от 1 до 10, от 2-4 до 20 и от 5-9 до 30. Если у нас есть список исходных номеров строк (
[1; 4; 9]
), мы можем использовать операцию фильтра, чтобы узнать, сколько из этих чисел меньше чем номер строки, которую мы пытаемся преобразовать. Умножьте этот результат на 10 и добавьте 10, и мы получим желаемый ответ.Например, при преобразовании 9 имеется два номера строки (1 и 4), меньшие 9. 2 * 10 + 10 дает 30. При преобразовании 3 один номер строки (1) меньше 3. 1 * 10 + 10 дает 20.
Вот код (слегка измененный, чтобы его было легче читать):
Первая замена:
GO TO
,GO SUB
иRUN
Остальная часть программы представляет собой одно выражение, которое принимает
g
и выполняет пару замен регулярных выражений (которые векторизуются, применяя к каждой строке вg
).Вот первая замена:
Регулярное выражение соответствует любому из
RUN
,GO SUB
иGO TO
, после которого следует число, за которым следует конец строки. Это гарантирует, что он не совпадает внутри строк и не совпадаетRUN
без номера строки.Порядок групп захвата важен. Первая группа захватывает команду (один из
RUN
,GO SUB
, илиGO TO
). Вторая группа, если используется, фиксирует либоSUB
илиTO
. Нам не нужно захватывать эту часть, но для группы без захвата потребуются дополнительные байты. Затем третья группа фиксирует номер строки.Мы используем функцию обратного вызова для замены. С обратным вызовом функцией в Пипе, весь матч является первым аргументом
a
, и захват группа в порядке , являются последующими аргументамиb
,c
,d
иe
. Итак, у нас есть команда в первой группе, которая входитb
, и номер строки в третьей группе, которая входитd
. Единственное изменение , которое мы должны сделать это , чтобы передать номер строки через нашу функцию преобразования, которая называется Lisp-стиль:(nd)
. Затем мы объединяем это вместе сb
пробелом и возвращаем его.Вторая замена: номера строк
Все, что осталось преобразовать, это номера строк в начале строк.
Регулярное выражение соответствует серии цифр в начале строки. Мы снова используем функцию обратного вызова; на этот раз самой функции преобразования
n
достаточно, поскольку все совпадение (первый аргументa
) - это число, которое мы хотим преобразовать.Поскольку это последнее выражение в программе, Pip автоматически печатает результат.
-n
Флаг отделяет список результатов с новой строкой.источник