Zahlen in ein "Nicht ganz Platz-Wert-System" umwandeln

11

Erstellen wir ein Zahlensystem, bei dem die größte Ziffer im Wert der n-ten Stelle (von rechts nach links) einer Zahlenlänge m immer gleich m - n + 1 ist. Um ein Beispiel zu geben, die größte 5-stellige Zahl, die in diesem System ausgedrückt werden kann wird 12345 geschrieben. Abgesehen von der Anzahl der verfügbaren Ziffern, die an einem bestimmten Ort verwendet werden können, ist jede andere Inkrementierung Standard. Wenn eine Ziffer ihre Zifferngrenze überschreiten soll, fügen wir der nächsten Ziffer eine hinzu.

So würde das Zählen in diesem System dargestellt:

1; 10; 11; 12; 100; 101; 102; 103; 110; 111; 112; 113; 120; 121; 122; 123; 1000; 1001 ...

Ihre Aufgabe ist es, eine Funktion zu schreiben, die eine Standard-Basis-10-Nummer verwendet und in mein Nummerierungssystem konvertiert.

Kürzerer Code ist vorzuziehen. Viel Glück!

** Wenn Sie nach 9 Ziffern benötigen (sollten Sie), können Sie Buchstaben verwenden oder eine zweistellige Zahl als Element einer Liste zurückgeben.

Testfälle

10 -> 111
20 -> 1003
30 -> 1023
50 -> 1123
100 -> 10035
23116 -> 1234567
21977356 -> 123456789A

Der letzte Fall kann je nach Implementierung unglaublich langsam ausgeführt werden. Sie müssen es nicht ausführen, wenn es zu lange dauert oder zu viel Speicher benötigt. Beachten Sie jedoch, dass es Möglichkeiten gibt, es schnell und mit wenig Speicher auszuführen.

Ando Bando
quelle
Ist es angesichts Ihres letzten Kommentars in Ordnung, wenn wir immer eine Liste mit den Ziffern zurückgeben?
Greg Martin
Ja, das ist ein vernünftiger Weg, um Ausgabe zu geben, solange die Zahlen korrekt sind
Ando Bando
1
Ich bekomme 100 -> 10035eher als 100 -> 10033, können Sie überprüfen?
Greg Martin
@ GregMartin 10035 scheint richtig. Ich habe meine Berechnungen mit dem Stift und nicht mit dem Programm durchgeführt und daher einen Rechenfehler gemacht. Ich denke, wir haben Computer für ein Lösegeld
Ando Bando
1
Vielleicht duplizieren? codegolf.stackexchange.com/questions/11735/…
GB

Antworten:

4

Mathematica, 64 Bytes

