Golf aleatorio del día # 2: números de una distribución normal


12

Sobre la serie

En primer lugar, puede tratar esto como cualquier otro desafío de golf de código y responderlo sin preocuparse por la serie. Sin embargo, hay una tabla de clasificación en todos los desafíos. Puede encontrar la tabla de clasificación junto con más información sobre la serie en la primera publicación .

Aunque tengo un montón de ideas para la serie, los desafíos futuros aún no están establecidos en piedra. Si tiene alguna sugerencia, hágamelo saber en la publicación de sandbox relevante .

Hoyo 2: números de una distribución normal

¡No puedo creer que esto no se haya hecho todavía! Debes generar números aleatorios, a partir de una distribución normal . Algunas reglas (la mayoría de ellas probablemente están cubiertas automáticamente por la mayoría de las presentaciones, pero algunas están en su lugar para garantizar la consistencia de los resultados entre idiomas muy diferentes):

  • Debe tomar dos enteros no negativos como entrada : una semilla Sy la cantidad Nde números que se devolverán. La salida debe ser una lista de Nnúmeros de coma flotante, extraída de una distribución normal con media 0 y varianza 1 . Cada vez que su envío recibe la misma semilla S, debe producir el mismo número. En particular, si se llama una vez con y una vez con , las primeras entradas de las dos salidas deben ser idénticas. Además, al menos 2 16 valores diferentes de deberían producir secuencias diferentes.(S, N1)(S, N2)min(N1, N2)S

  • Puede usar cualquier generador de números aleatorios incorporado que esté documentado para extraer números de una distribución (aproximadamente) uniforme , siempre que pueda pasarlo Sy admita al menos 2 16 semillas diferentes. Si lo hace, el RNG debería poder devolver al menos 2 20 valores diferentes para cualquier número dado que le solicite.

  • Si su RNG uniforme disponible tiene un rango más pequeño, no es visible o admite muy pocas semillas, primero debe construir un RNG uniforme con un rango suficientemente grande sobre el incorporado o debe implementar su propio RNG adecuado utilizando la semilla. Esta página puede ser útil para eso.
  • Si no implementa un algoritmo establecido para generar distribuciones normales, incluya una prueba de corrección. En cualquier caso, el algoritmo que elija debe producir una distribución normal teóricamente exacta (salvo las limitaciones del PRNG subyacente o los tipos de datos de precisión limitada).
  • Su implementación debe usar y devolver números de punto flotante (al menos 32 bits de ancho) o números de punto fijo (al menos 24 bits de ancho) y todas las operaciones aritméticas deben usar el ancho completo del tipo elegido.
  • No debe utilizar ninguna función integrada directamente relacionada con la distribución normal o las integrales gaussianas, como la función Error o su inversa.

Puede escribir un programa completo o una función y recibir información a través de STDIN, argumento de línea de comando, argumento de función o solicitud y producir salida a través del valor de retorno o imprimiendo en STDOUT (o la alternativa más cercana).

Sy Nserán enteros no negativos, cada uno menor de 2 20 . La salida puede estar en cualquier formato de lista o cadena conveniente y sin ambigüedades.

Este es el código de golf, por lo que gana el envío más corto (en bytes). Y, por supuesto, la presentación más corta por usuario también entrará en la tabla de clasificación general de la serie.

Tabla de clasificación

La primera publicación de la serie genera una tabla de clasificación.

Para asegurarse de que sus respuestas aparezcan, comience cada respuesta con un título, utilizando la siguiente plantilla de Markdown:

# Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

# Ruby, <s>104</s> <s>101</s> 96 bytes

(El idioma no se muestra actualmente, pero el fragmento requiere y analiza, y puedo agregar una tabla de clasificación por idioma en el futuro).


Espera, ¿podemos usar RNG de rango no entero?
mniip

Las respuestas existentes de PS 2 parecen usar [0, 1) RNG de punto flotante, ¿está permitido?
mniip

@mniip Sí, los RNG de punto flotante están permitidos, siempre que sean uniformes, visibles y capaces de devolver el número requerido de flotadores distintos.
Martin Ender

