Dobragem Pandigital


14

Inspirado por este CMC

Dado um número inteiro positivo maior que 0, execute a seguinte operação nele:

  • Se todos os dez dígitos únicos (1234567890 ) estiverem no número pelo menos uma vez, faça a contagem e saia do programa
  • Caso contrário, dobre o número e repita, incrementando a contagem.

A contagem começa em 0 e é o número de vezes que a entrada foi duplicada. Por exemplo, se a entrada fosse 617283945, ela precisaria ser duplicada uma vez porque 1234567890 possui todos os 10 dígitos.

Este é um portanto o código mais curto vence. A entrada pode ser tomada como uma sequência, se você desejar.

Casos de teste

input => output

617283945 => 1
2 => 67
66833 => 44
1234567890 => 0
100 => 51
42 => 55

Podemos considerar a entrada como uma string?
Stephen

@ Stephen, você pode receber a entrada como uma string.
caird coinheringaahing

3
É garantido que, para alguém n, exista algo kque nkseja pandigital? Eu adoraria ver uma prova.
shooqie

1
@bfontaine Mini desafio do bate-papo
caird coinheringaahing 15/17

3
@shooqie Proof! Para qualquer n que seja coprime para 10, também é coprime para 10 ^ 10 e, portanto, existe algum k tal que nk é 1 mod 10 ^ 10. 1234567890 * nk = 1234567890 mod 10 ^ 10; portanto, cada dígito necessariamente aparece pelo menos uma vez. Caso contrário, multiplique por 2, 5 ou 25 conforme necessário para tornar o último coprime com um dígito diferente de zero com 10 e uma variante da prova acima funciona (formalmente, n = 10 ^ m * p, em que p satisfaz a condição acima , 1234567890 * p * k, como acima, é pandigital; portanto, 1234567890 * p * k * 10 ^ m = 1234567890 * k * n é). :)
B. Mehta

Respostas:



4

J , 24 23 bytes

(]1&(+$:)2**)10>#@~.@":

Experimente online!

Explicação

(]1&(+$:)2**)10>#@~.@":  Input: integer n
                     ":  Format as string
                  ~.@    Unique
                #@       Length
             10>         Less than 10
           *             Multiply, gives n if previous was true, else 0
         2*              Multiply by 2
 ]                       Get the previous condition
  1&(   )                Execute this if true on 2n, else return 0
      $:                   Recurse
  1  +                     Add 1

Agradável. Eu estava preso na coleta dos resultados, não pensei em usar esse tipo de função recursiva.
Conor O'Brien

4

05AB1E , 11 10 bytes

-1 byte graças ao scottinet

[D9ÝåË#·]N

Experimente online! ou como um conjunto de testes

[          // Start infinity loop
 D         // Duplicate current value (or input)
  9Ý       // Push [0,1,2,3,4,5,6,7,8,9]
    å      // Does each exist in the current value
     Ë#    // Break if all equal (if every digit exists)
       ·   // Else double the current value
        ]N // End loop and print the number of times through the loop


@scottinet Obrigado! Não sei como senti falta disso.
Riley

@riley ia dizer, use xmas são 10 também ... Ótima resposta. O pensamento xse livraria D, mas é a mesma ideia.
Magic Octopus Urn

3

Perl 6 ,31 28 bytes (27 caracteres)

-3 bytes graças a @Joshua

{($_,2×*...*.comb.Set>9)-1}

Experimente online!

Explicação: Ainda é a mesma construção para gerar recursivamente listas. O primeiro elemento é o número fornecido ( $_), cada elemento seguinte é 2 vezes o anterior ( 2×*- usamos ×, porque, embora com caracteres de 2 bytes, ainda seja 1 byte mais barato que 2 * *), fazemos isso até que a condição final de *.comb.unique>9seja satisfeita , ou seja, quando houver mais de 9 caracteres únicos no número. (Tecnicamente, dividimos a string em uma lista de caracteres com .comb, forçamos um conjunto com .Set(é claro que Sets contêm cada elemento apenas uma vez) e comparamos com 9, que força o conjunto ao contexto numérico, o que, por sua vez, fornece seu número de elementos.)

Por fim, subtraímos 1 desta lista. Novamente, a lista é forçada ao contexto numérico; portanto, o que retornamos é 1 menor que o comprimento dessa lista.


Você pode usar em .Setvez de .uniquesalvar 3 bytes.
Joshua

@ Josué, bom ponto! Obrigado. Eu nunca pensei sobre isso.
Ramillies 15/09

3

JavaScript (ES6) + big.js , 84 74 73 70 bytes

Obrigado @ ConorO'Brien por salvar 10 bytes, sugerindo big.js em vez de bignumber.js
Agradecimentos a Rick Hitchcock por -1 byte
Agradecimentos a @Shaggy por -3 bytes

f=n=>[..."4"+2**29].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2))

