Dialekt RLE Brainfuck

14

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.

Galen Iwanow
źródło
10
Cześć, przegłosowałem to pytanie, ponieważ uważam, że zostanie zdominowane przez jeden lub dwa algorytmy wyrażenia regularnego oparte na RLE, które są następnie kopiowane do indywidualnego formatowania wyrażeń regularnych w każdym języku. Tutaj jest bardzo mało miejsca na golfa.
AdmBorkBork,
13
To wygląda jak ogólne wyzwanie dekodowania . Różnica polega na tym, że obsługiwane są liczby wielocyfrowe. Wydaje mi się, że to wciąż oszustwo, ale nie będę go wbijać.
xnor
4
@xnor Inną różnicą jest to, że cyfry nie zawsze są obecne - ta forma RLE gwarantuje znacznie mniejszą strukturę, a IMO może prowadzić do interesujących technik (porównaj moją odpowiedź w Pythonie tutaj z tą w powiązanym wyzwaniu!)
Lynn,
1
@ Lynn Nie opisałem tego wprost, ale jak widać w przykładzie, 1 jest zalecany; dodanie 0 nie powoduje, że łańcuch jest krótszy, więc odpowiedź brzmi nie, zero nie może poprzedzać polecenia.
Galen Iwanow
6
Myślę, że inny kierunek byłby bardziej interesujący (tj. Przekształcenie programu pieprzenia mózgu w najkrótszy równoważny program pieprzenia mózgu RLE).
Paŭlo Ebermann

Odpowiedzi:

24

Python 2 , 62 61 bajtów

lambda s:eval(re.sub('(\d*)(.)',r'+1*\1*1*"\2"',s))
import re

Wypróbuj online!

Podstawienie wyrażenia regularnego rozwija 3<2+-się do ciągu:

+1*3*1*"<"+1*2*1*"+"+1**1*"-"

który jest wtedy eval edytowany. (Zauważmy, kiedy \1jest pusty, otrzymujemy 1**1 = 1.) Pierwszy +to jednoargumentowy operator, który wiąże się z pierwszą liczbą, a pozostałe +s łączą łańcuch. To bije bardziej oczywiste

lambda s:re.sub('(\d+)(.)',lambda m:int(m.group(1))*m.group(2),s)
import re

o 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*1lewę. Wcześniej miałem \1Lw wyrażeniu regularnym i zdefiniowałem L=1jako argument lambda, co również jest całkiem fajne:3L jest długim literałem int i Ljest zmienną.

Lynn
źródło
1
To zręczne użycie Ldo obsługi pustego ciągu. Jest krótsza droga choć r'+1*\1*1*"\2"'.
xnor
3
... Dlaczego jest import reponiżej lambda?
Pozew funduszu Moniki
1
Stawianie lambdy na pierwszym miejscu oznacza, że ​​mogę użyć funkcji nagłówka / stopki tio.run, aby pokazać, jak należy wywoływać kod (wstawiam f=\ nagłówek - teraz lambda ma nazwę!)
Lynn
18

Pyt , 2 bajty

r9

Wypróbuj tutaj!

Jak to działa

r9 - Pełny program odbierający String od STDIN.

r - zestaw rozszerzonych operacji na łańcuchach Pytha.
 9 - Dziewiąte polecenie tego zestawu (dekodowanie długości przebiegu). Obsługuje liczby wielocyfrowe.
Pan Xcoder
źródło
31
Niezbędne przypomnienie: Przestań głosować na trywialne rozwiązania (takie jak to).
Pan Xcoder,
4
Wiedzieć o tym poleceniu i nie wiedzieć, że działa ono w przypadku braku liczb
Luis Mendo,
1
@ Mr.Xcoder Poczekaj, co? Czy cały kod golfowy nie ma najmniejszej liczby bajtów?
Deacon
4
@Deacon tak, ale odpowiedź na pytanie w golfa w języku Python jest zwykle trudniejsza do zrobienia i bardziej interesująca niż 2-bajtowa odpowiedź golflang.
Stephen
8
@Deacon Upvoting to nie tylko poprawianie krótkich rozwiązań. Zasadniczo zachęca się użytkowników do głosowania na rozwiązania, które są interesujące i kreatywne, w przeciwieństwie do trywialnych krótkich rozwiązań w językach golfowych.
LyricLy,
17

