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).


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..]).


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)
}

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 .


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


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!


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


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,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.