Obtenha um número aleatório de n dígitos com dígitos distintos e primeiro não um 0

22

Eu li essa pergunta e achei que seria um bom desafio.

Tarefa

Dê uma entrada para 0<n<10gerar um número aleatório com

  • exatamente n dígitos
  • o primeiro não é 0
    • então f(n)>10**(n-1)-1
  • dígitos distintos

Critérios de vitória

Isso é então o código mais curto vence.

Aleatória

Quero dizer, distribuído uniformemente aleatoriamente. Portanto, do ponto de vista do programa, cada número possível tem a mesma chance. Se o idioma em que você está escrevendo tem um gerador de números aleatórios estranho, não há problema em usá-lo.

Exemplo

A lista de valores para seleção aleatória de n=2é:

[10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98]
Roman Gräf
fonte
4
Exigir aleatoriedade sem especificar uma distribuição deve ser evitado.
flawr
retornar como um inteiro, não uma string, sim?
21717 Giuseppe
@Giuseppe gerar um número aleatório
mbomb007
4
Penso nisso cada vez que alguém faz uma pergunta número aleatório xkcd.com/221
Thunda
1
@ ais523 "Dê uma entrada 0 <n <10 gere um número aleatório com"
cleblanc 25/04/17

Respostas:

17

Python 2 , 77 bytes

from random import*
r=range(10)
while[1]>r:shuffle(r)
print`r`[1:input()*3:3]

Experimente online!

Embaralha a lista de 10 dígitos até que não comece com 0 e, em seguida, cria um número com os primeiros ndígitos listados.

