Rozwiń zakodowany ciąg

18

Istnieje klasyczne kodowanie i dekodowanie długości przebiegu.

input   output
a3b2c5  aaabbccccc

I to dość proste i zrobione wcześniej.

Wyzwanie polega również na uwzględnieniu niestandardowego zachowania, gdy wiele znaków poprzedza długość przebiegu ( jedna cyfra od 0–9). Każdy znak przed cyfrą długości przebiegu (ostatnią cyfrą przed cyfrą lub końcem ciągu) ma tę wartość przypisaną do niej indywidualnie i drukowaną w kolejności.

Niektóre wejścia i wyjścia testowe, w tym niektóre przypadki zbocza:

input   output
ab3c5   aaabbbccccc
a0b3    bbb  
13b1    111b
a13b1   aaa111b
a123b1  aaa111222b
aa2a1b1 aaaaab
  • Po sekwencji znaków ( [a-zA-Z0-9]+) musi następować długość jej przebiegu ( [0-9])
  • Należy brać pod uwagę tylko prawidłowe dane wejściowe ( ([a-zA-Z0-9]+[0-9])*)
    • tak, pusty ciąg jest prawidłowym wejściem.
  • Wejście odbywa się przez standardowe wejście, wyjście przez standardowe wyjście

To jest kod golfowy, liczba bajtów określa zwycięzcę.


źródło
@AlexA. Poprawny. Jest kilka esolangów, które lubię oglądać od czasu do czasu, które w przeciwnym razie są karane przez liczbę bajtów. (Z pewnością jestem otwarty na sugestie, dlaczego liczenie w ten sposób może być błędem)
4
@MichaelT Punktowanie według znaków zdecydowanie zachęca do kompresji kodu źródłowego do UTF32, co pozwala na kodowanie do 4 bajtów na znak, ale jest całkowicie nieczytelne.
isaacg
@isaacg fair 'nuff. Będę edytować, aby zmienić na bajty. Zastanowię się nad sposobem wyrażenia stylu sclipting, aby był akceptowalny dla przyszłych wyzwań.
Czy przesłanie ma się zakończyć bezbłędnie, jeśli dane wejściowe to pusty ciąg? Zgoda na meta jest to, że wyjście na stderr mogą być ignorowane, ale skoro wyraźnie wspomniał, muszę zapytać.
Dennis
@Dennis pusty ciąg znaków powinien zostać zatrzymany. Nie powinien wchodzić w nieskończoną pętlę ani drukować innego tekstu na standardowe wyjście.

Odpowiedzi:

3

Pip, 22 + 1 = 23 bajty

Używa -rflagi. Zauważ, że wymaga to albo 1) wprowadzenia EOF po wejściu (Ctrl-D w systemie Linux, Ctrl-Z w systemie Windows) lub 2) potokowania wejścia z innego miejsca.

(^_@<v)X_@vMa@`\D*\d+`

Wyjaśnienie:

                        a is first line of stdin (from -r flag) and v is -1 (implicit)
              `\D*\d+`  Pattern (regex) object that matches zero or more non-digits
                        followed by at least one digit
            a@          Find all non-overlapping matches in a, returning a list of strings
           M            To that list, map a lambda function:
  _@<v                    Argument sans last character (equivalent to Python a[:-1])
(^    )                   Split into a list of characters
        _@v               Last character of argument
       X                  Repeat each character of the list that many times
                          (String multiplication X, like most operators, works item-wise
                          on lists)
                        Auto-print (implicit)

Rezultatem operacji mapowania jest w rzeczywistości lista list, ale domyślnie listy są po prostu łączone podczas drukowania, więc nie jest wymagana ręczna konwersja na ciąg.

Przykład z wejściem a13b1:

Var a gets        "a13b1"
After regex match  ["a13" "b1"]
After map          [["aaa" "111"] ["b"]]
Final output       aaa111b

