Diversidade digital

16

Um número inteiro positivo pode ser representado em uma base inteira 1 <= b < inf.

Quando convertido para essa base, possui algum número de dígitos distintos.

Qualquer número inteiro positivo na base 1possui 1um dígito distinto.

A maioria dos números inteiros positivos na base 2tem 2dígitos distintos, as exceções são aquelas da forma 2^n - 1, que possuem apenas 1.

Portanto, o primeiro número inteiro positivo que pode ser representado em uma base inteira com 1dígito único é 1e o primeiro que pode ser representado com 2dígitos distintos é 2.

Podemos dizer que 1é o primeiro número inteiro com diversidade digital 1e 2é o primeiro número inteiro com diversidade digital 2.

Desafio:

Dado um número inteiro positivo, nretorne o primeiro número inteiro positivo (na base dez *) que possui uma diversidade digital de n.

* se o seu idioma suportar apenas uma base específica (por exemplo, unária ou binária), você poderá produzir nessa base.

Seu algoritmo deve funcionar em teoria para qualquer entrada inteira positiva: pode falhar porque a precisão do número inteiro do seu idioma é muito pequena para a saída; mas pode não falhar porque a conversão básica é definida apenas até algum limite.

Casos de teste

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

Isso é , a solução mais curta em bytes vence.

OEIS: A049363 - também o menor número pandigital na base n.

Jonathan Allan
fonte

Respostas:

11

Gelatina , 4 bytes

ṖaWḅ

Experimente online! ou verifique todos os casos de teste

Como funciona

Ṗ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.
Dennis
fonte
Esqueci valores lugar poderia transbordar, bate o meu péssimo 7 :)
Jonathan Allan
Eu gostaria que houvesse um gráfico de repetição vs bytes usado por usuário no codegolf. Talvez um gráfico do total de bytes usado vs representante atual.
Filip Haglund
Demorei um pouco para descobrir por que isso funciona ... bem feito!
Greg Martin
9

Python, 40 bytes

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

Teste em Ideone .

Como funciona

Um número com n dígitos distintos deve ser claramente expresso na base b ≥ n . Como nosso objetivo é minimizar o número, b também deve ser o menor possível, de modo que b = n é a escolha lógica.

Isso nos permite organizar os dígitos 0,…, n-1 para criar um número o menor possível, o que significa que os dígitos mais significativos devem ser mantidos o menor possível. Como o primeiro dígito não pode ser um 0 na representação canônica, o menor número é
(1) (0) (2) ... (n-2) (n-1) n = n n-1 + 2n n-3 +… + (N-2) n + (n-1) , que f calcula recursivamente.

Dennis
fonte
6

Python 2, 54 46 bytes

Este é um muito muito muito ! solução rápida e iterativa.

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

Experimente online

Não há recursão, portanto, ele funciona para entradas grandes. Aqui está o resultado den = 17000 (leva 1-2 segundos):

http://pastebin.com/UZjgvUSW

mbomb007
fonte
Quanto tempo levou a entrada 17000? Leva 26 segundos em minha máquina, que parece lento em comparação com 0,9 segundos de geléia ...
Dennis
Semelhante, mas o caminho inverso, por três bytes a menos:lambda n:n**~-n+sum(i*n**(n+~i)for i in range(2,n))
Jonathan Allan
2
46 bytes e muito mais rápido:n=r=input();k=2\nwhile k<n:r=r*n+k;k+=1\nprint r
Dennis
Sim, é incrível como os loops são mais rápidos do que as compreensões no Python.
Jonathan Allan
@ JonathanAllan Essa não é a razão. A computação dos poderes é muito lenta, enquanto o loop usa apenas multiplicação e adição.
Dennis
5

JavaScript (ES6), 29 bytes

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

J, 9 bytes

#.],2}.i.

Baseado no método @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

Explicação

#.],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

Existe uma solução alternativa baseada no uso do índice de permutação. Dada entrada n , criar a lista de dígitos [0, 1, ..., n], e encontrar a permutação usando um índice de n ! E converter isso como uma lista de base- n dígitos. A solução correspondente em J para 12 bytes

#.]{.!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
milhas
fonte
Poderia ser mais curto para construir [1,0,2,3,...,n-1]?
Jonathan Allan
1
@ JonathanAllan Não consigo encontrar um caminho, mas notei que os índices de permutação desses seriam ( n -1)!
miles
4