xnor
fonte
Definitivamente roda mais rápido e com menos memória para entrada de 9ou 10.
precisa saber é o seguinte
Solução pura! Você poderia explicar como [1::3]funciona para convertê-lo de uma lista para uma string? Eu nunca vi isso antes.
Julian Lobo
@JulianWolf Só funciona se cada elemento da lista tiver o mesmo comprimento. Na verdade, ele pega a representação de seqüência de caracteres da lista e, em seguida, corta cada terceiro caractere depois de pular o primeiro [.
mbomb007
@JulianWolf [1::3]obtém o caractere no índice 1, depois a cada terço. Pois [1, 2, 3], isso dá 123, pular os colchetes, vírgulas e espaços.
Dennis
Atire, ok - isso faz sentido. Eu estava esquecendo que isso [1, 2, 3]já havia sido estrito e que vírgulas e espaços precisavam ser pulados. Obrigado!
Julian Wolf.
10

Braquilog , 9 10 bytes

{~lℕ₁≜≠}ᶠṛ

Experimente online!

Como de costume no Brachylog, essa é uma submissão de função. O link TIO acima recebeu um argumento de linha de comando para transformar a função em um programa completo.

Eu tive que adicionar um byte extra da primeira versão disso, alterando para ℕ₁, para não permitir a saída 0 (algo que agora foi esclarecido).

Explicação

{~lℕ₁≜≠}ᶠṛ
{      }ᶠṛ  Pick a random value with these properties:
 ~l           it has length equal to the input;
   ℕ₁         it's a positive integer;
     ≜        it's a specific value (not a constraint);
      ≠       all its elements (digits in this case) are different.

Bastante ineficiente, porque o intérprete gera uma lista de todos os valores possíveis e, em seguida, escolhe um aleatoriamente (é isso que ᶠṛsignifica; Brachylog não tinha uma opção "escolher uma solução aleatória" no momento em que essa pergunta era feita).

Alguns comentários sobre a rotulagem aqui: se a opção for omitida, a seção entre chaves só produzirá um valor, uma restrição representando números com a propriedade que queremos; escolher um resultado aleatório, portanto, nos dá a restrição, e o intérprete gera o valor absoluto mínimo que atende à restrição (1, 10, 102, 1023, 10234, etc.), que não é o que queremos. Portanto, precisamos forçá-lo a construir a lista por meio de uma rotulagem explícita.

A maioria das implementações do Prolog que eu vi foram criadas para encontrar um resultado aleatório correspondente a uma restrição, mas geralmente não com probabilidade uniforme; Brachylog não tinha um, no entanto (um foi adicionado em resposta a esse desafio, mas obviamente não posso usá-lo devido a regras de brecha). Se isso acontecesse, e se desse uma probabilidade uniforme para esse problema, esse programa seria ~lℕ₁≠seguido apenas por esse componente interno, por um comprimento provável de 6 bytes.

Brachylog , 8 bytes, em colaboração com @Fatalize

~lℕ₁≠≜ᶠṛ

Experimente online!

Esse é o tipo de truque genial de baixo nível que só faz sentido com a maneira como o Prolog faz as coisas e não faz muito sentido quando descrito matematicamente.

Como antes, ~lℕ₁≠cria um valor que descreve uma restrição ("comprimento igual à entrada, número natural, todos os elementos diferentes"). Em seguida, ≜ᶠgera todos os valores possíveis que atendem à restrição. O ponto aqui é que, com a sequência de avaliação de Brachylog, nenhuma escolha real é feita até que apareça; portanto, a operação "encontrar todas as soluções" precisa se aplicar a nada além do "valor específico que cumpre uma restrição" . Isso significa que não há necessidade de {…}a selecionar seu escopo, economizando 2 bytes.


fonte
Eu iria postar uma solução ≜₁antes de perceber que ela foi adicionada por causa desse desafio
Unrelated String
8

Geléia , 9 bytes

⁵*ṖQL$€MX

Experimente online! (não funcionará no TIO por n> 6 devido à ineficiência da implementação)

ou uma implementação alternativa da mesma coisa:

⁵*ṖQL$ÐṀX

Quão?

Isso é bem sorrateiro e muito ineficiente! Jelly faz algumas coisas úteis implicitamente quando um átomo espera uma lista, mas recebe um número inteiro (isto é por design).
Esse código usa algumas dessas ações implícitas úteis:

  • O átomo monádico "pop", quando chamado com uma entrada inteira, implica implicitamente um intervalo a partir do qual pop, então uma entrada de n primeiro faz [1, 2, ..., n] e depois aparece, produzindo [1, 2 , ..., n-1] .

  • O átomo monádico Q, "desduplicar" ou "exclusivo", quando chamado com uma entrada inteira, cria implicitamente uma lista decimal para desduplicar, portanto, uma entrada de n onde:
    n = d k-1 × 10 k-1 + d k-2 × 10 k-2 + ... + d 1 × 10 + d 0
    cria primeiro
    [d k-1 , d k-2 , ..., d 1 , d 0 ]
    e depois produz os valores únicos por primeira aparência.
    Assim, por exemplo, n = 5835518 renderia [5, 8, 3, 1] .

Além disso, o átomo monádico M, "índices máximos de elementos", retorna os índices dos itens máximos de uma lista, economizando dois bytes na alternativa muito mais óbvia de testar a igualdade com a entrada e encontrar índices de verdade ⁵*ṖQL$€=⁸TX, ou⁵*ṖðQL⁼ð€TX

⁵*ṖQL$€MX - Main link: n                       e.g. 2
⁵         - literal 10
 *        - exponentiate: 10^n                      100
  Ṗ       - pop (make range 1 to 10^n, then pop)    [1  ,2  ,...,21   ,22 ,23   ,...,97   ,98   ,99]
     $€   - last two links as a monad for €ach:
   Q      -   unique (makes a decimal list first)   [[1],[2],...,[2,1],[2],[2,3],...,[9,7],[9,8],[9]]
    L     -   length                                [1  ,1  ,...,2    ,1  ,2    ,...,2    ,2    ,1  ]
       M  - indexes of maximal elements             [        ...,21       ,23,   ...,97   ,98       ]
          -                                         - i.e. all n-digit numbers with n-distinct digits.
        X - pick a random element from that list

Isso tudo é bastante ineficiente, tanto em tempo quanto em memória: primeiro é feita uma lista de 10 n números inteiros e um é descartado; depois, para cada um deles é feita uma lista de n números inteiros (não um objeto ou enum sofisticado de 4 bits) e depois desduplicado. Essa deduplicação possui uma implementação completamente baseada em lista (nenhum conjunto, conjunto classificado ou dicionários estão envolvidos sob o capô, cada dígito é verificado quanto à existência na lista que eventualmente obtém saída).
Off-line n = 7 usa ~ 0,5 GB e leva ~ 25 segundos, enquanto n = 8 usa ~ 4 GB e leva ~ 5 minutos - Eu não me incomodei em executar n = 9, pois tenho apenas 16 GB de RAM (acho que levaria ~ 45 minutos )

A implementação alternativa apenas usa o ÐṀrápido incorporado para manter o filtro mínimo (o que aqui adiciona um pouco de sobrecarga no gerenciamento para a mesma contagem de bytes).

Jonathan Allan
fonte
Oh uau. Eu estava tentando algo muito parecido com isso, mas perdi o truque de armazenar os valores para retornar nos índices da lista (preenchendo adequadamente a lista), em vez de tentar armazená-los separadamente. Esse é um truque que é útil no Jelly com bastante frequência e eu sempre sinto falta dele.
7

Gelatina , 11 bytes

9Xœ|⁵ḶẊ¤ḣ¹Ḍ

Experimente online!

Como funciona

9Xœ|⁵ḶẊ¤ḣ¹Ḍ  Main link. Argument: n

9            Set the return value to 9.
 X           Pick; pseudo-randomly select an integer from [1, ..., 9].
       ¤     Combine the three preceding links into a niladic chain.
    ⁵          Yield 10.
     Ḷ         Unlength; yield [0, ..., 9].
      Ẋ        Shuffle; pseudo-randomly select a permutation of [0, ..., 9].
  œ|         Multiset OR; prepend the selected integer to the selected permutation
             and remove the second occurrence of the first element.
         ¹   Identity; yield n.
        ḣ    Head; keep the first n digits of the permutation.
          Ḍ  Undecimal; convert from base 10 to integer.
Dennis
fonte
Isso é uma maneira muito inteligente para remover o duplicado ...
Leaky Nun
7

JavaScript (ES6), 72 71 70 69 bytes

f=(x,y="")=>x?!y.match(z=Math.random()*10|0)&&y|z?f(x-1,y+z):f(x,y):y

Esta é uma função recursiva que recebe o número de dígitos x . O segundo parâmetro y , inicialmente definido como a sequência vazia, controla o número à medida que o geramos dígito por dígito.

Primeiro, geramos um dígito aleatório z com Math.random()*10|0. Agora, queremos verificar se o y não contém z , e que y e z não são ambos 0 .

Podemos calcular a primeira condição com !y.match(z). y.match(z)retorna uma matriz (sempre verdadeira) se y contiver z , null (false) caso contrário; o !converte em um booleano e o inverte.

A segunda condição é verificada com y|z. Embora y seja uma sequência, JS a converte implicitamente em um número inteiro ao usar |. Este é um número inteiro positivo se y já contiver dígitos, 0 caso contrário. O resultado líquido é que y|zretorna 0 se y estiver vazio e z for 0 , ou um número inteiro positivo caso contrário.

Se essas duas condições forem verdadeiras, anexamos o dígito a y , diminuímos x e iniciamos o processo novamente. Caso contrário, simplesmente retornamos ao início e esperamos que o próximo dígito aleatório funcione. Quando x chega a 0 , simplesmente retornamos a string vazia para finalizar a recursão.


Versão anterior:

f=(x,y)=>x?~y>>(z=Math.random()*10|0)&1&&y|z?z+f(x-1,y|1<<z):f(x,y):""

Esta é uma função recursiva que recebe o número de dígitos. O segundo parâmetro inicialmente indefinido, y , é uma tabela de pesquisa de 10 bits nos dizendo quais dígitos já temos, convenientemente armazenados como um número inteiro.

Primeiro, geramos um dígito aleatório z com Math.random()*10|0. Agora, queremos verificar se o z 'th bit menos significativo do y não está definido, e que y e z não são ambos 0 .

Podemos calcular a primeira condição com ~y>>z&1; inverta y , mude z bits para a direita e pegue apenas o bit menos significativo. Isso fornece 1 se ainda não geramos o dígito em questão, ou 0 caso contrário.

A segunda condição foi inicialmente bastante difícil de descobrir (tentei usar y/zprimeiro para gerar NaNse ambos são 0), mas em algum momento percebi que isso simplesmente y|zseria suficiente. O resultado é 0 se y e z forem 0 ; caso contrário, um número inteiro positivo.

Se essas duas condições forem verdadeiras ( ~y>>z&1&&y|z), geramos o restante do número e acrescentamos z . O restante do número é gerado chamando a função novamente com x-1e y|1<<z( y , mas com o bit no índice z definido como 1 ). Quando x chega a 0 , simplesmente retornamos a string vazia para finalizar a recursão.

ETHproductions
fonte
5

ClojureScript, 81 79 bytes

#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))

Esta é uma função anônima, então você deve usá-la desta maneira:

(#(...) {arguments})

Onde você substitui {arguments}com seus argumentos.

Você pode tentar o código aqui (ClojureScript REPL).

Obrigado @cliffrootpor remover 2 bytes!


Código expandido:

(defn random-digits [n]
  (let [num-vector
        (subvec
          (shuffle (range 10))
          0 n)]
    (if (= (num-vector 0) 0)
      (recur n)
      (int (apply str num-vector)))))

Explicação:

Vou percorrer as linhas uma a uma, usando um exemplo de entrada de 8.


(defn random-digits [n] ...)

Muito simples, isso define a função random-digitscom um argumento, chamado n. Na minha resposta, usei uma função anônima ( #(...)), para salvar bytes.


(let [num-vector ...] ...)

Vamos examinar letde dentro para fora:

(shuffle (range 10))

No ClojureScript (e Clojure), (range n)é semelhante ao do Python range(n): fornece uma lista com todos os números de 0até n - 1( 9nesse caso).

shufflepega uma lista e retorna um vetor (que é ligeiramente diferente de uma lista) com todos os seus elementos embaralhados. Então, usando o nosso exemplo, temos algo parecido com isto:

[1 0 8 3 6 7 9 2 4 5]

(subvec {see above} 0 n)

(subvec vector start end)pega um vetor (apenas um vetor) e retorna um vetor que possui todos os elementos do índice startaté end. Nesse caso, estamos levando elementos do 0enésimo elemento para o argumento fornecido random-digits. Se aplicarmos isso ao nosso exemplo, obtemos:

[1 0 8 3 6 7 9 2]

(if (= (num-vector 0) 0)
  (recur n)
  (int (apply str num-vector)))

Esta ifdeclaração verifica se o primeiro elemento de num-vectoré a 0.

Se for 0, então chamamos a função novamente, com o argumento nusando recur.

Se não for 0:


(int (apply str num-vector))

(apply function list)pega uma lista e as cospe na função como argumentos. Por exemplo:

(apply + [2 3 4])

Torna-se em:

(+ 2 3 4)

O que é igual 9.

(str items)transforma cada item em itemsuma sequência e os concatena. intconverte qualquer coisa em um número inteiro. Portanto, se aplicarmos isso ao nosso exemplo, obtemos:

   (int (apply str [1 0 8 3 6 7 9 2]))
=> (int (str 1 0 8 3 6 7 9 2))
=> (int "10836792")
=> 10836792

Qual é a nossa resposta final.

clismique
fonte
2
Precisar amor ClojureScript por permitir que (int string), em vez de (Integer/parseInt string):)
cliffroot
1
@cliffroot Quero dizer, você pode fazer read-stringem Clojure, mas não é muito melhor ...
clismique
2 bytes salvo #(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))se move apply strparte ao fim, permite comparar a 0, em vez de \0e utilizações subvec, em vez de takepermite a utilização vector, como uma função e, assim, para removerfirst
cliffroot
@cliffroot Huh, não sabia que shuffletransformou a coleção em um vec. Obrigado! Terá que escrever uma nova explicação, embora ...
clismique
5

Python 2, 89 81 80 bytes

from random import*
lambda n:choice([i for i in range(10**n)if`set(`i`)`[5*n:]])

Experimente online

mbomb007
fonte
Não acho que você precise de um valor inicial para o intervalo.
Dennis
Agradável! Isso vai desacelerar. : D Pena que não posso usar um gerador em vez de uma lista.
mbomb007
Apenas 11%. Cair em um balde para o código de golfe.
Dennis
Sim, eu deveria usar 99**n, só para ter certeza de que todos eles. : D
mbomb007
Também pensei em fazê-lo dessa maneira, mas obtive 80 usando if`set(`i`)`[5*n:]].
Jonathan Allan
5

R, 45 bytes

k=0
i=scan()
while(!k[1])k=sample(0:9)[1:i]
k
Neil
fonte
Eu acho que você pode simplesmente definir, k=0já que é um vetor implícito de comprimento um, e você pode usar i = scan () para receber a entrada de stdin como um número. Também não tenho certeza de que uma lista de dígitos seja um envio "correto", mas não sou o juiz.
27417 Giuseppe
@ Giuseppe Obrigado pela contribuição, atualizou as duas sugestões (nos dois posts), obrigado.
Neil
Iria while(!k[1])trabalhar para salvar 2 bytes?
BLT
@BLT Atualizado, obrigado.
31417 Neil
3

Utilitários Bash + GNU, 46

seq 1e$[$1-1] 1e$1|egrep -v '(.).*\1'|shuf -n1

Experimente online .

Isso leva muito tempo para um n maior - cerca de 30s para n = 7, e aumenta 10 vezes para cada incremento, portanto, provavelmente 8-9 horas para n = 10.

Trauma Digital
fonte
pela questão, n = 10 não precisa de trabalho, mesmo, muito menos ser rápido
ysth
3

Java 7, 150 147 145 134 bytes

String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

-2 bytes graças a @TheLethalCoder

(antiga) Explicação:

String c(int n){                           // Method with integer parameter and String return-type
  String r="";                             //  Result-String
  for(int l=0,x;l<n;l=r.length()){         //  Loop until the length of the result-String is equal to the parameter integer
    x=new java.util.Random().nextInt(10);  //   Random digit
    if((l<1&x>0)                           //   If the length is zero and the random digit is not zero
       |(l>0&!r.contains(""+x)))           //     or the length is at least 1, and the result-String does not contain this random digit yet
      r+=x;                                //    Append the random digit to the result-String
  }                                        //  End of for-loop
  return r;                                //  Return result-String
}                                          // End of method

Código do teste:

Experimente aqui.

class M{
  String c(int n){String r="";for(int l,x;(l=r.length())<n;)if(l<1&(x=(int)(Math.random()*10))>0|(l>0&!r.contains(""+x)))r+=x;return r;}

  public static void main(String[] a){
    M m = new M();
    System.out.println(m.c(4));
    System.out.println(m.c(10));
  }
}

Exemplo de saída:

7194
8672953041
Kevin Cruijssen
fonte
Você não pode usar uma expressão lambda aqui? ou seja, n->...ou é que Java 8+?
TheLethalCoder
1
Você também pode pegar emprestado o truque que acabei de usar na minha resposta, definir o comprimento na verificação de comparação, ou seja, for(int l,x;(l=r.length())<n;)e salvar um byte.
TheLethalCoder
1
@TheLethalCoder Ah, claro, obrigado. Ótimo trabalho em equipe! ;) E sim, n->...é o Java 8. Pessoalmente, prefiro codegolf no Java 7, mesmo que o 8 seja sempre mais curto.
Kevin Cruijssen
2

