Это было вдохновлено печатью негатива вашего кода и игрой в гольф .
Рассмотрим прямоугольник символов, который соответствует следующим ограничениям:
- Состоит исключительно из печатных символов ASCII
- Размеры больше 1
- Каждая строка и каждый столбец содержит хотя бы один пробел.
- Каждая строка и каждый столбец содержит хотя бы один непробельный символ.
Например, следующее является допустимым прямоугольником 6x4:
%n 2e
1 g 3
&* __
3
Отрицательный для этого прямоугольника определяются как прямоугольник равных размеров, причем все пространства заменяются некосмическими символами, и все без пробела заменены пробелами. Отрицательный знак вышеуказанного прямоугольника может быть:
f ^
33 >
9 $
^ }|Q'
Любой непечатаемый ASCII-символ может быть использован для замены пробела.
задача
Ваша задача - написать программу с прямоугольным исходным кодом, который выводит действительный отрицательный знак для себя. Выведенный негатив должен также быть действительной программой на том же языке, что и оригинал, и он должен выводить источник оригинала.
Конечный пробел не может быть добавлен или удален, за исключением одного завершающего символа новой строки в конце любого вывода, что является необязательным.
Ни одна из программ не имеет права читать исходный код того или другого; также нельзя использовать среды REPL.
счет
Ваша оценка является продуктом измерений вашего кода (т. Е. Если ваш исходный код находится в прямоугольнике 12 на 25, ваша оценка равна 12 * 15 = 180). Кроме того, для каждого символа, используемого в комментарии, ваш счет увеличивается на 2 (если вы используете/* .. */
один раз в своем коде, а ваш код в прямоугольнике 10 на 10, ваша оценка будет 10 * 10 + 8 * 2 = 116).
Самый низкий балл побеждает.
При наличии связи выигрывает представление с наименьшим количеством пробелов в программе (либо оригинал, либо минус, в зависимости от того, сколько пробелов меньше).
Если все еще остается ничья, победит более ранний ответ.
Существует бонус -52% , если при объединении оригинала и негатива получается нормальная квинна. Например:
Original Negative Combined
A A B B BABA
A A B B ABAB
Ответы:
CJam (
51 49 47 46 4542 x 2) * 48% = 40,32Запуск приведенного выше кода дает следующий вывод:
работает, который печатает обратно исходный источник.
Источник и вывод - это просто поменялись местами строки.
Теперь приходит волшебство.
Наложение исходного и выходного результатов в следующий код:
который является идеальным Quine!
Попробуйте их онлайн здесь
Как это работает
Вся логика печати находится в самой первой строке, которая обрабатывает все три случая, описанные ниже.
Массив в последней строке выше - это массив, в котором есть блоки кода, соответствующие всем трем случаям.
Случай 1
В этом случае длина оставшегося стека равнялась 0, так как при выполнении блока у него была только копия самого блока, которая первоначально была выдвинута на третьем шаге выше. Итак, мы берем индекс
0
из последнего массива и выполняем его:В этом случае вторая строка является запретной операцией в том, что касается вывода на печать.
Дело 2
В этом случае стек уже содержал пустую строку, поэтому, когда был выполнен скопированный блок кода, в нем было 2 элемента - пустая строка и сам блок кода. Итак, мы берем индекс
1
из последнего массива и выполняем его:Дело 3
В этом случае стек имеет 6 элементов. Таким образом, после выталкивания последнего блока кода оставшаяся длина массива равна 5. Мы берем индекс
5
из массива и выполняем его. (Обратите внимание, что в массиве3
элементов индекс5
является индексом5%3 = 2
)источник
Python, 97x2 + 2 = 196
Не очень хорошее решение для начала, но, по крайней мере, оно работает (я думаю).
Выход:
источник
CJam, (
5856544846 x 2) * 48% = 44,16какие отпечатки
Непробельные символы в каждой строке остаются одинаковыми между двумя взаимными квинусами.
Но теперь действительно сладкая часть:
это Quine! :)
Проверьте это здесь.
Как это работает
Я рекомендую вам сначала прочитать объяснение о моем другом представлении, так как оно объясняет основы цитирования в CJam в целом.
Этот немного сложнее. Для взаимной квины, как и в другом случае, я изменяю строковое представление блока, добавляя пробелы до или после каждой строки и меняя 0 на 2, чтобы результирующая программа поместила пробелы в противоположный конец.
Обратите внимание, что пробелы вообще не влияют на взаимные квинусы. В первом они находятся в блоке, который на самом деле не используется, а во втором они находятся вокруг всего кода.
Чтобы получить обычную квинну при объединении обоих, нам нужно найти способ избежать всех этих модификаций. Обратите внимание, что структура пробела и кода означает, что, комбинируя оба, мы вставляем всю одну квинну в другую. Поэтому, если мы поместим весь код модификации в блок, мы можем запустить этот блок в зависимости от его фактического содержимого.
Итак, теперь у меня есть этот блок ... для взаимных квин, он содержит только код, который я на самом деле хочу запустить. Что касается объединенной квин, она также содержит всю квинну в произвольной позиции, что не имеет никакого смысла ... но, поскольку это блок, он не запускается автоматически. Таким образом, мы можем определить, следует ли изменять строку на основе содержимого этого блока. Вот для чего
_`'"#)!
. Он дублирует блок, преобразует его в строку, ищет символ"
(который во взаимных квинах появляется только вне блока) - поиск возвращает,-1
если символ не найден, и положительное целое число в противном случае - увеличивает результат и отрицает это логически. Таким образом, если"
был найден, это дает в0
противном случае это дает1
. Теперь мы просто делаем*
, который выполняет блок один раз, если результат был 1, а не совсем иначе.Наконец, вот как работает модифицирующий код:
Требование вознаграждения, (12 х 10) * 48% = 57,6
Оказывается, этот код может быть легко разбит на несколько строк с некоторыми изменениями. Мы добавляем 2 символа, чтобы получить 48 строк, которые затем удобно разделить на 8, чтобы у нас было 8 строк с 6 символами кода и 6 пробелами. Для этого нам также необходимо изменить несколько чисел и переставить оператор или два, чтобы они не разбивались на обе строки. Это дает нам рабочую версию с размером 12 х 8 ... один из требований. Итак, мы просто добавляем две строки, которые ничего не делают (нажмите 1, нажмите 1, нажмите 1, нажмите 1 ...), так что получим 12 x 10 :
Как предыдущий это производит
(Примечание: нет необходимости чередовать левую и правую череду на промежуточных строках, важна только позиция первой и последней строчек. Левая и правая стороны могут быть выбраны произвольно для всех остальных строк.)
И по чистой случайности, полный quine также все еще работает:
(Я говорю совпадение, потому что часть, которая заботится о том, чтобы не выполнять внутренний код, теперь странным образом перемежается с другой формулой quine, но все равно это работает нормально.)
При этом, я мог бы просто добавить 44 строки
1;
в мою первоначальную заявку, чтобы выполнить требование о вознаграждении, но12 x 10
выглядит намного аккуратнее. ;)Редактировать: Ха-ха, когда я сказал «чистое совпадение», я не мог быть больше на месте. Я посмотрел на то, как на самом деле работает последняя четверть, и это совершенно нелепо. Есть три вложенных блока (на самом деле 4, но самый внутренний не имеет значения). Единственная важная часть самого внутреннего из этих 3-х блоков состоит в том, что он содержит
"
(и не тот, который он сделал в исходном представлении, а тот,'"
который используется в конце для проверки того же символа). Итак, основная структура квин:Давайте рассмотрим это:
Так что это действительно делает некоторую забавную магию, но поскольку внутренний блок оставляет одну строку в стеке,
)!*
случается, превращает это в пустую строку. Единственным условием является то, что содержимое внутреннего блока после+
ничего не делает со стеком, поэтому давайте посмотрим на это:источник
Y/2
в комбинированной квине?CJam,
423733 x 2 = 66какие отпечатки
(Линии поменялись местами, и А
1
превращается в0
.)Проверьте это здесь.
Как это работает
Во-первых, вы должны понять основную сущность CJam:
Скобки просто определяют блок кода, например функцию, которая не выполняется немедленно. Если в стеке остается неисполненный блок, печатается его исходный код (включая фигурные скобки).
_
дублирует блок и~
выполняет вторую копию. Сам блок просто выталкивает строку, содержащую_~
. Таким образом, этот код оставляет стек в следующем состоянии:Блок и строка просто печатаются вплотную в конце программы, что делает это квинной.
Прелесть этого в том, что мы можем делать в блоке все, что захотим, и это остается квинной, потому что каждый фрагмент кода будет автоматически печататься в содержимом блока. Мы также можем изменить блок, получив его строковое представление с помощью
`
(который является просто строкой блока с фигурными скобками).Теперь давайте посмотрим на это решение. Обратите внимание, что любая часть взаимной квине содержит квиноподобный блок с
_~
, и anL
.L
Толкает пустую строку в стек, который не способствует выходу. Вот что делает блок:Таким образом, это выполнит часть quine, но заменит 1 на 0, а также добавит еще одну строку
L
, где в коде выше есть пробел. Подвох в том, что порядок этих двух строк определяется обменом внутри{ }*
. И поскольку внешняя часть взаимной квайны имеет0
перед собой замену на a1
, он никогда не выполняет этот обмен и, следовательно, снова производит первоначальный порядок.источник
CJam, 27 × 2 = 54
Выход:
'A'B>
сравнивает символы A и B.' '\n >
возвращает 1, потому что 32> 10, и' \n' >
возвращает 0, потому что два пробела равны.источник
CJam,
3029 x 2 = 58Выходы:
который выводит исходный источник.
Это основано на том же принципе, что и мое другое решение.
Попробуйте онлайн здесь
источник