Recebe entrada como string; suporta até cerca de 2 69 devido à conversão automática de notação científica que ocorre além desse ponto.

Snippet de teste

f=n=>[..."4"+2**29].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2))

;[617283945, 2, 66833, 1234567890, 100, 42].forEach(t=>console.log(`f(${t}) = `+f(t)))
<script src="https://cdn.rawgit.com/MikeMcl/big.js/c6fadd08/big.min.js"></script>

Alcance infinito, 106 88 87 84 bytes

Usando a opção de configuração para desativar efetivamente a notação científica ao converter números em strings, podemos ter um alcance quase infinito.


Talvez você possa encurtar o BigNumberbit usando big.js ?
Conor O'Brien

@ ConorO'Brien Isso definitivamente vai ajudar, especialmente porque newé opcional nesse. Vai atualizar, obrigado!
Justin Mariner

Salve um byte com f=n=>[..."0123456789"].every(d=>RegExp(d).test(c=Big(n)))?0:1+f(c.mul(2)).
21717 Ricky Hitchcock #

Não precisamos manipular números inteiros grandes para que você possa descartar o big.js, se desejar, reduzindo-o para 61 bytes. E você pode salvar 3 bytes substituindo a sequência de dígitos por "4"+2**29: tio.run/##BcGxDkAwEADQb2GQO41LNBZDbX7AKgbhKkSu0jZSX1/…
Shaggy

2

Gelatina , 12 , 11 bytes

QLn⁵
ḤÇпL’

Experimente online!

Tenho que ir rápido!

Explicação:

        # Helper link, takes one argument 'z'
Q       # The unique digits of 'z'
 L      # Length
  n     # Does not equal
   ⁵    # 10
        #
        # Main link
  п    # While <condition> is true, run <body> and return all intermediate results
        # Condition:
 Ç      #   The helper link
        # Body:
Ḥ       #   Double the input
        # Now we have a list of all the 'z's that we passed to the helper link
    L   # Return it's length
     ’  # minus one




2

Haskell, 44 bytes

until(\c->all(`elem`show(n*2^c))['0'..'9'])(+1)0

2

Clojure, 115 89 82 bytes

-26 bytes usando apenas uma string para representar a lista de caracteres (duh, em retrospecto) e alterando o uso de recursão para loop , o que me permitiu fazer algumas otimizações.

-7 bytes, livrando-se da chamada para bigint. Aparentemente, precisamos apenas manipular entradas que não causem um estouro.

#(loop[n % c 0](if(empty?(remove(set(str n))"1234567890"))c(recur(* 2 n)(inc c))))

Pré -olfo:

(defn pan [num]
  (loop [n num
         cnt 0]

    ; Remove all the characters from the stringified input
    ;  that are numeric. If the result is an empty list, all
    ;  the numbers were present.
    (if (empty? (remove (set (str n)) "1234567890"))
      cnt
      (recur (* 2 n) (inc cnt)))))

Você pode salvar 7 bytes usando em every?vez de empty? (remove …:#(loop[n % c 0](if(every?(set(str n))"1234567890")c(recur(* 2 n)(inc c)))))
bfontaine

@bfontaine Oh, você está certo! Obrigado. Eu vou consertar isso mais tarde. Obrigado.
Carcigenicate

2

Retina , 85 bytes

^\d*
$&¶$&
D`.(?=.*¶)
\d{10}¶\d+|\d*¶

[5-9]
#$&
T`d`EE
T`_d#`d_`\d#
#
1
}`\d\b
$&@
@

Experimente online! O link inclui casos de teste. Ligeiramente otimizado para o tempo de execução. Explicação:

^\d*
$&¶$&

Duplique o número de entrada.

D`.(?=.*¶)

Desduplique os dígitos na primeira cópia.

\d{10}¶\d+|\d*¶

Se restarem 10 dígitos, exclua os dois números, caso contrário, exclua a primeira cópia. Observe que excluir os dois números faz com que o restante do loop fique no-op.

[5-9]
#$&

Coloque um #antes de dígitos grandes.

T`d`EE

Dobre cada dígito.

T`_d#`d_`\d#

Adicione os carregamentos.

#
1

Lidar com uma transportadora líder.

}`\d\b
$&@

Acrescente um @loop até que todos os 10 dígitos sejam encontrados.

@

Imprima o número de @s adicionados.


2