Perl 6 , 44 bytes

{(->{+[~] (^10).pick($_)}...*>9 x$_-1).tail}

Tente

Expandido:

{  # bare block with implicit parameter 「$_」
  (

    ->{  # pointy block lambda with no parameters

      +                # turn the following into a numeric
      [~]              # concatenate the following

        (^10).pick($_) # grab $_ digits at random from 0..9
    }

    ...                # keep doing that until

    * > 9 x $_-1       # one of them is big enough

  ).tail # return the last one (only valid one)
}
Brad Gilbert b2gills
fonte
2

PHP, 67 bytes

Versão Online

Todas as versões baseadas em embaralhar os dígitos de 0 a 9

for($a=range(0,9);!$a[0];)shuffle($a);for(;$i<$argn;)echo$a[+$i++];

71 bytes

for($s="0123456789";!$s[0];)$s=str_shuffle($s);echo substr($s,0,$argn);

73 bytes

for($a=range(0,9);!$a[0];)shuffle($a);echo join(array_slice($a,0,$argn));
Jörg Hülsermann
fonte
2

MATL , 15 bytes

`4Y2GZr1)48=]8M

Experimente em MATL Online!

Explicação

`        % Do...while
  4Y2    %   Push predefined literal '0123456789'
  G      %   Push input n
  Zr     %   Random sample of n unique characters from that string
  1)     %   Pick the first
  48=    %   Is it 48? This is the loop condition
]        % End. If top of the stack evaluates to true: next iteration
8M       % Push the latest random sample. Implicitly display
Luis Mendo
fonte
2

