Этот вопрос входит в серию заданий на День Рождения Brain-flak, предназначенных для празднования первого Дня Рождения Brain-Flak. Вы можете найти больше информации о Дне Рождения Brain-Flak здесь .
Сегодня первый день рождения Brain-Flak! Поэтому я подумал, что мы устроим сюрприз на день рождения. Так что на вашем любимом языке распечатайте
Surprise!
Happy Birthday, Brain-Flak!
(Конечный пробел разрешен)
Как всегда программы должны быть в гольфе. Однако, поскольку программы Brain-Flak состоят из скобок, они не будут считать против вас любые скобки в вашем источнике. (Символы ()[]<>{}
не учитываются в общем количестве ваших байтов), но они должны быть сбалансированы, чтобы не расстраивать Brain-Flak.
правила
Вот разбивка правил
Скобки в вашем источнике должны быть сбалансированы. То есть скобки вашей программы должны быть заключены в следующую грамматику:
S -> SS | (S) | [S] | <S> | {S} | E
где
E
пустая строкаТо есть сбалансированная строка - это либо конкатенация двух сбалансированных строк, фигурные скобки вокруг сбалансированной строки, либо пустая строка.
Оценка программы - это количество байтов без скобок.
Ваша цель должна состоять в том, чтобы минимизировать ваш счет на любом языке, который вы выберете.
Применяются стандартные правила, поэтому вы можете написать либо полную программу, либо функцию.
в случае равного количества необработанных байтов действует как прерыватель связи
Там, безусловно , будет нулевой байт решения в некоторых языках ( Скобки ад , вводные , Glypho , Lenguage ). Попробуйте найти способы хорошо играть в гольф на языках, где это не тривиальная задача.
источник
><
считается сбалансированным, или же брекеты должны быть в правильном порядке (<>
)?Ответы:
Python 2 ,
39373634 байта-1 благодаря дзайме
-2 благодаря Эрику Аутгольферу
Попробуйте онлайн!
Соответствующие персонажи:
объяснение
Эта программа строит строку:
Это делается путем преобразования длинной строки скобок в коды символов. Как только строка построена, она выполняет ее.
Он строит строку со скелетом:
Это разбивает строку вдоль
{}
и отображает каждый раздел в код символа, соответствующий его длине. Затем мы можем собрать всю строку из паренов, что обойдется в ноль байтов.источник
()
вокруг,x
чтобы сохранить 2.Haskell (до GHC 8,4), (
10119 7767 76267540 байт), оценка15 1410Попробуйте онлайн!
Последняя строка определяет анонимную функцию
(<>)'y'pred(:)
. Позвоните,(<>)'y'pred(:)()
чтобы получить строку.Редактировать: Огромное спасибо @ Örjan Johansen за предложение передавать вспомогательные функции в качестве параметров вместо их объявления, сохраняя четыре байта оценки!
Байты без скобок
Как это работает?
Строка
"wxy"
в Haskell является синтаксическим сахаром для списка символов['w','x','y']
, который снова синтаксический сахар для последующего строительства с оператором консом:
и пустым списком:'w':'x':'y':[]
. Определяя,(<<>>)=(:)
мы получаем ту же строку, написав'w'<<>>('x'<<>>('y'<<>>[]))
.Поскольку символы упорядочены, мы можем вычислить предшественника каждого символа с помощью вызываемой функции
pred
. Используя только символ'y'
иpred
, строка становитсяpred(pred 'y')<<>>(pred 'y'<<>>('y'<<>>[]))
. Определив(<>)=pred
и(<><>)='y'
мы можем представить строку, используя только сбалансированные скобки:(<>)((<>)(<><>))<<>>((<>)(<><>)<<>>((<><>)<<>>[]))
Однако, в конце мы не хотим строку, а функцию, возвращающую строку, поэтому мы определяем наш оператор cons как
(<<>>) x xs ()=x:xs
. (Конечно сx
иxs
заменены на идентификаторы с использованием только сбалансированных скобок:(<<>>)(<>)(<><>)()=(<>):(<><>)
). Сюда,((<>)((<>)(<><>))<<>>((<>)(<><>)<<>>((<><>)<<>>[])())())
является функцией типа
() -> String
и добавление финала()
возвращает исходную строку:((<>)((<>)(<><>))<<>>((<>)(<><>)<<>>((<><>)<<>>[])())())()
С помощью этого метода мы достигаем решение со счетом 15. Тем не менее, мы можем конденсировать три объявления в одном, объявив функцию , которая принимает четыре аргумента:
'z'
,pred
,(:)
и()
для вызова.Следующая функция
encode
кодирует строку с символами, меньшими или равными'y'
следующим образом: (Почемуy
? Потому что это самый большой символ в"Surprise!\nHappy Birthday, Brain-Flak!"
и, следовательно, дает самое короткое представление. Еще раз спасибо Эрджану Йохансену за указание на это.)Попробуйте онлайн!
источник
'z'
как на самом деле не встречается в строке цели, я думаю, что вы можете уменьшить число байтов, используя'y'
взамен.(<<<>>>)(<><>)(<>)(<<>>)()=...;(<<<>>>)'y'pred(:)
Retina , 59 - 24 = 35 байт
Попробуйте онлайн! Для сравнения, скучное решение занимает 38 байтов.
источник
Желе ,
76 байтВнутри
“”
вам нужно поместить вывод этой программы Jelly:-1 байт благодаря Джонатану Аллану (разрешен трейлинг новой строки)
Есть 53127666317289661939246122975355844970973062889031671423309402549417051416384149 80886139013 (мы будем называть это
n
)()
между ними“”
.Пояснение :
источник
Lenguage , 0 байт
Всего 10024793746353848520175158940670214213802394805963081469362831141755126591573942436182287015467334956253918417576118983828148929806934751198148656645940502264502520032312455157880058174845907554602116807351044784410936407102892289953027884533102082518964744402664917253792543505897552998982122997648280947470217067174451441654554437678556775097996646071948 байт из сбалансированных скобок.
Программа на Python 3 для генерации моей любимой версии, учитывая достаточно времени и памяти:
источник
Haskell , (
1200613485 байт), оценка1817РЕДАКТИРОВАТЬ:
toEnum
версию для работы без расширений, переместив ееtoEnum
в основную функцию за счет a$
.Использовать как
putStrLn$(<<>>)()
.Попробуйте онлайн!
где
...
- строка результата следующего выражения:Единственные несбалансированные персонажи
Следующий вариант (13484 байта) имеет оценку 16, за исключением того, что ему требуется
ExtendedDefaultRules
расширение GHC , и поэтому он работает только в GHCi по умолчанию. (Если вам не нравится куча предупреждений, вы также хотите-fdefer-type-errors
и-Wno-deferred-type-errors
по какой-то причине.)Попробуйте онлайн!
Как это работает
<>
являются допустимыми символами операторов. Более того, если они заключены в скобки, они могут использоваться для любого значения, а не только для функций с двумя аргументами.(<<>>)
во второй строке находится основная функция, она принимает один фиктивный аргумент()
и возвращает последнюю строку.<>
берет два списка и добавляет длину второго к первому (во второй версии, также сначала преобразуя длину в символ). Операторы по умолчанию остаются ассоциативными, поэтому это легко цепочка.[]
с помощью<>
.()<>[]
символы), а затем (в основной версии) сопоставленияtoEnum
с результирующим списком.источник
Japt ,
1914131098 байтгде строка в начале:
Общее количество байтов «всего»
669433943354, так что вы можете попробовать это онлайн!объяснение
Фактический используемый метод объясняется в других ответах: разделить на
<>
, сопоставить каждый цикл прощения сchr(len(x))
, присоединиться снова на пустой строке. Здесь самое интересное - это игра в гольф.Перед «игрой в гольф» оригинальный код может выглядеть так
это довольно буквальное описание:
"...".split("<>").map(Z => Z.length.toChar()).join("")
теперь нам нужно минимизировать символы без скобок. Как? Ну, во-первых, мы можем немного поиграть в гольф:Это примерно представляет
"...".split("<>").map(Z => Z.length).map(Z => Z.toChar()).join()
.Теперь мы можем злоупотреблять тем, как Джапт обращается со скобками.
(
представляет повышение на один уровень, как в большинстве языков, но)
представляет снижение на два уровня (пробел уменьшается на один уровень), что означает, что мы можем оптимизировать код до:Этот код действует так же, как и выше, но использует на два меньше символов без скобок.
Кроме того, если оператор является первым входом функции, он превращается в строку, чтобы функция могла решить, что с ней делать. Это означает, что мы можем избежать кавычек, если мы просто сделаем каждый цикл круглых скобок на 1 байт короче, а
>
вместо этого разделимся на них (с некоторой хитрой договоренностью, чтобы отменить результат>)
в коде):Это экономит нам еще два байта, поскольку мы вынули две кавычки.
источник
Haskell , (
1965 313118073 байтов), оценка31 2319Попробуйте онлайн! Использование: Последняя строка является анонимной функцией. Привязать его к например
f
и позвонить сf()
.19 байтов не в скобках
плюс завершающий перевод строки.
Оценка 23 версии (3131 байт):
Попробуйте онлайн! 23 байта не в скобках
Оценка 31 версии (1965 байт):
Попробуйте онлайн!
После удаления всех скобок эти 31 байт остаются:
Как это работает?
['\n'..'~']
возвращает список всех символов новой строки, в~
который входят все печатные символы ASCII.(<<>>)
является идентификатором, выбранным, чтобы иметь нулевые байты согласно данному правилу оценки.(<<>>)=['\n'..'~']++(<<>>)
таким образом, получается бесконечное повторение списка символов.Во второй строке
zip"> ... "(<<>>)
застегивается длинная строка скобок с бесконечной строкой, получая список кортежей с символом скобки в первом компоненте и некоторым символом ASCII во втором. Для каждого кортежа в этом списке мы проверяем, соответствует ли он шаблону('{'{-}-},(<>))
, то есть имеет ли он{
скобку в качестве первого компонента.{- ... -}
это встроенный комментарий в Haskell,'{'{-}-}
равно как и сбалансированная версия'{'
. Если совпадение прошло успешно, второй компонент кортежа связывается с идентификатором(<>)
и добавляется к построению строки через понимание списка. НаконецputStr
печатает строку.putStr[(<>)|('{'{-}-},(<>))<-zip"> ... "(<<>>)]
Непосредственная печать строки составляет 46 байт:
источник
HTML, 37 байт
источник
<br>
тег, как это:Surprise!<br>Happy Birthday, Brain-Flak!
<br>
на один байт длиннее, так как<p>
я пробовал это перед публикацией. Это выглядит немного лучше. Я не использую закрывающий тег<p>
хотя.05AB1E , 24 байта
Использует кодировку 05AB1E . Попробуйте онлайн!
источник
Pyth,4⃠3⃠2 байтаВычеркнуто 4 не является обычным 4, если вы используете
zalgoUnicode magicСпасибо Роману Грэфу и Нилу за сохранение 1 байта.
Код
Cl(()()()
...()()())
где внешняя скобка содержит41505989310382548390036033574496753883572705382055993299460470741732071419050117038172961
сцепленные копии()
. (Stack Exchange не позволил мне опубликовать полный код.)Создает кортеж (
(
…)
) пустых кортежей (()
), принимает length (l
) и преобразует его в строку base-256 (C
).источник
h
чтобы добавить еще пару скобок?h
две позиции вправо, и это все равно будет работать отлично ;-)Japt , 6687 байт, оценка 5
Попробуйте онлайн!
Это аналогично моему другому ответу на Japt , но вместо строки он использует вложенные массивы. Преимущества вложенных массивов (помимо того факта, что их определение не занимает никаких байтов) состоят в том, что они предварительно организованы, поэтому вам не нужно делать какие-либо причудливые сплиты по
<>
магии или декодировать с огромного базовое число 256 или что-то в этом роде. Фактическая логика справедлива.map(X => X.length).map(X => String.fromCharCode(X)).join("")
.источник
Чип , 553 + 3 = 556 байт, оценка 127 + 3 = 130
+3 для Arg
-w
. Попробуйте онлайн!Байты без скобок
Ungolfed / несимметричный:
Как видите, в исходном коде используются только правые скобки, поэтому все левые скобки предназначены только для балансировки. В процессе разработки этого решения я нашел гораздо более плотное строковое представление в чипе, которое у меня было для моих предыдущих ответов, например, hello world , и поэтому я также обновил их.
Как это работает:
Бит, свисающий слева, производит 1-тактный импульс, чтобы все началось. Этот импульс перемещается вдоль
Z
«s» со скоростью 1 за цикл, что обеспечивает синхронизацию. Когда каждыйZ
получает питание, это соответствующий столбец производит ASCII - код символа по этому индексу, который затем получает выход элементовa
черезg
(один на один бит выходного байта, за исключением старшего бита ,h
который всегда 0). По окончанииt
прекращает выполнение.Кодировка ascii проста:
)
означает 1 иx
означает 0. Однако нижние 5 строк в основномx
, поэтому я инвертирую эти биты в окончательном решении, эффективно меняя местами два символа.Это лучший результат?
Я сомневаюсь в этом. В абсолютном минимуме, я думаю, нам нужно следующее: 1
a
через каждыйg
, так как это активные выходные биты, 1*
или аналогичный, чтобы обеспечить стартовый сигнал, 1,t
чтобы завершить выполнение, 36Z
с илиz
s, чтобы тайм-аут каждой буквы, и команда Arg-w
. Это все суммы до 48 баллов.Выше этого теоретического минимума мое решение имеет 7 новых строк, секунду
*
, дополнительныйZ
и 73x
с.источник
C 9265 байт, оценка 37
Посмотрите, как это работает онлайн .
C 8589934626 байт, оценка 34
Где
STRING
тот же большой строковый литерал, который использовался в приведенном выше примере, за исключением того, что он имеет два отличия в самой середине строки, где есть подстрока<>
. Непосредственно до этого<
, 4294962688 дополнительных[
символов, и сразу после этого>
4294962688 дополнительных]
символов.Программа будет работать при следующих допущениях:
INT_MAX - 2 ^ 31-1, а INT_MIN - -2 ^ 31.
Скомпилировано с поведением переноса для подписанной арифметики. (-Fwrapv)
Функция strspn способна обрабатывать 4294962689 символов одновременно.
Компилятор способен компилировать строковый литерал, состоящий из 8589934592 символов.
Эти предположения возможны на современных 64-битных архитектурах, где тип int равен 4 байта, а тип size_t равен 8 байтов. Функция strspn возвращает тип size_t, и тот же тип связан с внутренним пределом для максимального размера объекта. Тип size_t, равный 8 байтам, будет соответствовать последним двум предположениям.
Эта разница в этой версии заключается в том, что переменная i не должна сбрасываться в 0, поскольку она оборачивается до 0 после того, как последний символ напечатан.
источник
Haskell , 9735 байт, оценка 9
Попробуйте онлайн!
9 выигрышных байтов
Это работает в текущих версиях Haskell (GHC 8.4 или новее), где
(<>)
находится вPrelude
. Спасибо Орджану Йохансену за то, что он указал, что это нарушает мое предыдущее решение, но позволяет сохранить еще один байт оценки.объяснение
Как
(<>)
в двух списках такого же , как(++)
мы можем представить строку ,"abc"
как"a"<>"b"<>"c"
вместо этого. Строки представляют собой списки символов, поэтому['a']<>['b']<>['c']
обозначает одну и ту же строку. Теперь, как и в предыдущем ответе, мы хотим только один буквенный символ, поэтому мы будем придерживаться с он высокий один'c'
и представляют другие как предшественники этого:[pred(pred 'c')]<>[pred 'c']<>['c']
. Наконец, путем замены'c'
с(<><>)
которой является действительным идентификатором иpred
с(<<>>)
, мы получаем кодировку строки ,"abc"
которая состоит только из сбалансированной скобки:[(<<>>)((<<>>)(<><>))]<>[(<<>>)(<><>)]<>[(<><>)]
.Следующая функция кодирует произвольную строку таким образом:
Попробуйте онлайн!
источник
(<<>>)
он используется так много раз, я думаю, что он сэкономит много байтов, если вы поменяете его имя на имя<>
(передавая последний как дополнительный параметр).C # Интерактивный, 45 байт
Я знаю, это немного скучно, но если его выполнить в интерактивном режиме C #, то получится желаемый результат - и на самом деле я сомневаюсь, что в C # есть более простой способ решить эту проблему.
Однако есть более хитрый способ:
Но это 145 байт.
С переводом строки это выглядит так:
Это интерпретирует скобки как логические значения, а затем как строку.
На самом деле я не продвинутый игрок в гольф, поэтому любые предложения приветствуются!
источник
.Select(s =>
чтобы выполнить ееS -> <S>
, вы можете изменить ее на.Select(/*<*/s =>
C# Interactive
, также я думаю, что он интерпретируется в C # интерактивно, не компилируется, но все равно считается программой \ scriptCJam , 6683 байта, оценка 3
Я сократил код, чтобы не слишком загромождать страницу. Вы можете увидеть полный код в ссылке TIO. Единственные символы не в скобках
,c%
.Попробуйте онлайн!
объяснение
Программа запускается нажатием массива массивов пустых массивов. Каждый подмассив содержит количество пустых массивов, соответствующих значению ASCII символа в нужной строке. Затем для каждого subarray (
{...}%
) он получает длину array (,
) и преобразует эту длину в символ (c
).Результирующая строка печатается неявно.
источник
C
6964 байтаПопробуйте онлайн
Как я это сделал
*
на{}
,>
с<>
, и<
с,[]
чтобы они не учитывались, так что теперь это число кода равно 1 из-за начального символаS
.<>
, вычитает[]
, выводит текущую сумму{}
и завершает в конце строки\0
.C, 49 байт. Попробовать онлайн
источник
p
сохранить несколько байтов?Lua 5.3, 108097107033101 байт, оценка
2827Здесь
REPLACE
заменяется длина строки 108097107033034 свободных символов. Строка кодирует данные, помещая их{}
в определенные ключевые позиции. Первыйgsub
заменит строку на индексы{}
s (через пустую группу перехвата()
). Втораяgsub
разбивает эту результирующую строку на 3-значные блоки и заменяет каждый блок его представлением ASCII.Обратите внимание, что синтаксис для необработанных строк в Lua (в основном)
[[string contents]]
, что весьма полезно для уменьшения оценки.(Неэкранированная) строка, которую я генерирую, - это
print"Surprise!\nHappy Birthday, Brain-Flak!"
. Замена каждого символа его трехзначным десятичным кодом ASCII дает112114105110116034083117114112114105115101033092110072097112112121032066105114116104100097121044032066114097105110045070108097107033034
. Код, который я использую, может генерировать только последовательности увеличивающихся натуральных чисел (по крайней мере, 2 с интервалом), которые не начинаются с начальных нулей. Итак, это число разбивается на11, 2114, 105110, 1160340, 83117114, 112114105, 1151010330, 9211007209, 71121121210, 320661051141, 1610410009712, 10440320661140, 97105110045070, 108097107033034
. (Это последнее число точно соответствует длинеREPLACE
значения, так как последнее совпадение шаблона даст индекс финала}
, учитывая, что индексы Lua начинаются с 1. Если последнее число было нечетным, то шаблон и строка имели бы быть слегка измененным, хотя это не сложно.)На самом деле я не создавал и не запускал эту программу, потому что она слишком большая (хотя теоретически она могла работать на 64-битной машине, она не помещалась бы на моем жестком диске).
В качестве подтверждения концепции, вот небольшая программа, которая печатает
3
по тому же принципу:Это генерирует строку кода
p"3"
через число112034051034
через разделение11, 203, 405, 1034
.источник
Пип , 6681 байт, оценка 3
(с большим количеством скобок и несколькими квадратными скобками). Попробуйте онлайн!
Мы строим список списков, каждый из которых содержит
()
(ноль) некоторое количество раз.#*
сопоставляет оператор длины, в результате чего получается список чисел.C
берет каждое число как код ASCII и преобразует его в символ. Полученный список символов затем автоматически объединяется и печатается.Счастливого запоздалого дня рождения, Brain-Flak!
источник
Mathematica, 40 байт
Анонимная функция. Не требует ввода и возвращает строку в качестве вывода.
источник
Желе ,
1921 байтЗдесь нет ничего умного, только словарь + сжатие строки текста и завершающий перевод строки для удаления непревзойденного
<
.Для истинно гольфового подхода посмотрите этот ответ Эрика Аутгольфера.
Попробуйте онлайн!
источник
PHP, 42 байта
Попробуйте онлайн!
-5 байт скучный раствор
PHP, 60 байт
Попробуйте онлайн!
источник
<?=""?>
С накоплением , оценка 23
Где
...
пропущенная строка (Это может быть сгенерировано с этим .)Попробуйте онлайн!
Да, не так креативно. Получает число всех
<>
s и преобразует их в коды символов.источник
Perl 5 , 3304 байта, 16 баллов
Попробуйте онлайн!
Использует @ HeebyJeebyMan's Python-решение кодировки длины пробега текста.
источник
Java, 140 байт
Попробуйте онлайн
источник
C, 52 байта, оценка 46
Наивная версия. Вот оптимизированная версия .
источник
Древесный уголь , 37 байт
Попробуйте онлайн!
Просто печатает строку.
источник