Interpretator ciągów znaków

11

streszczenie

Wprowadzono nowy język manipulacji ciągami, wykorzystujący tylko znaki $+#-!*|@>! Twoim zadaniem jest zaimplementowanie dla niego interpretera w jak najmniejszej liczbie bajtów.

Wejście

Ciąg, który jest pojedynczą linią tego języka. Można to wziąć w dowolny rozsądny sposób (standardowe, parametr funkcji, argument wiersza poleceń itp.) Lub jako predefiniowaną zmienną. Jeśli program prosi o podanie danych przez użytkownika, zaakceptuj wszystkie dane wprowadzone przez użytkownika od standardowego wejścia i nic więcej, patrz poniżej. Możesz założyć, że jest to prawidłowy program.

Wynik

Bez względu na język, specyfikacje poniżej. Musisz wyprowadzić ciąg znaków w dowolny rozsądny sposób (standardowe wyjście, wyjście funkcji itp.) Lub wartość zmiennej. Gdy język wypisuje jawnie, musi to przejść do standardowego wyjścia. Standardowe luki są zabronione.

Specyfikacje językowe

Przetwarzanie i składnia

Język ma bardzo prostą formę przetwarzania, ponieważ wykonuje jedynie operacje na łańcuchach: zaczyna się od pustego łańcucha ( "") i zmienia go z każdym terminem. Termin składa się z jednej lub dwóch części: funkcji (poniżej), a następnie ewentualnie parametru (poniżej), który edytuje jego zachowanie. Warunki są oddzielone potokami ( |). Możesz założyć, że nie będzie to pusty program i żaden termin nie będzie pusty. Powinieneś wypisać wartość na końcu programu.

Funkcje

Język ma tylko 6 funkcji, jak pokazano poniżej. Każda funkcja akceptuje jeden lub zero parametrów.

  • + konkatenuje łańcuchy (pobiera jeden parametr łańcucha, łączy go z bieżącą wartością)
  • ! odwróć kolejność znaków bieżącej wartości (bez parametru)
  • * powtórz ciąg (pobiera jeden parametr liczby całkowitej, wielokrotnie powtarza bieżącą wartość)
  • - usuwa wszystkie wystąpienia wartości (pobiera jeden parametr ciągu, usuwa wszystkie jego wystąpienia z bieżącej wartości)
  • $ [pseudo-] losowo tasuje bieżącą wartość (bez parametru)
  • <wyślij aktualną wartość do stdout(bez parametrów)

Wartości

Są to wartości, które można przekazać do funkcji, reprezentowane przez wyrażenia regularne, które by do nich pasowały:

  • @[^|]*literał łańcuchowy, w tym dowolny znak inny niż fajka. Może być pusty.
  • #[0-9]+ literał całkowity
  • >następny wiersz stdin. Jeśli jest używany z *, przekonwertuj na liczbę całkowitą.

Przypadki testowe

╔════════════════════════╤═════════════╤══════════════╗
║code                    │input        │output        ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|!|+@hello|*>         │13           │31hello31hello║
║                        │2            │              ║
╟────────────────────────┼─────────────┼──────────────╢
║+>|+@abcdefg|$          │hello        │hcloeebafdlg  ║
╟────────────────────────┼─────────────┼──────────────╢
║+@how areyou|-@o|->     │w            │h areyu       ║
╟────────────────────────┼─────────────┼──────────────╢
║+@out|<|*#3             │             │out           ║
║                        │             │outoutout     ║
╟────────────────────────┼─────────────┼──────────────╢
║+>                      │what ever 345│what ever 345 ║
╟────────────────────────┼─────────────┼──────────────╢
║+@$pe<i@l|<|-@$pe<i@l|+>│A|$o $pe<!@| │$pe<i@l       ║
║                        │             │A|$o $pe<!@|  ║
╟────────────────────────┼─────────────┼──────────────╢
║<|+>|!|<                │input text   |              ║
║                        │             │txet tupni    ║ 
║                        │             │txet tupni    ║
╟────────────────────────┼─────────────┼──────────────╢
║+@>#                    │             |>#            ║
╚════════════════════════╧═════════════╧══════════════╝

