Советы по игре в гольф в INTERCAL


10

Какие общие советы у вас есть для игры в гольф в INTERCAL ? Я ищу идеи, которые могут быть применены к задачам по коду для игры в гольф, а также, по крайней мере, несколько специфичны для INTERCAL (то есть «удалить комментарии» не является полезным ответом).

Я знаю, что экзотические языки могут быть действительно полезны для победы в соревнованиях по гольфу, но я не вижу здесь много кода INTERCAL. Есть ли у вас какие-либо советы, которые могут помочь людям получить конкурентоспособные размеры кода с помощью INTERCAL? Может ли этот язык быть конкурентоспособным?

INTERCAL настолько не используется, что даже не имеет тега. Так грустно...


Большинство языков не имеют или не нуждаются в своих собственных тегах здесь, поскольку специфические для языка проблемы обычно не приветствуются.
Алекс А.

9
Подсказка о том, что это не лучший язык для игры в гольф, на странице в Википедии:Despite the language's intentionally obtuse and wordy syntax,
isaacg

Ответы:


2

Удаление пробелов / «шума» может пойти дальше, чем вы могли ожидать

INTERCAL - это язык без пробелов. В отличие от большинства нечувствительных к пробелу языков, нечувствительность идет гораздо дальше, чем вы могли бы ожидать.

Например, DO NOTэто два токена, но они могут быть записаны DONOTбез жалоб анализатора (в значительной степени в любой широко используемой реализации). (Конечно, вы могли бы также написать DON'T, но это не так кратко. Возможно, это будет легче читать, хотя, PLEASEN'Tвероятно, труднее читать, чем PLEASE NOT, хотя.) На самом деле, есть некоторые споры относительно того, что пробел вообще что-то делает; по крайней мере, один синтаксический анализатор INTERCAL позволяет делать это даже внутри числовых констант (не то, чтобы это было очень полезно при игре в гольф). Одна вещь, которую нужно иметь в виду, это то, что удаление пробелов из DO READ OUTдаров может сбить с толку некоторые старые парсеры INTERCAL из-за встроенногоDOREADOUTDO(хотя их авторы обычно считают это ошибкой, и, таким образом, в настоящее время она обычно работает в допустимой программе, не рекомендуется размещать подобный код в окрестности синтаксической ошибки, так как тогда может быть намного сложнее устранить неоднозначность).

Также помните, что вы можете перебивать символы, чтобы сэкономить место. В ASCII вы можете действительно справиться с этим только с '.!, но это очень полезный трюк сам по себе. (Когда вы не используете массивы, нет никакой двусмысленности из-за sparkears, даже если все ваши символы группирования одинаковы, поэтому для записей в гольф рекомендуется придерживаться только, 'если индекс массива действительно не требует a ".) Книжный червь может быть представлен одним байтом с использованием ?аббревиатуры (C-INTERCAL) или Latin-1 для ¥(CLC-INTERCAL), а не трех, которые нужны INTERCAL-72.


2

Сосредоточьтесь на том, чтобы делать как можно больше работы в одном утверждении

Идентификаторы операторов INTERCAL довольно многословны; DOв каждом утверждении два шумовых символа, само имя оператора также имеет тенденцию быть довольно длинным, и вы должны время от времени вставлять в него выражение, PLEASEчтобы синтаксический анализатор был доволен. (Лучшее, что вы можете сделать - это соотношение четыре DOк одному PLEASE, то есть вы используете 14 символов в идентификаторах для каждых 5 команд.) С другой стороны, синтаксис выражения довольно краткий (смешной, но краткий). Это означает, что часто целесообразно встраивать часть вашей программы в одно выражение, даже если использование нескольких операторов было бы более «естественным» способом выполнения действий.

Например, если вы хотите назначить #1в .1и #2к .2, вместо того , чтобы делать это в очевидном INTERCAL-72 образом:

DO.1<-#1DO.2<-#2

Стоит подумать о перегрузке случайной переменной, чтобы вы могли назначить обе сразу:

DO:1<-#1$#2

:1/!1$.2'добавленным где-то ранее в программе; обратите внимание, что эта нотация довольно сильно устарела в INTERCAL-72, так что для этого вам понадобится современный INTERCAL). Это только немного дольше, даже если вы принимаете во внимание настройку, и становится короче, если вам когда-либо понадобится или вы можете назначить одновременное присвоение .1и .2более одного раза.

Это не просто вычисления команд, где этот трюк работает. Если вам нужно спрятать переменную дважды, не делайте так:

DOSTASH.1DOSTASH.1

а вот так:

DOSTASH.1+.1

( +Нотация работает для большинства команд, где она может иметь концептуальный смысл.)


2

Используйте единственное RESUME для всех INTERCAL-72-стилей, если они работают

