String Manipulation Interpreter

11

Zusammenfassung

Es wurde eine neue Sprache zur Manipulation von Zeichenfolgen erstellt, in der nur die Zeichen verwendet werden $+#-!*|@>! Ihre Aufgabe ist es, einen Interpreter dafür in möglichst wenigen Bytes zu implementieren.

Eingang

Eine Zeichenfolge, die eine einzelne Zeile dieser Sprache ist. Dies kann auf jede vernünftige Weise (stdin, Funktionsparameter, Befehlszeilenargument usw.) oder als vordefinierte Variable erfolgen. Wenn das Programm nach Benutzereingaben fragt, akzeptieren Sie alle Benutzereingaben, die es von stdin verlangt, und nichts weiter, siehe unten. Sie können davon ausgehen, dass es sich um ein gültiges Programm handelt.

Ausgabe

Was auch immer die Sprache ausgeben würde, Spezifikationen unten. Sie müssen eine Zeichenfolge auf eine vernünftige Weise (Standardausgabe, Funktionsausgabe usw.) oder einen variablen Wert ausgeben. Wenn die Sprache explizit ausgegeben wird, muss dies zu stdout gehen. Standardlücken sind verboten.

Sprachspezifikationen

Verarbeitung und Syntax

Die Sprache hat eine sehr einfache Form der Verarbeitung, da nur Zeichenfolgen bearbeitet werden: Sie beginnt mit einer leeren Zeichenfolge ( "") und ändert sie mit jedem Begriff. Ein Begriff besteht aus einem oder zwei Teilen: einer Funktion (unten), gefolgt von möglicherweise einem Parameter (unten), der sein Verhalten bearbeitet. Begriffe werden durch Pipes ( |) getrennt. Sie können davon ausgehen, dass es sich nicht um ein leeres Programm handelt und kein Begriff leer ist. Sie sollten den Wert am Ende des Programms ausgeben.

Funktionen

Die Sprache hat nur 6 Funktionen, wie unten gezeigt. Jede Funktion akzeptiert entweder einen oder null Parameter.

  • + Zeichenfolgen verketten (nimmt einen Zeichenfolgenparameter und verkettet ihn mit dem aktuellen Wert)
  • ! kehre die Zeichenreihenfolge des aktuellen Wertes um (kein Parameter)
  • * Wiederholen Sie die Zeichenfolge (nimmt einen ganzzahligen Parameter und wiederholt den aktuellen Wert so oft)
  • - Entfernt alle Vorkommen eines Werts (nimmt einen Zeichenfolgenparameter, entfernt alle Vorkommen davon aus dem aktuellen Wert)
  • $ [pseudo-] mischt zufällig den aktuellen Wert (kein Parameter)
  • <Ausgabe des aktuellen Wertes an stdout(keine Parameter)

Werte

Dies sind die Werte, die an Funktionen übergeben werden können, dargestellt durch einen regulären Ausdruck, der mit ihnen übereinstimmt:

  • @[^|]*Ein String-Literal, einschließlich aller anderen Zeichen als Pipes. Es kann leer sein.
  • #[0-9]+ ein ganzzahliges Literal
  • >die nächste Zeile von stdin. Bei Verwendung mit *in Ganzzahl konvertieren.

Testfälle

╔════════════════════════╤═════════════╤══════════════╗
║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    ║
╟────────────────────────┼─────────────┼──────────────╢
║+@>#                    │             |>#            ║
╚════════════════════════╧═════════════╧══════════════╝

Beachten Sie, dass Testfall 2 zufällig ist, sodass jede Permutation der darin enthaltenen Zeichen gültig ist. Außerdem werden die Ausgaben in der Tabelle durch Zeilenumbrüche getrennt, aber Ihr Programm muss nicht dasselbe tun. Der letzte Wert ist jeweils die endgültige Ausgabe.

Beispiel (nicht Golf) Python-Interpreter

