Соревнование
В этом задании вы указываете исходный язык S
и целевой язык T
. Ваша задача - написать следующую программу P
на языке S
. Если в качестве входных данных указана допустимая программа Q
на языке , она выведет допустимую программу на языке, которая не требует ввода и вывода , то есть программу, примененную к исходному коду . Кроме того , вы должны представить в своем ответе нетривиальный пример программы (чем интереснее, тем лучше, хотя вы не набрали ни одного балла за это), итоговую программу и результаты . Это код-гольф, поэтому самый короткий код для побед.T
P
R
T
Q(R)
Q
R
Q
R
R
P
Другими словами, это проблема написания «универсального конструктора квин», который может создавать произвольные типы обобщенных квин.
Разъяснения
- Ваш исходный и целевой языки могут быть идентичны.
- Программа
P
должна принимать одну строку в качестве входных данных (из STDIN или эквивалентных) и выводить одну строку (в STDOUT или эквивалентные), как и каждая выходная программаR
. - Программы ввода
Q
также должны преобразовывать строку в другую строку, но их форма более гибкая: они могут быть функциями строка-строка, фрагментами кода, которые изменяют переменную с определенным именем, фрагментами, которые изменяют стек данных, если ваш целевой язык есть еще, и т. д. Вы также можете дополнительно ограничить формуQ
, указав, например, что они могут не содержать никаких комментариев. Однако вы должны иметь возможность реализовать любую вычислимую функцию строка-строка в качестве входной программыQ
, и вы должны явно указать, как они функционируют и какие дополнительные ограничения вы на них накладываете. - Программа вывода
R
действительно должна быть (обобщенной) формулой, поэтому она не должна читать какие-либо входные данные (пользовательский ввод, файлы и т. Д.), ЕслиQ
это не происходит. - Стандартные лазейки запрещены.
Пример
Предположим, я выбрал Python в качестве исходного языка, а Haskell в качестве целевого языка, и я также требую, чтобы программа ввода представляла собой однострочное определение String -> String
функции с именем f
. Если я дам программу перестановки строк
f x = reverse x
в качестве входных данных для моей программы на Python P
он выведет исходный код другой программы на Haskell R
. Эта программа печатает на STDOUT исходный код R
, но в обратном порядке. Если P
задана функция тождества
f x = x
в качестве входных данных программа вывода R
представляет собой квинну.
Выражения на Haskell → Выражения на Haskell, 41 байт
Попробуйте онлайн!
Как это устроено
P $ "Q"
=((++)<*>show).('(':).(++")$(++)<*>show$") $ "Q"
Конструкты"R"
по(++")$(++)<*>show$")
: добавление строки")$(++)<*>show$"
,('(':)
: предшествующий символ'('
и(++)<*>show
(=\x->x++show x
): добавление цитируемой версии этого,в результате
"R"
="(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
.R
=(Q)$(++)<*>show$"(Q)$(++)<*>show$"
работает"(Q)$(++)<*>show$"
,(++)<*>show
: добавление цитируемой версии этого,Q
к этому,в результате
Q "(Q)$(++)<*>show$\"(Q)$(++)<*>show$\""
=Q "R"
.(Парень вокруг
Q
необходим, потому чтоQ
может содержать$
так же легко, какR
и,$
к сожалению, право-ассоциативный.)демонстрация
источник
$
нуждается в круглых скобках, но и задниеlet
,do
или лямбда - выражении.let
/if
/case
/,do
если я сам их не испускаю. Возможно, это так же хорошо, что мне не пришлось.Источник = Цель = JavaScript, 66
Предположения для Q:
Q
должна быть анонимной функцией JavaScript от строки к строке.Примеры:
function(s) { return s.split('').reverse().join(''); }
В этом случае
P(Q)
(илиR
) будет:function a(){console.log(function(s) { return s.split('').reverse().join(''); }(a+'a()'))}a()
и, выполнив его, мы получим:)(a}))')(a'+a(} ;)''(nioj.)(esrever.)''(tilps.s nruter { )s(noitcnuf(gol.elosnoc{)(a noitcnuf
что в точности совпадает сQ(R)
.function(s) { return s; }
в этом случае
P(Q)
(илиR
) будет:function a(){console.log(function(s) { return s; }(a+'a()'))}a()
это JavaScript Quine . Само собой разумеется,Q(R)
будет то же самое, так как Q является функцией Identity.Некоторые заметки:
STDIN в JavaScript традиционно
prompt()
, однако я позволил себе воздержаться от традицииalert()
STDOUT, чтобы упростить процесс запуска вывода в виде программы с использованием копирования и вставки. (Я понимаю, что могу сохранить до 12 символов при переходе наalert()
).Я также могу сделать вещи намного короче в ES6, но сейчас я хочу остаться с Native JavaScript. Я рассматриваю возможность представить ответ S = Scala, T = ECMA6 в будущем, просто для опыта.
Я также понимаю, что JavaScript почти никогда не может победить CJam в код-гольфе , но мне пришлось принять этот вызов! Это было очень весело.
источник
Желе → 7 , 9 байт
Попробуйте онлайн!
Q является функцией 7 (то есть она не выходит за пределы верхнего элемента стека и выполняет ввод / вывод через стек) и задается в качестве аргумента командной строки.
объяснение
7 программа
Универсальный конструктор quine в 7, который я использую здесь:
Первое, на что следует обратить внимание, это то, что первые 7 являются эквивалентом начальных пробелов и не влияют на программу. Единственная причина, по которой это происходит, - подчиняться правилам PPCG против буквальных квин (это кодируется вторым
1
в программе, а не в самой себе).Остальная часть программы представляет собой один элемент стека (он сбалансирован
7
s и6
s), который при запуске выполняет следующее:Другими словами, этот элемент стека представляет собой программу, которая печатает верхнюю часть стека с
7
добавлением префикса в формате вывода 7 (что означает «печатать буквально, используя ту же кодировку, что и исходный код», и, таким образом, явно является лучшей кодировкой для quines). Здесь довольно повезло, что мы можем повторно использовать литерал7
для двух целей (выходной формат и начальный пробел). Очевидно, что, вставляя что-то непосредственно перед финалом3
, мы можем вывести функцию7
+ вход, а не просто выводить7
и ввод напрямую.Как этот элемент стека попадает в собственный исходный код? Что ж, когда достигнут конец программы,
eval
по умолчанию используется верхний элемент стека. Однако в процессе он фактически не извлекается из стека, поэтому приведенный литерал элемента стекаeval
все еще там. (Другими словами, программа не читает свой собственный источник - о чем свидетельствует тот факт, что она не может видеть7
в начале программы, который является разделителем элементов стека, а не частью литерала, - скорее состоит в основном из литерала, которыйeval
приводится по умолчанию.)Желейная программа
Это, пожалуй, одна из наименее похожих на желе программ, которые я написал; она состоит из трех nilads (
“ṚƓ^ṾṂ’
,³
,3
), которые просто выводятся в последовательности , потому что никакие операции не выполняются на них. Это3
достаточно очевидно, просто являясь целочисленной константой. Это³
также просто, если вы знаете Jelly: это явное обозначение Jelly для первого аргумента командной строки (где Jelly обычно принимает свои данные). Остальная часть программы Jelly представляет основную часть моего 7 универсального конструктора quine: используя тот факт, что все команды в 7 могут быть представлены с помощью цифр ASCII, мы можем интерпретировать717162234430
не как последовательность команд или даже как восьмеричное число (как это концептуально есть), а как десятичное число, означающее, что нам не нужно никакого специального форматирования для вывода. Это десятичное число становится“ṚƓ^ṾṂ’
в сжатой целочисленной записи Желе.пример
Если мы дадим в
24053
качестве программы Q, мы получим следующий вывод:Попробуйте онлайн!
2405
конкатенирует верхний элемент стека к себе:(Последний шаг может показаться немного запутанным; происходит то, что экранирование элемента стека преобразует каждую находящуюся в нем команду из «выполнить эту команду» в «добавить эту команду в начало стека», поэтому каждая команда добавляется в исходную элемент верхнего стека во время работы.)
Таким образом, выполнение результирующей программы R дает нам две копии R:
источник
CJam → CJam, 13 байтов
Попробуйте онлайн!
Входные данные
Q
должны быть фрагментом кода, который изменяет единственную строку в стеке.Q
читается со стандартного ввода.пример
Входные данные:
Он добавляет пробел между каждыми двумя символами и переворачивает строку.
Выход:
Вывод обобщенной формулы:
объяснение
Сначала он вычисляет квин, поэтому мы можем получить его строковое представление без лишних двойных кавычек. Затем замените полезную нагрузку вводом.
Это может быть место,
{`"_~"+ }_~7qt
где место является заполнителем полезной нагрузки. Но изменение полезной нагрузки7
экономит байт.источник
Древесный уголь → Perl (5),
2933 байтаПопробуйте онлайн!
Программа Perl Q должна возвращать фрагмент кода, который принимает ввод в виде строки с правой стороны и обеспечивает вывод в переменной
$_
. (Произвольные функции Perl могут быть преобразованы в эту форму путем переноса их какsub x {…}; $_=x
. В большинстве случаев, однако, синтаксис Perl означает, что перенос не требуется.)объяснение
Perl
Вот как выглядит универсальный Perl-конструктор Perine:
(В большинстве случаев вам захочется сыграть в эту игру
$_=q(say…"\$_=q($_);eval");eval
, но я не уверен, что вы можете вставить туда произвольный код Perl…
.)Другими словами, у нас есть внешняя оболочка,
$_=q(…);eval
которая присваивает строку$_
и затем оценивает ее. Внутри оболочки находится"\$_=q($_);eval"
, т. Е. Реконструкция оболочки вместе с ее содержимым с использованием значения, которое мы сохранили$_
, плюс код Q, заданный пользователем, плюсprint
для печати вывода. (К сожалению, мы не можем использоватьsay
; он добавляет новую строку, и это актуально в кавычках.)Древесный уголь
«Целью» этого ответа было создание обобщенных квин на Perl, поэтому, как только я разработал стратегию игры в гольф (такую я использовал во многих других ответах), пришло время написать программу P, которая в основном просто заменяет строка в шаблон. Здесь мне нужен был язык, который был хорош для печати константных строк (в идеале, для их небольшого сжатия) и интерполяции пользовательского ввода в них.
Попробовав несколько, я остановился на древесном угле, который никогда раньше не использовал (и который действительно мог бы работать с некоторой документацией); Он разработан для ASCII-графики, но способен записывать строки и в одном измерении. Символы ASCII печатаются буквально в Charcoal, что означает, что для печати константных строк не требуется шаблон, и мы можем использовать
S
команду для интерполяции строки, взятой из пользовательского ввода в программу.Можно пойти (немного) короче, хотя. Универсальный Quine-конструктор Perl содержит два довольно длинных повторяющихся раздела. Таким образом, мы можем использовать
A
команду, чтобы назначить их переменным (например,A…α
присваивать переменнойα
), и просто интерполировать переменные в строку, которую мы печатаем, используя их имена. Это экономит несколько байтов при буквальном написании строки.К сожалению, Charcoal также добавляет новую строку в программу, но это не так уж важно; просто
\n
добавить два байта для добавления этой новой строки к входу Q тоже.пример
Если мы дадим ввод
$_=reverse
(который переворачивает строку), мы получим следующий вывод:Попробуйте онлайн!
который похож на quine, который печатает свой источник назад, как и ожидалось.
источник
Желе → Недогруз , 15 байт
Попробуйте онлайн!
Принимает входную функцию недогрузки Q как командный аргумент. Q должен взять входные данные из стека и передать их в стек, не пытаясь проверить более глубокие элементы стека (так как их не будет).
объяснение
Недогрузка
Используемый здесь универсальный quine-конструктор Underload:
Большая часть программы является одним литералом. Мы следуем за тем
:^
, кто его копирует, затем оценивает одну копию (оставляя другую копию в стеке).Когда литерал начинает вычисляться, мы запускаем
a
(escape, который возвращает его в ту же форму, что и исходная программа A), и(:^)*
(который добавляет:^
), таким образом восстанавливая исходный код всей программы. Затем мы можем запустить функцию Q, чтобы преобразовать ее произвольным образом, и вывести результат с помощьюS
.Желе
На этот раз я не могу использовать Charcoal, потому что валидный интерпретатор Underload завершается с ошибкой в конце программы, если программа заканчивается переводом строки. (Некоторые интерпретаторы Underload, такие как TIO, не применяют это правило, но я хотел быть правильно переносимым.) К сожалению, Charcoal, естественно, добавляет завершающие символы новой строки в свой вывод. Вместо этого я использовал Jelly, что почти так же кратко в простых случаях, подобных этому; Программа состоит из литерала списка с двумя элементами (
““”
) и объединяет их в input (j
), тем самым интерполируя пользовательский ввод в программу.пример
Используя ввод
:S^
(распечатайте копию, затем оцените оригинал), мы получим следующую программу Underload:Попробуйте онлайн!
Это печатает себя бесконечно много раз, довольно интересным способом: после выполнения нормального поведения quine, это тогда бежит
eval
на копии того, что это выводит. Это приводит к тому, что вся реконструированная программа запускается снова, бесконечно (недогрузка является хвостовой рекурсивной). Завершение работы с самим собойeval
- единственный способ сделать бесконечный цикл в Underload.источник
RProgN 2 , 11 байтов
Объяснение программы
Объяснение Куайна
Создаваемая квинна проста, но использует функциональность непревзойденных обработчиков функций в RProgN2 для создания короткой и приятной квинезы, называемой «циклической» квиной. Это удивительно похожая концепция на <> <quine.
Конечно, из-за структуры этого quine, после функции concatenate можно поместить что угодно, кроме истинных no-ops (которые не преобразуются в строку), и
Некоторые квины
{`{.i}{
: Выходы{}i.{`{
.i
это просто «обратная» функция, поэтому эта программа выводит себя в обратном порядке.{`{.S§.}{
: Выходы..S`{{{}§
.S
преобразует строку в стек символов,§
сортирует стек лексографически, затем.
соединяет его обратно, выводя сам отсортированный.Попробуйте онлайн!
источник