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.

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.

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.


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


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

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

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!


(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.

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.


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!


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

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;}

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

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

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

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;


0

JavaScript (ES6), 39 bytes

Não usa =>

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

Bem-vindo ao PPCG!
— Stephen
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.