Die meisten Computer speichern Ganzzahlen in Binärform, geben sie jedoch in Dezimalform aus. Die Dezimalzahl ist jedoch nur eine Darstellung, die wir einfach als zweckmäßig empfinden.
Diese Herausforderung besteht darin, Code zu schreiben, um einen ganzzahligen Wert in Shortlex Decimal auszugeben .
Was ist das?
http://en.wikipedia.org/wiki/Shortlex_order
Shortlex verwendet die Länge der Ziffernfolge als primären Wertekennzeichner. Die Sequenz, beginnend mit einer leeren Zeichenfolge, die Null darstellt, lautet ...
ε,0,1,...,8,9,00,01,...98,99,000,001,...,998,999,0000,...
(Denken Sie an Excel-Spalten, aber verwenden Sie nur die Dezimalstellen.)
Schreiben Sie ein Programm oder eine Funktion, die eine Ganzzahl akzeptiert und eine Zeichenfolge zurückgibt, die der oben beschriebenen Darstellung dieser Ganzzahl in Form einer kurzen Dezimalzahl entspricht.
Testwerte:
0 → "" (leere Zeichenfolge)
1 → "0"
10 → "9"
11 → "00"
42 → "31"
100 → "89"
800 → "689"
1060 → "949"
10270 → "9159"
100501 → "89390"
19, 20, 21, 22
in Dezimalzahlen auf08, 09, 10, 11
shortlex abbildet. Deshalb habe ich das verwirrt100 -> 89
!Antworten:
JavaScript (ES6) 42
74Test in der FireFox-Konsole
Ausgabe
Wie habe ich darüber nachgedacht?
Bei einer festgelegten Anzahl von Ziffern steigt die Ausgabesequenz einfach an, sodass zwischen Eingabe und Ausgabe ein festes Delta besteht. Guck mal:
Aber die führenden Nullen sind schwierig zu verwalten, also habe ich einen Standardtrick, füge eine erste Ziffer hinzu und arbeite modulo (dh schneide die erste Ziffer in der Ausgabe ab). Dann -1-> +9, -11 -> +89, -111 -> +889 und so weiter.
Letzter Schritt: Es ist mir egal, wie hoch die erste Ziffer ist, daher muss nicht überprüft werden, ob die Eingangsnummer <oder> 111 ist ... (ehrlich gesagt, ich habe dies durch Ausprobieren herausgefunden.)
Prüfung
quelle
n-~(n+'')
statt nurn-~n
?(n+'').replace(...)
, Ersetzen funktioniert auf Zeichenfolgen, nicht Zahlen.Marbelous
177173170Es funktioniert nur für Werte unter 256, da Marbelous eine 8-Bit-Sprache ist.
Wie es funktioniert
Marbelous ist eine 2D-Sprache mit Werten, die durch 8-Bit-Murmeln dargestellt werden, die bei jedem Tick um eine Zelle nach unten fallen, es sei denn, ein Gerät verhindert, dass sie nach unten fallen. Dieses Marbelous-Programm besteht aus 3 Tafeln; Fangen wir mit dem einfachsten an:
:O
ist der Name der Karte (um genau zu sein, O ist der Name und: sagt dem Interpretierten, dass diese Zeile ein Name ist. Wenn Sie einer Karte einen Namen geben, können andere Karten darauf}0
zugreifen. Dies ist ein Eingabegerät Argument dieser Funktion: Diese Zelle wird durch einen Eingabemurmel (Wert) ersetzt, wenn die Funktion aufgerufen wird.+Z
Fügt jedem Marmor, der darüber läuft, 35 hinzu und lässt ihn fallen.+C
Führt dasselbe aus, fügt jedoch nur 12 hinzu. Ist{0
eine Ausgabezelle Wenn eine Kugel diese Zelle erreicht, wird die Funktion beendet und der Wert in diesem Ausgabegerät zurückgegeben.Alles in allem nimmt dieses Board einen Wert an und addiert dann 47 dazu. Für uns bedeutet dies, dass jede einstellige Zahl in den ASCII-Code der Ziffer -1 umgewandelt wird (dies funktioniert natürlich auch für 10).
Dieses Board sieht etwas komplizierter aus. Sie sollten sich
:I
als Name der Karte identifizieren können und einige Eingabe- und Ausgabegeräte entdeckt haben. Sie werden feststellen, dass wir zwei verschiedene Eingabegeräte haben}0
und}1
. Dies bedeutet, dass diese Funktion 2 Eingänge akzeptiert. Sie werden auch feststellen, dass es zwei Instanzen des}1
Geräts gibt. Beim Aufrufen der Funktion enthalten beide Zellen denselben Wert. Das}0
Eingabegerät befindet sich direkt über einem\/
Gerät, dies wirkt wie ein Mülleimer und entfernt jeglichen Marmor, der darauf fällt, sofort.Werfen wir einen Blick darauf, was mit einem der Murmeln passiert, die von den
}1
Eingabegeräten auf die Tafel gelegt werden:Es wird beim ersten Tick runterfallen und das
=9
Gerät treffen . Dies vergleicht den Wert der Murmel mit 9 und lässt die Murmel fallen, wenn die Anweisung=9
mit through bewertet wird. Wenn nicht, wird der Marmor nach rechts gedrückt.&0
und&1
sind Synchronisierer. Sie halten sich an Murmeln fest, die auf sie fallen, bis auch alle anderen&n
Synchronisierer gefüllt sind. Wie zu erwarten ist, wird dies bedingt ein anderes Verhalten auf einem anderen Teil der Platine auslösen.Wenn ich Ihnen sage, dass
++
es sich um einen Inkrementor handelt, sollten Sie bereits in der Lage sein, zu bestimmen, mit welchen Synchronisierungen die verschiedenen Synchronisierungen gefüllt werden. Die linke Seite&1
enthält den Eingabewert}1
+ 1, die&0
nächste 0 (00
ein hexadezimal dargestelltes Sprachliteral). Die zweite&1
enthält den Wert 1 und die rechte&0
wird mit einem gefülltF7
, der 9 von einem Wert abzieht, da die Addition in Marbelous modulo 256 ist.//
ist eine Ablenkvorrichtung, die jeglichen Marmor nach links drückt, anstatt ihn fallen zu lassen.Wenn Sie dies alles zusammenfassen, erhalten Sie Folgendes: Wenn der Marmor in
}1
9 ist, werden die&0
Synchronisierer gefüllt. Dies bewirkt, dass der Wert 0 in den{0
Ausgang undF7
(oder -9) in den{1
Ausgang fällt . Wenn}1
nicht 9,{0
wird mit}1
+ 1 gefüllt und{0
enthält 1. Es gibt auch ein{>
Gerät, dies ist ein spezieller Ausgang, der eine Kugel neben einer Tafel anstelle darunter ausgibt. Dies wird mit gefüllt,}1
wenn es gleich 9 ist.Okay, jetzt zum Großen. Dieses Board hat keinen expliziten Namen, da es das Hauptboard der Datei ist. Der implizite Name lautet
Mb
. Sie sollten in der Lage sein, einige Zellen zu erkennen. Es gibt ein Eingabegerät, einige Sprachliterale (00
undFF
). Es gibt einige Synchronisierer und einen Deflektor. Lassen Sie uns Schritt für Schritt durch diese.Der Eingabewert (die Befehlszeileneingabe, da dies die Hauptplatine ist) beginnt also in der zweiten Zelle von oben, wo er
}0
sich befindet. Es fällt herunter und erreicht das>0
Gerät, bei dem es sich um ein anderes Vergleichsgerät handelt. Jeder Marmor, der größer als 0 ist, fällt durch, jeder andere Marmor wird nach rechts gedrückt. (Da Marbelous-Variablen ohne Vorzeichen sind, wird nur genau 0 nach rechts verschoben.) Dieser Nullwert-Marmor trifft dann das@6
Gerät. Dies ist ein Portal und transportiert den Marmor zu einem anderen entsprechenden Portal, in diesem Fall direkt darüber. Die 0-Kugel erreicht dann den&0
Synchronisierer und löst einige Dinge an anderer Stelle aus.Wenn der Marmor nicht 0 ist, fällt er nach unten, wird durch
\\
Treffer nach rechts abgelenkt,--
wodurch er um eins verringert wird, und fällt dann auf/\
einen Kloner. Dieses Gerät nimmt eine Murmel und gibt eine Kopie davon rechts und eine links aus. Der linke wird nach oben zum anderen geführt,@0
wo der Marmor dieselbe Sequenz erneut durchläuft. Der linke wird woanders hingebracht. Dadurch erhalten wir eine Schleife, die die Befehlszeileneingabe einmal pro Schleife dekrementiert und bei jeder Schleife ein bestimmtes Verhalten auslöst, bis sie 0 erreicht. Anschließend wird ein anderes Verhalten ausgelöst.Lassen Sie uns einen Blick darauf werfen, was mit dem Marmor passiert, der in
@4
jede Schleife geschoben wird.Es gibt hier 3 Sprachliterale (
FF
), die sofort in Portale fallen. Diese Portale führen sie zu drei derII
Geräte.II
bezieht sich auf das Board, das:I
wir weiter unten in der Datei definiert haben. Da:I
es zwei verschiedene Eingabegeräte gibt, muss die Darstellung auf einer anderen Karte 2 Zellen breit sein. Da 6 Zellen enthalten sindII
, haben wir 3 Instanzen dieser Funktion auf dem Board.Die
FF
(oder 256 oder -1, wenn Sie wollen) Murmeln sitzen in den Eingabezellen der:I
Funktion und warten, bis genügend Eingabemurmeln vorhanden sind, um die Funktion zu starten (dh eine weitere). Hier kommt das@4
Portal ins Spiel. Dort fällt in jeder Schleife eine Kopie der dekrementierten Kommandozeilen-Eingabe durch. Dies wird das:I
Board ganz links auslösen . Anfänglich mit den Werten 256 (oder -1) und unabhängig von der Eingabe in der Befehlszeile mit -1. Die linke Murmel wird in die}0
Geräte der:I
Tafel und die rechte in die Murmel gelegt}1
. Wenn Sie sich erinnern, was dieses Board getan hat, können Sie feststellen, welches Ergebnis dies hat. Es gibt eine inkrementierte Version des rechten Eingangs auf dem linken Ausgang aus (und verwandelt eine 9 in eine 0, nicht in eine 10) und gibt entweder 1 oder -9 auf der rechten Seite aus.Der inkrementierte Wert wird von einem Portal direkt in die rechte Eingabezelle zurückgeführt, und der Wert auf der rechten Seite fällt in einen Synchronizer. Wenn ein Synchronisierer bereits eine Kugel in der Hand hält, kollidieren die beiden Kugeln. Kollidierende Murmeln werden modulo 256 addiert. Die Werte in den Synchronisierern bewirken also Folgendes: Sie beginnen leer, drehen sich dann zu 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 und dann zu 1 wieder (da 247 Modulo 256 hinzugefügt wird).
Sie können sich auch daran erinnern, dass eine Murmel nach rechts ausgegeben wird, wenn der Eingabewert auf 0 zurückspringt. Da die
:I
Karten direkt nebeneinander liegen, wird die Karte einmal nach rechts getriggert. Dies füllt die drei Synchronisierer mit Werten, die um eins höher sind, als sie sein sollten, um eine kurze Darstellung der Befehlszeileneingabe zu sein, bis diese auf 0 zurückgeschleift ist.Sie können sich auch daran erinnern, dass die
:O
Funktion einen Wert in den ASCII-Wert der Ziffer umwandelt, die den Wert -1 darstellt. Die Ausgabe dieserOO
Zellen fällt dann von der Platine, wodurch die entsprechenden ASCII-Zeichen an STDOUT ausgegeben werden.Was passiert also, wenn die Befehlszeileneingabemurmel 0 erreicht und diese
&0
Synchronisierer füllt ? Nun, ein paar Murmeln mit dem Wert 0 fallen nach unten und lösen die drei Synchronisierungen aus, die die Ziffern (+ 1) der Shortlex-Zahl unten auf der Platine enthalten.&3
wird zuerst ausgelöst, da es die höchstwertige Ziffer enthält,&2
gefolgt von&1
. Dieser Marmor wird dann zum anderen@5
Gerät teleportiert, bevor er schließlich auf die!!
Zelle trifft , die das Board terminiert.quelle
CJam,
1411 BytesProbieren Sie es online aus.
Wie es funktioniert
Dieser Ansatz basiert stark auf der Antwort von edc65 (mit seiner ausdrücklichen Erlaubnis ):
Beispiellauf
quelle
Python 2 (38)
(43)Keine Zeichenersetzung, nur Arithmetik.
Ungolfed:
Ich habe keinen guten Grund, warum die Rekursion funktioniert. Ich passe dieses Muster einfach an die Werteliste an. Wenn Sie jeweils
n-1
in geändert habenn
, erhalten Sie die reguläre Stellendarstellung.Beim Golfen
~-n
berechne ichn-1
mit höherer Priorität als/10
oder%10
und spare dabei Parens. Dasn*'_'
ist nur, um die leere Zeichenkette zu erzeugen, wennn=0
und jede andere Zeichenkette anders. Das'_'
kann zu diesem Zweck eine beliebige Zeichenfolge sein.quelle
Ruby,
7068666457 BytesDefiniert eine Funktion, die wie folgt aufgerufen werden soll
f[42]
. Hier ist die grobe Aufteilung des Algorithmus:0
getrennt.Dank für die Idee, einen Formatstring zu verwenden, geht an Falko!
Alternativ können Sie den Ansatz von edc65 verwenden:
Das sind 45 Bytes und ich beziehe es nur ein, weil ich ihn nicht damit besiege. ;)
quelle
Haskell, 67 Bytes
Diese Lösung addiert im Grunde genommen die angegebene Anzahl von Malen in Kurzschreibweise.
Verwendung:
quelle
CJam, 16 Bytes
Probieren Sie es online aus. Benötigt mindestens O (n) Zeit und Speicher. Überlassen Sie daher 100501 dem Offline-Interpreter.
Wie es funktioniert
Die Grundidee hinter diesem Ansatz besteht darin, mindestens N Shortlex-Dezimalstellen in ihrer natürlichen Reihenfolge zu berechnen und alle außer der N-ten zu verwerfen. Nicht sehr effizient, aber kurz.
Beispiellauf
quelle
Bash + Coreutils, 27 Bytes
Port of @ edc65's clevere Antwort mit den Verbesserungen von @ Dennis :
Ausgabe:
Vorherige Antwort:
Bash + Coreutils,
7154 BytesHier ist ein etwas anderer Weg, um es zu tun:
jot
gibt ansteigende hexadezimale Ganzzahlen austr
konvertiert dies in (0,1, ..., 8,9, b, ... f, 0a, 00,01, ..., 99,9b, ..., ff, 0aa, ..., 000 , ...)grep
filtert einfach alle Zeilen, die Ziffern enthalten (0,1, ..., 8,9,00, ..., 99,000 ....)sed
löscht alle bis auf die n-te Zeilesed
Zeilennummern beginnen bei 1, also Fehler, wenn 0 übergeben wird).grep
, müssen wir mehr Ganzzahlen zur Basis 11 mitseq
/dc
als der eingegebenen Zahl generieren . Das Wiederholen der Ziffern von n ist mehr als ausreichend.Beachten Sie, dass, sobald die Shortlex-Zahl gedruckt ist,
seq
weiterhin Zahlen bis zu erzeugt werden$1$1
, die sich insbesondere bei größeren Eingaben verlangsamen - O (n²), denke ich. Wir können denseq
Vorgang beschleunigen, indem wir das Programm unmittelbar nach dem Drucken beenden. Dies kostet 7 Byte:In der Frage gibt es keine Geschwindigkeitsanforderung, daher gehe ich für meine Hauptantwort auf die kürzere Version.
quelle
s='jot -w%x $1$1|tr 0-9a a0-9|grep -P ^\\d+$|sed $1!d 2>-'; echo ${#s}
. Ich vermute, Sie verwenden möglicherweise Python, um die Zeichenfolgenlänge zu messen, bei der "\\" als ein Zeichen behandelt wird.$a
scheint unnötig zu sein;cut -b2-<<<$[$1-~${1//?/8}]
sollte gut funktionieren.Python 2 -
84, 7066Alternativer Ansatz (gleiche Länge):
quelle
Python 3, 107 Zeichen
Das hat nicht gewonnen, aber ich fand es klug:
Ich definiere einen Generator für die gesamte Sequenz in 64 Zeichen. Leider muss ich einige Verzerrungen durchgehen, um das n-te Element des Generators zu erhalten ... wenn ich es nur könnte
S=lambda n:G()[n]
.quelle
Pyth , 12
Eine weitere Portierung der Antwort von @ edc65, wer ist der klare Gewinner (IMO):
Testpaket (Dank an @DigitalTrauama):
Erläuterung:
quelle
[8, 8, 9] -> 889
). Wie machst du das?jk
verwandelt Ihre Liste in einen String undv
verwandelt diesen in einen Int. Alsovjk[8 8 9]
wird die Nummer 889 vergeben.[2 -1] -> 19
und[1 11] -> 21
.Java 8, 60 Bytes
Port of @ edc65's erstaunliche JavaScript (ES6) Antwort , da ich bezweifle, dass es in Java auf arithmetische Weise kürzer gemacht werden kann.
Probieren Sie es hier aus.
quelle
Haskell , 57 Bytes
Probieren Sie es online!
Erstellt eine unendliche Liste von Shortlex-Zahlen und indiziert diese für die Antwort.
g n
Konstruiert die n-te "Generation" von Zahlen, indem die nächste Ziffer vor jeder der Zahlen der vorherigen Generation vorangestellt wird.quelle
05AB1E , 7 Bytes
Verwendet edc65's , um 8 Tricks zu ersetzen
Probieren Sie es online!
Erläuterung
quelle
Excel, 37 Bytes
Verwenden Sie den @ edc65-Ansatz:
quelle
Gelee , 5 Bytes
Probieren Sie es online!
Ich bin sehr neu bei Jelly. Wenn Sie dies verbessern können, kommentieren Sie dies bitte!
Erläuterung:
(Nach dem obigen Kommentar von res ist das Problem gleichbedeutend damit, die Zahl in die bijektive Basis 10 umzuwandeln.)
quelle