Diversità digitale


16

Un numero intero positivo può essere rappresentato in una base intera 1 <= b < inf.

Quando convertito in quella base ha un certo numero di cifre distinte.

Qualsiasi numero intero positivo nella base 1ha 1una cifra distinta.

La maggior parte dei numeri interi positivi nella base 2ha 2cifre distinte, le eccezioni sono quelle del modulo 2^n - 1, che hanno solo 1.

Quindi il primo numero intero positivo che può essere rappresentato in una base intera con 1una cifra univoca è 1e il primo che può essere rappresentato con 2cifre distinte è 2.

Possiamo dire che 1è il primo intero con diversità digitale 1ed 2è il primo intero con diversità digitale 2.

Sfida:

Dato un numero intero positivo, nrestituisce il primo numero intero positivo (in base dieci *) che presenta una diversità digitale di n.

* se la tua lingua supporta solo una base specifica (ad esempio unaria o binaria), puoi generare in quella base.

Il tuo algoritmo deve funzionare in teoria per qualsiasi input intero positivo: potrebbe non funzionare perché la precisione dell'intero della tua lingua è troppo piccola per l'output; ma potrebbe non fallire perché la conversione di base è definita solo fino ad un certo limite.

Casi test

input  output
   1     1
   2     2
   3     11
   4     75
   5     694
   6     8345
   7     123717
  17     49030176097150555672
  20     5271200265927977839335179
  35     31553934355853606735562426636407089783813301667210139
  63     3625251781415299613726919161860178255907794200133329465833974783321623703779312895623049180230543882191649073441
 257     87678437238928144977867204156371666030574491195943247606217411725999221158137320290311206746021269051905957869964398955543865645836750532964676103309118517901711628268617642190891105089936701834562621017362909185346834491214407969530898724148629372941508591337423558645926764610261822387781382563338079572769909101879401794746607730261119588219922573912353523976018472514396317057486257150092160745928604277707892487794747938484196105308022626085969393774316283689089561353458798878282422725100360693093282006215082783023264045094700028196975508236300153490495688610733745982183150355962887110565055971546946484175232

Questo è , la soluzione più breve in byte vince.

OEIS: A049363 - anche il numero pandigitale più piccolo nella base n.

Risposte:


11

Gelatina , 4 byte

ṖaWḅ

Provalo online! o verifica tutti i casi di test

Come funziona

ṖaWḅ  Main link. Argument: n

Ṗ     Pop; yield [1, 2, 3, ..., n-1].
  W   Wrap; yield [n].
 a    Logical AND; yield [n, 2, 3, ..., n-1].
   ḅ  Convert the result from base n to integer.

Ho dimenticato che i valori dei luoghi potrebbero traboccare, batte il mio pessimo 7 :)
Jonathan Allan,

Vorrei che ci fosse un grafico rep vs byte usato per utente su codegolf. Forse un grafico dei byte totali utilizzati rispetto al rappresentante attuale.
Filip Haglund,

Mi ci è voluto un po 'per capire perché questo funziona ... fatto slick!
Greg Martin,

9

Python, 40 byte

f=lambda n,k=1:n*(n<k+2)or-~f(n,k+1)*n-k

Provalo su Provalo Ideone .

Come funziona

Un numero con n cifre distinte deve essere chiaramente espresso in base b ≥ n . Poiché il nostro obiettivo è ridurre al minimo il numero, b dovrebbe anche essere il più piccolo possibile, quindi b = n è la scelta logica.

Questo ci lascia con l'organizzazione delle cifre 0, ..., n-1 per creare un numero il più piccolo possibile, il che significa che le cifre più significative devono essere mantenute il più piccolo possibile. Poiché la prima cifra non può essere uno 0 nella rappresentazione canonica, il numero più piccolo è
(1) (0) (2) ... (n-2) (n-1) n = n n-1 + 2n n-3 +… + (N-2) n + (n-1) , che f calcola in modo ricorsivo.


6

Python 2, 54 46 byte

Questo è molto, molto, molto ! soluzione rapida e iterativa.

n=r=input();k=2
while k<n:r=r*n+k;k+=1
print r

Provalo online

Non c'è ricorsione, quindi funziona per input di grandi dimensioni. Ecco il risultato di n = 17000(richiede 1-2 secondi):

http://pastebin.com/UZjgvUSW


Quanto tempo ha impiegato l'input 17000? Ci vogliono 26 secondi sulla mia macchina, che sembra lento rispetto agli 0,9 secondi di Jelly ...
Dennis

Simile ma viceversa per tre byte in meno:lambda n:n**~-n+sum(i*n**(n+~i)for i in range(2,n))
Jonathan Allan,

2
46 byte e molto più veloce:n=r=input();k=2\nwhile k<n:r=r*n+k;k+=1\nprint r
Dennis