Lua, 65 64 63 bajtów

Wspaniały ! Po raz pierwszy Lua bije Pythona!

Edycja: Zapisano jeden bajt dzięki @Jarhmander, dzięki za użyteczną sztuczkę wymuszenia pojedynczego wyniku

print(((...):gsub("(%d+)(.)",function(a,b)return b:rep(a)end)))

Wypróbuj online!

Objaśnienia

print)((...):gsub(             -- iterate over the argument and replace the strings
            "(%d+)(.)",       -- matching this pattern (at least one digit and a non-digit)
            function(a,b)     -- capture the digit and non-digit parts in separate variables
              return b:rep(a) -- repeat the non-digit a times, a being the digit part
            end)))                    
Katenkyo
źródło
@ Lynn Jeden bajt w dół, jeszcze 3!
Katenkyo,
Możesz zapisać bajt, usuwając ,""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 ).
Jarhmander,
11

Scala , 73 69 bajtów

"(\\d+)(.)".r.replaceSomeIn(_:String,m=>Some("$2"*m.group(1).toInt))

Wypróbuj online!

oowekyala
źródło
2
To miła odpowiedź! Witamy na stronie. :)
James
8

vim, 29 25 23 22 16 bajtów

:s/\D/a&<C-v><ESC>/g
D@"

<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

Promień
źródło
TheFamilyFroot miał fajną wskazówkę golfową: nie musisz używać grupy przechwytującej, możesz po prostu użyć grupy 0 (&lub\0) zamiast nawiasów. Ponadto, rada ode mnie, nie TheFamilyFroot jest to, że można użyćDzamiastddna-1bajt.
James
1
Dzięki za wszystkie sugestie, H.PWiz, TheFamilyFroot i DJMcMayhem. To sprawiło, że spadło poniżej 18-bajtowego rozwiązania Perl i zajęło drugie miejsce. Teraz musimy tylko znaleźć kolejne 15 bajtów, których możemy się pozbyć, a to pobije wbudowane Pyth. :-)
Ray
8

RLE Brainfuck, 204 bajty

-3>,[[->+>+<<]>>47-3<10+<->[-<+4>->+<[>-]>[3<+<[-]4>->]5<]3>57+[-]+<<[>>-<<[3>+3<-]]3>[3<+3>-]<[>>+7<+[->11-<+[-<+]->>+[-<[->10+<]>>+]<[-4>.4<]4>[-]-3<-<+7>-7<[8>+8<-]]8>[8<+8>-]<[3<.3<[-]-6>-]7<--5>-]<,]

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:

->>>,
[
  [->+>+<<]>>  clone 2 into 3 and 4
  if read char is between zero and nine
  (num buffer | max | is_digit | original char | read | temp0 | temp1)
                                                   ^
  47-
  <<<10+  set max
  <->  handle gross 0 case
  [  while max
    -  max minus one
    <+  buffer plus one
    >>>>-  read minus one
    IF STATEMENT : if read is 0
    >+<
    [>-]>[<
      <<+  is_digit = 1
      <[-]>>>  max = 0
    >->]<<  back to read
    <<<     back to max
  ]

  >>>57+[-]  reset `read` (need to add first to avoid infinite negative)

  +<<  check is_digit flag
  ( end marker | 0 | is_digit | original char | temp0 | temp1 | temp2 | temp3)
  x[  IF READ WAS DIGIT
    CODE 1a
    >>temp0 -<<x
    [>>>temp1 +<<<x-]
  ]
  >>>temp1 [<<<x+>>>temp1 -]
  <temp0 [
    START CODE 2a
    >>temp2 +
    7<y+[  IF THERE IS A NUMBER PREFIX
      -
      START CODE 1b
      >11-  end marker is negativeone
      <   on smallest digit
      +[-<+]->  find largest digit
      >+[  sum digits until we hit the end marker negativeone
        -
        <[->10+<]>  h1 = ten * h0; h0 = 0
        >
        +
      ]  leave the negativeone at zero though
      num | 0 | 0 | 0 | original char
            ^
      <num
      [->>>>.<<<<]  print `original char` `num` times
      >>>>[-]-  set `char` to negativeone
      <<<- last ditch guess
      END CODE 1b
      <y+
      7>temp2 -
      7<y[8>temp3 +8<y-]
    ]
    8>temp3 [8<y+8>temp3 -]
    <temp2 [
      CODE 2b
      <<<.  print original char
      <<<[-]-  set num buffer to new left edge
      >>>>>>temp2 -
    ]
    7<y--

    END CODE 2a
    5>temp0 -
  ]
  <
  ,
]
Orez
źródło
Czy przypadek brutto 0 odnosi się tylko do faktycznych zliczeń zerowych, czy też dzieje się tak również podczas analizowania, np. 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.
Ray
Przypadek brutto 0 służy do parsowania dowolnego 0. Ponieważ while maxpę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 bufor value+1🤔
Orez
6

