Hintergrund
In einigen möglichen Zukünften wird die Welt ihre numerischen Systeme von dezimal (Basis 10 oder b10
) auf eine andere Basis (binär b2
, oktal b8
, hexadezimal b16
oder sogar unär b1
, in diesem Fall sind wir geschraubt!) Umwandeln. In Vorbereitung auf dieses möglicherweise weltverändernde Ereignis entscheiden Sie sich daher, alle Ihre Programme auf die Basis zu stellen. Dies kann erreicht werden, indem nur singuläre 0
s und 1
s in Verbindung mit Operatoren verwendet werden, um die vorhandenen Zahlenkonstanten zu ersetzen.
Es gibt jedoch nur ein Problem: Sie müssen eine Menge Programme ändern, und die manuelle Konvertierung jeder Zahl in einen Ausdruck würde Wochen dauern! Sie entscheiden sich daher, ein Programm (oder eine Funktion) zu schreiben, um zu entscheiden, welcher Ausdruck jede Zahl ersetzen soll.
Eingang
Die Eingabe ist eine positive Ganzzahl. Ihr Code muss in der Lage sein, eine ganze Zahl bis zu 1000 zu verarbeiten.
(Wenn Ihr Code Dezimalstellen und / oder negative Eingaben unterstützt, lesen Sie die Informationen unter Bewertung .)
Ausgabe
Ihr Code muss einen Ausdruck ausgeben, der in mindestens einer Sprache als Eingabe ausgewertet wird. Dies kann jede Sprache sein; Es muss nicht dasselbe sein, in das Ihr Programm oder Ihre Funktion geschrieben ist. Außerdem muss dieser Ausdruck kein vollständiges Programm oder eine vollständige Funktion sein.
Der Übersichtlichkeit halber kann die Ausgabe folgende Operationen enthalten:
- inkrementieren / dekrementieren
- add / sum
- subtrahieren / negieren
- multiplizieren / verdoppeln (nur wenn es sich nicht direkt um die Zahl handelt
2
!) - Teilen / Modulo
- Exponenten / Logarithmen
- Quadrat / Quadrat (wieder nur, wenn diese nicht direkt die Zahl betreffen
2
!) - bitweise Operationen (bOR, bAND, bNOT, bXOR, Bitverschiebungen)
- Variablen setzen / holen
- Stapelmanipulation
Sie können nicht verwenden eval()
oder ähnliche Funktionen in der Ausgabe. Sie dürfen in der Ausgabe auch keine Funktionen verwenden, die andere als die oben genannten Aktionen ausführen.
Oh, und noch etwas: da wir die Ausgabe gültig zu sein in so viele Basen wie möglich wollen, die einzige Zahl , Konstanten sie enthalten sind 0
und 1
. Zahlen wie 10
(zehn) sind nicht zulässig, es sei denn, die Sprache interpretiert sie als a 1
und a 0
. Mit Strings Zahlen enthalten ist auch nicht erlaubt, wie es Zeichen wie CJam der Verwendung A
- K
(die darstellen 10
- 20
).
Testfälle
(Alle Ausgaben sind in JavaScript, funktionieren jedoch möglicherweise in anderen Sprachen.)
Eingang 1:
2
Mögliche Ausgabe 1:
1+1
Eingang 2:
13
Mögliche Ausgabe 2:
(a=1+1+1)*a+a+1
Eingang 3:
60
Mögliche Ausgabe 3:
(b=(a=1+1+1+1)*a)*a-a
Eingang 4:
777
Mögliche Ausgabe 4:
(c=(b=((a=1+1+1+1)*a-a+1)*a)*a+b)+c+c-a+1
Eingang 5:
1000
Mögliche Ausgabe 5:
Math.pow((a=1+1+1)*a+1,a)
Wertung
Ziel dieser Herausforderung ist es, die Ausgabe Ihres Codes so weit wie möglich zu verkürzen. Ihre Punktzahl wird folgendermaßen berechnet:
Basisbewertung: Die durchschnittliche Byteanzahl aller Ausgaben für Ganzzahlen von 1 bis 1000.
Dezimalpunktzahl : Wenn Ihr Code mindestens 3 Dezimalstellen unterstützt, ist dies die durchschnittliche Byteanzahl aller Ausgaben der Zahlenfolge, die um beginnt
0.001
und um endet1000
, und wird1.001
jedes Mal erhöht .0.001, 1.002, 2.003...998.999, 1000.000
Dann nimm 50% von dieser Punktzahl ab.Negative Bewertung: Wenn Ihr Code negative Zahlen und Nullen unterstützt, ist dies die durchschnittliche Byte-Anzahl der Ausgaben aller Ganzzahlen von
-1000
bis0
. Dann nimm 10% von dieser Punktzahl ab.
(Der einfachste Weg, diese zu berechnen, ist wahrscheinlich eine Schleife mit Ihrem Programm / Ihrer Funktion.)
Ihre endgültige Punktzahl ist der Durchschnitt der oben genannten Formeln.
Wenn die Ausgabe nicht deterministisch ist (dh etwas zufällig ist; mehrere Durchläufe mit derselben Eingabe ergeben mehrere eindeutige Ausgaben), wird die Bewertung für jede Eingabe durch die größte Ausgabe über zehn Durchläufe auf meiner CPU bestimmt.
Da Sie nicht wissen, wie wertvoll die Computerdaten in Zukunft sein werden, muss die Byteanzahl Ihres Generatorcodes weniger als 512 Bytes betragen.
Das niedrigste Ergebnis in zwei Wochen (am 30. September) wird zum Gewinner erklärt. Herzlichen Glückwunsch an Ihren Gewinner @ThomasKwa !
Bestenliste
Um sicherzustellen, dass Ihre Antwort korrekt angezeigt wird, starten Sie sie bitte mit dieser Überschrift:
# Language name/Other language name, X points
Wo X
ist die Punktzahl Ihrer Antwort? Beispiel:
# CJam/Pyth, 25.38 points
Wenn Sie Fragen oder Anregungen haben, lassen Sie es mich bitte wissen. Viel Glück!
quelle
0
oder1
standardmäßig sind?Integer.parseInt("1000", 1+1+1+1+1+1+1+1+1+1)
? Ich bin mir ziemlich sicher, dassparseInt
nur die erlaubten Operationen verwendet werden ;-)Antworten:
Python / Zilog Z80-Maschinencode,
11.65311.488Boni: Negative Zahlen.
Angenommen, das
hl
Registerpaar hat anfangs den Wert 0 und gibt das Ergebnis in zurückhl
.Es werden nur diese drei Anweisungen verwendet:
Wir verwenden eine kleine Modifikation der minimalen gewichtsausgeglichenen Binärdarstellung BBR2 . Da BBR2 die Gewichtung minimiert (Anzahl der Stellen ungleich Null), wir jedoch die Gewichtung plus die Anzahl der Bitverschiebungen minimieren möchten, ändern wir eine Konstante im Algorithmus von
3/2
auf5/3
.Verwenden Sie diesen Code, um die Punktzahl zu berechnen und zu überprüfen:
Beispielausgabe:
Oder in der Montage:
Weitere Beispielprogramme:
Mögliche Optimierungen: Regeln, die die OP
inc h
unddec h
Anweisungen, die direkt an das obere Byte der Veränderunghl
, sind illegal, sondernsla h
und die nicht dokumentiertsl1 h
(links Bitverschiebungen von 1 aufh
dieser Verschiebung in einem0
und1
respectively) sind zulässig.sla h
undsl1 h
sind jeweils zwei Bytes, aber sie können manchmal die Ausgabe verkürzen.quelle
+
übersetztdec
. Ich lese die negativen Beispiele immer wieder falsch.CJam / CJam,
143,26342.71328.89923.90121.90320.468Es gelten keine Boni.
Probieren Sie es online aus: Probelauf | Partiturrechner |Nachprüfung
Beispiel läuft
quelle
%
durch einen längeren Ausdruck ersetzt. Die Links sollten jetzt funktionieren.ß / BrainFuck, 34.201 Punkte
ß Quelle (194B):
Wenn jemand interessiert ist, werde ich eine Erklärung hinzufügen. Die BF-Ausgabe ist bereits ziemlich optimiert, aber ich denke, ich könnte die restlichen 318B des ß-Codes verwenden, um sie zu implementieren
Entfernung von Bedienerkollisionen.Proben:
Laufen in Windows:
Laufen unter Linux:
Validieren Sie im Online-BF-Interpreter .
Scores:
= 37.495
.= 60.959 * 0.5 = ~30.48
.= 38.4765234765235 * 0.9 = ~34.629
= (37.495 + 30.48 + 34.629)/3 = 34.201
.quelle
Ruby / Ruby, 29,77885
31,873 * 0,9 (negativ) 30,872 (positiv).
Grundlegende Strategie ist die symmetrische Darstellung der Basis 3 ("ausgeglichenes ternäres"), dh wenn die Ziffern sind
-1,0,1
anstelle von0,1,2
Hier ist die Ausgabe von 0 bis 40 vor der Bereinigung
Und nach dem Aufräumen
quelle
Ceylon / Ceylon,
49,8640,95 PunkteDie dritte Version verwendet Ceylon 1.2 für den Generator und 509 Byte Code:
import ceylon.language{S=String,I=Integer,e=expand}S q(I n)=>n==0then"0"else(n<0then"-"+p(-n,"-")else p(n,"+"));variable Map<[I,S],S>c=map{};S p(I n,S s){S v=c[[n,s]]else(n<8then s.join([1].repeat(n)))else(let(a="+-".replace(s,""))e(e{for(x in 2..8)let(l=(n^(1.0/x)).integer){for(r in l:2)if(r>1)let(w=r^x){if(w-n<n)"("+p(r,"+")+")^("+p(x,"+")+")"+(w<n then s+p(n-w,s)else(n<w then a+p(w-n,a)else""))}}}).reduce<S>((x,y)=>x.size<y.size then x else y))else"";c=[n,s]in c then c else map{[n,s]->v,*c};return v;}
Es geht auf 35,22 Punkte zurück, aber ich werde dies nicht in die Titelzeile setzen, da Celyon 1.2 erst am 29. Oktober veröffentlicht wurde. Ich glaube nicht, dass ich diesen Algorithmus in Ceylon 1.1 in dieser Größe implementieren kann.). Weitere Details hier unten, hier beschreibe ich die zweite Version. (Die erste Version ist in der Historie zu sehen - sie unterstützte nur positive Zahlen, passte aber in 256 Bytes.)
Zweite Version
Jetzt die zweite Version, die negative Ganzzahlen (und 0) unterstützt und generell eine etwas kürzere Ausgabe durch zusätzliche Verwendung erzeugt
-
. (Diese Version verwendet tatsächlich die erlaubte Länge, die erste hat versucht, unter 256 Bytes statt 512 zu bleiben.)Code hat die Länge 487, sodass später noch Platz für weitere Optimierungen bleibt. (Es gibt auch viele Reserven in Form von Leerzeichen und langen Variablennamen.)
Die Wertung:
Einige Beispielausgaben:
Wie Sie sehen, sind die negativen immer ein Byte (das führende
-
) länger als die entsprechenden positiven.Die Grundidee ist dieselbe wie im vorherigen Programm: Finden Sie ein Quadrat in der Nähe unserer Zielzahl und repräsentieren Sie dessen Wurzel und den Rest rekursiv. Aber jetzt lassen wir zu, dass unser Quadrat auch etwas größer als die Zielzahl ist, was den Rest negativ macht. (Das
+0.5
können die Konstante ändern, um den Algorithmus zu optimieren, aber anscheinend habe ich hier bereits das Optimum erreicht. Sowohl 0,4 als auch 0,6 liefern schlechtere Ergebnisse.)Um negative Werte negativ zu machen (und ansonsten die gleiche Struktur wie die positiven zu haben, übergeben wir den Operator
sign
an unsere rekursive Funktionp
- entweder"+"
oder"-"
. Wir können dies auch für den Schreiner in den trivialen Fällen (dh n <9) verwenden Was den Rest betrifft, wenn er positiv ist, und verwenden Sie das entgegengesetzte Vorzeichen für den Rest, wenn er negativ ist.Die
proof
Funktion behandelt das Anfangszeichen (mit einem Sonderfall für 0), diep
Funktion erledigt die eigentliche Arbeit mit Rekursion.Dritte Version für Ceylon 1.2
Die Golf-Version (dh Kommentare und Leerzeichen werden entfernt) wird mit genau 509 Byte Code oben angezeigt.
Dies verwendet dasselbe Grundprinzip wie die zweite Version, aber anstelle von nur Quadraten wird auch versucht, höhere Potenzen von Zahlen zu verwenden (versuchen Sie es mit Exponenten von 2 bis 8) und verwenden Sie das kürzeste Ergebnis. Außerdem werden die Ergebnisse zwischengespeichert, da dies ansonsten für größere Nummern mit vielen rekursiven Aufrufen unannehmbar langsam wäre.
Wertung:
Das große eingerückte Konstrukt in der Mitte besteht aus drei ineinander verschachtelten iterablen Begriffen, die beiden inneren in einem let-Ausdruck. Diese werden dann bei zweimaliger Verwendung der Erweiterungsfunktion nicht verschachtelt, und die
reduce
Funktion findet die kürzeste dieser Zeichenfolgen.Ich habe eine Feature-Anfrage eingereicht , um dies in einem einzigen Verständnis tun zu können.
Innerhalb des Verständnisses bauen wir eine Zeichenkette aus der Wurzel
r
, dem Exponentenx
und dem Rest (n-w
oderw-n
) auf.Der
let
Ausdruck und diemap
Funktion sind neu in Ceylon 1.2.map
hätte durch ersetzt werden könnenHashMap
(das hätte mehr Zeichen für den Import benötigt, obwohl es wahrscheinlich noch schneller wäre, da ich die Map nicht für jeden neuen Eintrag neu erstellen würde). Dielet
Ausdrücke wielet (w = r ^ x)
hätten durch eineif
Klausel wie ersetzt werden könnenif(exists w = true then r ^ x)
(und dann hätte ich auch die beidenexpand
Aufrufe nicht gebraucht ), aber das wäre noch ein bisschen länger und würde nicht in die 511 zulässigen Bytes passen.Hier sind die Beispielausgaben, die den oben ausgewählten entsprechen, mit Ausnahme der wirklich kleinen Zahlen, alle kürzer:
Zum Beispiel haben wir jetzt 1000 = (3 ^ 2 + 1) ^ 3 anstelle von 1000 = (6 ^ 2-4) ^ 2-5 ^ 2 + 1.
quelle
less than 512
. Sie können max. von 511 Bytes;)Ruby / dc,
20,29618.41416.968Dynamische Programmierung! Definiert eine Liste von Funktionen, die bei einer gegebenen DC-Anweisung einen neuen Ausdruck und den numerischen Wert dieses Ausdrucks zurückgeben. Ausgehend von
1
prefined wird dann eine Liste aller erreichbaren Werte bis einschließlich des gewünschten Werts erstellt.bearbeiten:
Es wurde eine Funktion für n-1 hinzugefügt , mit der der Algorithmus in mehreren Durchgängen ausgeführt wurde. Es scheint 7 Durchgänge zu benötigen, um sich zu stabilisieren. Einige Variablennamen mussten gekürzt werden, um innerhalb von 512 Byte zu bleiben.
2 bearbeiten:
Es wurden Funktionen für n (n-1) , n (n + 1) und n ^ 3 hinzugefügt , während ich dabei war. Kürzte den Code noch weiter und landete bei genau 512 Bytes.
Generierte Zahlen:
Die Ausgabe besteht vollständig aus fünf verschiedenen Zeichen:
1
Drückt den Wert 1 auf den Stapel;d
dupliziert die Oberseite des Stapels;+
,-
Und*
knallt die beiden Spitzenwerte und drückt ihre Summe, Differenz und Produkt sind. Jeder generierte Ausdruck fügt dem Stapel nach der Ausführung nur einen Wert hinzu....
quelle
-
Operator hinzufügen können, während Sie innerhalb der Byteanzahl bleiben?Python 2.6,
78.069- 66.265 PunkteSenden meiner Antwort für das, was es wert ist (nicht viel in diesem Fall ... aber klar zu demonstrieren, dass es für diese Herausforderung nicht ausreicht, einfach die Ausgabe als Summe bitverschobener Werte zu komponieren, wenn man berücksichtigt, dass es keine Ziffern gibt außerhalb von 0 oder 1 kann in der Ausgabe erscheinen). Ich könnte später mit einer anderen Art der Ausgabeerzeugung zurückkommen.
Der Code selbst ist nicht zu lang (176 Zeichen):
Es erzeugt eine korrekte, aber ausführliche Ausgabe:
Snippet, das die Punktzahl berechnet:
quelle