StickStack ist eine sehr einfache stapelbasierte Programmiersprache mit nur zwei Anweisungen:
|
Schiebt die Länge des Stapels auf den Stapel-
Entfernt die beiden obersten Elemente aus dem Stapel und drückt ihre Differenz zurück (second topmost - topmost
)
Sprachdetails
- Der Stack ist zu Beginn des Programms leer.
- Alle Anweisungen werden nacheinander von links nach rechts ausgeführt.
- Wenn sich weniger als 2 Zahlen auf dem Stapel befinden, ist der
-
Befehl unzulässig. - Am Ende der Ausführung sollte der Stapel genau eine Zahl enthalten .
Jede beliebige Ganzzahl kann von einem StickStack-Programm generiert werden. Beispielsweise:
|||--||-- generates the number 2 through the following stack states:
[]
[0]
[0, 1]
[0, 1, 2]
[0, -1]
[1]
[1, 1]
[1, 1, 2]
[1, -1]
[2]
Um Ihren StickStack-Code auszuwerten, können Sie diesen Online-Evaluator (CJam) verwenden . (Danke für @Martin für den Code.)
Die Aufgabe
Sie sollten ein Programm oder eine Funktion schreiben, die eine Ganzzahl als Eingabe ausgibt oder eine Zeichenfolge zurückgibt, die ein StickStack-Programm darstellt, das die angegebene Zahl ausgibt.
Wertung
- Ihre primäre Punktzahl ist die Gesamtlänge der StickStack-Programme für die unten angegebenen Testfälle. Niedrigere Punktzahl ist besser.
- Ihre Einreichung ist nur gültig, wenn Sie Ihr Programm für alle Testfälle ausgeführt und Ihre Punktzahl gezählt haben.
- Ihre sekundäre Punktzahl (Tiebreaker) ist die Länge Ihres Erzeugungsprogramms oder Ihrer Erzeugungsfunktion.
Testfälle eingeben
(Jede Nummer ist ein anderer Testfall.)
-8607 -6615 -6439 -4596 -4195 -1285 -72 12 254 1331 3366 3956 5075 5518 5971 7184 7639 8630 9201 9730
Ihr Programm sollte für alle Ganzzahlen (die Ihr Datentyp verarbeiten kann) funktionieren, nicht nur für die angegebenen Testfälle. Die Lösungen für die Testnummern sollten nicht in Ihr Programm fest einprogrammiert werden. Im Zweifelsfall werden die Testnummern geändert.
quelle
Antworten:
Python 2 - 5188
Ziemlich effizient in Bezug auf die Zeit und scheint (wahrscheinlich) die optimale Lösung zu sein. Ich habe beobachtet, dass ein Muster wie
|||||-|||-|-|-|------
(eine optimale Lösung für 25)kann abgegrenzt werden als
Dabei ist jeder der Gesamtwert am Ende die Summe von (der Wert jedes Levels multipliziert mit der Anzahl von '|' s). Also zum Beispiel oben haben wir
-1*1 + 2*1 - 3*1 + 4*2 - 5*1 + 6*4 = 25
. Auf diese Weise habe ich diese Lösung geschrieben, die eine ähnliche Ausgabe wie andere Antworten liefert, und das in trivialer Zeit.Ich bin der Meinung, dass dies die optimale Lösung ist, da ich jede mögliche optimale Höhe teste (ich teste tatsächlich viel mehr als nötig) und ich bin mir ziemlich sicher, dass die Lösung immer höchstens eine Schicht mit zwei | neben der letzten umfasst (das kann ich) garantieren dies für positive Zahlen, aber nicht 100% sicher über Negative).
Hier ist der Code, den ich zum Testen verwendet habe
quelle
Java, 5208
524053066152Dies ist eine rekursive Funktion, die näher an das Ziel heranreicht, mit Basisfällen, wenn es innerhalb von 5 liegt (was oft nur ein Schritt ist).
Grundsätzlich kann man bekommen
(a*b)+(a/2)
nach(a+b)*2
Sticks mit einem einfachen Muster suchen. Wenna
ungerade ist, ist das Ergebnis negativ, was zu einer seltsamen Logik führt.Dies dauert ungefähr eine Minute für 2 31 -1 mit einer Länge von 185 367 als Ergebnis. Es funktioniert jedoch fast sofort für alle Testfälle. Es zählt
4*(sqrt|n|)
im Durchschnitt. Der längste Einzeltestfall ist9730
ergibt einen 397-fachen Stockstapel:Aktualisieren:
Es wurde ein kürzerer Weg gefunden, das Grundmuster zu addieren / zu subtrahieren. Zurück an der Spitze (vorerst)!
Mit einem Geschirr und Testfällen:
Wird im unwahrscheinlichen Fall eines genauen Gleichstands (mehr) Golf spielen.
quelle
JavaScript (ES6) 5296
6572Bearbeiten Wie ich in meiner Erklärung sagte, bin ich nicht gut darin, ganzzahlige Gleichungen zu lösen. Ich habe den b-Wert nicht so gut geschätzt, also habe ich den Wertebereich erweitert, um es zu versuchen.
Und (wow) ich führe jetzt.Edit 2 Bugfix, gleiche Ergebnisse. Ich habe eine Idee, kann sie aber nicht umreißen.
Bytes: ~ 460, ziemlich golfen. Es funktioniert mit 32-Bit-Ganzzahlen, Laufzeit nahe 0.
Der Code ist die F-Funktion (im Snippet versteckt) unten.
Führen Sie das zu testende Snippet aus (in FireFox).
Code-Snippet anzeigen
Erläuterung
Zunächst positive Zahlen. Beginnen Sie mit einer "Basis" (versuchen Sie es in CJam, wenn Sie möchten, Leerzeichen erlaubt)
Zusammenfassung: 1 Stick, dann b * 2 Sticks, dann b * 2 Striche
Versuchen Sie dann, ein oder mehrere '- |' in der Mitte aufgeteilt. Jedes fügt ein festes Inkrement hinzu, das das Zweifache der Startbasis ist und mehrmals wiederholt werden kann. Wir haben also eine Formel mit b = Basis und r = Inkrement-Wiederholungsfaktor
Sehen? Der Additionswert erhöht sich schnell und jede Addition besteht nur noch aus 2 Zeichen. Das Basisinkrement gibt jedes Mal 4 weitere Zeichen.
Wenn v und unsere Formel v = b + r * 2 * b gegeben sind, müssen wir 2 ints b und r finden. Ich bin kein Experte für diese Art von Gleichung, aber b = int sqrt (v / 2) ist eine gute Ausgangsvermutung.
Dann haben wir ein r und ein b, die zusammen einen Wert in der Nähe von v ergeben. Wir erreichen v genau durch wiederholtes Inkrementieren (|| -) oder Dekrementieren (| -).
Folgen Sie der gleichen Argumentation für negative Zahlen, leider ist die Formel ähnlich, aber nicht gleich.
quelle
JavaScript, 398710
94 Byte / Zeichen Code
Ich habe eine Lösung gefunden! ... und dann lies Sparrs Antwort und es war genau das gleiche.
Dachte mir, ich würde es trotzdem posten, da js etwas weniger Zeichen zulässt.
Hier ist eine ungekürzte Version des Codes:
quelle
Python, 398710 (71 Byte)
Einfachste mögliche Lösung, denke ich. Verwendet 4 * n (+/- 1) Zeichen des Stickstacks, um n darzustellen.
quelle