Conversion de nombres en un «système de valeur de lieu pas tout à fait»

11

Permet de créer un système de nombres où le plus grand chiffre de la nième valeur (en comptant de droite à gauche) d'une longueur de nombre m est toujours égal à m - n + 1. Pour donner un exemple, le plus grand nombre à 5 chiffres exprimable dans ce système est écrit 12345. Mis à part le nombre de chiffres disponibles pour être utilisés dans un endroit particulier étant restreint, toutes les autres incrémentations sont standard. À savoir lorsqu'un chiffre doit dépasser sa limite de chiffres, nous en ajoutons un au chiffre suivant.

Voici comment le comptage serait représenté dans ce système:

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

Votre tâche consiste à écrire une fonction qui prend un nombre standard de base 10 et le convertit dans mon système de numérotation.

Un code plus court est préférable. Bonne chance!

** Si vous avez besoin de chiffres après 9 (vous devriez), vous pouvez choisir d'utiliser des lettres, ou vous pouvez renvoyer un nombre à 2 chiffres comme élément d'une liste.

Cas de test

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

Le dernier cas peut être incroyablement lent à exécuter en fonction de la façon dont vous avez implémenté. Vous n'avez pas besoin de l'exécuter s'il prend trop de temps ou utilise trop de mémoire. Notez cependant qu'il existe des moyens de l'exécuter rapidement et en utilisant peu de mémoire.

Ando Bando
la source
Compte tenu de votre dernier commentaire, est-ce correct si nous renvoyons toujours une liste avec les chiffres?
Greg Martin
Oui, c'est une façon raisonnable de donner une sortie, tant que les chiffres sont corrects
Ando Bando
1
Je reçois 100 -> 10035plutôt que 100 -> 10033, pouvez-vous vérifier?
Greg Martin
@GregMartin 10035 semble juste. J'ai fait mes calculs par plume et non par programme et j'ai donc fait une erreur de calcul. Je suppose que nous avons des ordinateurs pour une reasom
Ando Bando

Réponses:

4

Mathematica, 64 octets

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

Fonction sans nom prenant un argument entier positif et renvoyant une liste d'entiers.

Join[{{1}},Array[Range,#-1,3]-1]renvoie la liste imbriquée { {1}, {0,1,2}, {0,1,2,3}, ..., {0,1,...,#} }. Renvoie ensuite Tuplesl'ensemble (trié) de tous les tuples dont le premier élément se trouve {1}, dont le deuxième se trouve {0,1,2}, etc. ce sont les #nombres à chiffres dans ce système de numérotation. Join@@Array[...,#]renvoie un tableau de tous les nombres dans ce système de numérotation avec au plus des #chiffres, et Part[...,#]extrait le #th tel nombre.

C'est désespérément lent! Il fonctionne bien pour l'entrée jusqu'à 9. Pour une entrée plus grande, testez-la en remplaçant l'extrémité ,#],#]&par ,Ceiling[0.9Log[#]]],#]&; cela met un plafond plus réaliste sur le nombre de chiffres nécessaires pour aller assez loin dans le système de numérotation pour trouver celui que nous voulons.

Greg Martin
la source
3

Mathematica, 93 octets

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},#]&

Fonction pure avec premier argument #. Si un entier non négatif est donné, il affichera la liste correcte des chiffres (même gère 0correctement!).

Explication

Nest[f,expr,n]donne le résultat de l'application faux expr ntemps. Dans ce cas, exprest la liste {0}et nest l'entier d'entrée #. La fonction fest compliquée:

# (* 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 *)
ngenisis
la source
Belle utilisation de y___,z_:0pour augmenter la longueur de la liste!
Greg Martin
2
@GregMartin JungHwan Min l'a utilisé hier dans un problème similaire .
ngenisis
3

Perl 6 , 38 octets

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

Prend un entier positif et génère une liste d'entiers représentant les chiffres.

Explication:

{                                    }  # 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
la source
2

Pyth - 14 octets

Renvoie simplement la nthvaleur qui correspond au "modèle de valeur inférieure à la valeur de position".

e.f.A.eghkbjZT

Suite de tests .

Maltysen
la source
2
Est-ce que cela fonctionne sur l'entrée 2018967, où le dernier chiffre est égal à 10?
Greg Martin
1

Haskell, 65 octets

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

iaugmente les nombres dans le système numérique avec les chiffres dans l'ordre inverse. iteratecrée la liste infinie de tous ces nombres commençant par zéro qui est représenté par []. Il ne reste alors plus qu'à prendre ( !!) le nombre demandé et reversece.

La dernière ligne est une fonction, pas une définition de fonction, elle ne peut donc pas apparaître telle quelle dans un fichier de code source. Au lieu de cela, placez uniquement les autres lignes dans le code source et utilisez la dernière ligne de l'interpréteur (ou liez la fonction à un nom en ajoutant f=la dernière ligne à la dernière ligne).

Exemple d'utilisation:

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

(8 octets pourraient être enregistrés si la [5,3,0,0,1]représentation du résultat était autorisée.)

Christian Sievers
la source
1

Haskell, 49 octets

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

La première ligne est une définition auxiliaire et la seconde est évaluée en fonction. Il prend un entier et retourne une liste d'entiers. Essayez-le en ligne!

Explication

Je définis xcomme la liste infinie de représentations mentionnées dans le texte du défi; la fonction principale décrémente juste son argument et indexe en x. La première ligne fonctionne comme ceci:

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.

Vous voyez que xc'est défini en termes de lui-même, mais Haskell est paresseux, donc ce n'est pas un problème.

Zgarb
la source