Conversione di numeri in un "sistema di valori non abbastanza"


11

Consente di creare un sistema di numeri in cui la cifra più grande nell'ennesimo valore del posto (contando da destra a sinistra) di una lunghezza numerica m è sempre uguale a m - n + 1. Per dare un esempio il numero più grande di 5 cifre esprimibile in questo sistema è scritto 12345. A parte il numero di cifre disponibili da utilizzare in un determinato luogo con restrizioni, tutte le altre incrementazioni sono standard. Vale a dire quando una cifra deve superare il limite di cifre, ne aggiungiamo una alla cifra successiva.

Ecco come sarebbe rappresentato il conteggio in questo sistema:

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

Il tuo compito è quello di scrivere una funzione che accetta un numero base 10 standard e lo converte nel mio sistema di numerazione.

È preferibile un codice più breve. Bonne Chance!

** Se hai bisogno di cifre dopo 9 (dovresti) puoi scegliere di usare lettere, oppure puoi restituire un numero di 2 cifre come elemento di un elenco.

Casi test

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

L'ultimo caso potrebbe essere incredibilmente lento a seconda della modalità di implementazione. Non è necessario eseguirlo se impiega troppo tempo o utilizza troppa memoria. Tuttavia, ci sono modi per farlo funzionare rapidamente e usando poca memoria.


Dato il tuo ultimo commento, va bene se restituiamo sempre un elenco con le cifre?
Greg Martin,

Sì, è un modo ragionevole di fornire output, purché i numeri siano corretti
Ando Bando

1
Sto ottenendo 100 -> 10035piuttosto che 100 -> 10033, puoi verificarlo?
Greg Martin,

@GregMartin 10035 sembra giusto. Ho fatto i miei calcoli con la penna e non con il programma e quindi ho fatto un errore di calcolo. Immagino che abbiamo un computer per un ritoom
Ando Bando il

Risposte:


4

Mathematica, 64 byte

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

Funzione senza nome che accetta un argomento intero positivo e restituisce un elenco di numeri interi.

Join[{{1}},Array[Range,#-1,3]-1]restituisce l'elenco nidificato { {1}, {0,1,2}, {0,1,2,3}, ..., {0,1,...,#} }. Quindi Tuplesrestituisce l'insieme (ordinato) di tutte le tuple il cui primo elemento si trova in {1}, il cui secondo elemento si trova in {0,1,2}, e così via; questi sono i #numeri -digit in questo sistema di numerazione. Join@@Array[...,#]restituisce un array di tutti i numeri in questo sistema di numerazione con al massimo #cifre ed Part[...,#]estrae il #numero.

Questo è irrimediabilmente lento! Funziona bene per l'input fino a 9. Per input più grandi, testalo sostituendo l'estremità ,#],#]&con ,Ceiling[0.9Log[#]]],#]&; questo mette un limite più realistico al numero di cifre necessarie per andare abbastanza lontano nel sistema di numerazione per trovare quello che vogliamo.


3

Mathematica, 93 byte

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

Funzione pura con il primo argomento #. Se viene fornito un numero intero non negativo, verrà visualizzato l'elenco di cifre corretto (anche se gestito 0correttamente!).

Spiegazione

Nest[f,expr,n]dà il risultato dell'applicazione fai expr ntempi. In questo caso, exprè l'elenco {0}ed nè l'intero di input #. La funzione fè complicata:

# (* 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 *)

Buon uso di y___,z_:0per aumentare la lunghezza della lista!
Greg Martin,

2
@GregMartin JungHwan Min lo ha usato ieri in un problema simile .
ngenesi

3

Perl 6 , 38 byte

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

Accetta un numero intero positivo e genera un elenco di numeri interi che rappresentano le cifre.

Spiegazione:

{                                    }  # 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

2

Pyth - 14 byte

Restituisce semplicemente il nthvalore che si adatta al "modello di valore inferiore al luogo".

e.f.A.eghkbjZT

Test Suite .


2
Funziona sull'input 2018967, dove l'ultima cifra è uguale a 10?
Greg Martin,

1

Haskell, 65 byte

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

iaumenta i numeri nel sistema numerico con le cifre in ordine inverso. iteratecrea l'elenco infinito di tutti questi numeri che iniziano con zero, rappresentato da []. Quindi tutto ciò che resta da fare è prendere ( !!) il numero richiesto e reverseesso.

L'ultima riga è una funzione, non una definizione di funzione, quindi non può apparire come in un file di codice sorgente. Invece, inserisci solo le altre righe nel codice sorgente e usa l'ultima riga nell'interprete (o associa la funzione a un nome anteponendo f=all'ultima riga).

Esempio di utilizzo:

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

(8 byte potrebbero essere salvati se [5,3,0,0,1]fosse una rappresentazione consentita del risultato.)


1

Haskell, 49 byte

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

La prima riga è una definizione ausiliaria e la seconda restituisce una funzione. Prende un numero intero e restituisce un elenco di numeri interi. Provalo online!

Spiegazione

Definisco xla lista infinita di rappresentazioni menzionate nel testo della sfida; la funzione principale riduce semplicemente il suo argomento e gli indici in x. La prima riga funziona in questo modo:

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.

Vedi che xè definito in termini di se stesso, ma Haskell è pigro, quindi questo non è un problema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.