Gelatina , 12 bytes

9×!X+!Œ?’ḣƓḌ

Atualmente, um byte atrás da minha outra resposta Jelly, mas eu realmente gosto deste.

Experimente online!

Como funciona

9×!X+!Œ?’ḣƓḌ  Main link. No arguments.

9             Set the argument and the return value to 9.
  !           Yield 9!
 ×            Compute 9 × 9!.
   X          Pick; pseudo-randomly select an integer j from [1, ..., 9 × 9!].
     !        Yield 9!
    +         Compute k := j + 9!.
              The result will belong to [9! + 1, 10!].
      Œ?      Get the permutation P of R := [1, ..., r], with minimal r, such that
              P is the lexicographically k-th permutation of R.
              Since k belongs to [9! + 1, 10!], r = 10 and this generates a per-
              mutation between [2,1,3,4,5,6,7,8,9,10] and [10,9,8,7,6,5,4,3,2,1].
        ’     Subtract 1 from all integers in P.
          Ɠ   Read an integer n from STDIN and yield it.
         ḣ    Head; keep the first n digits of the permutation.
           Ḍ  Undecimal; convert from base 10 to integer.
Dennis
fonte
2

APL (Dyalog) , 27 19 17 bytes

Requer ⎕IO←0qual é o padrão em muitos sistemas.

