Numeri interi ordinati in base alle loro radici digitali


24

La radice digitale (anche ripetuta somma digitale) di un numero intero positivo è il valore (a singola cifra) ottenuto da un processo iterativo di somma delle cifre, su ciascuna iterazione usando il risultato della precedente iterazione per calcolare una somma di cifre. Il processo continua fino al raggiungimento di un numero a una cifra.

Ad esempio, la radice digitale di 65536 è 7 , perché 6 + 5 + 5 + 3 + 6 = 25 e 2 + 5 = 7 .


L'ordinamento di tutte le radici digitali non ha molto senso, dal momento che inizierebbe con infiniti 1 s.

Creeremo invece elenchi di tutti i numeri interi a singola cifra insieme alle loro radici digitali, quindi tutti i numeri a doppia cifra insieme alle loro radici digitali, quindi il triplo, il quadruplo e così via.

Ora, per ognuna di quelle liste, le ordineremo in modo che tutti gli interi con radici digitali di 1 compaiano prima, quindi tutti gli interi con radici digitali di 2 e così via. L'ordinamento sarà stabile, in modo che l'elenco di numeri interi con determinate radici digitali sia in ordine crescente dopo l'ordinamento.

Infine concateneremo questi elenchi in un'unica sequenza. Questa sequenza inizierà con tutti i numeri a una cifra, quindi tutti i numeri a doppia cifra (ordinati per radice digitale), quindi tutti i numeri a tre cifre e così via.


Sfida:

Dai positivo intero n in ingresso e uscita n 'esimo numero della sequenza sopra descritta. Puoi scegliere se l'elenco è 0 -indexed di 1 -indexed.

La sequenza è la seguente:

1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 19, 28, 37, 46, 55, 64, 73, 82, 91, 11, 20, 29 ... 
72, 81, 90, 99, 100, 109, 118, ... 
981, 990, 999, 1000, 1009, 1018, 1027, ...

Casi test:

I casi di test sono 1 indicizzati.

   n   f(n)  
   9      9
  10     10
  11     19
  40     13
  41     22
  42     31
  43     40
  44     49
  45     58
 600    105
 601    114
 602    123
 603    132
 604    141
 605    150
4050   1453
4051   1462
4052   1471
4053   1480
4054   1489
4055   1498

Più facile da copiare:

n =    9, 10, 11, 40, 41, 42, 43, 44, 45, 600, 601, 602, 603, 604, 605, 4050, 4051, 4052, 4053, 4054, 4055, 
f(n) = 9, 10, 19, 13, 22, 31, 40, 49, 58, 105, 114, 123, 132, 141, 150, 1453, 1462, 1471, 1480, 1489, 1498

chiarimenti:

  • Non puoi generare tutti e n i primi elementi. Dovrai solo emettere l' n .
  • Il codice deve teoricamente funzionare per tutti i numeri interi fino a 10 ^ 9 , ma va bene se va in timeout su TIO (o altri interpreti con limiti di tempo) per input maggiori di 999 .
  • Le spiegazioni sono incoraggiate.

È , quindi vince il codice più corto in ogni lingua! Non essere scoraggiato da altre soluzioni nella lingua in cui vuoi giocare a golf, anche se sono più brevi di quello che puoi gestire!


2
Nota divertente: questo non è ancora in OEIS
apnorton

Risposte:


16

Python 2 , 78 60 52 46 45 byte

-6 byte grazie a GB .
-1 byte grazie a Jakob .

n=input()
b=10**~-len(`n`)
print~-b+n/b+n%b*9

Provalo online!

Raggiunse infine una forma chiusa, indicizzata 1.


Python 2 , 78 byte

0-indicizzati.

d=10;k=1
exec'\nk+=9\nif k>d+7:k=d;d*=10\nif k>=d:k-=d/10*9-1'*input()
print k

Provalo online!


2
Speravo di vedere una soluzione che non creasse l'intera sequenza. Ben fatto :-)
Stewie Griffin,

Come hai ottenuto la soluzione in forma chiusa? (modifica: sembra che ci sia una spiegazione su Wikipedia )
Sevko,