Sì, è sorprendente quanto siano più veloci mentre i loop sono comprensibili in Python.
Jonathan Allan,

@JonathanAllan Non è questo il motivo. Il calcolo dei poteri è molto lento, mentre il loop utilizza solo la moltiplicazione e l'aggiunta.
Dennis,

5

JavaScript (ES6), 29 byte

f=(b,n=b)=>n>2?f(b,--n)*b+n:b

5

J, 9 byte

#.],2}.i.

Basato sul metodo di @Dennis .

uso

   f =: #.],2}.i.
   (,.f"0) >: i. 7
1      1
2      2
3     11
4     75
5    694
6   8345
7 123717
   f 17x
49030176097150555672

Spiegazione

#.],2}.i.  Input: n
       i.  Get range, [0, 1, ..., n-1]
    2}.    Drop the first 2 values, [2, 3, ...., n-1]
  ]        Get n
   ,       Prepend it, [n, 2, 3, ..., n-1]
#.         Convert that to decimal from a list of base-n digits and return

Esiste una soluzione alternativa basata sull'utilizzo dell'indice di permutazione. Data di ingresso n , creare l'elenco di cifre [0, 1, ..., n], e trovare la permutazione utilizzando un indice di n !, E convertito che, come un elenco di basali n cifre. La soluzione corrispondente in J per 12 byte