Ułożone , 24 bajty

['(\d+)(.)'[\#~*]3/repl]

Wypróbuj online!

Wyjaśnienie

['(\d+)(.)'[\#~*]3/repl]
[                      ]   anonymous function, taking string as argument
 '(\d+)(.)'                for all matches of this regex:
           [    ]3/repl      replace (stack = (whole match, digit, repetend))
            \#~              convert digit to number
               *             repeat the character by that digit
Conor O'Brien
źródło
5

TeX, 124 bajty

\newcount\n\def\b{\afterassignment\r\n0}\def\r#1{\ifx;#1\else\p#1\expandafter\b\fi
}\def\p#1{#1\ifnum\n>1\advance\n-1\p#1\fi}

(napisano w dwóch wierszach, aby były widoczne, ale kod można zapisać w jednym wierszu)

Definiuje to makro, \bktóre pobiera dane wejściowe w formularzu \b<input>;i drukuje dane wyjściowe, które są potrzebne do dokumentu.

Manuel
źródło
5

Retina , 28 23 bajtów

dzięki @Leo za -5 bajtów

\d+
$*
+`1(1\D)
$1$1
1

Wypróbuj online!

ovs
źródło
Czy możesz użyć \bw drugim wyrażeniu regularnym, aby dopasować tylko jeden 1na serię 1s?
Neil,
Or you could do something like this
Leo
4

Pyon, 66 bytes

print(re.sub("\d+.",lambda k:(int(k.group()[:-1])*k.group()[-1]),a

Try it online!

Pyon is pretty much just Python, but this is shorter because re is automatically imported when you use it, and a is automatically set to an argument or the input

-4 bytes thanks to Mr. Xcoder

HyperNeutrino
źródło
You should change g[0] to g[:-1] (fails for the given test case or any number higher than 9).
Mr. Xcoder
Anyway why would you even need a lambda which actually wastes bytes? Golfed and corrected for 66 bytes
Mr. Xcoder
@Mr.Xcoder whoops, not sure what I was thinking... thanks
HyperNeutrino
@Mr.Xcoder oh yeah I try to golf things a lot that end up being ungolfs xD
HyperNeutrino
4

Python 2, 100 93 89 bytes

-7 with thanks to Mr.Xcoder

n=b=""
for y in input():
 if"/"<y<":":n+=y
 elif""==n:b+=y
 else:b+=y*int(n);n=""
print b

Try it online!

ElPedro
źródło
A few golfs for 93 bytes. It can be golfed further though.
Mr. Xcoder
3

R, 121 106 90 bytes

function(s,a=strsplit)cat(rep(el(a(gsub("\\d","",s),"")),pmax(el(a(s,"\\D")),"1")),sep="")

Try it online!

Saved 15 bytes by realising that rep() will coerce to numeric. Saved another 16 thanks to Giuseppe, mainly from the use of pmax to replace empty strings with 1

function(s) {
  x <- el(strsplit(s,"\\D")) # Split the string on anything that is not a digit...
  x <- pmax(x, "1")          # ... and replace any empty strings with 1. This gets us the numbers of repeats
  y <- gsub("\\d","",s)      # Remove all digits from the original string...
  y <- el(strsplit(y))       # ... and split into individual units. This gets us the symbols to repeat
  z <- rep(y, x)             # Implement the repeats. x is coerced to numeric
  cat(z, sep = "")           # Print without separators
}
user2390246
źródło
very nice! I believe ifelse(x>"",x,1) is a byte shorter, and \\D is equivalent to [^\\d] and best of all, you don't need perl=T, so this is a sweet 99 bytes. I really didn't think this could be fewer than 100 bytes!
Giuseppe
@Giuseppe Very clever use of pmax giving a nice big improvement - thanks!
user2390246
replace "1" with 1 as pmax will coerce to character for the comparison.
Giuseppe
85 bytes by changing the aliases
Giuseppe
2

PowerShell, 66 62 bytes

-join("$args"-split'\b'|%{(,$(,$_[0]*$n+$_))[!!($n=$($_-1))]})

Try 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 are 10,+]>+>,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", whereas 10+"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 gives 5.

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, sweet 0 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 -joined, using an array here incurs no additional cost.

Then, I multiply that string array 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.

briantist
źródło
1
Great explanation, that alone warrants an upvote already.
Mast
1
Thanks @Mast, and because of your comment I looked over my answer again and realized how I could save 4 bytes.
briantist
2

QuadR, 17 bytes

\d+.
¯1((⍎↓)⍴↑)⍵M

Try it online!

Thanks to Adám for providing the correct version of the code.

How it works:

\d+.           Regex to match any sequence of digits followed by a character.
¯1((⍎↓)⍴↑)⍵M   Transformation line
¯1(      )⍵M   Arguments: -1 and the matching expression
   ( ↓)        'Drop' the last item (-1) from the match (⍵M), yielding a string which is a sequence of digits.
              Execute. In this case, it transforms a string into a number.
              'Take' the last item (-1) from the match (⍵M), yielding a character.
              Reshape it. That will take the character resulting from the 'Take' operation and repeat it n times,
               where n is the result from the 'Drop' and 'Execute' operations.
J. Sallé
źródło
Equivalent to the APL function '\d+.'⎕R{¯1((⍎↓)⍴↑)⍵.Match}
Adám
1

Java 8, 148 bytes

s->{for(s=s.format(s.replaceAll("(\\d+)","%1\\$0$1d"),0);!s.matches("\\D+");s=s.replaceAll("0(\\D)","$1$1"));return s.replaceAll("((.)+)\\2","$1");}

Gdamn Java regexes are so useless sometimes.. Last time it was lack of using the capture group "$1" for anything, now this.. I want to replace 3c with ccc or 000c with ccc as a one-liner, but unfortunately Java has no way of doing this without a loop. Ah well.

Explanation:

Try it here.

s->{                          // Method with String as both parameter and return-type
  for(s=s.format(s.replaceAll("(\\d+)","%1\\$0$1d"),0);
                              //  Replace every numbers of that many zeroes
                              //  (i.e. "3>2+" -> "000>00+")
      !s.matches("\\D+");     //  Loop as long as the String contains zeroes
    s=s.replaceAll("0(\\D)",  //   Replace every 0 followed by a non-0 character,
                   "$1$1")    //   with two times this captured non-0 character
  );                          //  End of loop
  return s.replaceAll("((.)+)\\2","$1");
                              //  Reduce every repeated character amount by 1,
                              //  and return this as result
}                             // End of method
Kevin Cruijssen
źródło
1
Hi Kevin, good to see you here, dealing with puzzles other than twisty :)
Galen Ivanov
@GalenIvanov Oh, hi! I had no idea you were active on PPCG as well.
Kevin Cruijssen
I wasn't until recently :) I'm learning J and decided that this is a good opportunity to test my skills.
Galen Ivanov
1

Haskell, 84 bytes

f s@(x:r)|(n:m,x:r)<-span(`elem`['0'..'9'])s=(x<$[1..read$n:m])++f r|1<3=x:f r
f e=e

Try it online!

Explanation:

span(`elem`['0'..'9'])s splits the given string s 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 to x and the remainder to r. x<$[1..read$n:m] reads the string of digits n:m as number and repeats x that many times. The result is concatenated to the recursive treatment of the remaining string r.

Laikoni
źródło
1

R, 151 bytes

Outgolfed by user2390246! This is now basically a garbage approach compared to that one, but I'll continue to improve it.

function(s,G=substr)for(i in el(strsplit(gsub("(\\d+.)","!\\1!",s),"!")))cat("if"(is.na(g<-as.double(G(i,1,(n=nchar(i))-1))),i,rep(G(i,n,n),g)),sep='')

Try it online!

Also outputs a bunch of warnings.

function(s){
s <- gsub("(\\d+.)","!\\1!",s)               # surround groups with !
X <- el(strsplit(s,"!"))                   # split to groups
for( i in X ){                             # iterate over groups
 n <- nchar(i)                             # length of group
 r <- substr(i,1,n-1)                      # potential number (first n-1 chars)
 d <- substr(i,n,n)                        # last character
 if( is.na(as.double(r)) ){                # if it's not a number
   cat(i)                                  # print out the whole string
  } else {
   cat(rep(d,as.double(r)),sep="")         # repeat d r times, and print with no separator
  }
 }
}

Next up, seeing if using a grep is more efficient than substr

Giuseppe
źródło
A different approach
user2390246
1

JavaScript (ES6), 46 bytes

a=>a.replace(/(\d+)(.)/g,(_,n,b)=>b.repeat(n))

Pretty straightforward explanation:

a=>a.replace(/(\d+)(.)/g,                      // Match globally the following: a number N followed by a character
                         (_,n,b)=>b.repeat(n)) // Replace each occurrence by the matched character repeated N times
XavCo7
źródło
1

Ruby, 35 bytes

->s{s.gsub(/(\d+)(.)/){$2*$1.to_i}}

Try it online!

Alex
źródło
1

Untyped Lambda Calculus, 452 bytes

(λp.λq.(λb.λg.(λi.(λp.λq.λb.p q b)(q(λq.λj.λl.j((λq.λj.qλq.λl.(λu.g i j(λp.u)(g j(λq.λg.q(b(p(λp.λq.p q))(p(λp.λq.p(p q)))q g))(λp.u)(λu.u qλq.λu.g j i q(b l(p(λp.λq.p(p(p(p q)))))q u))))λp.p(λp.λb.q p((λp.λq.l(λp.l)(λp.λq.p q)(λq.p j q)q)p b))λp.λp.p)l q))(λp.p)(λp.p(λp.λp.p)λp.λp.p)(λp.λq.p)))(b(p(λp.λp.p))(p(λp.λq.p(p q)))))(λp.λq.λb.p(q b))λp.λq.q(λp.λq.λb.p(λp.λb.b(p q))(λp.b)λp.p)p)λp.λq.λb.q(q(q(q(q(q(p q b))))))

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.

PixelToast
źródło
1
Hello and welcome to the site! This looks like an interesting solution but we do expect languages to have a valid interpreter, do you have one of Untyped Lambda Calculus?
Post Rock Garf Hunter
Also, what does the qλq notation mean? I've never seen that before.
Zacharý
1

C++, 239 235 bytes

-4 bytes thanks to Zacharý

#include<regex>
using s=std::string;std::regex m("[0-9]*[<>+.,\\[\\]-]");s t(s r){s d,h;std::sregex_iterator i(r.begin(),r.end(),m),e;while(i!=e){h=(*i)[0];int g=std::strtol(h.data(),NULL,10);g+=!g;d+=s(g,h[h.size()-1]);++i;}return d;}
HatsuPointerKun
źródło
1
Can you change g=(g?g:1) to g+=!g? If that doesn't work, can't you remove the parentheses around g?g:1
Zacharý
0

Dart, 78 bytes (with regex), 102 bytes (without regex)

With Regex:

(i)=>i.splitMapJoin(new RegExp(r"(\d+)(.)"),onMatch:(m)=>m[2]*int.parse(m[1]))

Without Regex:

(i,[n=0,d=0])=>i.codeUnits.map((c)=>i[d++]*((c-=48)>=0&&c<10?0*(n=n*10+c):n<1?1:(n=0*(c=n))+c)).join()

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 of n (special cased if n == 0, in that case it will always emit 1 character) and n is set to 0. (n=0*(c=n))+c sets the char code argument to the value of n, multiplies n/c with 0, stores 0 to n, then adds c. This resets our n without being in a statement context.

Dwayne Slater
źródło
0

Python3, 96 bytes

s,r=input(),""
while s:
 d=0
 while"/"<s[d]<":":d+=1
 r+=int(s[:d] or 1)*s[d];s=s[d+1:]
print(r)

I tried another implementation in Python, but i don't beat /codegolf//a/146923/56846 :(

user285259
źródło