Ruby, 37 35 34 bytes

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

A resposta para um dado nassume o formulário 10234...(n-1)na basen . Usando n=10como exemplo:

Começar com n :10

Multiplique por n e adicione 2:102

Mutliply by n e adicione 3:1023

E assim por diante.

EDIT: Mais curto para usar o mapa, ao que parece.

EDIT 2: Obrigado pela dica, m-chrzan!

Lee W
fonte
(2...n)será um byte mais curto.
m-Chrzan
3

CJam , 9 bytes

ri__,2>+b

Experimente online!

Explicação

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.
Martin Ender
fonte
3

CJam (9 bytes)

qi_,X2$tb

Demonstração online

Dissecação

Obviamente, o menor número com diversidade digital né encontrado pela conversão [1 0 2 3 ... n-1]de base em base n. No entanto, observe que a conversão básica incorporada não exige que os dígitos estejam no intervalo 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

Observe que, no caso especial n = 1, obtemos 1 [0] 1 1 tbo 1 [0 1] bque é 1.

Peter Taylor
fonte
3

Haskell, 31 bytes

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

Converte a lista [n,2,3,...,n-1]em base nusando o método de Horner via dobra. Uma versão menos golfe disso é fornecida na página OEIS .

Obrigado a nimi por 3 bytes!

xnor
fonte
Não conheço Haskell muito bem, a dobra exige que a função seja nomeada ( f?) Para ser uma solução válida de golfe? (é apenas fnão é referenciado mais tarde no código)
Jonathan Allan
@ JonathanAllan O formulário da função lambda em Haskell é \n->fold1..., e é apenas o nome dele. Você pode escrever uma função sem ponto em que a variável de entrada não é nomeada pela combinação de sub-funções, mas isso seria horrível aqui com três referências a n.
Xnor
Legal, obrigado pela explicação. A sintaxe de Haskell me confunde um pouco.
Jonathan Allan
Você pode usar foldle começar com n:f n=foldl((+).(*n))n[2..n-1]
nimi
3

05AB1E , 9 bytes

DL¦¨v¹*y+

Experimente online!

Explicação

n = 4 usado por exemplo.

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
Emigna
fonte
2

C ++ - 181 55

Estava prestes a publicar essa solução realmente legal 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 então eu percebi que é muito mais fácil:

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

Perl 6 ,  34 31  30 bytes

Traduzido do exemplo Haskell na página 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
  • [&(…)] vira em um operador infix no local
  • O […]mostrado acima transforma um infix op em uma dobra (esquerda ou direita, dependendo da associação do operador)

Expandido:

{
  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
Brad Gilbert b2gills
fonte
2

Brain-Flak , 84 76 bytes

Agradecimentos ao Wheat Wizard por jogar 8 bytes

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

Experimente online!

Explicação

O programa envia os valores de 0para n-1para a pilha substitui o topo 0e 1por 1e 0. Em seguida, multiplica o topo da pilha porn e adiciona o valor abaixo dela até que haja apenas um valor restante na pilha.

Essencialmente, ele encontra os dígitos do menor número na base nque contém ndígitos diferentes (pois n> 1 é sempre do formato 1023...(n-1)). Em seguida, calcula o número dado os dígitos e a base.

Código anotado

(({})<>)       # 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
0 '
fonte
Você pode substituir {}{}(()(<()>))([][()])por (<{}{}>)([(())][])para salvar quatro bytes #
Post Rock Garf Hunter 15/16/16
Você poderia, então, substituir aquele com (<{}{}>)((()))a salvar mais quatro bytes
post rock Garf Hunter
1

Julia, 26 bytes

\(n,k=n)=k<3?n:n\~-k*n+~-k

Experimente online!

Dennis
fonte
1

PHP, 78 bytes

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

Versão Online

60 bytes trabalha apenas até n = 16 com a precisão nas caixas de teste

Para n = 144 INF

n = 145 NAN

for(;$j<$a=$argn;)$t+=($j<2?1-$j:$j)*$a**($a-1-$j++);echo$t;
Jörg Hülsermann
fonte
0

JavaScript (ES6), 39 bytes

Não usa =>

function f(b,n){throw f(b,n>2?--n:1)*b}
user71511
fonte
Bem-vindo ao PPCG!
Stephen