Probieren Sie es online aus! IMO besser, wenn Sie es über IDLE oder was auch immer Sie verwenden ausführen. (Ich habe es bis auf 424 Bytes nach unten gespielt, aber ich bin sicher, dass Sie viel besser machen können).

Artemis vertraut SE immer noch nicht
quelle
2
Das Zulassen, dass sich die Eingabe bereits in einer Variablen befindet, ist nicht Standard, ebenso wie das Zulassen, dass die Ausgabe in einer Variablen erfolgt.
Jonathan Allan
Ihre Beispiele scheinen jedes Mal eine neue Zeile zu drucken, wenn sie <angetroffen werden. Ist das obligatorisch?
Verkörperung der Unwissenheit
Wird das Programm Zeilenumbrüche enthalten? Denn wenn es kann, macht es Chas Browns Antwort ungültig
Verkörperung der Unwissenheit
2
Bei zukünftigen Fragen sollten Sie umständliche E / A-Formate vermeiden . Die Beschränkung der Eingabe auf stdin kostet in einigen Sprachen zusätzliche Bytes und bringt nicht viel mit der Herausforderung.
Arnauld
1
@digEmAll Wie ist der, den ich gerade hinzugefügt habe +@>#? Ich habe es auch #benutzt.
Artemis vertraut SE

Antworten:

3

Ruby -palF\| , 146 142 Bytes

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

Probieren Sie es online aus!

Port of Chas Browns Python-Antwort . Druckt nach der Ausgabe keine Zeilenumbrüche.

Wie üblich ist die Ruby 2.6-Version mit Endlosbereichsindizierung ( i[2..]) 2 Byte kürzer .

Kirill L.
quelle
6

R , 287 286 273 269 ​​Bytes

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}

Probieren Sie es online aus!

  • -1 danke an @Kirill L.
  • -4 danke an @Giuseppe

Abgerollter Code und Erklärung:

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
quelle
3

Python 2 , 215 219 209 208 Bytes

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

Probieren Sie es online aus!

-4 weil raw_inputerforderlich ist.

9 Bytes dank Verkörperung der Ignoranz ; 1 Byte nur von Ascii .

Chas Brown
quelle
Andere Eingaben als das Programm müssen von stdin stammen, wie in der Frage angegeben.
Artemis vertraut SE
Ich benutze Python 3, aber soweit mir bekannt war, erfordert die Verwendung von Eingaben raw_input. Korrigieren Sie mich, wenn ich falsch liege.
Artemis vertraut SE
Gemäß Py 2.7 docs: input([prompt])Entspricht eval (raw_input (prompt)). Diese Funktion fängt keine Benutzerfehler ab. Wenn die Eingabe nicht syntaktisch gültig ist, wird ein SyntaxError ausgelöst.
Artemis traut SE
Das Problem, das Sie ansprechen, ist also so etwas wie hier , wo die Eingabezeichenfolgen in Anführungszeichen gesetzt werden müssten - und nicht wie in einer „wahren“ Situation ohne Anführungszeichen. Auch hier sind die E / A-Regeln normalerweise etwas locker. aber ich werde ändern.
Chas Brown
Danke fürs Ändern. Sie könnten ein paar Bytes sparen, indem Sie zu Python 3 wechseln und Ihren alten Code + 3 Bytes für Klammern verwenden, aber ... +1 trotzdem
Artemis vertraut SE
2

C # (Visual C # Interactive Compiler) , 305 Byte

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

Probieren Sie es online aus!

Verkörperung der Unwissenheit
quelle
1

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

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

Probieren Sie es online aus!

Xcali
quelle
1

Javascript, 292 267 Bytes

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
quelle
Testfall 6 funktioniert nicht ganz ...
Artemis vertraut SE am
1
@ArtemisFowl, danke, der reguläre Ausdruck funktionierte nicht richtig und der Wechsel zu split..join sparte ein paar Bytes.
Johan du Toit