Seu programa / função deve
- produzir exatamente um número inteiro
- gera qualquer número inteiro com probabilidade positiva
- gerar um número inteiro maior que 1.000.000 ou menor que -1.000.000 com pelo menos 50% de probabilidade.
Exemplo de saídas (tudo deve ser possível):
59875669123
12
-42
-4640055890
0
2014
12
24
-7190464664658648640055894646646586486400558904644646646586486400558904646649001
Esclarecimentos:
- É permitida uma quebra de linha à direita.
- Zeros à esquerda não são permitidos.
-0
é permitido.
O menor código vence.
way too long to fit in an integer
- Isso só é verdade se você assumir queinteger
significa oint
tipo de dados em um arco de 32/64 bits, o que não é necessariamente uma suposição válida. "Inteiro" começou como um termo matemático , que não possui restrições de tamanho.Respostas:
CJam,
161413 bytesIsso será executado por um período muito longo, porque usa o registro de data e hora atual (da ordem de 10 a 12 ) para determinar se o loop deve terminar. Estou usando isso como envio, pois é o mais curto, mas existem duas alternativas de 14 bytes, que têm seus próprios méritos:
Este não é limitado pelo período do PRNG, pois o intervalo de todos os números aleatórios depende do carimbo de data / hora atual. Portanto, isso deve ser capaz de produzir qualquer número, embora a probabilidade de números positivos negativos ou mesmo pequenos seja muito pequena.
Abaixo está uma versão equivalente que usa em
3e5
vez do carimbo de data e hora. E20
para o primeiro intervalo (como o envio de 13 bytes). É muito mais rápido e também cumpre todas as regras. É uma espécie de caso limitativo obter 50% de probabilidade de números além de 1.000.000, mantendo um tempo de execução razoável e um tamanho de código pequeno. A explicação e justificativa matemática se referem a esta versão:Isso geralmente leva alguns segundos para ser executado. Você pode substituir o
5
por um2
para torná-lo ainda mais rápido. Porém, o requisito com probabilidade de 50% será atendido somente para 1.000, em vez de 1.000.000.Estou começando em 0. Então eu tenho um loop, do qual rompo com probabilidade 1 / (3 * 10 5 ). Dentro desse loop, adiciono um número inteiro aleatório entre -1 e 18 (inclusive) ao meu total em execução. Há uma probabilidade finita (embora pequena) de que cada número inteiro seja produzido, com números inteiros positivos muito mais prováveis que negativos (não acho que você verá um negativo em sua vida). Romper com uma probabilidade tão pequena e aumentar a maior parte do tempo (e adicionar muito mais do que subtrair) garantem que geralmente ultrapassemos 1.000.000.
Alguma justificativa matemática:
A probabilidade de fazermos menos que esse número de etapas é
que avalia como
0.324402
. Portanto, em cerca de dois terços dos casos, daremos mais 117.647 etapas e facilmente cada 1.000.000.9e9
sem adicionar bytes (exceto anos de tempo de execução).... ou 11 bytes?
Finalmente, há uma versão de 11 bytes, que também não é limitada pelo período do PRNG, mas que fica sem memória quase sempre. Ele gera apenas um número aleatório (com base no registro de data e hora) a cada iteração e o utiliza para incrementar e terminar. Os resultados de cada iteração permanecem na pilha e são resumidos apenas no final. Agradecemos a Dennis por essa ideia:
fonte
Kmr
em um período ainda é provavelmente sempre um grande número positivo maior que o período. E não pode produzir todos os números possíveis nesse caso.Java,
133149Saídas de exemplo
Ungolfed
Resposta antiga (antes da alteração da regra)
fonte
-
.Mathematica - 47
Basicamente, apenas gere um número aleatório usando distribuição normal com variação igual a 1500000. Isso produzirá um número inteiro entre -10 ^ 6 e 10 ^ 6 com probabilidade 49.5015%.
fonte
Python 2,
7569 bytesÉ trivial verificar se o loop while no meio pode gerar todos os números inteiros (embora com tendência a zero). "12" é escolhido de modo que haja aproximadamente metade dos números excedendo ± 10 6 .
Solução mais antiga:
Python 2, 44 bytesCom base no solução Mathematica .Realmente não funciona porque o Python
float
tem apenas precisão finita.fonte
Ruby, 70
Para possibilitar a geração de números muito grandes, retornarei o número como um
String
de um lambda. Se isso não for permitido, conte 8 caracteres extras (paraputs f[]
) para torná-lo um programa em vez de uma função.Explicação
Gere um número entre
-1,000,000
e1,000,000
. Se o número é1
maior ou igual, ele será retornado como aString
.Se o número for menor que
1
, a função é chamada recursivamente para retornar um número fora do intervalo de números. Para garantir que números negativos também possam ser gerados, a-
é prefixado ao resultadoString
se o número inicial for maior que-500,000
.Espero ter entendido o desafio corretamente!
fonte
R, 38
Empates da distribuição gaussiana com média de 2.000.000, escolhidos aleatoriamente e desvio padrão de 1.000.000, de modo que cerca de 2/3 dos empates se situem entre 1.000.000 e 3.000.000. A distribuição é ilimitada, portanto, em teoria, isso pode gerar qualquer número inteiro. O pacote Rmpfr substitui os R's incorporados em flutuadores duplos por precisão arbitrária.
fonte
sample(c(1,-1),1)
pensar no todo . Apenas centralizar em 1e6 deve ser suficiente .. #Perl, 53 caracteres
Certamente não vejo motivo para trabalhar com números inteiros ao imprimir um :)
Tem probabilidade igual de imprimir um número com ou sem um "-" inicial.
Imprime um número de 1 dígito 10% das vezes, um número de 2 dígitos 9% das vezes, um número de 3 dígitos 8,1% das vezes, um número de 4 dígitos 7,29% das vezes, um número de 5 dígitos 6,56% do tempo, um número de 6 dígitos 5,9% do tempo, etc. Qualquer comprimento é possível, com probabilidade decrescente. Os números de um a cinco dígitos representam cerca de 41,5% dos casos de saída, e o número 1.000.000 (ou -1.000.000) apenas 6 milionésimos de um por cento, portanto, o número de saída estará fora do intervalo -1.000.000 a 1.000.000, cerca de 54,6 % do tempo.
"0" e "-0" são saídas possíveis, o que espero não seja um problema.
fonte
print int(rand(20)-10)||1
. Eu preciso de uma maneira de gerar 0 como saída, no entanto. Talvez || morra 0, se o lixo após o zero for permitido. Caso contrário, é necessário um caminho curto para imprimir o zero e sair sem saída adicional seint(rand(20)-10)==0
.Perl, 114 caracteres
Demolir:
A probabilidade de obter um valor entre -1.000.000 e 1.000.000 tende a zero, mas é possível.
Perl, 25Gera um número inteiro aleatório no intervalo de +/- 2 ^ 99.
Demolir
Testado com 1 milhão de amostras:
Isso atende a todas as regras:
Editar:
Eu tive que aumentar o expoente para que números inteiros maiores fossem gerados. Eu escolhi 99 porque mantém o código o mais curto possível.fonte
-2^31
e+2^31-1
(32 bits). Você pode aumentar facilmente os expoentes se desejar gerar números inteiros maiores, mas isso pode falhar dependendo da implementação do Perl.1.#INF
para ser exato) #C #,
126107 bytesUngolfed:
Chance de gerar um número de n dígitos é 1/2 ^ (n-10), que é maior que 0 para todos os n positivos e 1/2 para n = 11.
Também cria zeros à esquerda, que não parecem ser proibidos na pergunta original ou em qualquer um de seus comentários.fonte
using System;
, você não precisaSystem.Random
duas vezes, mas apenasRandom
, certo?using
instruções. Pouparia apenas 1 caractere de qualquer maneira.-1E6, 1E6+1
.Perl, 62 bytes
print $n=int rand(20)-10;while($n&&rand>.1){print int rand 10}
Tive a mesma idéia que o @Hobbs, de gerar um dígito de cada vez, mas o código dele não atendia ao requisito adicional de zeros à esquerda. Gerar o primeiro dígito em vez de apenas o sinal resolveu isso. E, a menos que exista uma maneira mais curta de sair, se imprimirmos um zero, ou uma maneira mais curta de gerar os -9 a 9 iniciais, isso deve ser feito pelo tamanho.
Em um loop de shell:
while perl -e '...'; do echo;done |less
Eu acho que este é um dos mais curtos que não requer RAM infinita para satisfazer o problema. Como um bônus, a saída não é fortemente influenciada por nada, e o tempo de execução é muito rápido.
Tentei usar o bit a bit e salvar um caractere na condição while, mas acho que isso acaba sendo verdade com mais frequência, para que o loop termine mais cedo. Seria necessário mais caracteres para ajustar outras coisas para combater isso, para manter a probabilidade de gerar abs (saída)> 1M.
fonte
Javascript (73)
Esta solução usa que você pode construir um número com base n multiplicando o número anterior por n e adicionando um dígito na base n . Temos um adicional
..?..:..
para podermos criar todos os números inteiros negativos. O código a seguir deve ser testado em um console do navegador.A probabilidade de obter um número inteiro> =
2^1
(ou <=-(2^1)
) é igual à chance de o loop ser executado 2 vezes. A chance disso acontecer é(98/99)^2
. A chance de obter um número maior que2^20
(ou <=-(2^20)
) é, portanto,(98/99)^21 = 0.808
ou 81%. Isso tudo é teoricamente, e assumindo que Math.random seja verdadeiramente aleatório. Obviamente não é.Snippet testando esse código. Também de uma maneira mais legível.
Mostrar snippet de código
fonte
GolfScript, 20 bytes
Sim, este também é meio lento.
Comparado a idiomas como CJam e Pyth, o GolfScript sofre com uma palavra-chave detalhada de geração de números aleatórios (
rand
). Para superar esse problema, eu precisava encontrar uma maneira de usá-lo apenas uma vez.Esse código funciona escolhendo repetidamente um número aleatório entre 0 e 8 8 −1 = 16.777.215 inclusive, e incrementando um contador até que o número aleatório seja 0. O valor resultante do contador tem uma distribuição geométrica com uma mediana de aproximadamente -1 / log 2 ( 1-8 8) ) , 11.629.080, portanto atende ao teste "mais de 1.000.000 pelo menos 50% do tempo".
Infelizmente, o número aleatório assim gerado é sempre estritamente positivo. Assim, a
.2&(*4/
parte extra é necessária para deixá-la negativa ou zero. Ele funciona extraindo o segundo bit mais baixo do número (que é, portanto, 0 ou 2), diminuindo-o para torná-lo -1 ou 1, multiplicando-o pelo número original e dividindo o resultado por 4 (para se livrar de os dois bits mais baixos, que agora estão correlacionados com o sinal, e também para permitir que o resultado se torne zero). Mesmo após a divisão por 4, o valor absoluto do número aleatório ainda possui uma mediana de -1 / log 2 (1 - 1/8 8 ) / 4 ≈ 2,907,270, portanto, ainda passa no teste de 50%.fonte
JavaScript, 81 bytes
Este código cumpre todas as regras:
0
na saídaComo bônus, o algoritmo é executado com uma complexidade de tempo de O (log 10 n) e, portanto, retorna o número inteiro quase instantaneamente.
Isso pressupõe um ambiente REPL. Tente executar o código acima no console do navegador ou use o snippet da pilha abaixo:
Algoritmo :
s
até que aMath.random() > 0.1
.Math.random() > 0.5
, torne o número negativo (acrescentando a sequências
com-
).Este algoritmo não possui uma distribuição uniforme entre todos os números inteiros. Inteiros com maior número de dígitos são menos prováveis que os mais baixos. Em cada uma das iterações de loop, há uma chance de 10% de parar no dígito atual. Eu só tenho que ter certeza de que paro após 6 dígitos mais de 50% do tempo.
Esta equação de @nutki explica o valor máximo da porcentagem de chance de interrupção com base na condição acima:
Assim, 0,1 está dentro do alcance para satisfazer todas as três regras da questão.
fonte
TI-BASIC, 14 bytes
Semelhante à resposta R de @ ssdecontrol, isso se baseia na distribuição gaussiana com média de -1.000.000 ou 1.000.000, escolhida aleatoriamente e desvio padrão 9. A distribuição é ilimitada, portanto, em teoria, isso pode gerar qualquer número inteiro.
Explicação :
fonte
:
significa "imprimir" devido à forma como a explicação é apresentada). Mas pode gerar números com mais de 20 dígitos?randNorm
?Bash, 66
Quase sempre imprime 5000000. Mas, se encontrar um número válido
/dev/random
, ele imprimirá esse número.E este é mais rápido:
fonte
/dev/urandom
que é menos aleatório./dev/urandom
em um script shell é basicamente o mesmo que chamarrand()
em outros idiomas. Embora se você realmente esteja usando o bash, não o POSIX sh, poderá obter números aleatóriosecho $RANDOM
. O wiki.ubuntu.com/DashAsBinSh fornecehexdump /dev/urandom
como equivalente o bare-POSIX-minimum/bin/dash
.C ++, 95 bytes
Expandido:
Explicação:
A função continua imprimindo dígitos aleatórios consecutivos até que uma chave com valor aleatório use o valor necessário para interromper a função. d é a variável que mantém o valor do próximo dígito a ser impresso. s é a variável de comutação que aceita valores inteiros aleatórios no intervalo [0, 9], se s == 9, não serão impressos mais dígitos e a função será encerrada.
As variáveis d e s são inicializadas para dar tratamento especial ao primeiro dígito (tirando-o do intervalo [-9, 9] e se o primeiro dígito for zero, a função deve terminar para evitar zeros à esquerda). O valor de d pode ser atribuído como d = rand ()% 10, mas o primeiro dígito não pode ser negativo. d é atribuído como d = (rand ()% 19 + d + 9)% 10 e inicializado em -18, de modo que o primeiro valor de d varia de [-9, 9] e os próximos valores sempre variam de [0 9].
A variável s varia aleatoriamente entre [0, 9] e, se s é igual a 9, a função termina. Assim, após a impressão do primeiro dígito, o próximo será impresso com uma probabilidade de 90% (assumindo que rand () seja verdadeiramente aleatório e para satisfazer a terceira condição). s pode ser facilmente atribuído como s = rand ()% 10; no entanto, há uma exceção: se o primeiro dígito for zero, a função deverá terminar. Para lidar com essa exceção, s foi atribuído como s = 9-rand ()% 10 * min (d * d + s + 1,1) e inicializado como -1. Se o primeiro dígito for zero, o mínimo retornará 0 es será igual a 9-0 = 9. A atribuição da variável s sempre varia de [0, 9]; portanto, a exceção pode ocorrer apenas no primeiro dígito.
Características (supondo que rand () seja verdadeiramente aleatório)
O número inteiro é impresso dígito por dígito, com uma probabilidade fixa de 90% de imprimir outro dígito após a impressão do último.
0 é o número inteiro com maior chance de ser impresso, com uma probabilidade de aproximadamente 5,2%.
A probabilidade de imprimir um número inteiro no intervalo [-10 ^ 6, 10 ^ 6] é de aproximadamente 44% (o cálculo não está escrito aqui).
Números positivos e negativos são impressos com a mesma probabilidade (~ 47,4%).
Nem todos os dígitos são impressos com a mesma probabilidade. Por exemplo: no meio da impressão do número inteiro, se o último dígito for 5, o dígito 3 terá uma chance ligeiramente menor de ser impresso a seguir. Em geral, se o último dígito foi d, o dígito (d + 18)% 10 terá uma chance ligeiramente menor de ser impresso a seguir.
Exemplo de saídas (10 execuções)
fonte
Bash, 42 bytes
printf "%d\n" 0x$(xxd -p -l5 /dev/random)
/ dev / random no OSX tem apenas bytes aleatórios,
xxd -p -l5
converte 5 dos caracteres ascii em hexadecimal e oprintf
transforma em formato decimal.fonte
Pitão , 11 bytes
Nota: este programa provavelmente trava com um erro de memória em qualquer computador real. Para testá-lo, tente substituir
G
por uma sequência mais curta, como neste código, que gera números com uma média de 28000:Esse código faz um loop, adicionando um número aleatório de -1 a 8 a
Z
, com uma probabilidade de 2 ^ -26 de sair do loop em cada repetição. A probabilidade 2 ^ -26 é obtida selecionando-se um elemento aleatório (O
) do conjunto de todos os subconjuntos (y
) do alfabeto (G
).Detalhes técnicos e justificativa:
A probabilidade 2 ^ -26 é derivada de dois fatos:
y
quando chamada em seqüências, é a função de conjunto de potência, constrói a lista de todos os subconjuntos da entrada. Como a entrada,,G
possui 26 caracteres, este conjunto de energiayG
possui 2 ^ 26 entradas.OyG
seleciona um elemento aleatório dessas 2 ^ 26 entradas. Exatamente uma dessas entradas, a sequência vazia, será avaliada como falsa quando transmitida paraW
o loop while. Portanto, há uma probabilidade de 2 ^ -26 de sair do loop a cada vez.Em qualquer número fixo de ciclos de loop K, a probabilidade de obter o número K * 3,5 + me obter K * 3,5 - m é igual, porque cada sequência de adendos que atinge um total pode ser invertida, -1 -> 8, 0 -> 7, etc., para alcançar o outro. Além disso, números mais próximos de K * 3.5 são claramente mais prováveis que números mais distantes. Portanto, se K> 2000000 / 3.5 = 571428.5, a probabilidade de obter um número acima de 1000000 é maior que 75%, porque alguns dos resultados acima desse número podem ser colocados em uma correspondência individual com todos os resultados abaixo desse número. O número e a metade inferior podem ser colocados em uma correspondência individual com aqueles abaixo de 1000000. A probabilidade de obter pelo menos 571429 loops é (1-2 ^ -26) ^ 571429, o que não é menor que (1-2 ^ -26 * 571429), o número esperado de vezes que sai do loop nas primeiras 571429 tentativas, que é de 99,1%. Assim, em 99,1% ou mais dos ensaios, há uma chance de 75% ou mais de obter pelo menos 1000000, portanto, há mais de 50% de chance de obter mais de 1000000.
Esse código baseia-se no comportamento de
O
onde um bug foi introduzido acidentalmente há 3 dias e foi corrigido hoje. Ele deve funcionar em qualquer versão do Pyth 3 antes de 22 de dezembro ou depois de hoje. O código a seguir é equivalente e sempre funcionou:fonte
Java, 113 bytes
Este programa imprime um número binário no fluxo de saída padrão. Você pode ter que esperar um pouco porque a probabilidade de terminar o número (ou ser positivo) é de aproximadamente 0. A idéia de que o valor absoluto de um número gerado seja menor que 1 milhão é divertida, mas possível.
Ungolfed:
Saída de amostra: será lançada quando um número terminar de ser gerado.
fonte
Java (JDK) ,
140127 bytes-13 bytes
introduzindo mais lógica no cabeçalho do loop - graças a @ceilingcatExperimente online!
fonte