APL (Dyalog Unicode) , 19 + 2 = 21 bytes

0∘{∧/⎕D∊⍕⍵:⍺⋄⍺+12×⍵}

Experimente online!

Este é um dyadic Dfn( d espirre f unctio n ), tendo 0, quando o seu argumento esquerda e o número inteiro como a direita. Como a entrada deveria ser apenas o número inteiro, adicionei 2 bytes para o argumento 0∘à contagem de bytes.

f←não está incluído na contagem de bytes, pois não é necessário . Isso facilita a criação dos casos de teste.

Como funciona:

Os cabeçalhos: removi os da contagem de bytes após algumas conversas na sala da APL, pois a função faz o que deveria fazer e os resultados estão incorretos apenas devido às configurações padrão do REPL da APL.

⎕FR←1287Define o F loat R ePresentation para 128 bits decimal (7 é o código para decimal em REPL da APL). ⎕PP←34Define a recisão P rint P para 34 dígitos. Ambos são necessários, uma vez que a representação padrão da APL para grandes números os transforma em notação científica (por exemplo, 3.14159265359E15), o que atrapalha muito o código.

0∘{∧/⎕D∊⍕⍵:⍺⋄⍺+12×⍵}  Dyadic Dfn
0                      Fixes 0 as the left argument  
          :             If
     D                 String representation of all digits [0, 9]
                       "is in"
        ⍕⍵              String representation of the input
   ∧/                   AND-reduction. Yields 1 (true) iff all digits are in the right argument.
                       return the left argument
                       Else
                 2×⍵    Double the right arg
             ⍺+1        increment the left arg
                       Recursively call this function with the new arguments.

2

Java 8, 132 110 87 74 bytes

n->{int c=0;for(;(n+"").chars().distinct().count()!=10;n*=2)c++;return c;}

-57 bytes graças a @ OlivierGrégoire .

Explicação:

Experimente aqui. (Nota: o caso de teste para 2está desativado porque deve parar em 2 68 , mas o tamanho de longé limitado a 2 63 -1.)

n->          // Method with long parameter and integer return-type
  int c=0;   //  Count-integer, starting at 0
  for(;(n+"").chars().distinct().count()!=10;
             //  Loop (1) as long as the unique amount of digits in the number are not 10
    n*=2)    //    After every iteration: multiply the input by 2
   c++;      //   Increase the count by 1
             //  End of loop (1) (implicit / single-line body)
  return c;  //  Return the counter
}            // End of method

Resposta antiga de 132 bytes usando uma Stringentrada e uma expressão regular:

n->f(n,0)int f(String n,int c){String t="";for(int i=0;i<10;t+="(?=.*"+i+++")");return n.matches(t+".*")?c:f(new Long(n)*2+"",c+1);}

Experimente aqui. (Nota: o caso de teste para 2está desativado porque causa uma StackOverflowException devido à recursão um pouco demais.)

A regex total para verificar se a String contém todos os 9 dígitos se torna ^(?=.*0)(?=.*1)(?=.*2)(?=.*3)(?=.*4)(?=.*5)(?=.*6)(?=.*7)(?=.*8)(?=.*9).*$, o que usa uma observação positiva para toda a String.


1
111 bytes (sim, a contagem de bytes é "uni-digital" ;-)
Olivier Grégoire

Observe que 2 nunca funcionará porque esperamos 2^68o primeiro número pandigital, mas os longos em Java são limitados a 2^63-1.
Olivier Grégoire

1
87 bytes . Obrigado reduce\ o /
Olivier Grégoire

1
74 bytes . Parando aqui ;-)
Olivier Grégoire 14/11

1
@KevinCruijssen Eu sei que você eliminou seu método antigo, mas quero ressaltar que você pode usar o seguinte regex para corresponder aos 10 dígitos: (?:.*?(\d)(?!.*\1)){10}
jaytea

1

Casca , 10 bytes

←Vö>9Lud¡D

Experimente online!

Explicação

        ¡D    Repeatedly double the input, collecting results in a list
 V            Return the first index where the following is true
     L          The length of
       d        the digits
      u         with duplicates removed
  ö>9           is greater than 9
←             Decrement (as Husk uses 1-indexing)

1

Mathematica, 59 48 47 46 38 bytes

-9 bytes graças a Jenny_mathy.