Если вам нужно написать эквивалент оператора «if», нормальный метод, использующий код INTERCAL-72, - NEXTдважды, а затем выполнить вычисление RESUME. (В современном коде часто вычисляемый COME FROMбудет лучше, но этот совет предполагает, что ваш код предпочитает NEXT.) Почти наверняка вам придется платить за первые байты NEXT, поскольку они переходят из одной ветви «если» в другую. Разделение второго NEXTтакже нетривиально, если у вас нет большого количества утверждений «если», которые попадают в одно и то же место при просмотре #1. Однако, это RESUMEможет быть где угодно в программе (потому что управление собирается оставить его немедленно где угодно).

Есть два способа справиться с этим. Если у вас много утверждений «если», то, RESUMEвероятно, требуется однозначный номер строки, так что ваше второе NEXTутверждение может быть максимально коротким. Если возможно, постарайтесь сделать его вычисляемым RESUME, который естественным образом встречается в вашем коде (по общему признанию, это сложно, так как редко они появляются в «нормальном потоке» кода, а не в NEXTредактировании); тогда единственной стоимостью является номер строки. Вы должны будете использовать единственную логическую переменную для всех этих NEXTs; универсальный консенсус здесь должен использоваться .5, главным образом потому, что это переменная, которую стандартная библиотека использует для логических возвращаемых значений.

В качестве альтернативы можно использовать недокументированную (технически недокументированную, потому что я заметил подсказку в документации INTERCAL, когда я заметил) функцию стандартной библиотеки. Поскольку центральное расположение для a RESUMEочень полезно, стандартная библиотека использует его внутри. Номера строк в INTERCAL являются глобальными (с соглашениями о пространствах имен, но которые могут быть разбиты, если вы знаете, что делаете), так что вы можете NEXTперейти прямо к внутренним компонентам стандартной библиотеки, если хотите, и, в частности, NEXTк ее центральному расположению RESUME. , Это достаточно популярно в существующем коде INTERCAL, поэтому в стандартных заменах библиотек, как правило, приходится его реализовывать, чтобы избежать взлома существующих программ.

Рассматриваемая строка (буквально или эффективно, в зависимости от реализации):

(1001) DO RESUME .5

Основная причина не использовать это номер длинной строки; если вам нужно использовать много конструкций в стиле INTERCAL-72, то лучше использовать свой собственный, чтобы присвоить ему более короткое число.

Конечно, вы можете комбинировать приемы, писать что-то вроде

(9)DO(1001)NEXT

который лишь незначительно длиннее, чем

(9)DORESUME.5

и имеет то преимущество, что булевы значения становятся #2и #3(которые труднее читать, но обычно легче генерировать). На самом деле, возможно, стоит даже добавить дополнительный код для обработки, #0и #1если вы собираетесь много чего делать (но вычисление COME FROM, вероятно, будет работать лучше в этом случае, если ваши требования не очень странные).


2

INTERCAL не определяет приоритет, но он также не допускает ошибки при неоднозначном приоритете

Выражение как

#1$#2~#3

является неоднозначным, и может означать

'#1$#2'~#3

или

#1$'#2~#3'

Спецификация INTERCAL намеренно оставляет неясным, что подразумевается, и, в общем, стандарта нет (хотя C-INTERCAL и CLC-INTERCAL прилагают усилия, чтобы соответствовать друг другу в более простых случаях). Тем не менее, оригинал не является неправильным ; это неоднозначно, и я бы не советовал использовать его в производственном коде (но тогда я бы не советовал использовать сам INTERCAL в производственном коде), но это будет иметь некоторый смысл в большинстве компиляторов.

Другими словами, возможно, стоит просто удалить символы группировки и надеяться, что ваша программа все еще работает. Большинство интерпретаторов будут последовательно анализировать любое заданное неоднозначное выражение, поэтому для каждой пары группирующих символов есть вероятность 1 к 2, в которой нет необходимости; это может составить довольно большую экономию. (К сожалению, парсеры INTERCAL имеют тенденцию быть достаточно запутанными, так как никто не совсем уверен, что на самом деле представляют собой правила , но обычно это можно определить экспериментально. В простейших случаях операторы, как правило, имеют одинаковый приоритет и одинаковую ассоциативность.)


2

В C-INTERCAL рассмотрим сокращение кода с использованием CREATE

CREATEЗаявление позволяет создавать новый синтаксис. Это особенно полезно в гольфе, потому что позволяет давать заявлениям более короткие имена. Вы также можете использовать его для эффективного «определения функции» посредством создания нового оператора (что имеет огромное преимущество в том, что позволяет вызывать функцию в середине выражения).

Стоимость установки здесь довольно высока, но если есть конструкция, которой вы часто пользуетесь, придумать более короткий синтаксис для нее, вероятно, будет хорошей идеей.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.