Pip ma podstawową obsługę wyrażeń regularnych od… 2 dni temu . Świetny czas!

DLosc
źródło
Ten działa (podobnie jak master) z -rflagą. (Pytanie określa, że ​​dane wejściowe muszą pochodzić ze STDIN.)
Dennis
@Dennis Oops, przegapiłem to. Dodano flagę do liczby bajtów. Powinienem był być w stanie użyć specjalnej zmiennej qzamiast abez dodatkowych flag, ale wydaje się, że jest błąd i dwukrotnie pyta o dane wejściowe.
DLosc
Wreszcie język golfa z obsługą wyrażeń regularnych!
Dennis
@Dennis Widzę, że teraz przechodzisz na pip!
Optymalizator
8

Perl / Bash 54 40 + 1 = 41 bajtów

perl -pe's:(\D*\d*)(\d):"\$1=~s/./\$&x$2/egr":ege'

Zasadniczo jest to wyrażenie regularne w wyrażeniu regularnym. I trochę magii.

Wyjaśnienie

Wyrażenie zewnętrzne /(\D*\d*)(\d)/gwyodrębnia każdą zakodowaną grupę przebiegów. Przechwytujemy rzeczy do powtórzenia $1i liczbę powtórzeń $2. Teraz podstawiamy każdą taką grupę ekspansją tej grupy. W tym celu oceniamy kod "\$1=~s/./\$&x$2/egr" dwa razy (jak za pomocą /eeflagi na zewnętrznym podstawieniu).

Pierwsza ocena interpoluje tylko liczbę powtórzeń w ciągu - pozostałe zmienne są chronione odwrotnym ukośnikiem. Przyjmując dane wejściowe a14, otrzymalibyśmy kod $1=~s/./$&x4/egr, który zostanie ponownie oceniony.

Spowoduje to zastosowanie podstawienia do treści $1(rzeczy do powtórzenia a1). Podstawienie pasuje do każdego znaku .. $&Zmienna posiada cały mecz, który powtarzamy x4razy. Robimy to /globalnie dla każdego dopasowania i /rzwracamy podstawiony ciąg zamiast modyfikować $1zmienną (która jest tylko do odczytu). Tak więc wynikiem wewnętrznej substytucji jest aaaa1111.

-pFlaga zastosuje zmiany do każdej linii wejścia i wypisuje wynik.

amon
źródło
3
Zwyczajowo ocenia się to jako rozwiązanie Perla, w którym dodaje się 1 bajt dla -pmodyfikatora. Liczę 45 bajtów. Ponadto powinieneś być w stanie używać \Dzamiast [a-z], co również wyeliminowało potrzebę i.
Dennis
7

CJam, 33 31 27 bajtów

Uhh, brak wyrażeń regularnych sprawia, że ​​to dość długo ...

qN+{:XA,s&L\:L>{])~e*[}&X}%

Jak to działa

Przechodzimy przez wszystkie znaki ciągu wejściowego i w każdej iteracji śledzimy ostatnio napotkany znak (zaczynając od pustego znaku po raz pierwszy). Następnie sprawdzamy, czy bieżący znak nie jest liczbą, a ostatni znak jest liczbą. Jeśli tak, to powtarzamy każdy poprzedni znak (który jeszcze się nie powtórzył) liczbę razy.

(Nieco przestarzałe rozszerzenie kodu)

q{                       }%        e# Read the input (q) and loop through each character
  L                                e# Put variable L (initially empty character) on stack
   A,                              e# Put variable A (equals 10) and create an array 0..9
     s                             e# Convert the array to string "0123456789"
      &                            e# Do a set intersect b/w previous char and 0-9 string
                                   e# If numeric, it gives 1 char string, otherwise 0
       \:LA,s&                     e# Swap to bring current character on top. Store it in L
                                   e# and do the same set intersect with it
              >                    e# Means we are checking that current char is non-numeric
                                   e# and previous numeric
               {      }&           e# Run this block if above is true
                ])~                e# Wrap everything not already repeated in an array and
                                   e# take out the last character and convert it to integer.
                                   e# This is the run length of the preceding string
                   e*              e# Repeat each character in the string, run length times
                     [             e# Start a new array to help when next run length is found
                        L          e# Restore the current character back on stack to be used
                                   e# in next iteration
                           )~e*    e# The last string-run-length pair is not decoded..
                                   e# So we do that now

