Sobre a série
Primeiro, você pode tratar isso como qualquer outro desafio de golfe com código e respondê-lo sem se preocupar com a série. No entanto, existe uma tabela de classificação em todos os desafios. Você pode encontrar a tabela de classificação junto com mais informações sobre a série no primeiro post .
Embora eu tenha várias idéias alinhadas para a série, os desafios futuros ainda não estão definidos. Se você tiver alguma sugestão, informe-me na postagem da sandbox relevante .
Furo 2: Números de uma distribuição normal
Não acredito que isso ainda não foi feito! Você deve gerar números aleatórios, a partir de uma distribuição normal . Algumas regras (a maioria delas provavelmente são cobertas automaticamente pela maioria dos envios, mas algumas existem para garantir a consistência dos resultados entre idiomas muito diferentes):
Você deve usar dois números inteiros não negativos como entrada : uma semente
S
e a quantidadeN
de números a serem retornados. A saída deve ser uma lista deN
números de ponto flutuante, extraídos de uma distribuição normal com média 0 e variação 1 . Sempre que sua submissão recebe a mesma semente,S
ela deve produzir o mesmo número. Em particular, se for chamado uma vez com e uma vez com , as primeiras entradas das duas saídas deverão ser idênticas. Além disso, pelo menos 2 16 valores diferentes de devem produzir sequências diferentes.(S, N1)
(S, N2)
min(N1, N2)
S
Você pode usar qualquer gerador de números aleatórios incorporado que esteja documentado para desenhar números de uma distribuição (aproximadamente) uniforme , desde que você possa transmiti
S
-lo e suportar pelo menos 2 16 sementes diferentes. Se o fizer, o RNG deve poder retornar pelo menos 2 20 valores diferentes para qualquer número que você solicitar.- Se o seu RNG uniforme disponível tiver um alcance menor, não puder ser cultivado ou suportar poucas sementes, você deve primeiro criar um RNG uniforme com um intervalo suficientemente grande em cima do incorporado ou implementar seu próprio RNG adequado usando a semente. Esta página pode ser útil para isso.
- Se você não implementar um algoritmo estabelecido para gerar distribuições normais, inclua uma prova de correção. Em qualquer um dos casos, o algoritmo que você escolher deve gerar uma distribuição normal teoricamente exata (exceto restrições do PRNG subjacente ou tipos de dados de precisão limitada).
- Sua implementação deve usar e retornar números de ponto flutuante (pelo menos 32 bits de largura) ou números de ponto fixo (pelo menos 24 bits de largura) e todas as operações aritméticas devem fazer uso da largura total do tipo escolhido.
- Você não deve usar nenhuma função interna diretamente relacionada à distribuição normal ou integrais gaussianas, como a função Error ou sua inversa.
Você pode escrever um programa completo ou uma função e receber entradas via STDIN, argumento de linha de comando, argumento de função ou prompt e produzir saída via valor de retorno ou imprimindo em STDOUT (ou alternativa mais próxima).
S
e N
serão números inteiros não negativos, cada um menor que 2 20 . A saída pode estar em qualquer lista conveniente ou inequívoca ou formato de string.
Isso é código de golfe, então a submissão mais curta (em bytes) vence. E, é claro, o menor envio por usuário também entrará na tabela geral de líderes da série.
Entre os melhores
O primeiro post da série gera uma tabela de classificação.
Para garantir que suas respostas sejam exibidas, inicie todas as respostas com um título, usando o seguinte modelo de remarcação:
# Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes
(O idioma não é mostrado no momento, mas o snippet exige e o analisa, e eu posso adicionar um cabeçalho por idioma no futuro.)
Respostas:
Dyalog APL, 33 bytes
{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕
Box-Muller :
fonte
⎕rl
para serS+1
porque⎕rl←0
tem um significado especial.+1
, tudo o que diz é que você precisa suportar pelo menos 2 ^ 16 valores diferentes. Portanto, trabalhar corretamente no intervalo [1..2 ^ 16] deve estar OK.R, 68 bytes
Isso usa a
runif()
função, que gera desvios aleatórios de uma distribuição uniforme. A semente para a geração de números aleatórios é especificada usandoset.seed()
, que por padrão usa o algoritmo de Mersenne-Twister com um período de 2 ^ 19937-1.O resultado é um vetor R de comprimento N contendo os desvios normais padrão calculados.
Utiliza o método Box-Muller: Para duas variáveis aleatórias uniformes independentes U e V,
fonte
f=
(a função não precisa necessariamente ser nomeada, se funções não nomeadas estiverem presentes no seu idioma).Error: unexpected '}' in "f=fu...
Além disso, sempre recebo uma mensagem de erro . Tem certeza de que obtém os mesmos primeiros números se ligarf(0,1)
ef(0,2)
?Dyalog APL,
4234Essa é uma função que assume
S
como argumento à esquerda eN
como argumento à direita.É uma implementação da transformação Box-Muller, usando o operador aleatório interno do Dyalog APL
?
, que por padrão é um twister de Mersenne que retorna valores de 64 bits, o que deve ser suficiente.Explicação:
⎕RL←⍺
: defina a semente aleatória como⍺
.?⍵2⍴0
: gera⍵
pares de números aleatórios entre 0 e 1.{
...}/
: aplique a seguinte função a cada par:(.5*⍨¯2×⍟⍺)×1○⍵×○2
: calcule oZ0
valor (sqrt(-2 ln ⍺)×cos(2π⍵)
).fonte
?0
retorna um número de ponto flutuante entre 0 e 1.Perl, 67
Box-Muller como em outras entradas.
f
leva parâmetros em ordemS, N
.Usar:
fonte
Java,
164161 bytesIsso recebe entrada via função e saída via stdout. Ele usa o método Box-Muller.
fonte
s=0;s++<n;
->;n-->0;
?Commodore 64 Básico,
767063 bytesComo o conjunto de caracteres PETSCII contém alguns símbolos não presentes no Unicode, fiz substituições:
/
=SHIFT+N
,┌
=SHIFT+O
,●
=SHIFT+Q
,╮
=SHIFT+I
,─
=SHIFT+E
Isso implementa a transformação Box-Muller padrão para gerar os números; Eu escolhi a metade do pecado (x) da transformação porque o Commodore 64 Basic possui um atalho de dois caracteres para
sin()
, mas não paracos()
.Embora os estados manuais Caso contrário, o valor do argumento para
RND
não importa: se um número negativo é passado, o gerador de números aleatórios não é meramente re-semeado, é re-semeado com esse número . Isso torna a propagação muito mais simples: em vez de precisar dePOKE
cinco locais de memória, eu apenas preciso fazer uma chamada de não fazer nadaRND
, o que reduz o código de duas linhas / 121 bytes para 1 linha / 76 bytes.Edit: Golfed seis bytes off, percebendo que eu poderia combinar as duas
INPUT
instruções, e que o espaço depoisTO
era opcional.Edit: Jogou mais sete partidas: o Commodore Basic, de fato, tem o Pi como uma constante interna, e é até tipificável em um teclado moderno (
SHIFT+PgDn
no caso de você estar se perguntando).fonte
Código da máquina 80386, 72 bytes
Hexdump do código:
Aqui está o código fonte (pode ser compilado pelo Visual Studio):
Aqui eu uso um gerador de números aleatórios Lehmer . Ele usa o seguinte algoritmo:
Aqui 4294967291 é um número primo grande (2 ^ 32-5) e 116 é um número pequeno (menor que 128; veja abaixo) que é sua raiz primitiva . Eu escolhi uma raiz primitiva que tem uma distribuição mais ou menos aleatória de zeros e uns na representação binária (01110100). Esse RNG possui o período máximo possível de 4294967290, se a semente for diferente de zero.
Os números relativamente pequenos que usei aqui (116 e 4294967291, que também podem ser representados como -5) me permitem aproveitar a
lea
codificação da instrução:Ele é montado em 3 bytes se os números puderem caber em 1 byte.
A multiplicação e a divisão usam
edx
eeax
como seus registros de trabalho, e é por isso que crieiseed
o segundo parâmetro para a função (afastcall
convenção de chamada usaedx
para passar o segundo parâmetro). Além disso, o primeiro parâmetro é passadoecx
, o que é um bom local para armazenar um contador: um loop pode ser organizado em 1 instrução!Para converter um número inteiro em um número de ponto flutuante, explorei a representação de números de ponto flutuante de precisão única: se eu definir os 9 bits altos (expoente) no padrão de bits
001111111
e deixar os 23 bits baixos aleatoriamente, obtenha um número aleatório no intervalo de 1 a 2. Eu peguei a ideia daqui . Para definir os 9 bits mais altos, usei algumas brincadeiras emebx
:Para gerar dois números aleatórios, usei um loop aninhado de 2 iterações. Eu o organizei com
xor
:O código de ponto flutuante implementa a transformação Box-Muller .
fonte
Haskell, 118
144Exemplo de uso:
O tipo de retorno de
random
é restrito aFloat
, o que fazrandom
gerar uma flutuação uniforme em [0, 1). A partir de então, é uma fórmula simlpe box-muller com alguma mágica inútil para a geração de listas.fonte
Golflua, 63
70Golflua informações e instruções.
Retorna uma tabela contendo os valores. No exemplo que estou usando
~T.u( )
, que é igual areturn table.unpack( )
lua.Muitos caracteres foram salvos configurando o ambiente da função para
M
(akamath
).fonte
SAS, 108
Eu já postei uma resposta em R que é mais curta que isso, mas há muito poucas respostas SAS no PPCG, então por que não adicionar outra?
Com algum espaço em branco:
Isso define uma macro que pode ser chamada como
%f(5, 3)
. A macro executa uma etapa de dados que percorre os números inteiros 1 a N e, a cada iteração, calcula um desvio normal aleatório usando o Box-Muller e imprime no log usando aput
instruçãoO SAS não possui built-in para pi, portanto, o melhor que podemos fazer é aproximar-se com arctangent.
A
ranuni()
função (que foi preterida, mas requer alguns caracteres a menos que a função mais recente) retorna um número aleatório de uma distribuição uniforme. A documentação do SAS não fornece muitos detalhes sobre a implementação do RNG, a não ser que tenha um período de 2 ^ 31-2.Nas macros SAS, as variáveis de macro são referenciadas com um precedente
&
e resolvem seus valores no tempo de execução.Como você provavelmente já testemunhou, o SAS raramente é um candidato real em um concurso de código-golfe .
fonte
Java, 193 bytes
Embora isso não supere o atual líder Java, decidi postar de qualquer maneira para mostrar um método diferente de cálculo. É uma versão de golfe do OpenJDK
nextGaussian()
.Com quebras de linha:
fonte
(s,n)->{java.util.Random r=new java.util.Random(s);for(float a,v;n-->0;System.out.println(v*Math.sqrt(-2*Math.log(a)/a)))for(a=0;a>=1|a==0;a=v*v+(v=2*r.nextFloat()-1)*v)v=2*r.nextFloat()-1;}
T-SQL, 155 bytes
Use com EXEC RS, N, porque não há STD_IN no T-SQL, em que S e N são a semente e N, respectivamente. S produzirá sequências "aleatórias" (RAND (semente) é uma péssima implementação de números aleatórios) quando S> 2 ^ 16 (possivelmente antes disso, mas não garanto). Usa o Box-Muller como a maioria das soluções até agora. 8388607 é 2 ^ 23-1, o que deve gerar 2 ^ 20 valores diferentes.
fonte
Powershell, 164 bytes
O mesmo que a maioria das respostas com o Box-Muller. Não tem muita experiência com o Powershell, então qualquer ajuda com o golfe seria apreciada.
fonte
Ruby, 72 bytes
Entrada (como função lambda):
Resultado:
PS: Eu gostaria de saber se isso pode ser jogado mais. Eu sou apenas um iniciante.
fonte
Matlab, 77
A primeira entrada deve ser
n
, a segundas
.fonte
Oitava,
919688 bytesOu, com espaço em branco:
Coloque a semente na frente e use o método Box-Mueller.
Nota: O Octave permite a geração de matrizes de números aleatórios e pode usar operações padrão nessas matrizes que produzem saídas de matriz. O
.*
operador é a multiplicação elemento a elemento de duas matrizes para produzir o resultado.fonte
n(0,1)
en(0,2)
conseguir números diferentes, não é?Pitão, 32 bytes
Nenhum Python sendo usado agora em super cotações por causa das novas funções que o Pyth possui agora. Mais um Box-Mueller.
Esse espaço no começo é importante.
A propagação parece não funcionar no intérprete online, mas funciona bem na versão local.O intérprete on-line parece estar corrigido, então aqui está um link permanente: link permanentefonte
.nZ
) que não foi implementado, quando a pergunta foi feita. (Na verdade, foi implementado hoje.) Portanto, esta resposta não deve fazer parte da competição ( meta.codegolf.stackexchange.com/questions/4867/… ).STATA, 85 bytes
Recebe a entrada via padrão (o primeiro número é S e depois N). Define a semente como S. Define o número de observações como N. Cria uma variável e define seu valor como o valor da transformação Box Muller (obrigado a @Alex por mostrá-lo). Em seguida, lista todas as observações em uma tabela com o cabeçalho da coluna a e os números de observação próximos a eles. Se não estiverem bem, informe-me e posso remover cabeçalhos e / ou números de observação.
fonte
R, 89 bytes
Eu sei que R já foi feito antes, mas eu queria mostrar uma abordagem diferente da Box-Muller que todos os outros usavam. Minha solução usa o Teorema do Limite Central .
fonte
a
em seu código de tal forma que o resultado é "justo".)TI-Básico, 74 bytes
Na
¹
verdade, é o operador inverso.fonte
Perl,
150108107 bytesIsso usa o método polar Marsaglia . Chamado com f (S, N).
Movida a atribuição de
$a
para o cálculo de$c
.107:
Removido o armazenamento do número de reposição e a definição de
$b
.108:
150:
fonte
Swift,
144142Nada inteligente, apenas vendo como o Swift funciona.
Eu esperava poder usar (0 ... n) .map {}, mas o compilador não parece reconhecer o mapa {}, a menos que você use um parâmetro.
fonte
forEach
, se você não quer um valor de retorno, e eu tenho certeza que a_ in
é obrigatória/0xffffffff
para btwHaskell , 97 bytes
Experimente online!
Apenas sua transformação básica de Box-Muller, em uma lista infinita de números aleatórios.
fonte
Python 3 , 118 bytes
Experimente online!
fonte
SmileBASIC, 81 bytes
Bem, agora que respondi à primeira pergunta, tenho que fazer todo o resto ...
Gerar números aleatórios é barato, mas semear o RNG usa a função interna mais longa do idioma
RANDOMIZE
,.Talvez haja alguma maneira de otimizar a fórmula. Não vejo como é necessário usar duas chamadas RNG.
fonte