Eu li essa pergunta e achei que seria um bom desafio.
Tarefa
Dê uma entrada para 0<n<10
gerar um número aleatório com
- exatamente n dígitos
- o primeiro não é
0
- então
f(n)>10**(n-1)-1
- então
- dígitos distintos
Critérios de vitória
Isso é código-golfe, 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]
code-golf
number
random
grid
game
king-of-the-hill
javascript
code-golf
arithmetic
statistics
code-golf
math
code-golf
math
code-golf
string
palindrome
code-golf
string
interactive
code-golf
quine
polyglot
code-golf
string
stack-exchange-api
code-golf
number-theory
decision-problem
code-golf
tips
code-golf
string
internet
code-golf
graphical-output
image-processing
fractal
code-golf
ascii-art
geometry
hexagonal-grid
code-golf
string
restricted-source
hello-world
code-golf
game
code-golf
cipher
code-golf
permutations
cops-and-robbers
permutations
cops-and-robbers
code-golf
internet
stack-exchange-api
code-golf
ascii-art
random
code-golf
tips
code-golf
ascii-art
code-golf
code-golf
kolmogorov-complexity
code-golf
string
unicode
code-golf
number
sequence
primes
palindrome
code-golf
game
decision-problem
code-golf
math
geometry
code-golf
graphical-output
interactive
code-golf
set-partitions
code-golf
number
arithmetic
restricted-source
code-golf
decision-problem
python
recursion
code-golf
ascii-art
code-golf
source-layout
code-golf
function
recursion
functional-programming
code-golf
game
combinatorics
permutations
code-golf
string
file-system
code-golf
string
hashing
code-golf
stack-exchange-api
code-golf
string
code-golf
math
number
arithmetic
polyglot
Roman Gräf
fonte
fonte
Respostas:
Python 2 , 77 bytes
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
n
dígitos listados.fonte
9
ou10
.[1::3]
funciona para convertê-lo de uma lista para uma string? Eu nunca vi isso antes.[
.[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.[1, 2, 3]
já havia sido estrito e que vírgulas e espaços precisavam ser pulados. Obrigado!Braquilog ,
910 bytesExperimente 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
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
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
≜₁
antes de perceber que ela foi adicionada por causa desse desafioGeléia , 9 bytes
Experimente online! (não funcionará no TIO por n> 6 devido à ineficiência da implementação)
ou uma implementação alternativa da mesma coisa:
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
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).fonte
Gelatina , 11 bytes
Experimente online!
Como funciona
fonte
JavaScript (ES6),
72717069 bytesEsta é 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 é quey|z
retorna 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:
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/z
primeiro para gerarNaN
se ambos são 0), mas em algum momento percebi que isso simplesmentey|z
seria 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 comx-1
ey|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.fonte
ClojureScript,
8179 bytesEsta é uma função anônima, então você deve usá-la desta maneira:
Onde você substitui
{arguments}
com seus argumentos.Você pode tentar o código aqui (ClojureScript REPL).
Obrigado
@cliffroot
por remover 2 bytes!Código expandido:
Explicação:
Vou percorrer as linhas uma a uma, usando um exemplo de entrada de
8
.Muito simples, isso define a função
random-digits
com um argumento, chamadon
. Na minha resposta, usei uma função anônima (#(...)
), para salvar bytes.Vamos examinar
let
de dentro para fora:No ClojureScript (e Clojure),
(range n)
é semelhante ao do Pythonrange(n)
: fornece uma lista com todos os números de0
atén - 1
(9
nesse caso).shuffle
pega 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:(subvec vector start end)
pega um vetor (apenas um vetor) e retorna um vetor que possui todos os elementos do índicestart
atéend
. Nesse caso, estamos levando elementos do0
enésimo elemento para o argumento fornecidorandom-digits
. Se aplicarmos isso ao nosso exemplo, obtemos:Esta
if
declaração verifica se o primeiro elemento denum-vector
é a0
.Se for
0
, então chamamos a função novamente, com o argumenton
usandorecur
.Se não for
0
:(apply function list)
pega uma lista e as cospe na função como argumentos. Por exemplo:Torna-se em:
O que é igual
9
.(str items)
transforma cada item emitems
uma sequência e os concatena.int
converte qualquer coisa em um número inteiro. Portanto, se aplicarmos isso ao nosso exemplo, obtemos:Qual é a nossa resposta final.
fonte
(int string)
, em vez de(Integer/parseInt string)
:)read-string
em Clojure, mas não é muito melhor ...#(let[a(subvec(shuffle(range 10))0 %)](if(=(a 0)0)(recur %)(int(apply str a))))
se moveapply str
parte ao fim, permite comparar a0
, em vez de\0
e utilizaçõessubvec
, em vez detake
permite a utilização vector, como uma função e, assim, para removerfirst
shuffle
transformou a coleção em umvec
. Obrigado! Terá que escrever uma nova explicação, embora ...Python 2,
898180 bytesExperimente online
fonte
99**n
, só para ter certeza de que todos eles. : Dif`set(`i`)`[5*n:]]
.R, 45 bytes
fonte
k=0
já 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.while(!k[1])
trabalhar para salvar 2 bytes?Utilitários Bash + GNU, 46
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.
fonte
Java 7,
150147145134 bytes-2 bytes graças a @TheLethalCoder
(antiga) Explicação:
Código do teste:
Experimente aqui.
Exemplo de saída:
fonte
n->...
ou é que Java 8+?for(int l,x;(l=r.length())<n;)
e salvar um byte.n->...
é o Java 8. Pessoalmente, prefiro codegolf no Java 7, mesmo que o 8 seja sempre mais curto.Perl 6 , 44 bytes
Tente
Expandido:
fonte
PHP, 67 bytes
Versão Online
Todas as versões baseadas em embaralhar os dígitos de 0 a 9
71 bytes
73 bytes
fonte
MATL , 15 bytes
Experimente em MATL Online!
Explicação
fonte
Gelatina , 12 bytes
Atualmente, um byte atrás da minha outra resposta Jelly, mas eu realmente gosto deste.
Experimente online!
Como funciona
fonte
APL (Dyalog) ,
271917 bytesRequer
⎕IO←0
qual é o padrão em muitos sistemas.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 dezaté ...
⊃⍺
o primeiro dígito da última tentativa×
é positivofonte
Python 2 ,
100939290 bytesObrigado a @ mbomb007 por remover 2 bytes
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.
fonte
return(n==len(set(`k`)))*k or f(n)
. Teste-o onlinePitão , 11 bytes
Usa o mesmo algoritmo da resposta de Dennis .
Experimente online!
fonte
Perl, 48 bytes
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.
fonte
Lote, 156 bytes
x
mantém uma máscara de bits dos dígitos usados.f
indica 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=10
poderia ser suportado por 165 bytes:(
r
conté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 funcionoun=10
(a versão numérica na verdade levou 166 bytes!):A abordagem original de 170 bytes também funcionou para
n=10
:Usa manipulação de string para detectar dígitos duplicados.
fonte
Bash , 66 bytes
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!
fonte
Pitão,
1528 bytesExperimente aqui
fonte
0
, então acho que você desejará mudar^TttQ
para^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.C #,
127132128126125 bytesExperimente 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
while
loop:fonte
0
, ele primeiro tentaria oif(s.Length<1&r>0)
que é falso, mas depois fará oif(!s.Contains(r+""))
que é verdadeiro e ainda será anexado"0"
aos
primeiro dígito..Next(10)
... com um;
. Portanto, não há melhorias adicionais, mas é uma boa ideia.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;};
:)C (gcc) ,
123122100951041039997 bytesEste gerando um número aleatório real
Experimente online!
C (gcc) ,
8785 bytesAqui está imprimindo uma sequência de dígitos.
Experimente online!
fonte
PHP,
6563 bytesrecebe entrada do STDIN; corra com
-nR
.criar número aleatório entre
1
e10^N
inclusive;repita enquanto a contagem de caracteres distintos é <
N
.fonte
while(count(count_chars($x=rand(1,10**$argn),1))<$argn);echo$x;
-2 BytesMathematica
6560 BytesAqui está uma versão mais rápida, mas adiciona 9 bytes:
fonte
Java 9 JShell, 86 bytes
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:
E depois:
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).
fonte
C,
9693 bytesA inicialização aleatória de Fisher-Yates até o primeiro dígito não ser zero.
É uniforme, supondo que
rand()%i
seja uniforme. (Como para a maioria das i,RAND_MAX/i
deixa 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 .
fonte
Axioma, 191 bytes
ungolf it, resultado do teste
fonte
Água-viva , 17 bytes
Experimente online!
Resposta do garfo da geléia de Dennis .
fonte
Ruby,
5352 bytesEmbaralhe até o primeiro dígito não ser 0, depois combine os dígitos e converta para um número inteiro.
Experimente online!
fonte