Wypróbuj online tutaj

Optymalizator
źródło
Doceniam pokaz problemu, który powoduje kwalifikator bajtów. Dziękuję Ci. Zastanawiam się trochę, jak sformułować kwalifikację tak, aby języki, w których pojedyncza instrukcja jest znakiem wielobajtowym, nie były karane za ten styl języka bez umożliwienia kodowania UTF, które pokazałeś, aby dostać się przez lukę. PS Naprawdę lubię widzieć podział algorytmów, który podajesz.
6

rs , 43 71 znaków

Cóż, to szybko się zmieniło. Głupie liczby ...

(\d)(\D)/\1 \2
+(\w)(\w+?)(\d)(?= |$)/\1\3 \2\3
(\w)(\d)/(\1)^^(\2)
 /

Wypróbuj tutaj!

Wersja oryginalna (nie działała z danymi wejściowymi podobnymi do 123 ):

+(\D)(\D+)(\d)/\1\3\2\3
(\D)(\d)/(\1)^^(\2)

Wyjaśnienie

Pierwszy wiersz umieszcza spacje między seriami zawierającymi liczby, np. Zwrot a313 wa3 13 .

Druga linia w sposób ciągły rozszerza skompresowane kodowanie aa5 to a5a5.

Trzecia linia przekształca każde wystąpienie a5w aaaaaużycie operatora powtarzania .

Ostatni wiersz usuwa spacje.

kirbyfan64sos
źródło
Jak sobie z tym radzi a123b1?
Optymalizator
@Optimizer Nie dobrze. Muszę go trochę ulepszyć ...
kirbyfan64sos
@Optimizer Naprawiono.
kirbyfan64sos
5

JavaScript ( ES6 ), 86 83 bajtów

alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>b.replace(/./g,y=>y.repeat(c))))

Skomentowano:

alert( // output final result
    prompt(). // take input
    replace(/(.+?)(\d)(?!\d)/g, // replace ungreedy capture group of any characters 
                                // followed by a digit (captured)
                                // and not followed by a digit (negative lookahead)
        (a, b, c)=> // replace with a function
            b.replace(/./g, // replace all characters in b
                y=>y.repeat(c) // with that character repeated c times
            )
    )
)
nderscore
źródło
Czy nie alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(c+1).join(b)))zrobisz tego samego? Ma tylko 71 bajtów.
Ismael Miguel
@ IsmaelMiguel, który działałby tylko wtedy, gdyby przed cyfrą był jeden znak. Funkcja tablic obsługuje powtarzanie każdego znaku osobno.
nderscore
Spróbuj, Array(6).join('12')a wróci '1212121212'.
Ismael Miguel
Ten działa: alert(prompt().replace(/(.+?)(\d)(?!\d)/g,(a,b,c)=>Array(-~c).join(b)))(te same 71 bajtów długości, testowane na es6fiddle.net/ia7gocwg )
Ismael Miguel
1
Znalazłem inny (oczywisty) sposób na powiedzenie 3 bajtów: D
nderscore
4

CJam, 27 25 bajtów

r_'A+1>.{64&1$>{])~f*o}&}

Wypróbuj online w interpretatorze CJam .

Jak to działa