Respuestas:


8

Dyalog APL, 33 bytes

{(.5*⍨¯2×⍟?0)×1○○2×?0}¨⍳⎕⊣⎕rl←1+⎕

Box-Muller :

⎕         ⍝ evaluated input
⎕rl←1+⎕   ⍝ set APL's random seed to 1+⎕ (S)
          ⍝   add 1 because ⎕rl←0 has special meaning: sets the seed randomly
{ }¨⍳N    ⍝ do the thing in braces N times
?0        ⍝ random number 0≤x<1
1○○2×A    ⍝ sin(2πA)
.5*⍨¯2×⍟B ⍝ sqrt(-2lnB)

Estoy bastante seguro de que esto no puede ser superado por ningún otro idioma.
Zero Fiber

2
Esto no cumple con esta regla: "En particular, si se llama una vez con (S, N1) y una vez con (S, N2), las primeras entradas mín. (N1, N2) de las dos salidas deben ser idénticas".
marinus

@marinus Gracias, arreglado. También cambié ⎕rla ser S+1porque ⎕rl←0tiene un significado especial.
ngn

Probablemente no necesite realmente +1, todo lo que dice es que necesita admitir al menos 2 ^ 16 valores diferentes. Por lo tanto, trabajar correctamente en el rango [1..2 ^ 16] debería estar bien.
marinus

S = 0 haría que el cálculo no sea repetible, lo que viola la regla que citó anteriormente.
ngn

8

R, 68 bytes

function(S,N){set.seed(S);sqrt(-2*log(runif(N)))*cos(2*pi*runif(N))}

Esto utiliza la runif()función, que genera desviaciones aleatorias de una distribución uniforme. La semilla para la generación de números aleatorios se especifica usando set.seed(), que por defecto usa el algoritmo Mersenne-Twister con un período de 2 ^ 19937-1.

El resultado es un vector R de longitud N que contiene las desviaciones normales estándar calculadas.

Esto utiliza el método Box-Muller: para dos variables aleatorias uniformes independientes U y V, ingrese la descripción de la imagen aquí


Si esa es una sintaxis válida en R, puede omitir el f=(la función no necesariamente necesita ser nombrada, si las funciones sin nombre son algo en su idioma).
Martin Ender

@ MartinBüttner: agradezco la sugerencia, pero que yo sepa R no sabría qué hacer con una función sin nombre.
Alex A.

Error: unexpected '}' in "f=fu...Además, siempre recibo un mensaje de error , ¿estás seguro de que obtienes los mismos primeros números si llamas f(0,1)y f(0,2)?
falla

4

Dyalog APL, 42 34

{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}

Esta es una función que toma Scomo argumento izquierdo y Ncomo argumento derecho.

     5{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}10
3.019132549 ¯0.2903143175 ¯0.7353414637 1.421417015 2.327544764 ¯0.00005019747711 ¯0.9582127248 ¯0.2764568462
      ¯0.1602736853 ¯0.9912352616
     5{⎕RL←⍺⋄{(.5*⍨¯2×⍟⍺)×1○⍵×○2}/?⍵2⍴0}20
3.019132549 ¯0.2903143175 ¯0.7353414637 1.421417015 2.327544764 ¯0.00005019747711 ¯0.9582127248 ¯0.2764568462
      ¯0.1602736853 ¯0.9912352616 0.642585109 ¯0.2450019151 ¯0.415034463 0.03481768503 ¯0.4621212815 ¯0.760925979
      0.2592913013 1.884867889 ¯0.9621252731 0.3062560446

Es una implementación de la transformación Box-Muller, utilizando el operador aleatorio incorporado de Dyalog APL ?, que por defecto es un tornado de Mersenne que devuelve valores de 64 bits, lo que debería ser suficiente.

Explicación:

  • ⎕RL←⍺: establece la semilla aleatoria en .
  • ?⍵2⍴0: genera pares de números aleatorios entre 0 y 1.
  • {... }/: aplica la siguiente función a cada par:
    • (.5*⍨¯2×⍟⍺)×1○⍵×○2: calcular el Z0valor ( sqrt(-2 ln ⍺)×cos(2π⍵)).