10⊥⊢↑{?⍨10}⍣{×⊃⍺}

Experimente online!

Embaralha os dígitos até que seja válido:

10⊥ decodificar da base 10 dígitos para o número regular,

 então

 primeiros elementos de

{... }⍣{... } repetindo a função ...
?⍨10 embaralhar os primeiros números inteiros positivos dez
até ...
⊃⍺ o primeiro dígito da última tentativa
× é positivo

Adão
fonte
1

Python 2 , 100 93 92 90 bytes

Obrigado a @ mbomb007 por remover 2 bytes

from random import*
def f(n):k=randint(10**~-n,10**n-1);return(n==len(set(`k`)))*k or f(n)

Tenta números no necessário até que um seja encontrado com dígitos únicos. Aposto que há uma maneira muito mais limpa de fazer isso, mas ninguém vem à mente.

Julian Wolf
fonte
return(n==len(set(`k`)))*k or f(n). Teste-o online
mbomb007
1

Pitão , 11 bytes

jk<{+OS9.ST
jk<{+OS9.STQ implicit Q

       9     9
      S      [1,2,3,4,5,6,7,8,9]
     O       random element

          T  10
        .S   random permutation of [0,1,2,3,4,5,6,7,8,9]

    +        add the results from the previous two paragraphs together
   {         deduplicate
  <        Q first (input) elements
jk           join by empty string

Usa o mesmo algoritmo da resposta de Dennis .

Experimente online!

Freira Furada
fonte
1

Perl, 48 bytes

1until$_=1+int rand 10**$n-1,/.{$n}/&&!/(.).*\1/

Explicação:

Gere repetidamente números inteiros aleatórios de 1 a 10 ** $ n-1, rejeitando-os até que haja um comprimento correto (portanto, pelo menos 10 ** ($ n-1)) sem dígitos repetidos.

ysth
fonte
1

Lote, 156 bytes

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set/a"r=r*10+d,f=10,x|=1<<d

xmantém uma máscara de bits dos dígitos usados. findica o número de dígitos disponíveis (contagem decrescente de 9). Dígitos aleatórios são gerados até que um dígito não utilizado seja encontrado. n=10poderia ser suportado por 165 bytes:

@set/af=9,r=x=0
@for /l %%i in (1,1,%1)do @call:c
@echo %r:~1%
@exit/b
:c
@set/a"d=9-%random%%%f,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%
@set/a"f=10,x|=1<<d

( rcontém um zero à esquerda extra porque é mais golfista dessa maneira.) A abordagem anterior para 165 bytes incluiu o primeiro dígito em especial e também funcionou n=10(a versão numérica na verdade levou 166 bytes!):

@set/ar=%random%%%9+1,x=0
@for /l %%i in (2,1,%1)do @set/a"x|=1<<d"&call:c
@echo %r%
@exit/b
:c
@set/a"d=%random%%%10,e=x>>d&1
@if %e%==1 goto c
@set r=%r%%d%

A abordagem original de 170 bytes também funcionou para n=10:

@set/ar=%random%%%9+1
@for /l %%i in (2,1,%1)do @call:c
@echo %r%
@exit/b
:c
@set/ad=%random%%%10
@call set s=%%r:%d%=%%
@if not "%s%"=="%r%" goto c
@set r=%r%%d%

Usa manipulação de string para detectar dígitos duplicados.

Neil
fonte
1

Bash , 66 bytes

a=0;while [[ $a == 0* ]];do a=`shuf -i0-9 -n$1|xargs`;done;echo $a

Experimente online!

Para a frente, use shuf, xargs é usado para unir linhas e continua a tentar enquanto a combinação começa com 0.

Não posso bater 46 caracteres de outra resposta, mas, portanto, é rápido!

marcosm
fonte
1

Pitão, 15 28 bytes

=+YhO9VtQ#KOTI!hxYK=+YKB;jkY

Experimente aqui

Maria
fonte
1
Bem-vindo ao PPCG, e ótimo trabalho usando uma linguagem de golfe logo de cara :-) Vejo dois pequenos problemas: 1) parece que o segundo dígito é sempre 0, então acho que você desejará mudar ^TttQpara ^TtQ(-1 byte, bônus!). 2) todos os dígitos da saída devem ser exclusivos, então você terá que forçar isso a acontecer de alguma forma.
ETHproductions
@ETHproductions Arg !! Obrigado por apontar isso. Eu consertei isso.
Maria
1