r_                        e# Read a token from STDIN and push a copy.
  'A+                     e# Append the character A to the copy.
     1>                   e# Discard the first character of the copy.
       .{               } e# For each character C of the input string and the
                          e# corresponding character D of the copy:
         64&              e#   Take the bitwise and of D and 64. This pushes @
                          e#   if D is a letter and NUL if it is a digit.
            1$>           e#   Compare the result to a copy of C. This pushes 1
                          e#   if and only if D is a letter and C is a digit.
               {      }&  e#   If the result was 1, do the following:
                ]         e#     Wrap the stack in an array.
                 )~       e#     Pop and evaluate the last character.
                   f*     e#     Repeat each char in the array that many times.
                     o    e#     Print all characters.
Dennis
źródło
3

Pyth, 33 32 28 bajtów

ssmm*vedkPdPcz-hMJf<@zT\=UzJ

Wypróbuj online: Demonstracja lub Uprząż testowa

Wyjaśnienie

Wyjaśnię kod, używając przykładowego wejścia aa1a23b2. Mam nadzieję, że jest to nieco łatwiejsze do naśladowania niż bez.

                               implicit: z = input string = 'aa1a23b2'
                         Uz    the indices of z: [0, 1, 2, 4, 5, 6, 7]
                  f            filter for indices T, which satisfy:
                   <@zT\=        z[T] < "="
                               this gives us the list of indices [2, 4, 5, 7], 
                               which correspond to digits in z. 
                 J             assignment, J = [2, 4, 5, 7]
               hMJ             increment all element in J: [3, 5, 6, 8]
              -            J   and remove the elements of J:
                                 [3, 5, 6, 8] - [2, 4, 5, 7] = [3, 6, 8]
            cz                 split z at these indices: ['aa1', 'a23', 'b2', '']
           P                   remove last element: ['aa1', 'a23', 'b2']
  m                            map each string d to:
   m     Pd                      map each string k of d-without-last-char to:
     ved                           int(last element of d)
    *   k                          * k
                               this creates [['a', 'a'], ['aaa', '222'], ['bb']]
 s                             sum the lists: ['a', 'a', 'aaa', '222', 'bb']
s                              sum the strings: 'aaaaa222bb'
Jakube
źródło
2

Ruby 73

gets.split(/(\d)(?!\d)/).each_slice(2){|s,i|s.chars.map{|c|$><<c*i.to_i}}

Testy: http://ideone.com/L1fssb

Cristian Lupascu
źródło
2

JavaScript 112

alert(prompt().replace(/.*?\d+/g,function(m){for(i=n=m.length-1,o="";i--;){j=m[n];while(j--)o=m[i]+o}return o}))

wolfhammer
źródło
2

Python 2.7, 98 bajtów

import re
print"".join(c*int(m[-1])for m in 
re.findall(r".+?\d(?!\d)",raw_input())for c in m[:-1])

To po prostu wyszukuje wyrażenia regularne dla cyfr, po których nie występuje cyfra, a następnie wykonuje arytmetykę ciągów dla każdej grupy i łączy je wszystkie z powrotem.

rekurencyjny
źródło
Możesz zapisać 2 bajty, przechodząc z Python 2 na 3. raw_inputstaje się, inputale printpotrzebuje nawiasów.
Alex A.
To prawda, ale wolę grać w golfa w Pythonie 2.7.
rekurencyjny
1

Julia, 105 99 95 87 bajtów

s->join([join([string(b)^(int(p[end])-48)for b=chop(p)])for p=matchall(r"\D*\d*\d",s)])

Tworzy to nienazwaną funkcję, która pobiera ciąg znaków jako dane wejściowe i zwraca ciąg znaków. Aby to nazwać, nadaj mu nazwę, npf=s->... .

Używane są tutaj dwa wyrażenia tablicowe, jedno zagnieżdżone w drugim. Zewnętrzne rozumienie działa na każde dopasowanie ciągu wejściowego względem wyrażenia regularnego\D*\d*\d . Wewnętrzne zrozumienie powtarza każdy znak dopasowania zgodnie z cyfrą końcową. Elementy tablicy wewnętrznej są połączone w ciąg, więc tablica zewnętrzna jest tablicą ciągów. Są one łączone i zwracane.