1
En v14.0 ?0devuelve un número de coma flotante entre 0 y 1.
ngn

3

Perl, 67

sub f{srand$_[0];map{cos(atan2(1,1)*rand 8)*sqrt-2*log rand}1..pop}

Box-Muller como en otras entradas. ftoma los parámetros en orden S, N.

Utilizar:

$ perl -le 'sub f{srand$_[0];map{cos(atan2(1,1)*rand 8)*sqrt-2*log rand}1..pop}print for f(5,3)'
-1.59212831801942
0.432167710756345
-0.533673305924252

3

Java, 164161 bytes

class B extends java.util.Random{B(int s,int n){super(s);for(;n-->0;System.out.println(Math.sqrt(-2*Math.log(nextDouble()))*Math.cos(2*Math.PI*nextDouble())));}}

Esto toma la entrada a través de la función y la salida a través de stdout. Utiliza el método Box-Muller.


55
s=0;s++<n;-> ;n-->0;?
Geobits

1
@Geobits Parece una lambda: D
TheNumberOne

3

Commodore 64 Basic, 76 70 63 bytes

1INPUTS,N:S=R/(-S):F┌I=1TON:?S●(-2*LOG(R/(1)))*S╮(2*π*R/(1)):N─

Como el juego de caracteres PETSCII contiene algunos símbolos que no están presentes en Unicode, he realizado sustituciones: /= SHIFT+N, = SHIFT+O, = SHIFT+Q, = SHIFT+I, =SHIFT+E

Esto implementa la transformación estándar de Box-Muller para generar los números; Elegí la mitad sin (x) de la transformación porque Commodore 64 Basic tiene un acceso directo de dos caracteres para sin(), pero no para cos().

Aunque el manual establece lo contrario, el valor del argumento RND sí es importante: si se pasa un número negativo, el generador de números aleatorios no solo se vuelve a sembrar, sino que se vuelve a sembrar con ese número . Esto hace que la siembra sea mucho más simple: en lugar de necesitar POKEcinco ubicaciones de memoria, simplemente necesito hacer una llamada de no hacer nada RND, lo que reduce el código de dos líneas / 121 bytes a 1 línea / 76 bytes.

Editar: Golfé seis bytes al darme cuenta de que podía combinar las dos INPUTdeclaraciones, y que el espacio después TOera opcional.

Editar: Golfed otros siete: Commodore Basic, de hecho, tiene Pi como una constante incorporada, e incluso se puede escribir en un teclado moderno ( SHIFT+PgDnen caso de que se lo pregunte).


3

80386 código máquina, 72 bytes.

Hexdump del código:

60 8b 7c 24 24 33 ed 8d 75 fb 8d 46 79 f7 e2 f7
f6 8b da b3 7f 0f cb d1 eb 89 1f d9 07 d9 e8 de
e9 33 ee 75 e5 d9 ed d9 c9 d9 f1 dc c0 d9 e0 d9
fa d9 c9 d9 eb de c9 dc c0 d9 ff de c9 d9 1f 83
c7 04 e2 c6 61 c2 04 00

Aquí está el código fuente (puede ser compilado por Visual Studio):

__declspec(naked) void __fastcall doit(int count, unsigned seed, float* output)
{
    _asm {
                                // ecx = count
                                // edx = seed
        // save registers
        pushad;
        mov edi, [esp + 0x24];  // edi = pointer to output
        xor ebp, ebp;           // ebp = 0
        lea esi, [ebp - 5];     // esi = 4294967291 (a prime number)

    myloop:
        // Calculate the next random number
        lea eax, [esi + 121];   // eax = 116
        mul edx;
        div esi;
        mov ebx, edx;

        // Convert it to a float in the range 1...2
        mov bl, 0x7f;
        bswap ebx;
        shr ebx, 1;

        // Convert to range 0...1 and push onto the FPU stack
        mov [edi], ebx;
        fld dword ptr [edi];
        fld1;
        fsubp st(1), st;

        // Make 2 such random numbers
        xor ebp, esi;
        jnz myloop;

        // Calculate sqrt(-2*ln(x))
        fldln2;
        fxch;
        fyl2x;
        fadd st, st(0);
        fchs;
        fsqrt;

        // Calculate cos(2*pi*y)
        fxch st(1);
        fldpi;
        fmul;
        fadd st, st(0);
        fcos;

        // Calculate and write output
        fmulp st(1), st;
        fstp dword ptr [edi];
        add edi, 4;

        // Repeat
        loop myloop

        // Return
        popad;
        ret 4;
    }
}