Zauważ, że przypadek testowy 2 jest losowy, więc każda kombinacja znaków w nim jest poprawna. Ponadto wyniki w tabeli są oddzielone znakami nowej linii, ale twój program nie musi robić tego samego. Ostatnia wartość w każdym przypadku końcowy wynik.

Przykład (nie golfa) interpretera Pythona

Wypróbuj online! IMO lepiej, jeśli uruchomisz go przez IDLE lub cokolwiek używasz. (Grałem w golfa do 424 bajtów później, ale jestem pewien, że dużo lepiej zrobisz).

Artemida wciąż nie ufa SE
źródło
2
Zezwolenie na wejście w zmienną jest niestandardowe, podobnie jak wyjście w jednym.
Jonathan Allan,
Twoje przykłady wydają się drukować nowy wiersz za każdym razem, gdy <napotkasz. Czy to jest obowiązkowe?
Embodiment of Ignorance
Czy program będzie zawierał nowe linie? Ponieważ jeśli to możliwe, unieważnia odpowiedź Chasa Browna
Embodiment of Ignorance
2
W przypadku przyszłych pytań rozważ rozważ unikanie uciążliwych formatów We / Wy . Ograniczenie wejścia do standardowego wejścia kosztuje dodatkowe bajty w niektórych językach i nie wnosi zbyt wiele do wyzwania.
Arnauld,
1
@digEmAll Jak tam ten, który właśnie dodałem +@>#? Użyłem #również.
Artemis wciąż nie ufa

Odpowiedzi:

3

Rubin -palF\| , 146 142 bajtów

r='';$F.map{|i|x=i[1]!=?>?i[2..-1]:gets.chomp;eval %w[r.reverse! r*=x.to_i 0 $><<r r=r.chars.shuffle*'' r.gsub!x,'' r+=x][i[0].ord*5%11]};$_=r

Wypróbuj online!

Odpowiedź Pythona Port of Chas Brown . Nie drukuje nowych wierszy po wydrukowaniu.

Jak zwykle, wersja Ruby 2.6 będzie o 2 bajty krótsza z nieskończonym indeksowaniem zakresu ( i[2..]).

Kirill L.
źródło
6

R , 287 286 273 269 ​​bajtów

function(C,x='',`[`=gsub,`!`=intToUtf8,`?`=utf8ToInt){for(k in el(strsplit(C,'\\|'))){B=eval(parse(t='^.'['','(?<=.)>$'['readLines(,1)','[@#](.+)'['"\\1"',k],,T]]));x=switch((?substr(k,1,1))%%13-2,strrep(x,B),paste0(x,B),,B['',x,f=T],!rev(?x),print(x),,!sample(?x))};x}

Wypróbuj online!

  • -1 dzięki @Kirill L.
  • -4 dzięki @Giuseppe

Rozwijany kod i objaśnienie:

function(C){                                      # C is the string manipulation expression
  x = ''                                          # initialize x = ''
  tokens = el(strsplit(C,'\\|'))                  # split C by pipe '|'
  for(k in tokens){                               # for each token k
    arg2 = k
    arg2 = gsub('[@#](.+)','"\\1"',k)             # replace @X or #X with "X" (in quotes)
    arg2 = gsub('(?<=.)>$','"readLines(,1)"',
                 arg2,perl=T)                     # replace > with readLines(,1)
    arg2 = gsub('^.','',arg2)                     # remove the first character
    B = eval(parse(t=arg2))                       # evaluate the string : this will be our 
                                                  # second argument B
    A = substr(k,1,1)                             # take the first character : 
                                                  # i.e. the main command (+,-,! etc)
    x = switch(A,                                 # switch on the main command, execute the 
            '+'=paste0(x,B),                      # corresponding expression and 
            '!'=intToUtf8(rev(utf8ToInt(x))),     # store the result into x
            '*'=strrep(x,B),                      # Note: in the actual code we switch on
            '-'=B['',x,f=T],                      # the utf8 value MOD 13-2 of the command
            '$'=intToUtf8(sample(utf8ToInt(x))),
            '<'=print(x)
        )
    }
    x                                             # return x (and print it implicitly)
}
digEmAll
źródło
3