@sevko Il 78-byter era la mia soluzione originale (variante un po 'non golfata qui ). Questo funziona già senza calcolare alcuna radice cubica, ma piuttosto generando il numero sequenza per numero, in base alle regole che ho osservato nella sequenza. Sulla base di questi calcoli iterativi si può contare quante volte viene eseguita ogni espressione.
Ovs,

@sevko con l' aiuto di WolframAlpha sono stato in grado di costruire una forma chiusa. Inizialmente il programma che utilizzava la forma chiusa era molto più lungo (~ 95 byte) ma con un po 'di golf e WolframAlpha questo arrivò alla sua forma attuale.
Ovs,

4

Python 3 , 80 byte

f=lambda i,k=1:k>i and sorted(range(k//10,k),key=lambda n:n%-9)[i-k]or f(i,k*10)

Provalo online!

1-indicizzati. Questo è il migliore che potrei gestire in Python 3 (beh, tranne per il 78-byter , che è una porta della mia soluzione Python 2 in basso; penso che questo sia molto più interessante, però). I programmi completi di Python 2 sono avvantaggiati per questa particolare sfida, perché hanno input()bisogno di una conversione intin Python 3 (+5 byte), execè una funzione, piuttosto che un'istruzione (+2 byte) ed /esegue la divisione di numeri interi di default se i suoi argomenti sono numeri interi in Py 2 (+1 byte), quindi è decisamente più breve della risposta di ovs .

Come funziona

Impostare

f=lambda i,k=1:k>i and ... or f(i,k*10)

Questo definisce una funzione ricorsiva f che accetta un argomento intero i e un altro, k , il cui valore predefinito è 1 . Mentre k ≤ i , la funzione f restituisce f (i, 10k) , moltiplicando k per 10 ogni volta fino a quando diventa maggiore di i .

Intervallo target e indicizzazione corretta

...range(k//10,k)...[i-k]

Dopo questo insieme di operazioni, restiamo con i , l'input iniziale e la variabile k che rappresenta la potenza più piccola di 10 maggiore di i . In questo modo, siamo in grado di generare l'intervallo (intero) [piano (k / 10), k) , che sostanzialmente include tutti gli interi che sono:

  • maggiore o uguale alla massima potenza di 10 inferiore o uguale a i
  • meno di k , la più piccola potenza di 10 maggiore di i

Poiché ignoriamo gli interi inferiori a x = floor (k / 10) , dobbiamo spostare l'indicizzazione in modo da tenere conto dei numeri mancanti. Il modo ovvio è sottrarre il loro conteggio, x , da i , in modo da indicizzarli nell'elenco (dopo l'ordinamento, che è descritto di seguito), quindi con ix . Tuttavia, poiché l'elenco contiene 9k / 10 , elementi, e l'indicizzazione in un elenco di indice -y per alcuni positivi y produce la y esimo elemento dalla fine in Python, questo è semplicemente equivalente di indicizzazione con ik , salvando 4 byte.

Ordinamento di ogni blocco in base alla radice digitale

sorted(...,key=lambda n:n%-9)

La formula per la funzione radice digitale è 1 + ((n-1) mod 9) (vedere la sezione sulla formula della congruenza di questo articolo di Wikipedia ). Poiché 1 verrebbe aggiunto in questo modo a ciascuno di essi, è superfluo durante l'ordinamento, quindi restiamo con (n-1) mod 9 . Il modo in cui l' %operatore di Python funziona quando vengono dati numeri negativi su RHS è molto conveniente, perché possiamo usare n pymod -9 invece di salvare ancora un altro byte.


Python 2 , 72 byte

Ispirato dalla presentazione di Chas Brown .

lambda i:sorted(range(1,10**len(`i`)),key=lambda n:(len(`n`),n%-9))[i-1]

Provalo online!



4

Gelatina ,  15 14 10  9 byte

D,Ḣ$‘Ḍḅ9’

Provalo online!

Come?

Utilizza una versione golf della soluzione a forma chiusa creata da ovs nella loro risposta Python ...

La formula esposta da ovs è: 9 * (n% b) + (n / b) + b - 1 dove b = 10 piano (log (n, 10))

Ora se c è il conteggio delle cifre decimali di n, allora b-1 è c-1 nove in decimale.
Questo è lo stesso di nove volte il valore di c-1 in decimale (ad es 111*9=999.).

Inoltre n / b è la cifra iniziale di n e n% b è il resto delle cifre come un numero decimale.

Una formula come b * x + y può essere implementata come una conversione [x,y]dalla base b
(cioè b ^ 1 * x + b ^ 0 * y = b * x + y )

Pertanto, possiamo prendere un numero, n (ad esempio 7045), dividerlo in cifre iniziali e finali, posizionando la cifra iniziale alla fine ( [[0,4,5],7]), aggiungere una a tutte le cifre del primo elemento per soddisfare l'aggiunta di b-1 ( [[1,5,6],7]) li converte da liste decimali in numeri interi ( [156,7]) e li converte dalla base nine ( 1411).

Nell'implementazione che segue aggiungiamo una a tutte le cifre di entrambi gli elementi quando forniamo b-1 ( [[0,4,5],8]), convertiamo da liste decimali a numeri interi ( [156,8]), convertiamo dalla base nine ( 1412) e quindi sottraggiamo quella aggiunta da questo processo ( 1411).

D,Ḣ$‘Ḍḅ9’ - Link: positive integer, n    e.g. 4091
D         - to base ten                       [4, 0, 9, 1]
   $      - last two links as a monad:
  Ḣ       -   head (modifies the list too)    4
 ,        -   pair (the modified list) with   [[0, 9, 1], 4]
    ‘     - increment (vectorises)            [[1, 10, 2], 5]
     Ḍ    - from base ten (vectorises)        [202, 5] (since 1*10^2+10*10^1+2*10^0 = 100+100+2 = 202)  
      ḅ9  - convert from base 9               1823 (since 202*9^1 + 5*9^0 = 202*9 + 6*9 = 1818 + 5 = 1823)
        ’ - decrement                         1822

Precedente, 14 byter:

æċ⁵DL,’%9ƊƲÞị@

Provalo online!

Questo crea l'elenco fino alla potenza successiva di 10 sopra l'input ordinando questi numeri naturali per [digitalRoot, digitCount]poi trova il valore nell'indice immesso.


3

Haskell , 94 88 byte

([n|x<-[0..],i<-[1..9],n<-[10^x..10^(x+1)-1],until(<10)(sum.map(read.pure).show)n==i]!!)

Provalo online! 0-indicizzati.

Spiegazione:

La comprensione dell'elenco genera la sequenza come elenco infinito in cui indicizziamo con !!:

  • x è uno in meno del numero attuale di cifre ed è disegnato dall'elenco infinito [0,1,2,3, ...]
  • iscorre nell'intervallo da 1a 9ed è utilizzato per l'ordinamento per le radici digitali
  • nscorre su tutti i numeri con x+1cifre
  • until(<10)(sum.map(read.pure).show)calcola la radice digitale ( vedi qui per una spiegazione )
  • nviene aggiunto all'elenco se la sua radice digitale è uguale i.

2

Retina , 65 byte

.
9
.+
*
L$`
$`
O$`_(_{9})*(_*)
$2
_+
$.&
N$`
$.&
"$+L`^|\d+"^~G`

Provalo online! 1-indicizzati. Spiegazione:

.
9
.+
*
L$`
$`

Costruisci un elenco di righe di _s da 0 fino alla potenza successiva di 10 (esclusivo).

O$`_(_{9})*(_*)
$2

Ordinali tutti in ordine di radice digitale.

_+
$.&

Converti da unario a decimale.

N$`
$.&

Ordinali in ordine di lunghezza.

"$+L`^|\d+"^~G`

Estrarre l' nelemento th.


2

Pyth ,  36 31 25 24 23  22 byte

1-indicizzati.

@o%tN9rFK^LThBlt`Q-QhK

Suite di test!

Come funziona (obsoleto)

@smo%tN9dcU^TKhs.lQT^LTSK – Full program. Q = input.
             Khs.lQT      – Take floor(log10(Q))+1 and store it in K.
          U^T             – Generate [0 ... T^K).
         c                – Cut at locations...
                    ^LTSK – Of the powers of 10 less than K.
  m     d                 – Map over those.
   o  N                   – Sort them by...
    %t 9                  – Themselves decremented, modulo 9.
@s                        – Flatten the result and retrieve the Q'th entry.

2

05AB1E , 19 11 byte

Port of my Python answer .

-6 byte (!) Grazie a Kevin Cruijssen .

g<°©‰`9*®O<

Provalo online!

Code           Explanation            Stack
               implicit input         [n]
g              length                 [len(n)]
 <             decrement              [len(n)-1]
  °            10 ** a                [10**(len(n) - 1)]
   ©           store value            [10**(len(n) - 1)]
    ‰          divmod                 [[n // 10**(len(n) - 1), n % 10**(len(n) - 1)]]
     `         push items to stack    [n // 10**(len(n) - 1), n % 10**(len(n) - 1)]
      9*       multiply by 9          [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9]
        ®      retrieve value         [n // 10**(len(n) - 1), n % 10**(len(n) - 1) * 9, 10**(len(n) - 1)]
         O     sum the stack          [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1)]
          <    decrement              [n // 10**(len(n) - 1) + n % 10**(len(n) - 1) * 9 + 10**(len(n) - 1) - 1]
               implicit output

Mi hai battuto, stava lavorando a una risposta che era una porta della tua risposta Python. ;) 13 byte:g<°©÷¹®%9*®O< . Qui la spiegazione che stavo per pubblicare per questo .
Kevin Cruijssen,

1
@KevinCruijssen grazie mille. Il registro sembra essere abbastanza utile. Sono stato in grado di ridimensionare altri due byte utilizzando divmod.
Ovs


1

Perl 6 ,  68  58 byte

{({|(10**$++..^10**++$).sort({({.comb.sum}…*==*).tail})}…*)[$_]}

Provalo in base 0

{sort({.chars,({.comb.sum}…*==*).tail},^10**.chars)[$_]}

Provalo in base 1

Allargato:

{  # bare block lambda with implicit parameter $_

  sort(
    {
      .chars,         # sort by the length first

      (  # generate sequence to find digital sum

        { .comb.sum } # one round of digital sum
         * == *      # stop when the digital sum matches itself (1..9)

      ).tail          # get the last value
    },

    ^                 # Range up to (and excluding)
      10 ** .chars    # the next power of 10

  )[ $_ ] # index into the sequence
}

1

Rubino , 43 38 byte

->x{9*(x%b=10**~-x.to_s.size)+x/b+b-1}

Provalo online!

Originariamente una porta dell'eccellente risposta Python di ovs, poi semplificata ancora.



1

K4 , 38 byte

Soluzione:

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:

Esempi:

q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:40
13
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:601
114
q)k)-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\:4051
1462

Spiegazione:

La soluzione di Port of Jonathan Allan mentre esaurisco la memoria costruendo le radici digitali da 1 a 1e9.

-1+9/:10/:'(0;c-1)_1_(1+c:#x)#x:1+10\: / the solution
                                  10\: / convert to base 10
                                1+     / add 1
                              x:       / save as x
                             #         / take from x
                     (      )          / do together
                          #x           / count x
                        c:             / save as c
                      1+               / add 1
                   1_                  / drop the first
                  _                    / cut at these indices
           ( ;   )                     / 2-item list
              c-1                      / length - 1
            0                          / .. zero
      10/:'                            / convert each from base 10
   9/:                                 / convert from base 9
-1+                                    / subtract 1

Bonus:

La traduzione della soluzione ovs è più semplice ma più lunga:

-1+b+/1 9*(_%;.q.mod).\:x,b:10 xexp#1_$x:

Si afferma esplicitamente che: "Il codice deve teoricamente funzionare per tutti i numeri interi fino a 10 ^ 9 " . Sembra che questo non ...?
Stewie Griffin,

Urgh. Quindi userò una delle risposte bonus mentre finirò la memoria cercando di calcolare fino a 10e6 e tanto meno 10e9. Risolverà più tardi.
streetster,


0

J, 24 byte

(]/:([:+/[:".&>":)^:_"0)

Questa espressione tacita è racchiusa tra parentesi per indicare che dovrebbe essere trattata da sola piuttosto che come parte di qualsiasi espressione successiva (come gli argomenti).

La frase '] /:' ordina (crescente '/:') l'array originale ']' dalla somma '+ /' delle cifre L'espressione

". &> ":

converte un numero in un vettore di caratteri con '":', quindi applica il suo inverso '".' - carattere al numero - applicato a ciascun elemento '&>'. Quindi, 65536 -> '65536' -> 6 5 5 3 6.

La congiunzione di potenza '^:' vicino alla fine dell'espressione applica il codice che abbiamo appena spiegato (a sinistra) un determinato numero di volte. In questo caso, il numero di volte specificato è infinito '_' che significa continuare ad applicare fino a quando il risultato non smette di cambiare.

L'ultimo "" 0 "significa applicare l'intera espressione a sinistra a ciascun elemento scalare (0-dimensionale) a destra, che sarebbe l'array di numeri a cui vogliamo applicare questo.


Come stai creando gli elenchi di input? Sto scrivendo una soluzione in K, ma metà della risposta sta generando le liste ...
streetster,

Supponevo che le liste fossero inserite esternamente. Non vedo dove la creazione dell'elenco sia parte del problema.
DevonMcC,

" Prendi un intero positivo n come input e genera l'ennesimo numero nella sequenza sopra descritta." Devi creare la sequenza (o trovare un modo per aggirare la generazione della sequenza - vedi altre risposte).
streetster,

0

Elisir , 239 byte

q=:math
e=Enum
r=fn x,f->cond do
x<10->x
1->f.(e.sum(Integer.digits x),f)end end
fn p->e.at(e.at(Stream.unfold({0,[0]},fn {a,c}->{c,{a+1,c++e.sort(trunc(q.pow 10,a)..trunc(q.pow 10,a+1)-1,&r.(&1,r)<=r.(&2,r))}}end),1+trunc q.log10 p),p)end

Provalo online!

Spiegazione in arrivo (lentamente)! Non penso che possa essere molto più breve di questo, ma sono sempre aperto ai suggerimenti


0

Perl 5 -pF , 27 byte

$_=9x$#F+$_%10**$#F*9+$F[0]

Provalo online!

Usa la formula di @ ovs e le spiegazioni di @ JonathanAllen per elaborare un bel codice compatto.

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.