Aquí uso un generador de números aleatorios de Lehmer . Utiliza el siguiente algoritmo:

x(k+1) = 116 * x(k) mod 4294967291

Aquí 4294967291 es un número primo grande (2 ^ 32-5), y 116 es un número pequeño (menos de 128; ver más abajo) que es su raíz primitiva . Elegí una raíz primitiva que tiene una distribución más o menos aleatoria de ceros y unos en representación binaria (01110100). Este RNG tiene el período máximo posible de 4294967290, si la semilla no es cero.


Los números relativamente pequeños que utilicé aquí (116 y 4294967291, que también se pueden representar como -5) me permiten aprovechar la leacodificación de instrucciones:

8d 46 79     lea eax, [esi+121]

Se ensambla en 3 bytes si los números pueden caber en 1 byte.


El uso de multiplicación y división edxy eaxcomo sus registros de trabajo, es por eso que hice seedel segundo parámetro a la función (la fastcallconvención de llamada usa edxpara pasar el segundo parámetro). Además, se pasa el primer parámetro ecx, que es un buen lugar para mantener un contador: ¡se puede organizar un bucle en 1 instrucción!

e2 c6        loop myloop

Para convertir un número entero en un número de coma flotante, exploté la representación de números de coma flotante de precisión simple: si establezco los 9 bits altos (exponente) en el patrón de bits 001111111y dejo los 23 bits bajos al azar, obtener un número aleatorio en el rango 1 ... 2. Tomé la idea de aquí . Para establecer los 9 bits más altos, utilicé algunos ajustes de bits en ebx:

mov ebx, edx;    xxxxxxxx|yyyyyyyy|zzzzzzzz|aaaaaaaa
mov bl, 0x7f;    xxxxxxxx|yyyyyyyy|zzzzzzzz|01111111
bswap ebx;       01111111|zzzzzzzz|yyyyyyyy|xxxxxxxx
shr ebx, 1;      00111111|1zzzzzzz|zyyyyyyy|yxxxxxxx

Para generar dos números aleatorios, utilicé un bucle anidado de 2 iteraciones. Lo organicé con xor:

xor ebp, esi;    first time, the result is -5
jnz myloop;      second time, the result is 0 - exit loop

El código de punto flotante implementa la transformación Box-Muller .


2

Haskell, 118  144 

import System.Random;h z=let(u,r)=random z in(cos$2*pi*fst(random r)::Float)*sqrt(-2*log u):h r;g=(.(h.mkStdGen)).take

Ejemplo de uso:

*Main> g 3 0x6AE4A92CAFA8A742
[0.50378895,-0.20593005,-0.16684927]
*Main> g 6 0x6AE4A92CAFA8A742
[0.50378895,-0.20593005,-0.16684927,1.1229043,-0.10026576,0.4279402]
*Main> g 6 0xE09B1088DF461F7D
[2.5723906,-0.5177805,-1.3535261,0.7400385,3.5619608e-3,-8.246434e-2]

El tipo de retorno de randomestá restringido a Float, lo que hace randomgenerar un flotante uniforme en [0, 1). A partir de entonces, es una fórmula simlpe box-muller con algo de magia sin sentido para la generación de listas.


2

Golflua, 63 70

Golflua información e instrucciones.