C #, 127 132 128 126 125 bytes

n=>{var s="";for(int l,r;(l=s.Length)<n;)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))s+=r;return s;};

Experimente Online!

Emprestou a idéia da resposta de @ KevinCruijssen para inicializar o aleatório r, noif instrução para salvar 2 bytes.

Tenho certeza de que isso ainda pode ser jogado, mas não tenho tempo no momento.


Versão antiga usando um whileloop:

n=>{var s="";while(s.Length<n){int r=new System.Random().Next(10);if(s.Length<1&r>0)s+=r;else if(!s.Contains(r+""))s+=r;}return s;};
TheLethalCoder
fonte
Eu não acho que isso esteja correto. Digamos que o primeiro inteiro aleatório seja 0, ele primeiro tentaria o if(s.Length<1&r>0)que é falso, mas depois fará o if(!s.Contains(r+""))que é verdadeiro e ainda será anexado "0"ao sprimeiro dígito.
Kevin Cruijssen
@KevinCruijssen Corrigido e jogando golfe ainda mais
TheLethalCoder
1
@KevinCruijssen Ah, eu resolvi, no seu exemplo você não termina o .Next(10)... com um ;. Portanto, não há melhorias adicionais, mas é uma boa ideia.
TheLethalCoder
1
Acabei de publicar. E oops, você está certo eu perdi que ponto e vírgula .. Você ainda pode golf-lo assim que: n=>{var s="";for(int l=0,r;l<n;l=s.Length)if((l<1&(r=new System.Random().Next(10))>0)|(l>0&!s.Contains(r+"")))r+=x;return s;};:)
Kevin Cruijssen
1
@KevinCruijssen Acabei de pegar a idéia emprestada da sua resposta enquanto você escrevia esse comentário! Agradáveis melhoria graças
TheLethalCoder
1

