Есть 95 печатных символов ASCII :
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
В шрифте Consolas (по умолчанию блок кода Stack Exchange) некоторые символы имеют зеркала вокруг вертикальной оси симметрии:
- Эти пары символов являются зеркалами друг друга:
()
[]
{}
<>
/\
- Эти символы являются зеркалами самих себя:
! "'*+-.8:=AHIMOTUVWXY^_ovwx|
(Обратите внимание, что пробел один.) - У них нет зеркал:
#$%&,012345679;?@BCDEFGJKLNPQRSZ`abcdefghijklmnpqrstuyz~
( i
, l
, 0
, #
, И , возможно , другие персонажи являются их собственные зеркала в некоторых шрифтах , но мы будем придерживаться формы Consolas.)
Строка называется зеркалом сама по себе, если она состоит только из 39 зеркальных символов , расположенных так, что строка имеет центральную вертикальную линию симметрии. Так ](A--A)[
зеркало само по себе, но ](A--A(]
это не так.
Напишите однолинейную программу четной длины, которая сама по себе является зеркалом. Когда к нему добавлено N копий его левой половины, и к нему добавлено N копий его правой половины, он должен вывести N + 1. N является неотрицательным целым числом.
Например, если программа была ](A--A)[
(левая половина:, ](A-
правая половина:) -A)[
, то:
- Бег
](A--A)[
должен выводить1
. (N = 0) - Бег
](A-](A--A)[-A)[
должен выводить2
. (N = 1) - Бег
](A-](A-](A--A)[-A)[-A)[
должен выводить3
. (N = 2) - Бег
](A-](A-](A-](A--A)[-A)[-A)[-A)[
должен выводить4
. (N = 3) - , , ,
- Бег
](A-](A-](A-](A-](A-](A-](A-](A-](A-](A--A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[-A)[
должен выводить10
. (N = 9) - и т.п.
правила
- Выведите на стандартный вывод или ближайшую альтернативу вашего языка. Там может быть необязательный завершающий перевод строки. Вклад не должен быть взят.
- Процесс должен теоретически работать для N до 2 15 с -1 или выше, при условии достаточной памяти и вычислительной мощности.
- Требуется полная программа, а не просто команда REPL .
Самая короткая начальная программа (N = 0) в байтах побеждает.
источник
#
тоже есть свое отражение, но, вы правы, не в консолах.Ответы:
Пип,
1284 байтаТеперь на 66% меньше байтов!
x
переменная, предварительно инициализированная в""
. В числовом контексте это становится0
.+
, является выражением формыx+x+...+x
. Это верное утверждение, которое ничего не делает.+
первой половины, является выражением формы++x+x+...+x
.++x
приращенияx
к1
, а остальное добавляет его к себе N раз. Поскольку выражения оцениваются слева направо в Pip, приращение гарантированно произойдет первым, а результат будет равен количеству уровней отражения.К сожалению, Pip плохо обрабатывает огромные выражения: это решение вызывает
maximum recursion depth exceeded
ошибку для N больше 500 или около того. Вот предыдущее решение, которое не для 8 байтов :Больше на Пипе
источник
Fatal error: maximum recursion depth exceeded while calling a Python object
.x+x+...+x
генерирует O (N) глубину рекурсии. Может быть, это лишает законной силы этот ответ. Я добавлю заметку.GolfScript, 10 байт
Попробуйте онлайн с помощью Web Golfscript: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Web GolfScript имеет ограничение в 1024 символа, но интерпретатор Ruby прекрасно обрабатывает N = 32767 :
Как это работает
Без какого-либо ввода у GolfScript изначально есть пустая строка в стеке.
В первой левой половине происходит следующее:
!
применяет логическое НЕ к пустой строке. Это подталкивает1
.:{
сохраняет целое число в стеке в переменной{
.Да, это действительный идентификатор, хотя нет способа извлечь сохраненное значение.
)
увеличивает целое число в стеке:
это неполная инструкцияВ последующих левых половинах происходит следующее:
:!
(где:
остаток от предыдущего) сохраняет целое число в стеке в переменной!
.Да, это также действительный идентификатор. Это нарушает
!
команду, но мы ее больше не используем.:{
,)
И:
работа , как и раньше.В первой правой половине происходит следующее:
::
(где:
остаток от предыдущего) сохраняет целое число в стеке в переменной:
.Да, даже это действительный идентификатор. Как и в случае с
{
, нет способа извлечь сохраненное значение.(
уменьшает целое число в стеке, получая количество левых половинок.}
, поскольку он не имеет аналогов и немедленно прекращает выполнение.Это недокументированная функция. Я называю их суперкомментариями .
Оставшийся код просто игнорируется.
источник
}
во второй половине вашего кода в зеркальном конкурсе."\""/"
четвертой двойной кавычке также не будет совпадений, так как второй был экранирован.Машинный код Z80,
86 байтов *<8ww8>
* Предполагает определенные условия, введя из Amstrad BASICA
изначально 0 при вводе из бейсика. Он увеличиваетA
n раз, а затем записывает его n раз в одну и ту же ячейку памяти (которую BASIC устанавливает в слегка случайную позицию)! ОперацияJR
Jump Relative никогда не делает ничего, посколькуC
флаг всегда не установлен, поэтому используется для «закомментирования» следующего байта! Эта версия слегка обманывает, предполагая определенные условия входа, а именно, вход из BASIC гарантирует, чтоA
всегда 0. Местоположение(HL)
не гарантируется безопасным, и фактически, вероятно, опасное местоположение. Приведенный ниже код намного надежнее, поэтому он намного длиннее.Машинный код Z80, 30 байтов
Как ASCII:
o!.ww.!>A=o>{))((}<o=A<!.ww.!o
По сути, первая половина гарантирует создание нулевого значения, а вторая половина увеличивает его и записывает в память. В расширенной версии ниже
##
обозначен код, который не имеет смысла в своей половине зеркала.Разбивка разрешенных инструкций:
Из 39 разрешенных инструкций 28 являются операциями загрузки (все блоки от 0x40 до 0x7F являются однобайтовыми
LD
инструкциями), большинство из которых здесь не помогут! Единственная разрешенная инструкция загрузки в память -LD (HL), A
это значит, что я должен хранить значение вA
. ПосколькуA
это единственный регистр с разрешеннойINC
инструкцией, это на самом деле очень удобно!Я не могу загрузить
A
с 0x00, чтобы начать с, потому что ASCII 0x00 не разрешенный символ! Все доступные значения далеки от 0, и все математические и логические инструкции запрещены! За исключением ... Я все еще могу сделатьADD HL, HL
, добавить 16-битныйHL
себе! Помимо прямой загрузки значений (здесь нет смысла!), INCrementingA
и DECrementingA
,L
илиHL
это единственный способ изменить значение регистра! На самом деле есть одна специальная инструкция, которая может быть полезна в первой половине, но во второй половине боль обходится, и инструкция с одним дополнением, которая здесь почти бесполезна и просто займет место.Итак, я нашел наиболее близкое значение к 0, которое я мог: 0x41. Как это близко к 0? В двоичном виде это 0x01000001. Поэтому я уменьшаю его, загружаю
L
и делаюADD HL, HL
дважды!L
теперь ноль, который я загружаю обратноA
! К сожалению, код ASCII дляADD HL, HL
это ,)
так что я теперь нужно использовать(
дважды. К счастью,(
этоJR Z, e
, гдеe
находятся следующие байты. Таким образом, он поглощает второй байт, и мне просто нужно убедиться, что он ничего не делает, будучи осторожным сZ
флагом! Последней инструкцией, влияющей наZ
флаг, былаDEC A
(нелогично,ADD HL, HL
не меняет ее), и, поскольку я знаю, чтоA
в тот момент это было 0x40, гарантируется, чтоZ
она не установлена.Первая инструкция во второй половине
JR Z, #28
ничего не будет делать первые 255 раз, потому что флаг Z может быть установлен только в том случае, если A переполнился с 255 до 0. Однако после этого выходной сигнал будет неправильным, поскольку в любом случае он сохраняет только 8-битные значения, не должно иметь значения. Код не должен быть расширен более 255 раз.Код должен быть выполнен как фрагмент кода, поскольку все доступные способы возврата полностью запрещены. Все инструкции RETurn превышают 0x80, и несколько разрешенных операций перехода могут переходить только к положительному смещению, поскольку все 8-битные отрицательные значения также запрещены!
источник
A
Регистр всегда 8 бит, в противном случае процессор не будет совместим с Z80. Я бы сказал, что при наличии достаточного количества памяти и вычислительной мощности здесь это было закрыто!A
регистр чего-либо, кроме 8 бит? Изменение его до 16-бит нарушило бы код , опираясь на 255 + 1 = 0, например. Вам придется изобрести процессор, назовем его Z160, который использует 16-битный регистр по умолчанию, но все еще использует тот же 8-битный набор команд из Z80. Weird!J
16 16байтОбычаи:
Объяснение:
J оценивает справа налево.
(_=_)
isinf equals inf
is true, имеет значение1
, поэтому выражение становится1+]...[+1
. ((8=8)
также будет работать, но это выглядит круче. :))[
и]
вернуть их левый и правый аргументы соответственно, если у них есть 2 аргумента. Если они получают только 1, они возвращают это.+
добавляет 2 аргумента. Если он получает только 1, он возвращает это.Теперь давайте оценим выражение уровня 3 (идущее справа налево):
Как мы видим, правая половина из
1
's' добавляется, а левая часть1
'' s 'опускается, в результате чего получается целое числоN
, уровень зеркала.Попробуйте это онлайн здесь.
источник
Haskell, 42 байта
К счастью,
--
строковый комментарий в Haskell (-> ) является зеркальным, а половина (->-
) является допустимой функцией. Остальное - математика, чтобы получить числа0
и1
. В основном мы имеем(0)-(-1)
с комментариямиN=0
и prepend(0)-(-1)-
на каждом шаге.Если числа с плавающей запятой разрешены для вывода, мы можем построить
1
из8/8
и обойтись с 26 байтами:Haskell, 26 байтов
Выходы
1.0
,2.0
и т.д.источник
program.hs
а затем запустить$ runhaskell program.hs
из командной строки и посмотреть результат. Я не знаю Хаскелла, поэтому не могу точно сказать, что нужно изменить.runhaskell
это сценарий оболочки, который устанавливает некоторое окружение и, наконец, вызываетghc
компилятор Haskell. Вы можете запустить свой код непосредственноghc
:ghc -e "(8-8)-(-8/8)--(8\8-)-(8-8)"
. Это запускает,ghc
который оценивает код, предоставленный в качестве аргумента, печатает результат и завершает работу. Нет REPL, нет взаимодействия. Конечно, это добавило бы +1 к числу байтов для-e
.-e
не влияет на счет в этом случае. Мы не считаем байт дляperl -E
илиgcc -std=c99
ни.CJam, 14 байтов
Попробуйте онлайн в интерпретаторе CJam: N = 0 , N = 1 , N = 2 , N = 3 , N = 41
Обратите внимание, что этот код заканчивается сообщением об ошибке. Используя интерпретатор Java, это сообщение об ошибке может быть подавлено закрытием или перенаправлением STDERR. 1
Как это работает
В левой половине происходит следующее:
]
оборачивает весь стек в массив.X
добавляет1
к этому массиву.:+
вычисляет сумму всех элементов массива.Oo
печатает содержимое пустого массива (т.е. ничего)В первой правой половине происходит следующее:
o
печатает целое число в стеке, которое является желаемым выводом.O+
пытается добавить пустой массив к самому верхнему элементу стека.Тем не менее, стек был пустым до нажатия
O
. Это терпит неудачу и прекращает выполнение программы.Оставшийся код просто игнорируется.
1 Согласно мета-опросу Должны ли быть разрешены выходы с ошибкой? это разрешено
источник