If[!FreeQ[DigitCount@#,0],#0[2#]+1,0]&

Experimente online usando a matemática!


2
46 bytes: Se [Tr [1 ^ Union @ IntegerDigits @ #] <10, # 0 [2 #] + 1,0] &
J42161217

O Mathematica permite funções recursivas anônimas. : o Obrigado!
totallyhuman

2
38 bytes: Se [! FreeQ [DigitCount @ #, 0], # 0 [2 #] + 1,0] &
J42161217

Ah, obrigada! BTW, `` pode ser usado para código, mas o espaço em branco à esquerda não é permitido. afuncionará, mas 'a' não.
totallyhuman

BTW, você pode usar este rodapé no TIO Print/@f/@{617283945,2,66833,1234567890,100,42}
J42161217

1

R , 74 bytes

function(x){while(!all(0:9%in%el(strsplit(c(x,""),"")))){F=F+1;x=2*x};F*1}

Experimente online! Observe que R dará a resposta errada f(2)devido a limitações de como o idioma armazena números inteiros grandes.

Explicação: Para o teste de pandigitalidade, a entrada é coagida a um vetor de caracteres juntando-se a uma sequência vazia e depois dividida em dígitos individuais. Em seguida, verificamos se todos os 0: 9 estão presentes no vetor resultante; caso contrário, incrementamos o contador, duplicamos a entrada e repetimos.

O contador usa F, que é inicializado como FALSE. Para garantir que seja coagido a numérico, multiplicamos por um antes de retornar.


usar c(x,"")é um truque parael(strsplit(...))
Giuseppe

1

PowerShell , 70 69 bytes

for($n=[bigint]$args[0];([char[]]"$n"|group).count-le9;$n*=2){$i++}$i

Experimente online!

(Quase o dobro do tempo que o Python responder: - \)

Recebe entrada $args[0], lança como a [bigint], salva para $n. Insere um forloop. A cada iteração, verificamos se o $number convertido em uma string e depois em um chararray, quando Group-Objectjuntos, possui um .count -less que ou equal 9. Ou seja, a única maneira de ser igual a 10 é se pelo menos um dígito de cada número 1234567890estiver presente. Se sim, saímos do loop. Caso contrário, nós$n*=2 e continuamos. A cada iteração dentro do loop, estamos simplesmente incrementando $i. Quando saímos do loop, simplesmente saímos $i.

Observe que para entradas como 1234567890onde todos os dígitos já são contabilizados, isso não produzirá nada, que é um valor falsey no PowerShell e equivalente a 0quando convertido como um [int]. Se não estiver certo, podemos simplesmente colocar um+ na frente da saída $ipara convertê-la explicitamente como um número inteiro.

Guardou um byte graças a Roland Heath.


Você poderia usar le9 em vez de ne10? Não estou familiarizado com o PowerShell, mas isso pode economizar um byte.
Roland Heath

@RolandHeath Indeed; boa decisão. Obrigado!
AdmBorkBork 15/09



0

Perl, 43 + 1 bytes

for$x(0..9){$_*=2,++$\,redo LINE if!/$x/}}{

Usando a -pbandeira. Isso se baseia na solução fornecida pelo Xcali acima.


0

Swift 4 , 111 bytes

func p(_ x:Int,_ c:Int=0)->Int{if !(String(Set(String(x)).sorted())=="0123456789"){return p(x*2,c+1)};return c}

Nota: Não funcionará para x = 2, devido ao estouro.

Explicação - A entrada x é primeiro convertida para string. Então Set () remove os caracteres repetidos. Em seguida, é classificado para corresponder ao resultado. Se não corresponder, x é o dobro e o contador é incrementado.


1
não funciona porque o var é de 64 bits. Existem muitas outras respostas com o mesmo problema.
Naresh


Se você acha que isso deve ser permitido, leve-o ao OP. Pode ser uma prática comum, mas o OP não o permitiu especificamente, e os casos de teste parecem sugerir que você precisa dar suporte ao 2. #
Post Rock Garf Hunter

1
@FunkyComputerMan, na verdade, eu permiti respostas que não conseguem lidar com números fora dos limites do idioma, mas Shaggy parece ter excluído o comentário perguntando sobre isso. Esta resposta está boa.
caird coinheringaahing

0

Rubi, 46. 45 39. 38 bytes

def f n;n.digits.uniq[9]?0:1+f(n*2)end

Experimente online!

Atualizações:

  1. -1 usando em def f n;vez de def f(n);.
  2. -6 usando em …[9]vez de….size==10
  3. -1 removendo um ponto e vírgula

0

Japonês , 15 bytes

LÆ*2pXÃbì_â Ê¥A

Tente


Explicação

Entrada implícita de número inteiro U.

LÆ    Ã

Crie uma matriz de números inteiros de 0para 99e passe cada um deles por uma função em que Xestá o elemento atual.

*2pX

Umultiplicado por 2 elevado à potência de X.

b

Obtenha o índice do primeiro elemento que retorna true quando passado pela função a seguir.

ì_â

Divida em uma matriz de dígitos e remova as duplicatas.

Ê¥A

Obtenha o comprimento da matriz e verifique a igualdade com 10 .


Alternativa, 15 bytes

@*2pX)ìâ sÊ¥A}a

Tente


Explicação

Entrada implícita de número inteiro U.

@            }a

Começando com 0, retorne o primeiro número que retorna true quando passado pela função a seguir, Xsendo o número atual.

*2pX)

Como acima, multiplique Upor 2 à potência de X.

ìâ

Divida em uma matriz de dígitos, remova duplicatas e junte-se a um número inteiro.

Converta em uma string, obtenha o comprimento e converta novamente em um número inteiro.

¥A

Verifique a igualdade com 10.


0

QBIC , 48 bytes, nc

{q=1[z|q=q*instr(!:$,!a-1$)]~q>0|_Xp\p=p+1┘b=b*2

Isso deve funcionar, em teoria. No entanto, na prática, isso falha porque o QBasic lança números de dez dígitos (pelo menos necessário para obter todos os dígitos) para notação científica ... Marquei-o como não concorrente por causa disso.

Explicação

{             DO ad infinitum
q=1           set q to 1
[z|           FOR a = 1 to 10
q=q*instr     multiply q by the position
(!:$             - in 'b' (read from cmd line at start) cast to string (! ... $)
,!a-1$)          - of the number a-1 [0-9] cast to string
]             NEXT
~q>0          IF any character was not found, instr gave a 0. If q != 0 all digits were present
|_Xp          THEN quit, printing  p (is 0 at start)
\p=p+1        ELSE increase step counter p
┘b=b*2        and double 'b'

0

GNU dc, 61 bytes

A entrada é copiada da parte superior da pilha (que deve estar vazia); a saída é empurrada para o topo da pilha.

[I~1r:ad0<s]ss[d1+r;a1=p]sp[d2*lfx]sh[0Sadlsxlpx11!=h]dsfxz1-

Explicação

Usamos a variável de matriz a, armazenando 1 in a[d]se o dígito destiver presente, caso contrário, retornamos a 0 lá. Usamos a extensão GNU ~para obter quociente e restante em um único comando.

# populate a[0-9] from the digits
[I~1r:ad0<s]ss

# check pandigit
# return 1 more than lowest unset element of a[]
# start with stack=0
[d1+r;a1=p]sp

# Test for pandigit; double and repeat if needed
[dd+lfx]sh
[0Sadlsxlpx11!=h]dsfx

# We left one value on the stack for each doubling, plus the original
z1-

Como bônus, isso funcionará em bases arbitrárias de números (não apenas decimais): simplesmente defina o raio de entrada conforme necessário (a constante 11na definição def será lida usando essa base numérica, portanto, é automaticamente correta).

Teste

for i in 617283945 2 66833 1234567890 100 42
do
    printf '%s => ' $i
    dc -e $i \
       -e '[I~1r:ad0<s]ss[d1+r;a1=p]sp[dd+lfx]sh[0Sadlsxlpx11!=h]dsfxz1-' \
       -e p
done
617283945 => 1
2 => 67
66833 => 44
1234567890 => 0
100 => 51
42 => 55

0

REXX, 57 bytes

arg n
do b=0 while verify(0123456789,n)>0
  n=n*2
  end
say b

0

q / kdb + , 33 bytes

Solução:

(#)1_{x*2 1 min!:[10]in 10 vs x}\

Exemplos:

q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[100]
51
q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[1234567890]
0
q)(#)1_{x*2 1 min!:[10]in 10 vs x}\[42]
55

Explicação:

Todos os bytes estão na igualdade, podem ser capazes de jogar este abaixo um pouco mais. Utiliza o scanadvérbio de q :

count 1_{x*2 1 min til[10] in 10 vs x}\ / ungolfed solution
        {                            }\ / scan over this lambda until it yields same result
                              10 vs x   / convert to base 10
                           in           / left list in right list, returns boolean list
                   til[10]              / range 0..9
               min                      / return the minimum of the list, 0 or 1
           2 1                          / list (2;1) indexed into with 0 or 1
         x*                             / return x multiplied by either 2 or 1
      1_                                / 1 drop, drop one element from front of list
count                                   / count the length of the list

Notas:

Se cairmos para o kprompt, podemos ter uma solução de 25 bytes. Converte o número em uma lista de caracteres:

q)\
  #1_{x*2 1@&/($!10)in$$x}\[100]
51
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.