RLE Brainfuck
(związany z BF-RLE )
Hipotetyczny kod RLE ( Run-Length Encoding dialekt ) Brainfuck akceptuje symbole 8 poleceń, a także cyfry. Cyfry są używane do reprezentowania liczby kolejnych powtórzeń polecenia, umożliwiając w ten sposób kodowanie w czasie wykonywania kodu źródłowego.
8>
jest równe >>>>>>>>
.
Długość jest zawsze po lewej stronie polecenia.
Twoim zadaniem jest napisanie najkrótszego programu / funkcji, która tłumaczy łańcuch wejściowy (fragment RLE Brainfuck) na zwykły program Brainfuck.
Na przykład:
Wejście:
10+[>+>3+>7+>10+4<-]3>2+.>+.7+2.3+.2<2+.>15+.>.3+.6-.8-.2<+.<.
Ouptut:
++++++++++[>+>+++>+++++++>++++++++++<<<<-]>>>++.>+.+++++++..+++.<<++.>+++++++++++++++.>.+++.------.--------.<<+.<.
Wygra najkrótszy kod w liczbie bajtów w każdym języku.
Odpowiedzi:
Python 2 ,
6261 bajtówWypróbuj online!
Podstawienie wyrażenia regularnego rozwija
3<2+-
się do ciągu:który jest wtedy
eval
edytowany. (Zauważmy, kiedy\1
jest pusty, otrzymujemy1**1 = 1
.) Pierwszy+
to jednoargumentowy operator, który wiąże się z pierwszą liczbą, a pozostałe+
s łączą łańcuch. To bije bardziej oczywisteo 14 bajtów. Zwykle
"\2"
nie zawsze działało, ale na szczęście\
i"
nie są dowcipami.xnor zapisał bajt, dostarczając
1*\1*1
lewę. Wcześniej miałem\1L
w wyrażeniu regularnym i zdefiniowałemL=1
jako argument lambda, co również jest całkiem fajne:3L
jest długim literałem int iL
jest zmienną.źródło
L
do obsługi pustego ciągu. Jest krótsza droga choćr'+1*\1*1*"\2"'
.import re
poniżej lambda?f=\
nagłówek - teraz lambda ma nazwę!)Pyt , 2 bajty
Wypróbuj tutaj!
Jak to działa
źródło
Lua,
656463 bajtówWspaniały ! Po raz pierwszy Lua bije Pythona!Edycja: Zapisano jeden bajt dzięki @Jarhmander, dzięki za użyteczną sztuczkę wymuszenia pojedynczego wyniku
Wypróbuj online!
Objaśnienia
źródło
,""
i otaczając parens cały argument print. Wyrażenia zawarte w parens są dostosowane do jednej wartości w Lua (patrz lua.org/manual/5.3/manual.html#3.4 ).Scala ,
7369 bajtówWypróbuj online!
źródło
Perl 5 , 18 bajtów
Kod 17 bajtów + 1 dla
-p
.Wypróbuj online!
źródło
vim,
2925232216 bajtów<C-V>
to 0x16,<ESC>
to 0x1b.Działa poprzez zastąpienie każdej cyfry poleceniem, które dołącza ten znak do bufora. Liczby są pozostawione same sobie i modyfikują te polecenia. W tym momencie bufor jest programem vimscript, który produkuje pożądany program Brainfuck, więc pobieramy go do rejestru i uruchamiamy.
Wypróbuj online!
Edycja: Zmniejszenie rozmiaru dzięki sugestiom: H.PWiz: 5, TheFamilyFroot: 5, DJMcMayhem: 1
źródło
&
lub\0
) zamiast nawiasów. Ponadto, rada ode mnie, nie TheFamilyFroot jest to, że można użyćD
zamiastdd
na-1
bajt.RLE Brainfuck, 204 bajty
Rozumiem, że specyfikacje dla środowiska do pieprzenia mózgu nie są bardzo dobrze zdefiniowane. Ten program zakłada, że komórki na taśmie pozwalają na dowolnie duże liczby całkowite dodatnie i ujemne, bez przepełnienia. Ten kod będzie także transkrybował komentarze niepolecane, ale rozszerzy kodowanie komentarzy w czasie wykonywania (np. „Patrz 3b” → „patrz bbb”). Powstały program powinien działać tak samo, więc nie martwię się zbytnio.
Jestem prawie pewien, że mógłbym jeszcze trochę pograć w golfa, ale jestem wykończony pracą z nim.
Oto niestandardowy interpreter + testy, których używałem do testowania. Jeśli przekażesz dane wejściowe w polu Standardowe dane wejściowe, powinno ono działać z tym wejściem zamiast uruchamiać testy.
Mój nieuporządkowany niepochlebny blat roboczy:
źródło
10+
? OP wyjaśnił w komentarzu, że liczba będzie zawsze większa od 0, więc możesz być w stanie zgolić kilka bajtów, jeśli jest to pierwszy.while max
pętla zawsze działa co najmniej raz, a ja bezwarunkowo zwiększam bufor, w którym przechowuję wartość cyfry w tej pętli, muszę uruchomić ten bufor na -1. Zastanawiam się, czy mógłbym zaoszczędzić trochę bajtów, logicznie pozostawiając ten buforvalue+1
🤔Ułożone , 24 bajty
Wypróbuj online!
Wyjaśnienie
źródło
TeX, 124 bajty
(napisano w dwóch wierszach, aby były widoczne, ale kod można zapisać w jednym wierszu)
Definiuje to makro,
\b
które pobiera dane wejściowe w formularzu\b<input>;
i drukuje dane wyjściowe, które są potrzebne do dokumentu.źródło
Retina ,
2823 bajtówdzięki @Leo za -5 bajtów
Wypróbuj online!
źródło
\b
w drugim wyrażeniu regularnym, aby dopasować tylko jeden1
na serię1
s?Pyon, 66 bytes
Try it online!
Pyon is pretty much just Python, but this is shorter because
re
is automatically imported when you use it, anda
is automatically set to an argument or the input-4 bytes thanks to Mr. Xcoder
źródło
g[0]
tog[:-1]
(fails for the given test case or any number higher than 9).lambda
which actually wastes bytes? Golfed and corrected for 66 bytesPython 2,
1009389 bytes-7 with thanks to Mr.Xcoder
Try it online!
źródło
Haskell, 60 bytes
Try it online!
źródło
R,
12110690 bytesTry it online!
Saved 15 bytes by realising that
rep()
will coerce to numeric. Saved another 16 thanks to Giuseppe, mainly from the use ofpmax
to replace empty strings with1
źródło
ifelse(x>"",x,1)
is a byte shorter, and\\D
is equivalent to[^\\d]
and best of all, you don't needperl=T
, so this is a sweet 99 bytes. I really didn't think this could be fewer than 100 bytes!pmax
pmax
giving a nice big improvement - thanks!"1"
with1
aspmax
will coerce tocharacter
for the comparison.PowerShell,
6662 bytesTry it online!
Breakdown
What a mess!
Starting from
$args
, which is a single element array containing the RLE string, I'm forcing into an actual string by wrapping it quotes.Then split it by word boundary (
\b
in regex). That will give me an array of strings, where each element is either a number or the BF token(s) that come after the number. So in the example, the first 4 elements of this split array are10
,+]>+>
,3
,+>
(all are string).Next, I pipe that into
ForEach-Object
(%
) to deal with each element.The middle is a well-known PowerShell golfism, with a twist; it's essentially a DIY ternary operator, in which you create a 2 element array then index into it using the boolean expression you want to test, whereby a false result gives you element 0 and a true result gives you element 1.
In this case, I actually create a single element array with the unary comma
,
operator, because I don't want output in the true case.First let's look at the indexer, even though it gets executed later.
The idea of this is that
$_
(the current element) could either be a valid number, or some other string. If it's a number, I want$n
to be the value of that number minus 1 (as a number, not a string). If it's not, I want$n
to be false-y.PowerShell usually tries to coerce the right-hand value to the type of the left side, but it can depend on the operation. For addition,
"10"+5
would give you a new string,"105"
, whereas10+"5"
will give you an integer (15
).But strings can't be subtracted so instead PowerShell can infer the numeric value automatically with a string on the left side of subtraction, therefore
"10"-5
gives5
.SO, I start with
$_-1
, which will give me the number I want when$_
is actually a number, but when it's not I get nothing. On the surface, "nothing" is falsey, but the problem is that is stops execution of that assignment, so$n
will retain its previous value; not what I want!If I wrap it in a subexpression, then when it fails, I get my falsey value:
$($_-1)
.That all gets assigned to
$n
and since that assignment is itself wrapped in parentheses, the value that was assigned to$n
also gets passed through to the pipeline.Since I'm using it in the indexer, and I want
1
if the conversion succeeded, I use two boolean-not
expressions!!
to convert this value to boolean. A successful number conversion ends up as true, while the falsey nothingness gives us that sweet, sweet0
that allows for returning the only element in that fake ternary array.Getting back to that array, the element is this:
$("$($_[0])"*$n*$_)
$(,$_[0]*$n+$_)
"$($_[0])"
- this is an annoyingly long way of getting the first character of the current element (let's say, getting+
from+[>+
), but as a string and not as a[char]
object. I need it to be a string because I can multiply a string by a number to duplicate it, but I can't do that with a character.Actually I managed to save 4 characters by using a
[char]
array instead of a string (by using another unary comma,
), so I was able to remove the quotes and extra sub-expression. I can multiply an array to duplicate its elements. And since the entire result of this iteration ends up being an array anyway and needs to be-join
ed, using an array here incurs no additional cost.Then, I multiply that
stringarray by$n
, to duplicate it$n
times. Recall that$n
could be$null
or it could be the value of the preceding digits minus one.Then
+$_
adds the current element onto the end of the duplicated first character of that element. That's why$n
is minus one.This way,
10+[>+
ends up with$n
equal to 9, then we make 9+
's and add that back to the+[>+
string to get the requisite 10, plus the other single elements along for the ride.The element is wrapped in a subexpression
$()
because when$n
is$null
, the entire expression fails, so creating the array fails, so the indexer never runs, so$n
never gets assigned.The reason I used this ternary trick is because of one of its peculiarities: unlike a real ternary operator, the expressions that define the elements do get evaluated whether or not they are "selected", and first for that matter.
Since I need to assign and then use
$n
on separate iterations, this is helpful. The ternary array element value gets evaluated with the previous iteration's$n
value, then the indexer re-assigns$n
for the current iteration.So the
ForEach-Object
loops ends up outputting everything its supposed to (a bunch of errors we ignore), but as an array of new strings.So that whole thing is wrapped in parentheses and then preceded by unary
-join
to give the output string.źródło
QuadR, 17 bytes
Try it online!
Thanks to Adám for providing the correct version of the code.
How it works:
źródło
'\d+.'⎕R{¯1((⍎↓)⍴↑)⍵.Match}
Proton, 50 bytes
Try it online!
źródło
Java 8, 148 bytes
GdamnJava regexes are so useless sometimes.. Last time it was lack of using the capture group"$1"
for anything, now this.. I want to replace3c
withccc
or000c
withccc
as a one-liner, but unfortunately Java has no way of doing this without a loop. Ah well.Explanation:
Try it here.
źródło
Haskell, 84 bytes
Try it online!
Explanation:
span(`elem`['0'..'9'])s
splits the given strings
into a prefix of digits and the remainder. Matching on the result on the pattern(n:m,x:r)
ensures that the digit prefix is non-empty and binds the character after the digits tox
and the remainder tor
.x<$[1..read$n:m]
reads the string of digitsn:m
as number and repeatsx
that many times. The result is concatenated to the recursive treatment of the remaining stringr
.źródło
R, 151 bytes
Outgolfed by user2390246! This is now basically a garbage approach compared to that one, but I'll continue to improve it.
Try it online!
Also outputs a bunch of warnings.
Next up, seeing if using a
grep
is more efficient thansubstr
źródło
JavaScript (ES6), 46 bytes
Pretty straightforward explanation:
źródło
Ruby, 35 bytes
Try it online!
źródło
Untyped Lambda Calculus, 452 bytes
Input and output comprise of right-fold lists of church encoded character codes, for example the character code of a newline is 10 so the church encoding would be
λf.λx.f(f(f(f(f(f(f(f(f(f x)))))))))
. Converting "ABCD" to a list looks likeλf.λx.f 65 (f 66 (f 67 (f 68 x)))
but with the numbers church-encoded.Applying an encoded string to the program and reducing it all the way should give you an encoded output string with the RLE applied.
źródło
qλq
notation mean? I've never seen that before.Funky, 42 bytes
Try it online!
źródło
C++,
239235 bytes-4 bytes thanks to Zacharý
źródło
g=(g?g:1)
tog+=!g
? If that doesn't work, can't you remove the parentheses aroundg?g:1
Dart, 78 bytes (with regex), 102 bytes (without regex)
With Regex:
Without Regex:
Both must be invoked like
(<code here>)("input string")
.Regex one is quite standard, but the regex-less one is quite special.
Regex-less abuses optional parameters to allocate local variables in "single return" function, otherwise you'd need to make a block and have the return keyword. For each code unit, if the code unit is between 0 and 9 it is accumulated to
n
and an empty string is returned. Otherwise, the the character is multiplied by the value ofn
(special cased if n == 0, in that case it will always emit 1 character) andn
is set to 0.(n=0*(c=n))+c
sets the char code argument to the value ofn
, multipliesn
/c
with 0, stores 0 ton
, then addsc
. This resets ourn
without being in a statement context.źródło
Python3, 96 bytes
I tried another implementation in Python, but i don't beat /codegolf//a/146923/56846 :(
źródło