W Julii ciągi znaków można traktować jak tablice znaków. Zauważ jednak, że typy Chari Stringw Julii nie mają zdefiniowanych takich samych metod; w szczególności nie ma metody powtarzania ^znaków. Wykorzystuje to skomplikowane obejście:

  • Pętla nad ciągiem pomijając ostatni znak, który jest usuwany za pomocą chop() .
  • Konwertuj bieżący znak na ciąg za pomocą string().
  • Konwertuj cyfrę końcową, która jest również znakiem, na liczbę całkowitą. Pamiętaj jednak, że na przykładint('4') nie zwraca 4. Raczej zwraca kod, który w tym przypadku wynosi 52. W ten sposób możemy odjąć 48, aby odzyskać rzeczywistą liczbę całkowitą.
  • Powtórz string(b)zgodnie z int(p[end]) - 48.

Przykłady:

julia> f("ab3c5")
"aaabbbccccc"

julia> f("a0b3")
"bbb"

julia> f("13b1")
"111b"
Alex A.
źródło
1

Python 3, 148 144 136 135 bajtów

w,o,r,d=''.join,'',[],[]
for c in input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print(o)

Dzięki Pietu1998 i mbomb007 za sugestie.

Python 2, 161 151 147 139 139 138 bajtów

Może dzisiejszy dzień był długi w pracy, ale nie mogę przez całe życie wymyślić, jak grać w golfa ...

w,o,r,d=''.join,'',[],[]
for c in raw_input()+' ':
 if'/'<c<':':d+=[c]
 elif d:o+=w(x*int(w(d))for x in r);r=[c];d=[]
 else:r+=[c]
print o
Kade
źródło
3
Zmiana na Python 3 oszczędza kilka bajtów ( raw_poza, nawiasy do print). len(d)>0można zastąpić, dponieważ pusta lista jest fałszem, a niepusta lista jest prawdą. list(...)można przejść bezpośrednio do for. Nawiasy kwadratowe w w([...])są niepotrzebne, ponieważ jest to jedyny argument. Możesz usunąć miejsce w ) for. To wszystko, co do tej pory wymyśliłem.
PurkkaKoodari
@ Pietu1998 Dzięki za pomoc!
Kade
Bez zbytniej zmiany podejścia możesz się go pozbyć, list()ponieważ ciągi są iterowalne. Możesz użyć w=r=''. Jeśli chcesz to bardzo zmienić, zobacz moje rozwiązanie. :)
rekursywny
if c.isdigit()może się stać if'/'<c<':', jeśli się nie mylę.
DLosc
@DLosc dzięki, to wydaje się działać.
Kade
0

Java 7, 175 bajtów

String c(String s){String r="",a[];for(String x:s.split("(?<=(\\d)(?!\\d))")){a=x.split("");for(int i=0,j,l=a.length-1;i<l;i++)for(j=0;j++<new Short(a[l]);r+=a[i]);}return r;}

Wyzwanie jest trudniejsze niż się wydaje, imo ..

Kod niepoznany i testowy:

Wypróbuj tutaj.

class M{
  static String c(String s){
    String r = "",
           a[];
    for(String x : s.split("(?<=(\\d)(?!\\d))")){
      a = x.split("");
      for(int i = 0, j, l = a.length-1; i < l; i++){
        for(j = 0; j++ < new Short(a[l]); r += a[i]);
      }
    }
    return r;
  }

  public static void main(String[] a){
    System.out.println(c("ab3c5"));
    System.out.println(c("a0b3"));
    System.out.println(c("13b1"));
    System.out.println(c("a13b1"));
    System.out.println(c("a123b1"));
    System.out.println(c("aa2a1b1"));
    System.out.println(c("123"));
  }
}

Wynik:

aaabbbccccc
bbb
111b
aaa111b
aaa111222b
aaaaab
111222
Kevin Cruijssen
źródło