Python 2 , 215 219 209 208 bajtów

from random import*
I=raw_input;o=''
for t in I().split('|'):p=t[1:]=='>'and I()or t[2:];exec"o=o[::-1] o*=int(p) 0 print(o) o=''.join(sample(o,len(o))) o=o.replace(p,'') o+=p".split()[ord(t[0])*5%11]
print o

Wypróbuj online!

-4, ponieważ raw_inputjest wymagane.

9 bajtów dzięki Embodiment of Ignorance ; 1 bajt tylko z Ascii .

Chas Brown
źródło
Dane inne niż program muszą pochodzić ze standardowego wejścia, jak określono w pytaniu.
Artemis nadal nie ufa
Używam Pythona 3, ale o ile wiedziałem, że użycie danych wejściowych wymaga raw_input. Popraw mnie, jeśli się mylę ...
Artemis nadal nie ufa
Zgodnie z dokumentacją Py 2.7: input([prompt])Equivalent to eval (raw_input (prompt)). Ta funkcja nie wychwytuje błędów użytkownika. Jeśli dane wejściowe nie są poprawne pod względem składniowym, zostanie zgłoszony błąd SyntaxError.
Artemis nadal nie ufa
Problem, który poruszasz, przypomina coś tutaj , w którym ciągi wejściowe musiałyby być cytowane - zamiast cytowania, jak w „prawdziwej” sytuacji standardowej. Ponownie zwykle reguły we / wy są nieco luźne; ale zmodyfikuję.
Chas Brown,
Dzięki za zmianę. Możesz zaoszczędzić kilka bajtów, przechodząc na Python 3 i używając starego kodu + 3 bajty w nawiasach, ale ... +1 tak czy inaczej
Artemis nadal nie ufa
2

C # (interaktywny kompilator Visual C #) , 305 bajtów

a=>{string s="",d,g;foreach(var c in a.Split('|')){g=$"{c,2}";d=g[1]==62?ReadLine():g.Substring(2);var z=c[0]%14;s=z<1?string.Concat(Enumerable.Repeat(s,int.Parse(d))):z<2?s+d:z<4?s.Replace(d,""):z<5?s:z<6?string.Concat(s.Reverse()):string.Concat(s.OrderBy(_=>Guid.NewGuid()));Write(z==4?s:"");}return s;}

Wypróbuj online!

Wcielenie ignorancji
źródło
1

Perl 5 -MList::Util=shuffle -pF/\|/ , 220 217 210 183 bajtów

map{$,=s/..//r;$\=reverse$\if/^!/;$,ne""||chomp($,=<>),$\=~s/\Q$,//g if/^-/;say$\if/^</;$\=join"",shuffle$\=~/./g if/^\$/;$\.=$,eq""?<>=~s/\n//r:$,if/^\+/;$\x=$,eq""?<>:$,if/^\*/}@F}{

Wypróbuj online!

Xcali
źródło
1

JavaScript, 292 267 bajtów

f=(p)=>{c='';p.split`|`.map(l=>{v=l.substr(2);v=l[1]=='#'?parseInt(v):l[1]=='>'?prompt():v;c={'+':_=>c+v,'-':_=>c.split(v).join``,'*':_=>c.repeat(v),'$':_=>[...c].sort(_=>.5-Math.random()).join``,'!':_=>[...c].reverse().join``,'<':_=>alert(c)||c}[l[0]]();});return c}

JSFiddle

Johan du Toit
źródło
Przypadek testowy 6 nie do końca działa ...
Artemis wciąż nie ufa
1
@ArtemisFowl, Dzięki, wyrażenie regularne nie działało poprawnie i przejście na split..join pozwoliło zaoszczędzić kilka bajtów.
Johan du Toit,