\g(n,s)`_ENV,b=M,{}rs(s)~@i=1,n b[i]=q(l(r()^-2))*c(r()*pi)$~b$

Devuelve una tabla que contiene los valores. En el ejemplo que estoy usando ~T.u( ), que es lo mismo que return table.unpack( )en lua.

> ~T.u(g(3,1234567))
0.89302672974232 0.36330401643578 -0.64762161593981
> ~T.u(g(5,1234567))
0.89302672974232 0.36330401643578 -0.64762161593981 -0.70654636393063 -0.65662878785425
> ~T.u(g(5,7654321))
0.3867923683064 -0.31758512485963 -0.58059120409317 1.2079459300077 1.1500121921242

Se guardaron muchos caracteres configurando el entorno de la función en M(aka math).


2

SAS, 108

Ya publiqué una respuesta en R que es más corta que esta, pero hay muy pocas respuestas SAS en PPCG, entonces, ¿por qué no agregar otra?

%macro f(s,n);data;do i=1 to &n;x=sqrt(-2*log(ranuni(&s)))*cos(8*atan2(1,1)*ranuni(&s));put x;end;run;%mend;

Con algo de espacio en blanco:

%macro f(s, n);
    data;
        do i = 1 to &n;
            x = sqrt(-2 * log(ranuni(&s))) * cos(8 * atan2(1, 1) * ranuni(&s));
            put x;
        end;
    run;
%mend;

Esto define una macro que se puede llamar como %f(5, 3). La macro ejecuta un paso de datos que recorre los números enteros 1 a N, y en cada iteración calcula una desviación normal aleatoria usando Box-Muller y la imprime en el registro usando la putdeclaración.

SAS no tiene incorporado para pi, por lo que lo mejor que podemos hacer es aproximarlo con arctangent.

La ranuni()función (que está en desuso pero requiere un par de caracteres menos que la función más nueva) devuelve un número aleatorio de una distribución uniforme. La documentación de SAS no brinda muchos detalles sobre la implementación de RNG, aparte de que tiene un período de 2 ^ 31-2.

En las macros SAS, las variables macro se referencian con un precedente &y se resuelven a sus valores en tiempo de ejecución.

Como probablemente haya presenciado, SAS rara vez es un contendiente real en un concurso de .


2

Java, 193 bytes

Si bien esto no supera al líder actual de Java, decidí publicar de todos modos para mostrar un método diferente de cálculo. Es una versión de golf de OpenJDK's nextGaussian().

class N extends java.util.Random{N(int s,int n){super(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*nextFloat()-1)*v)v=2*nextFloat()-1;}}

Con saltos de línea:

class N extends java.util.Random{
    N(int s,int n){
        super(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*nextFloat()-1)*v)v=2*nextFloat()-1;
    }
}

2
+1 por usar Marsaglia (o más bien por no usar el sencillo Box-Muller);)
Martin Ender

¿No puede ser esto una lambda? Algo así como:(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;}
Justin

2
@Quincunx podría, por un byte. Pero no me gusta ocultar mis declaraciones de funciones en un código sin contar, sea cual sea el consenso actual sobre meta al respecto. Vale la pena un byte para mí;)
Geobits

2

T-SQL, 155 bytes

CREATE PROC R(@S BIGINT,@N INT)AS
DECLARE @ INT=0,@K INT=8388607WHILE @<@N
BEGIN
SELECT SQRT(-2*LOG(RAND(@S*@%@K)))*COS(2*PI()*RAND(@S*9*@%@K))SET @+=1
END

Use con EXEC RS, N porque no hay STD_IN en T-SQL donde S y N son la semilla y N respectivamente. S producirá secuencias "aleatorias" (RAND (semilla) es una implementación de números aleatorios realmente mala) cuando S> 2 ^ 16 (posiblemente antes de eso, pero no lo garantizo). Utiliza Box-Muller como la mayoría de las soluciones hasta ahora. 8388607 es 2 ^ 23-1, que con suerte debería generar 2 ^ 20 valores diferentes.


2

Powershell, 164 bytes

Param($s,$n)$q=2147483647
$a=GET-RANDOM -SETSEED $s
FOR(;$n---gt0;){$a=GET-RANDOM
$b=GET-RANDOM
[math]::SQRT(-2*[math]::LOG($a/$q))*[math]::COS(2*[math]::PI*$b/$q)}

Igual que la mayoría de las respuestas con Box-Muller. No tiene mucha experiencia con Powershell, por lo que cualquier ayuda al golf sería apreciada.


2

Ruby, 72 bytes

->n,s{include Math;srand s;n.times{p sqrt(-2*log(rand))*sin(2*rand*PI)}}

Entrada (como función lambda):

f.(6, 12353405)

Salida:

-1.1565142460805273
0.9352802655317097
1.3566720571574993
-0.9683973210257978
0.9851210877202192
0.14709635752306677

PD: Me gustaría saber si esto se puede jugar más. Solo soy un principiante.


@ MartinBüttner Creo que he estado usando demasiado C estos días. Se olvidó por completo.
Zero Fiber

2

Matlab, 77

La primera entrada debe ser n, la segunda s.

a=input('');
rand('seed',a(2));
for i=1:a;
    (-2*log(rand))^.5*cos(2*pi*rand)
end

2

Octava, 91 96 88 bytes

function r=n(s,n)rand("seed",s);x=rand(2,n);r=cos(2*pi*x(1,:)).*sqrt(-2*log(x(2,:)));end

O, con espacios en blanco:

function r=n(s,n)
  rand("seed",s);
  x=rand(2,n);
  r=cos(2*pi*x(1,:)).*sqrt(-2*log(x(2,:)));
end

Establezca la semilla por adelantado y use el método Box-Mueller.

NB: Octave permite la generación de matrices de números aleatorios y puede usar operaciones estándar en estas matrices que producen salidas de matrices. El .*operador es la multiplicación elemento por elemento de dos matrices para producir el resultado.


Creo que esto no cumple con las condiciones, si llamas n(0,1)y n(0,2)obtienes primeros números diferentes, ¿verdad?
falla

Mierda, tienes razón. Lo arreglé pero me costó 5 bytes ...
dcsohl

2

Pyth, 32 bytes

No se está utilizando Python ahora en super comillas debido a las nuevas funciones que Pyth tiene ahora. Sin embargo, otro Box-Mueller.

 .xvzVQ*@_y.lOZ2.71 2.ty*3.14OZ1

Ese espacio al principio es importante.

.xvz             Seed RNG with evaluated input
VQ               For N in second input
*                Multiplication
 @       2       Square root
   _y            Times negative 2
    .l )         Natural log
     OZ          Of random float (RNG with zero give [0, 1) float)
 .t       1      Cosine from list of trig functions
  y              Double
   *             Multiplication
    .nZ          Pi from constants list
    OZ           Random Float

La siembra no parece funcionar en el intérprete en línea, pero funciona bien en la versión local. El intérprete en línea parece estar arreglado, así que aquí hay un enlace permanente: enlace permanente


1
Utiliza una característica de Pyth ( .nZ) que no se implementó cuando se hizo la pregunta. (En realidad se implementó hoy). Por lo tanto, esta respuesta no debe ser parte de la competencia ( meta.codegolf.stackexchange.com/questions/4867/… ).
Jakube

K, volveré a la solución de 32 caracteres
Maltysen

Sí, eso sería mejor Todavía puede mostrar su nueva solución en una sección separada de su respuesta. Pero el código de tu competencia debería ser el que funciona con el viejo Pyth.
Jakube

1
Por cierto, tampoco creo que la solución 32 sea válida. Dado que utiliza la semilla aleatoria inicializada, que solo se agregó hace unos 5 días.
Jakube

1

STATA, 85 bytes

di _r(s)_r(n)
set se $s
set ob $n
g a=sqrt(-2*ln(runiform()))*cos(2*runiform()*_pi)
l

Toma la entrada a través de la entrada estándar (el primer número es S, luego N). Establece la semilla en S. Establece el número de observaciones en N. Hace una variable y establece su valor en el valor de la transformación de Box Muller (gracias a @Alex por mostrarlo). Luego, enumera todas las observaciones en una tabla con el encabezado de columna a y los números de observación junto a ellas. Si no está bien, avíseme y puedo eliminar los encabezados y / o los números de observación.


1

R, 89 bytes

Sé que R se ha hecho antes, pero quería mostrar un enfoque diferente al Box-Muller que todos los demás usaron. Mi solución usa el Teorema del límite central .

f=function(S,N){set.seed(S);a=1000;for(i in(1:N)){print(sqrt(12/a)*(sum(runif(a))-a/2))}}

1
Me temo que el teorema del límite central no satisface "el algoritmo que elija debe producir una distribución normal teóricamente exacta". No importa cuántas variables uniformes sumes, siempre que la suma sea finita, la distribución normal siempre será aproximada. (Si bien el teorema del límite central es una buena idea, tuve que descartarlo precisamente porque no está claro para qué valor debe usarse aen su código, de modo que el resultado sea "justo".)
Martin Ender

1
Valió la pena intentarlo;)
Michal

1

TI-Basic, 74 bytes

Prompt S,N:S→rand:For(X,1,N:0→A:0→V:0→W:While A≥1 or A=0:2rand-1→V:2rand-1→W:V²+W²→A:End:Disp VW√(Aֿ¹-2log(A:End

1      1111111   11   1111111111111111111     1111   111111   1111111   11111111111111  11    111111111   111

El ¹es en realidad el operador inverso.


1

Perl, 150 108 107 bytes

Esto utiliza el método polar Marsaglia . Llamado con f (S, N).

Movió la asignación de $aen el cálculo de $c.

107:

sub f{srand$_[0];map{do{$c=($a=-1+2*rand)**2+(-1+2*rand)**2}until$c<1;print$a*sqrt(-2*log($c)/$c)}1..$_[1]}

Se eliminó el almacenamiento de números de repuesto y la definición de $b.

108:

sub f{srand$_[0];map{do{$a=-1+2*rand,$c=$a**2+(-1+2*rand)**2}until$c<1;print$a*sqrt(-2*log($c)/$c)}1..$_[1]}

150:

sub f{srand$_[0];map{$h?$h=!print$s:do{do{$a=-1+2*rand,$b=-1+2*rand,$c=$a*$a+$b*$b}until$c<1;$d=sqrt(-2*log($c)/$c);$s=$b*$d;$h=print$a*$d;}}1..$_[1]}

1

Swift, 144 142

Nada inteligente, solo viendo cómo funciona Swift.

import Foundation;func r(s:UInt32,n:Int){srand(s);for i in 0..<n{println(sqrt(-2*log(Double(rand())/0xffffffff))*sin(2*Double(rand())*M_PI))}}

Esperaba poder usar (0 ... n) .map {} pero parece que el compilador no reconoce el mapa {} a menos que use un parámetro.


por supuesto...? esforEach si no quieres un valor de retorno, y estoy bastante seguro de que _ ines obligatorio
solo ASCII el

¿cuál es el /0xffffffffpor cierto
ASCII de sólo

1

Haskell , 97 bytes

import System.Random
h(a:b:c)=sqrt(-2*log a::Float)*cos(2*pi*b):h c
f a=take a.h.randoms.mkStdGen

Pruébalo en línea!

Solo su transformación básica de Box-Muller, en una lista infinita de números aleatorios.



0

SmileBASIC, 81 bytes

Bueno, ahora que he respondido la primera pregunta, tengo que hacer todo el resto ...

La generación de números aleatorios es barato, pero la siembra de la RNG utiliza la más larga función incorporada en el lenguaje, RANDOMIZE.

DEF N S,N
RANDOMIZE.,S
FOR I=1TO N?SQR(-2*LOG(RNDF()))*COS(PI()*2*RNDF())NEXT
END

Quizás haya alguna forma de optimizar la fórmula. No veo cómo se requiere usar dos llamadas RNG.


Se está obligado a tener dos muestras independientes para la transformación de Box-Muller
ASCII de sólo
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.