Part[Join@@Array[Tuples@Join[{{1}},Array[Range,#-1,3]-1]&,#],#]&

Unbenannte Funktion, die ein positives Ganzzahlargument verwendet und eine Liste von Ganzzahlen zurückgibt.

Join[{{1}},Array[Range,#-1,3]-1]Gibt die verschachtelte Liste zurück { {1}, {0,1,2}, {0,1,2,3}, ..., {0,1,...,#} }. Dann Tupleskehrt der (sortiert) Menge aller Tupel , deren erstes Element liegt in {1}, dessen zweites Element liegt in {0,1,2}, und so weiter; Dies sind die #-stelligen Zahlen in diesem Nummerierungssystem. Join@@Array[...,#]Gibt ein Array aller Zahlen in diesem Nummerierungssystem mit höchstens #Ziffern zurück und Part[...,#]extrahiert die #th-Zahl.

Das ist hoffnungslos langsam! Es läuft gut für die Eingabe von bis zu 9. Bei größeren Eingang Test durch das Ende ersetzt ,#],#]&mit ,Ceiling[0.9Log[#]]],#]&; Dies begrenzt die Anzahl der Stellen realistischer, die erforderlich sind, um im Nummerierungssystem weit genug zu gehen, um die gewünschte zu finden.

Greg Martin
quelle
3

Mathematica, 93 Bytes

Nest[#/.{x___,y_}:>{x,y+1}//.x:{y___,z_:0,w_,v___}/;w>Tr[1^x]-Tr[1^{v}]:>{y,z+1,0,v}&,{0},#]&

Reine Funktion mit erstem Argument #. Wenn eine nichtnegative Ganzzahl angegeben wird, wird die korrekte Liste der Ziffern ausgegeben (sogar 0korrekt behandelt!).

Erläuterung

Nest[f,expr,n]gibt das Ergebnis der Anwendung fauf expr nZeiten. In diesem Fall exprist dies die Liste {0}und ndie Eingabe-Ganzzahl #. Die Funktion fist kompliziert:

# (* Starting with the input # *)
 /. (* Apply the following rule *)
   {x___,y_} (* If you see a list of the form {x___,y} *)
            :> (* replace it with *)
              {x,y+1} (* this *)
                     //. (* Now apply the following rule repeatedly until nothing changes *)
                        x:{y___,z_:0,w_,v___} (* If you see a list x starting with a sequence y of 0 or more elements, 
                                                 followed by an optional element z (default value of 0),
                                                 followed by an element w,
                                                 followed by a sequence v of 0 or more elements *)
                                             /; (* such that *)
                                               w>Tr[1^x]-Tr[1^{v}] (* w is greater than the length of x minus the length of {v} *)
                                                                  :> (* replace it with *)
                                                                    {y,z+1,0,v}& (* this *)
Genisis
quelle
Gute Verwendung von y___,z_:0, um die Länge der Liste zu erhöhen!
Greg Martin
2
@ GregMartin JungHwan Min hat es gestern in einem ähnlichen Problem verwendet .
Genisis
3

Perl 6 , 38 Bytes

{map({|[X] 1,|map ^*,3..$_},1..*)[$_]}

Nimmt eine positive Ganzzahl und gibt eine Liste von Ganzzahlen aus, die die Ziffern darstellen.

Erläuterung:

{                                    }  # a lambda

 map({                    },1..*)       # for each number length from 0 to infinity,
                                        # offset by 1 to avoid a +1 in next step...

           1,|map ^*,3..$_              # generate the digit ranges, e.g.:
                                        #     length 0  ->  (1)  # bogus, but irrelevant
                                        #     length 1  ->  (1)
                                        #     length 2  ->  (1, 0..2)
                                        #     length 3  ->  (1, 0..2, 0..3)
                                        #     length 4  ->  (1, 0..2, 0..3, 0..4)

       [X]                              # take the cartesian product

      |                                 # slip the results into the outer sequence

                                 [$_]   # Index the sequence generated this way
smls
quelle
2

Pyth - 14 Bytes

Gibt einfach den nthWert zurück, der zum "Wertmuster weniger als Platz" passt.

e.f.A.eghkbjZT

Testsuite .

Maltysen
quelle
2
Funktioniert dies bei der Eingabe 2018967, bei der die letzte Ziffer gleich 10 ist?
Greg Martin
1

Haskell, 65 Bytes

i(x:r)|x>length r=0:i r|1<2=1+x:r
i[]=[1]
reverse.(iterate i[]!!)

ierhöht die Zahlen im Zahlensystem mit den Ziffern in umgekehrter Reihenfolge. iterateErstellt die unendliche Liste all dieser Zahlen beginnend mit Null, dargestellt durch []. Dann müssen Sie nur noch !!die gewünschte Nummer nehmen ( ) und reversees.

Die letzte Zeile ist eine Funktion, keine Funktionsdefinition, daher kann sie nicht wie in einer Quellcodedatei angezeigt werden. Fügen Sie stattdessen nur die anderen Zeilen in den Quellcode ein und verwenden Sie die letzte Zeile beim Interpreter (oder binden Sie die Funktion an einen Namen, indem Sie f=der letzten Zeile voranstellen ).

Anwendungsbeispiel:

*Main> reverse.(iterate i[]!!) $ 100
[1,0,0,3,5]

(8 Bytes könnten gespeichert werden, wenn [5,3,0,0,1]das Ergebnis zulässig wäre.)

Christian Sievers
quelle
1

Haskell, 49 Bytes

x=[1]:[n++[d]|n<-x,d<-[0..length n+1]]
(x!!).pred

Die erste Zeile ist eine Hilfsdefinition, und die zweite Zeile ergibt eine Funktion. Es nimmt eine Ganzzahl und gibt eine Liste von Ganzzahlen zurück. Probieren Sie es online aus!

Erläuterung

Ich definiere xals die unendliche Liste von Darstellungen, die im Herausforderungstext erwähnt werden; Die Hauptfunktion dekrementiert nur ihr Argument und indiziert in x. Die erste Zeile funktioniert folgendermaßen:

x=                     -- The list of lists x contains
 [1]:                  -- the list [1], followed by
 [n++[d]|              -- integer d appended to list n, where
  n<-x,                -- n is drawn from x, and
  d<-[0..length n+1]]  -- the new "digit" d is drawn from this range.

Sie sehen, dass dies xin Bezug auf sich selbst definiert ist, aber Haskell ist faul, so dass dies kein Problem ist.

Zgarb
quelle