Schreiben Sie ein Programm, das eine Zeichenfolge mit ungerader Länge akzeptiert, die nur die Zeichen .
und enthält :
. Erstellen Sie mit Hilfe eines anfänglich leeren Stapels eine Zahl aus dieser Zeichenfolge wie folgt:
Für jedes Zeichen c in der Zeichenfolge (von links nach rechts) ...
- Wenn c ist
.
und der Stapel weniger als 2 Elemente enthält, drücken Sie 1 auf den Stapel. - Wenn c ist
.
und der Stapel 2 oder mehr Elemente enthält, lassen Sie die beiden obersten Werte vom Stapel fallen und legen Sie ihre Summe auf den Stapel. - Wenn c ist
:
und der Stapel weniger als 2 Elemente enthält, drücken Sie 2 auf den Stapel. - Wenn c ist
:
und der Stapel 2 oder mehr Elemente enthält, lassen Sie die beiden obersten Werte vom Stapel fallen und schieben Sie ihr Produkt auf den Stapel.
Die resultierende Zahl ist der Wert oben im Stapel. Ihr Programm sollte diese Nummer auf stdout ausgeben (mit einem optionalen nachgestellten Zeilenumbruch).
(Eine kleine Analyse zeigt, dass immer nur eine Zahl übrig ist, es sei denn, die Zeichenfolge hat eine gerade Länge, weshalb wir diese ignorieren. Tatsächlich enthält der Stapel nie mehr als 2 Elemente.)
Zum Beispiel ist die Zahl für ::...:.:.
9:
2 1 2 2 /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9 \
: : . . . : . : . <-- string, one character at a time
Zur Überprüfung der Gesundheit sind hier die Zahlen für alle Zeichenfolgen der Länge 1, 3 und 5:
. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8
Das kürzeste Programm in Bytes gewinnt. Tiebreaker ist früherer Beitrag.
- Sie können davon ausgehen, dass die Eingabe immer gültig ist, dh eine Zeichenfolge, die nur ungerade Werte enthält
.
und:
deren Länge ungerade ist. - Anstatt ein Programm zu schreiben, können Sie eine Funktion schreiben, die eine gültige Zeichenfolge verwendet und die generierte Zahl ausgibt oder zurückgibt.
Antworten:
CJam,
27 24 2322 BytesZiemlich einfach. Ich benutze CJam's Stack als den in der Frage genannten Stack;)
Algorithmus
Schauen wir uns zuerst den ASCII-Code für
.
und an:
.Da in CJam Indexumbrüche durchgeführt werden, können Sie sehen, ob wir diese Werte direkt verwenden können, um die gewünschte Operation zu erhalten.
Daher kann ich die ASCII-Codes nicht einfach in einer Operationszeichenfolge mit 4 Längen verwenden. Versuchen wir einige andere Werte
was auf eine 4 länge schnur hinausläuft
Ich kann diese Mod 10-Operation verwenden, aber das kostet 2 Bytes. Versuchen wir etwas anderes
Nice !, jetzt subtrahieren wir nur 1 für die Stapelgrößenbedingung, um die Indizes zu erhalten
0, 1, 2 and 3
und ein5
Längenarray ("1+2* "
) als Schalterfall zu verwenden. Das letzte Leerzeichen ist nur ein Füllzeichen, um es auf Länge 5 zu bringen. Dies ist nur 1 zusätzliches Byte im Vergleich zur Modding-Operation.Probieren Sie es hier online aus
Dank cosechy 1 Byte gespart
quelle
> <> (Fisch) , 33 Bytes
Ziemlich einfach mit kleinen Tricks / Optimierungen.
Erläuterung:
i
= Codepunkt des nächsten Eingabezeichens,-1
wenn das Ende der Eingabe erreicht ist;a
= 10;b
= 11;)
=>
i
Codepunkt des ersten Eingabezeichens,b%1-
top_of_stack mod 11 - 1
Masken48 ('.') , 56 (':')
zu1 , 2
i:1+?\~n;
Wenn das Ende der Eingabe erreicht ist, das letzte Ergebnis drucken und beendenb%1-
Maskeneingabe an1 , 2
0@
drücken0
unter die zwei nummerni5a*)
Lesen Sie die nächste Eingabe und maskieren Sie sie0 , 1
Vergleich mit50
1
(':'
) multipliziere die beiden obersten Elemente und erstelle einen Stapel [0 Produkt][0 sum]
oder einen Stapel zu erstellen[0+product=product]
40.
Sprung (Schleife) zurück zu Position(4,0)
, unserem Punkt4
,i:1+?\~n;
quelle
Haskell,
7365 BytesEine einfache Lösung, da der Stapel nie mehr als 2 Elemente enthält.
quelle
C 104 Bytes
Das ist zu lang.
quelle
Pyth,
2524 BytesIch habe eine Idee, als ich @ isaacgs Lösung studierte. Aber ich benutze einen Stapel.
Online-Demonstration oder Testsuite
Erläuterung
Als erstes konvertiere ich die Eingabezeichenfolge in 0s und 1s. A
"."
wird umgewandelt in a0
, a":"
in a1
.Dann reduziere ich diese Liste von Zahlen:
quelle
JavaScript (ES6), 65
Wir verwenden nur 2 Zellen unseres Stapels.
Geben Sie einen Wert in s [0] ein.
Geben Sie dann an jeder ungeraden Position (von 0 an gezählt) in der Eingabezeichenfolge einen Wert in s [1] ein.
Führe an jeder geraden Position eine Berechnung aus (addiere oder multipliziere) und speichere das Ergebnis in s [0].
Vergessen Sie also den Stack und verwenden Sie nur 2 Variablen, a und b.
Ein schneller Test
Ausgabe
quelle
f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
Pyth, 27 Bytes
Ein Stapel? Wer braucht schon einen Stapel.
Demonstration.
quelle
Retina ,
1057573 BytesMein erstes Retina-Programm! (Vielen Dank an Martin Büttner für die Einsparung von 2 Bytes, ganz zu schweigen von der Erfindung der Sprache.)
Jede Zeile sollte in einer separaten Datei abgelegt werden. Oder Sie können sie alle in eine Datei einfügen und das
-s
Flag verwenden. Die<empty>
Notation steht für eine leere Datei / Zeile.Inspiriert von der Antwort von mbomb007, verfolge ich jedoch einen etwas anderen Ansatz. Ein Hauptunterschied ist, dass ich den Stapel vor der dotty Schnur baue (mit der Oberseite des Stapels nach rechts zeigend). Dies macht es einfach, Symbole an Ort und Stelle in die entsprechenden Zahlen umzuwandeln. Ich benutze
a
stattdessen auch1
, es nur am Ende auszutauschen, um zu vermeiden, Mehrdeutigkeiten in Sequenzen wie zu analysieren$1a
. Wenn eine Antwort wieaaaaaa
eine unäre Zahl akzeptabel ist, können die letzten beiden Zeilen / Dateien entfernt werden, um 4 Bytes zu sparen.Erläuterung:
Stimmt überein, wenn sich 0 oder 1 Elemente auf dem Stapel befinden (
(a+;)?
), gefolgt von einem Punkt (\.
); In diesem Fall wird der Punkt durch ersetzta;
(dh es wird eine 1 gedrückt).Stimmt überein, wenn sich 0 oder 1 Elemente auf dem Stapel befinden, gefolgt von einem Doppelpunkt. In diesem Fall wird der Doppelpunkt durch ersetzt
aa;
(dh es wird eine 2 gedrückt).Stimmt überein, wenn sich zwei Elemente auf dem Stapel befinden, gefolgt von einem Punkt. Löscht den Punkt und das Semikolon zwischen den Elementen und fügt sie hinzu.
Stimmt überein, wenn der Stapel zwei Elemente enthält, von denen das oberste eine 2 ist, gefolgt von einem Doppelpunkt. Löscht den Doppelpunkt und die 2 und wiederholt die andere Zahl zweimal, wobei sie mit 2 multipliziert wird.
Der reguläre Ausdruck stimmt überein, wenn sich zwei Elemente auf dem Stapel befinden, von denen das oberste eine 1 ist, gefolgt von einem Doppelpunkt. Löscht den Doppelpunkt und die 1 und lässt die andere Zahl unverändert (dh multipliziert mit 1).
)`
zeigt das Ende einer Schleife an. Wenn Änderungen an der Zeichenfolge vorgenommen wurden, kehrt die Steuerung an den Anfang des Programms zurück und führt die Ersetzungen erneut aus. Wenn sich die Zeichenfolge nicht mehr ändert, haben wir alle Punkte und Doppelpunkte ersetzt, und alles, was übrig bleibt, ist die Bereinigung ...Löscht das verbleibende Semikolon.
Wandelt alle Einsen in Einsen um. Auch dieser Schritt ist nicht erforderlich, wenn Unärzahlen ein Symbol verwenden dürfen.
quelle
Rust, 170 Zeichen
Mehr Beweis, dass Rust beim Golfen absolut schrecklich ist. Voller ungolfed Code:
Hier ist ein interessanter Trick, den ich in diesem verwendet habe. Sie können ein Zeichen in einer if / else-Anweisung abschneiden, indem Sie einen Wert zurückgeben, der sofort verworfen wird. Dies bedeutet, dass Sie nur ein Semikolon anstelle von zwei benötigen.
Beispielsweise,
kann in geändert werden
Das spart ein Zeichen, indem ein Semikolon abgeschnitten wird.
quelle
Haskell,
888179 BytesEs scheint, dass mich jemand bei einer Haskell-Lösung bis an die Grenze geschlagen hat, nicht nur das, ihre Lösung ist kürzer als meine. Das ist schade, aber ich sehe keinen Grund, nicht zu posten, was ich mir ausgedacht habe.
quelle
APL (50)
Ich bin hier im Nachteil, weil APL keine Stack-basierte Sprache ist. Endlich musste ich die Reduzierung missbrauchen, um das Programm zu verkürzen.
Die innere Funktion nimmt links einen 'Befehl' und rechts einen Stapel und wendet ihn an und gibt den Stapel zurück. Die äußere Funktion reduziert es über den String, beginnend mit einem leeren Stapel.
Erläuterung:
(⌽⍵),⊂⍬
: die anfängliche Liste zu reduzieren.⊂⍬
ist eine leere Liste, die den Stapel darstellt,(⌽⍵)
die Umkehrung der Eingabe. (Die Verkleinerung wird von rechts nach links über der Liste angewendet, sodass die Zeichenfolge von rechts nach links verarbeitet wird. Durch vorheriges Umkehren der Eingabe werden die Zeichen in der richtigen Reihenfolge angewendet.){
...}
: die innere Funktion. Es nimmt den Stapel rechts und ein Zeichen links und gibt den geänderten Stapel zurück.F←'.:'⍳⍺
: Der Index des Zeichens in der Zeichenfolge.:
Je nach Wert ist dies 1 oder 2.2>⍴⍵:F,⍵
: Wenn 2 größer als die aktuelle Stapelgröße ist, hängen Sie einfach den aktuellen Wert an den Stapel an.⋄
: Andernfalls,2↓⍵
: Entferne die beiden obersten Gegenstände vom Stapel(
...)/2↑⍵
: Reduziere eine gegebene Funktion darüber und füge sie dem Stapel hinzu.⍎F⌷'+×'
: Die Funktion ist entweder+
(Addition) oder×
(Multiplikation), ausgewählt mitF
.⊃
: Geben Sie schließlich das oberste Element auf dem Stapel zurückquelle
Ruby - 96 Zeichen
Das interessante Stück ist hier
eval
.Abgesehen davon gehe ich davon aus, dass der Stapel nach dem ersten Zeichen immer 2, math, 2, math, ... ist. Dadurch kann ich weniger Code verwenden, indem ich zwei Zeichen gleichzeitig nehme - ich muss nie rechnen herausfinden, ob ein Zeichen Mathematik oder eine Zahl ist. Es ist positionell.
Ungolfed:
quelle
TI-BASIC,
7873706966 BytesTI-BASIC eignet sich gut für Einzeiler, da das Schließen von Klammern optional ist. Umgekehrt ist es eine schlechte Sprache, in der das Speichern mehrerer Werte erforderlich ist, da das Speichern in einer Variablen zwei bis vier Byte Speicherplatz beansprucht. Daher ist es das Ziel, so viel wie möglich in jede Zeile zu schreiben. TI-BASIC ist auch schrecklich (für eine Token-Sprache) bei der Manipulation von Strings jeglicher Art; Sogar das Lesen eines Teilstrings ist langwierig.
Tricks beinhalten:
int(e^([boolean]
statt1+(boolean
; spart ein Bytequelle
".:.":prgmDOTTY
und beispielsweise 4 Bytes zu sparen.1+(":"=sub(Ans,1,1
Gehen,
129115112 Bytes(etwas) ungolfed:
Versuchen Sie es online hier: http://play.golang.org/p/B3GZonaG-y
quelle
Python 3, 74
First transformiert die Eingabeliste in eine Folge von 1 und 2, wobei der erste Wert als Anfangswert verwendet wird
x
.s
Nehmen Sie dann von vorne zwei Elemente gleichzeitig ab , nehmen Sie die erste Zahl und addieren oder multiplizieren Sie sie mit der aktuellen Zahl, je nachdem, ob die zweite 1 oder 2 ist.quelle
Nun, das ist so einfach, raffiniert von der OP (absichtlich)
es ist nur ...
Code: C (80 Byte)
Eingang
Länge = 2n + 1 Vektor V vom Typ char '.' oder ':'
Ausgabe
eine ganze Zahl k
Funktion
Simulation:
versuche es hier
quelle
*(V-1)
) Null ist?Retina,
181135129 BytesJede Zeile sollte in einer separaten Datei sein.
<empty>
repräsentiert eine leere Datei. Die Ausgabe erfolgt in Unary.Wenn${0}1
verwendet, trennen sich die Klammern$0
von der ersten passenden Gruppe1
, ansonsten wäre dies der Fall$01
. Ich habe versucht, mit$001
, aber dies scheint nicht in der .NET-Variante von Regex zu funktionieren.Edit: Gefunden das
$&
ist das selbe wie$0
.Im Pseudocode wäre dies im Wesentlichen eine do-while-Schleife, wie unten dargestellt. Ich drücke die erste Zahl, dann die Schleife: drücke die zweite Zahl, entferne die Operation (Anweisung), mache Mathe, entferne die Op. Wiederholen Sie die Schleife. Beachten Sie, dass beim Aufspringen einer Operation auch das Leerzeichen entfernt wird, nachdem alle Anweisungen ausgeführt wurden.
Kommentiert:
quelle
(:)(.*)
->$1$2
, von denen ich mir ziemlich sicher bin, dass es nur(:.*)
-> sein könnte$1
(da Sie die beiden Gruppen in der gleichen Reihenfolge halten und nichts anderes mit ihnen machen) ).Python 3, 122 Bytes
Ungolfed:
In Python verweisen Sie auf den Index einer Liste wie folgt:
Sie können einen booleschen Wert in das setzen,
True
ist1
undFalse
ist0
.Probieren Sie es hier online aus
quelle
Perl, 77 Bytes
erweitert:
Das
@o
Array ordnet den Operatoren Ziffern zu. Dann ersetzen wir Zahlenpaare durch den entsprechenden Operator, der nach infix geordnet ist. Der reguläre Ausdruck beginnt mit,\B
daher stimmen wir nicht mit dem ersten Zeichen überein. Das Ergebnis vons///g
sagt uns, wie viele offene Parens wir am Anfang brauchen. Wenn wir dann den vollständigen Infix-Ausdruck zusammengestellt haben, können wir ihn auswerten. (Löscheneval
Sie, wenn Sie stattdessen den Ausdruck sehen möchten.)Hier ist das Testkabel, mit dem ich die Ergebnisse verifiziert habe:
Input ist die Liste der Dotty-Ausdrücke und ihrer Werte (in der Frage angegeben) und Output sind Paare von {actual, expected}.
quelle