RLE Brainfuck
(относится к BF-RLE )
Гипотетический диалект RLE ( Run-Length Encoding ) Brainfuck принимает символы для 8 команд, а также принимает цифры. Цифры используются для представления количества последовательных повторений команды, что позволяет кодировать длину строки исходного кода.
8>
равно >>>>>>>>
.
Длина всегда в левой части команды.
Ваша задача - написать самую короткую программу / функцию, которая переводит входную строку (фрагмент RLE Brainfuck) в обычную программу Brainfuck.
Например:
Входные данные:
10+[>+>3+>7+>10+4<-]3>2+.>+.7+2.3+.2<2+.>15+.>.3+.6-.8-.2<+.<.
Ouptut:
++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>++.>+.+++++++..+++.<<++.>+++++++++++++++.>.+++.------.--------.<<+.<.
Победит самый короткий код в количестве байтов на каждом языке.
Ответы:
Python 2 ,
6261 байтПопробуйте онлайн!
Подстановка регулярного выражения раскрывается
3<2+-
в строку:который затем
eval
ред. (Обратите внимание, что когда\1
пусто, мы получаем1**1 = 1
.) Первый+
- это унарный оператор, который привязывается к первому числу, а другие+
- конкатенация строк. Это бьет более очевиднымна 14 байтов. Обычно
"\2"
не будет всегда работать, но , к счастью ,\
и"
не Brainfuck команды.xnor сохранил байт, предоставив
1*\1*1
трюк. Ранее я имел\1L
в регулярном выражении, и определилL=1
как лямбда-аргумент, который также довольно круто:3L
это длинный int литерал иL
является переменной.источник
L
для обработки пустой строки. Хотя есть более короткий путьr'+1*\1*1*"\2"'
.import re
ниже лямбды?f=\
заголовок - теперь у лямбды есть имя!)Pyth , 2 байта
Попробуй это здесь!
Как это устроено
источник
Луа,
656463 байтаБольшой ! На этот раз Луа побеждает Питона!Редактировать: Сохранение одного байта благодаря @Jarhmander, спасибо ему за полезный трюк для форсирования одного результата
Попробуйте онлайн!
Пояснения
источник
,""
и заключив в скобки весь аргумент print. Выражения, заключенные в скобки, в Lua корректируются на одно значение (см. Lua.org/manual/5.3/manual.html#3.4 ).Scala ,
7369 байтПопробуйте онлайн!
источник
Perl 5 , 18 байт
Код 17 байтов + 1 для
-p
.Попробуйте онлайн!
источник
vim,
2925232216 байт<C-V>
0x16,<ESC>
0x1b.Он работает путем замены каждого нецифрового числа командой, которая добавляет этот символ в буфер. Подсчет оставлен в покое и изменяет эти команды. На данный момент буфер представляет собой программу vimscript, которая создает желаемую программу Brainfuck, поэтому мы помещаем ее в регистр и запускаем.
Попробуйте онлайн!
Изменить: Уменьшение размера благодаря предложениям: H.PWiz: 5, TheFamilyFroot: 5, DJMcMayhem: 1
источник
&
или\0
) вместо этого без скобок. Кроме, наконечник от меня, не TheFamilyFroot является точто вы могли бы использоватьD
вместоdd
для-1
байта.RLE Brainfuck, 204 байта
Насколько я понимаю, технические характеристики среды для мозгового удара не очень четко определены. Эта программа предполагает, что ячейки в ленте допускают произвольно большие положительные и отрицательные целые числа без переполнения. Этот код также будет транскрибировать некомандные комментарии, но расширит кодировку комментариев по длине прогона (например, «см. 3b» → «см. Bbb»). Полученная программа должна работать так же, так что я не слишком обеспокоен.
Я почти уверен, что смогу сыграть несколько байтов, но я устал от работы с ним.
Вот пользовательский интерпретатор + тесты, которые я использовал для его тестирования. Если вы передадите ему ввод в поле «Стандартный ввод», он должен работать с этим вводом вместо выполнения тестов.
Мой грязный негольфовый рабочий стол:
источник
10+
? ОП пояснил в комментарии, что счетчик всегда будет больше 0, так что вы можете сократить некоторые байты, если он будет первым.while max
цикл всегда выполняется по крайней мере один раз, и я безоговорочно поднимаю буфер, в котором храню значение цифры в этом цикле, мне нужно запустить этот буфер в -1. Интересно , если бы я мог сохранить несколько байт, оставляя этот буфер логически наvalue+1
хотя 🤔С накоплением , 24 байта
Попробуйте онлайн!
объяснение
источник
TeX, 124 байта
(пишется в две строки, чтобы быть видимым, но код может быть написан в одну строку)
Это определяет макрос,
\b
который принимает входные данные в форме\b<input>;
и печатает выходные данные, необходимые для документа.источник
Retina ,
2823 байтаспасибо @Leo за -5 байт
Попробуйте онлайн!
источник
\b
во втором регулярном выражении, чтобы соответствовать только одному1
за прогон1
s?Пион , 66 байт
Попробуйте онлайн!
Pyon в значительной степени просто Python, но он короче, потому что
re
автоматически импортируется при его использовании, иa
автоматически устанавливается в качестве аргумента или ввода-4 байта благодаря мистеру Xcoder
источник
g[0]
наg[:-1]
(не подходит для данного теста или любого числа больше 9).lambda
байт? Гольф и исправление для 66 байтовPython 2 ,
1009389 байт-7 с благодарностью Mr.Xcoder
Попробуйте онлайн!
источник
Haskell , 60 байт
Попробуйте онлайн!
источник
R ,
12110690 байтПопробуйте онлайн!
Сэкономили 15 байтов, поняв, что
rep()
приведут к числовому. Сохранено еще 16 благодаря Джузеппе, в основном благодаря использованиюpmax
для замены пустых строк на1
источник
ifelse(x>"",x,1)
это байты короче, а\\D
это эквивалентно[^\\d]
и лучше всего, вам не нужноperl=T
, так это сладкие 99 байт . Я действительно не думал, что это может быть меньше, чем 100 байтов!pmax
pmax
дать хорошее большое улучшение - спасибо!"1"
на,1
какpmax
приведитеcharacter
для сравнения.PowerShell ,
6662 байтаПопробуйте онлайн!
Сломать
Какой беспорядок!
Начиная с
$args
, который является массивом из одного элемента, содержащего строку RLE, я добавляю фактическую строку, заключая ее в кавычки.Затем разделите его по границе слова (
\b
в регулярном выражении). Это даст мне массив строк, где каждый элемент является либо номером, либо токеном (ами) BF, которые идут после числа. Таким образом , в примере, первые 4 элемента этого массива являются сплит10
,+]>+>
,3
,+>
(все строки).Затем я передаю это в
ForEach-Object
(%
) для работы с каждым элементом .Середина - хорошо известный гольфизм PowerShell с изюминкой; по сути это троичный оператор DIY, в котором вы создаете массив из 2 элементов, а затем индексируете его, используя логическое выражение, которое вы хотите проверить, в результате чего ложный результат дает вам элемент 0, а истинный результат дает вам элемент 1.
В этом случае я фактически создаю массив из одного элемента с унарным
,
оператором запятой , потому что я не хочу выводить в истинном случае.Сначала давайте посмотрим на индексатор, хотя он будет выполнен позже.
Идея этого в том, что
$_
(текущий элемент) может быть допустимым числом или какой-либо другой строкой. Если это число, я хочу$n
быть значением этого числа минус 1 (как число, а не строка). Если это не так, я хочу$n
быть ложным.PowerShell обычно пытается привести правое значение к типу левой стороны, но это может зависеть от операции. Кроме того,
"10"+5
даст вам новую строку"105"
, тогда как10+"5"
даст вам целое число (15
).Но строки не могут быть вычтены, поэтому вместо этого PowerShell может автоматически вывести числовое значение со строкой в левой части вычитания, поэтому
"10"-5
дает5
.Итак, я начинаю с того
$_-1
, что$_
я получу желаемое число, когда на самом деле это число, но когда это не так, я ничего не получаю. На первый взгляд «ничто» не является ложным, но проблема в том, что он останавливает выполнение этого присваивания, поэтому$n
сохраняет свое прежнее значение; не то, что я хочу!Если я обернуть его в подвыражения, а затем , когда это не удается, я получаю свою ценность falsey:
$($_-1)
.Все это присваивается,
$n
и поскольку это присваивание само заключено в круглые скобки, значение, которое было присвоено,$n
также передается в конвейер.Поскольку я использую его в индексаторе и хочу,
1
чтобы преобразование прошло успешно, я использую два логическихnot
выражения!!
для преобразования этого значения в логическое. Успешное преобразование чисел заканчивается как истина, в то время как ничтожность не дает нам того сладкого, сладкого,0
что позволяет вернуть единственный элемент в этом поддельном троичном массиве.Возвращаясь к этому массиву, элемент выглядит так:
$("$($_[0])"*$n*$_)
$(,$_[0]*$n+$_)
"$($_[0])"
- это надоедливо долгий способ получить первый символ текущего элемента (скажем, получить+
из+[>+
), но как строку, а не как[char]
объект. Мне нужно, чтобы это была строка, потому что я могу умножить строку на число, чтобы дублировать ее, но я не могу сделать это с символом.На самом деле мне удалось сохранить 4 символа, используя
[char]
массив вместо строки (используя другую унарную запятую,
), поэтому я смог удалить кавычки и дополнительное подвыражение. Я могу умножить массив, чтобы дублировать его элементы. И поскольку весь результат этой итерации в любом случае оказывается массивом, и его необходимо-join
редактировать, использование массива здесь не требует дополнительных затрат.Затем я умножаю этот массив
строкна$n
, чтобы дублировать его$n
раз. Напомним, что это$n
может быть$null
или это может быть значение предыдущих цифр минус один.Затем
+$_
добавляет текущий элемент в конец дублированного первого символа этого элемента. Вот почему$n
минус один.Таким образом, в
10+[>+
итоге получается$n
равным 9, затем мы делаем 9+
и добавляем это обратно в+[>+
строку, чтобы получить необходимые 10, а также другие отдельные элементы для поездки.Элемент обернут в подвыражение,
$()
потому что, когда$n
есть$null
, все выражение терпит неудачу, таким образом создание массива терпит неудачу, таким образом, индексатор никогда не выполняется, поэтому$n
никогда не назначается.Причина, по которой я использовал этот троичный трюк, заключается в одной из его особенностей: в отличие от реального троичного оператора, выражения, определяющие элементы , оцениваются независимо от того, «выбраны» они или нет, и сначала в этом отношении.
Поскольку мне нужно назначить, а затем использовать
$n
на отдельных итерациях, это полезно. Значение элемента троичного массива оценивается с использованием значения предыдущей итерации$n
, затем индексатор переназначает$n
для текущей итерации.Таким образом,
ForEach-Object
циклы в итоге выводят все, что должны (куча ошибок, которые мы игнорируем), но в виде массива новых строк.Так что все это заключено в круглые скобки, а затем предшествует унарный,
-join
чтобы получить строку вывода.источник
QuadR , 17 байт
Попробуйте онлайн!
Спасибо Adám за предоставление правильной версии кода.
Как это устроено:
источник
'\d+.'⎕R{¯1((⍎↓)⍴↑)⍵.Match}
Протон , 50 байт
Попробуйте онлайн!
источник
Java 8, 148 байт
Проклятыерегулярные выражения Java иногда так бесполезны .. В прошлый раз это былоотсутствие использования группы захвата"$1"
для чего-либо, теперь это .. Я хочу заменить3c
наccc
или000c
наccc
как однострочника, но , к сожалению , Java не имеет возможности делать это без петля. Ах хорошо.Объяснение:
Попробуй это здесь.
источник
Haskell , 84 байта
Попробуйте онлайн!
Объяснение:
span(`elem`['0'..'9'])s
разбивает данную строкуs
на префикс цифр и остаток. Соответствие результата в шаблоне(n:m,x:r)
гарантирует, что префикс цифры не пуст и привязывает символ после цифр к,x
а остаток кr
.x<$[1..read$n:m]
читает строку цифрn:m
как число и повторяетx
это много раз. Результат объединяется с рекурсивной обработкой оставшейся строкиr
.источник
R 151 байт
Outgolfed пользователем 2390246 ! В настоящее время это в основном мусорный подход по сравнению с этим, но я буду продолжать его совершенствовать.
Попробуйте онлайн!
Также выводит кучу предупреждений.
Далее, посмотрим, является ли использование
grep
более эффективным, чемsubstr
источник
JavaScript (ES6), 46 байт
Довольно простое объяснение:
источник
Рубин , 35 байт
Попробуйте онлайн!
источник
Нетипизированное лямбда-исчисление , 452 байта
Вход и выход состоят из правильных списков закодированных церковью кодов символов, , например, код символа новой строки равен 10, поэтому кодировка церкви будет такой
λf.λx.f(f(f(f(f(f(f(f(f(f x)))))))))
. Преобразование "ABCD" в список выглядит,λf.λx.f 65 (f 66 (f 67 (f 68 x)))
но с цифрами, закодированными церковью.Применение закодированной строки к программе и ее полное сокращение должно дать вам закодированную строку вывода с примененным RLE.
источник
qλq
запись? Я никогда не видел этого раньше.трусливый , 42 байта
Попробуйте онлайн!
источник
C ++,
239235 байт-4 байта благодаря Захари
источник
g=(g?g:1)
наg+=!g
? Если это не сработает, вы не можете убрать круглые скобкиg?g:1
Dart, 78 байтов (с регулярным выражением), 102 байта (без регулярного выражения)
С регулярным выражением:
Без регулярных выражений:
Оба должны быть вызваны как
(<code here>)("input string")
.Regex one довольно стандартен, но без регулярных выражений совершенно особенный.
Без регулярных выражений злоупотребляет необязательными параметрами для размещения локальных переменных в функции «одиночного возврата», в противном случае вам потребуется создать блок и иметь ключевое слово return. Для каждой единицы кода, если единица кода находится между 0 и 9, она накапливается
n
и возвращается пустая строка. В противном случае символ умножается на значениеn
(в специальном регистре, если n == 0, в этом случае он всегда будет испускать 1 символ), иn
устанавливается в 0. Устанавливает(n=0*(c=n))+c
аргумент кода char в значениеn
, умножаетсяn
/c
на 0 , сохраняет от 0 доn
, затем добавляетc
. Это сбрасывает наши,n
не находясь в контексте заявления.источник
Python3, 96 байт
Я пробовал другую реализацию в Python, но я не разбил /codegolf//a/146923/56846 :(
источник