#.]{.!A.i.,]  Input: n
        i.    Make range [0, 1, ..., n-1]
           ]  Get n
          ,   Join, makes [0, 1, ..., n-1, n]
     !        Factorial of n
      A.      Permutation index using n! into [0, 1, ..., n]
  ]           Get n
   {.         Take the first n values of that permutation
              (This is to handle the case when n = 1)
#.            Convert that to decimal from a list of base-n digits and return

Potrebbe essere più breve da costruire [1,0,2,3,...,n-1]?
Jonathan Allan,

1
@JonathanAllan Non riesco a trovare un modo, ma ho notato che gli indici di permutazione di questi sarebbero ( n -1)!
miglia

4

Rubino, 37 35 34 byte

->n{s=n;(2...n).map{|d|s=s*n+d};s}

La risposta per un dato nassume la forma 10234...(n-1)in base n. Usando n=10come esempio:

Inizia con n:10

Moltiplica per ne aggiungi 2:102

Mutliply by ne aggiungi 3:1023

E così via.

EDIT: sembra più breve usare la mappa.

EDIT 2: Grazie per la punta, m-chrzan!


(2...n)sarà un byte più breve.
m-chrzan,

3

CJam , 9 byte

ri__,2>+b

Provalo online!

Spiegazione

ri   e# Read input N.
__   e# Make two copies.
,    e# Turn last copy into range [0 1 2 ... N-1].
2>   e# Discard up to two leading values.
+    e# Prepend a copy of N.
b    e# Treat as base-N digits.

3

CJam (9 byte)

qi_,X2$tb

Demo online

Dissezione

Ovviamente il numero più piccolo con diversità digitale nsi trova convertendo [1 0 2 3 ... n-1]base in base n. Tuttavia, tieni presente che la conversione di base integrata non richiede che le cifre siano comprese nell'intervallo 0 .. n-1.

qi    e# Read integer from stdin
_,    e# Duplicate and built array [0 1 ... n-1]
X2$t  e# Set value at index 1 to n
b     e# Base conversion

Si noti che nel caso particolare n = 1otteniamo 1 [0] 1 1 tbdando 1 [0 1] bche è 1.


3

Haskell, 31 byte

f n=foldl((+).(*n))n[2..n-1]

Converte l'elenco [n,2,3,...,n-1]in base nusando il metodo di Horner tramite piegatura. Una versione meno giocata di questo è data nella pagina OEIS .

Grazie a nimi per 3 byte!


Non conosco troppo bene Haskell, il fold richiede che la funzione sia nominata ( f?) Per essere una valida soluzione da golf? (non fè più menzionato più avanti nel codice)
Jonathan Allan,

@JonathanAllan La forma della funzione lambda in Haskell è \n->fold1..., che è lunga quanto la denominazione. Puoi scrivere una funzione priva di punti in cui la variabile di input non è nominata combinando sotto-funzioni, ma sarebbe terribile qui con tre riferimenti a n.
xnor

Bene, grazie per la spiegazione. La sintassi di Haskell mi confonde un po '.
Jonathan Allan,

È possibile utilizzare foldle iniziare con n:f n=foldl((+).(*n))n[2..n-1]
nimi

3

05AB1E , 9 byte

DL¦¨v¹*y+

Provalo online!

Spiegazione

n = 4 usato per esempio.

D           # duplicate input
            # STACK: 4, 4
 L          # range(1, a)
            # STACK: 4, [1,2,3,4]
  ¦¨        # remove first and last element of list
            # STACK: 4, [2,3]
    v       # for each y in list
     ¹*     # multiply current stack with input
       y+   # and add y
            # STACK, first pass: 4*4+2 = 18
            # STACK, second pass: 18*4+3 = 75

2

C ++ - 181 55

Stavo per pubblicare quella soluzione davvero interessante usando <numeric>:

#import <vector>
#import <numeric>
using namespace std;int f(int n){vector<int> v(n+1);iota(v.begin(),v.end(),0);swap(v[0],v[1]);return accumulate(v.begin(),v.end()-1,0,[n](int r,int a){return r*n+a;});}

e poi ho capito che è molto più semplice:

int g(int n){int r=n,j=2;for(;j<n;)r=r*n+j++;return r;}

2

Perl 6 ,  34 31  30 byte

Tradotto dall'esempio di Haskell nella pagina OEIS .

{(1,0,|(2..^$^n)).reduce: $n×*+*}        # 34
{(1,0,|(2..^$^n)).reduce: $n* *+*}       # 34

{reduce $^n×*+*,1,0,|(2..^$n)}           # 31
{[[&($^n×*+*)]] 1,0,|(2..^$n)}           # 31

{reduce $_×*+*,1,0,|(2..^$_)}            # 30
  • [&(…)] giri in un operatore infix sul posto
  • Quanto […]sopra mostrato trasforma un'operazione infix in una piega (sinistra o destra a seconda dell'associatività dell'operatore)

Allargato:

{
  reduce

    # declare the blocks only parameter 「$n」 ( the 「^」 twigil )
    # declare a WhateverCode lambda that takes two args 「*」
    $^n × * + *

    # a list that always contains at least (1,0)
    1, 0,
    # with a range slipped in
    |(
      2 ..^ $n # range from 2 up-to and excluding 「$n」
               # it is empty if $n <= 2
    )
}

Uso:

my &code = {reduce $_×*+*,1,0,|(2..^$_)}

say code 1; # 1
say code 2; # 2
say code 3; # 11
say code 4; # 75
say code 7; # 123717

# let's see how long it takes to calculate a largish value:

my $start-time = now;
$_ = code 17000;
my $calc-time = now;
$_ = ~$_; # 25189207981120412047...86380901260421982999
my $display-time = now;

say "It takes only { $calc-time - $start-time } seconds to calculate 17000";
say "but { $display-time - $calc-time } seconds to stringify"

# It takes only 1.06527824 seconds to calculate 17000
# but 5.3929017 seconds to stringify

2

Brain-Flak , 84 76 byte

Grazie a Wheat Wizard per giocare a golf 8 byte

(({})<>){(({}[()]))}{}(<{}{}>)((())){{}({<({}[()])><>({})<>}{}{})([][()])}{}

Provalo online!

Spiegazione

Il programma invia i valori da 0a n-1allo stack sostituisce la parte superiore 0e 1con 1e 0. Quindi moltiplica la parte superiore dello stack per ne aggiunge il valore al di sotto di esso fino a quando non rimane un solo valore nello stack.

In sostanza trova le cifre per il numero più piccolo nella base nche contiene ncifre diverse (per n> 1 è sempre del modulo1023...(n-1) ). Quindi calcola il numero dato le cifre e la base.

Codice annotato

(({})<>)       # Pushes a copy of n to the right stack and switches to right stack
{(({}[()]))}{} # While the top of the stack != 0 copy the top of the stack-1
               #   and push it
(<{}{}>)       # Discard the top two values (0 and 1 for n > 1) and push 0
((()))         # Push 1 twice (second time so that the loop is works properly)
{{}            # Loop while stack height > 1
  (            #   Push...
    {<({}[()])><>({})<>}{} # The top value of the stack * n
    {}         #     Plus the value below the top of the stack
  )            #   End push
([][()])}{}    # End loop

È possibile sostituire {}{}(()(<()>))([][()])con (<{}{}>)([(())][])per salvare quattro byte
Post Rock Garf Hunter

Potresti quindi sostituirlo con (<{}{}>)((()))per salvare altri quattro byte
Post Rock Garf Hunter,



1

PHP, 78 byte

for(;$i<$a=$argn;)$s=bcadd($s,bcmul($i<2?1-$i:$i,bcpow($a,$a-1-$i++)));echo$s;

Versione online

60 byte funziona solo fino a n = 16 con la precisione nelle prove

Per n = 144 INF

n = 145 NAN

for(;$j<$a=$argn;)$t+=($j<2?1-$j:$j)*$a**($a-1-$j++);echo$t;


0

JavaScript (ES6), 39 bytes

Does not use =>

function f(b,n){throw f(b,n>2?--n:1)*b}

Welcome to PPCG!
Stephen
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.