C (gcc) , 123 122 100 95 104 103 99 97 bytes

Este gerando um número aleatório real

j;f(n){for(int i,k=n,s[10]={j=0};n;s[i+=i?0:k==n]=!s[i]?j+=i*pow(10,--n):1)i=rand()%10;return j;}

Experimente online!

C (gcc) , 87 85 bytes

Aqui está imprimindo uma sequência de dígitos.

f(n){for(int i,k=n,s[10]={0};n;s[i+=i?0:k==n]=!s[i]?--n,putchar(48+i):1)i=rand()%10;}

Experimente online!

cleblanc
fonte
1

PHP, 65 63 bytes

while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;

recebe entrada do STDIN; corra com -nR.

criar número aleatório entre 1e 10^Ninclusive;
repita enquanto a contagem de caracteres distintos é < N.

Titus
fonte
1
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;-2 Bytes
Jörg Hülsermann
0

Mathematica 65 60 Bytes

0For[a=11,Max@DigitCount@a>1,a=RandomInteger[10^{#-1,#}]]+a&

Aqui está uma versão mais rápida, mas adiciona 9 bytes:

FromDigits@Join[f=(s=RandomSample)[r=Range@9,1],s[r/.f[[1]]->0,#-1]]&
Kelly Lowder
fonte
0

Java 9 JShell, 86 bytes

n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)

Experimente online!

Nota: Não estou contando as importações, pois esses pacotes são importados por padrão no JShell, mas não há um link Try-it-online que eu conheça para o JShell, portanto, forneço um para o Java 9 com código de cabeçalho e rodapé para fazê-lo funcionar nesse contexto. No JShell, você pode fazer:

jshell> Function<Integer,Long> f =
   ...> n->new Random().longs(0,10).limit(n-1).reduce(new Random().nextInt(9)+1,(a,b)->a*10+b)
f ==> $Lambda$27/633070006@5702b3b1

E depois:

jshell> f.apply(6)
$26 ==> 746202

Como funciona:

Definimos uma função de Inteiro para Longo e criamos um fluxo infinito de longos aleatórios no intervalo de 0 a 9, limitamos aos primeiros itens n-1 e depois a reduzimos com um int aleatório de 1 a 9 como o valor inicial e uma função que multiplica o valor por 10 e adiciona o próximo valor do fluxo.

Eu usei longs, então isso deve funcionar com até 18 dígitos (n = 18).

David Conrad
fonte
0

C, 96 93 bytes

f(n){char d[11],i=0,r;for(;i++^10;d[i-1]=d[r=rand()%i],d[r]=47+i);*d^48?d[n]=0,puts(d):f(n);}

A inicialização aleatória de Fisher-Yates até o primeiro dígito não ser zero.

É uniforme, supondo que rand()%iseja uniforme. (Como para a maioria das i, RAND_MAX/ideixa um pequeno resto, existe um viés muito pequeno. Esse viés diminui à medida que RAND_MAX cresce).

Veja como funciona online .

Veja como gerar números corretos para quando n for igual a 2, conforme mostrado na pergunta .

2501
fonte
0

Axioma, 191 bytes

g(a:NNI):Complex INT==(a<1 or a>9=>%i;r:List NNI:=[];b:=a;repeat(a=0=>break;d:=random()$INT rem 10;a=b and d=0=>0;~member?(d,r)=>(a:=a-1;r:=cons(d,r)));reduce(+,[r.i*10^(i-1)for i in 1..#r]))

ungolf it, resultado do teste

-- Return one number of 'a' different random digits if 0<a<10
f(a:NNI):Complex INT==
    a<1 or a>9=>%i
    r:List NNI:=[];b:=a
    repeat
       a=0=>break
       d:=random()$INT rem 10
       a=b and d=0  =>0
       ~member?(d,r)=>(a:=a-1;r:=cons(d,r))
    reduce(+,[r.i*10^(i-1)for i in 1..#r])

(4) -> [[i,g(i)] for i in 0..10]
   (4)
   [[0,%i], [1,9], [2,76], [3,135], [4,6810], [5,48675], [6,415768],
    [7,7461539], [8,98421537], [9,825046739], [10,%i]]
                                          Type: List List Complex Integer
(5) -> [[i,g(i)] for i in [3,3,3,3,3,3,3,3,3]]
   (5)
   [[3,653],[3,128],[3,254],[3,268],[3,914],[3,594],[3,276],[3,240],[3,398]]
RosLuP
fonte
0

Ruby, 53 52 bytes

Embaralhe até o primeiro dígito não ser 0, depois combine os dígitos e converta para um número inteiro.

->n{a=*0..9;a.shuffle!while a[0]==0;eval a[0,n]*''}

Experimente online!

Valor de tinta
fonte