Su programa / función debería
- salida exactamente un entero
- generar cualquier número entero con probabilidad positiva
- genera un número entero mayor que 1,000,000 o menor que -1,000,000 con al menos un 50% de probabilidad.
Ejemplos de salidas (todo debe ser posible):
59875669123
12
-42
-4640055890
0
2014
12
24
-7190464664658648640055894646646586486400558904644646646586486400558904646649001
Aclaraciones:
- Se permite un salto de línea final.
- Los ceros iniciales no están permitidos.
-0
esta permitido.
El código más corto gana.
way too long to fit in an integer
- Esto solo es cierto si asume que esointeger
significa elint
tipo de datos en un arco de 32/64 bits, lo cual no es necesariamente una suposición válida. "Entero" comenzó como un término matemático , que no tiene restricciones de tamaño.Respuestas:
CJam,
161413 bytesEste tendrá una duración de un muy largo tiempo, ya que utiliza la marca de tiempo actual (del orden de 10 12 ) para determinar si el bucle debe terminar. Estoy usando esto como el envío, ya que es el más corto, pero hay dos alternativas de 14 bytes, que tienen sus propios méritos:
Este no está limitado por el período del PRNG, ya que el rango de todos los números aleatorios depende de la marca de tiempo actual. Por lo tanto, esto debería ser capaz de producir cualquier número, aunque la probabilidad de números negativos, o incluso pequeños números positivos, es muy pequeña.
A continuación se muestra una versión equivalente que utiliza en
3e5
lugar de la marca de tiempo. Y20
para el primer rango (como el envío de 13 bytes). Es mucho más rápido y también cumple con todas las reglas. Es una especie de caso limitante obtener una probabilidad del 50% para números más allá de 1,000,000 mientras se mantiene un tiempo de ejecución razonable y un tamaño de código pequeño. La explicación y la justificación matemática se refieren a esta versión:Esto suele tardar unos segundos en ejecutarse. Puede reemplazarlo
5
con a2
para que funcione aún más rápido. Pero luego, el requisito de la probabilidad del 50% solo se cumplirá para 1,000 en lugar de 1,000,000.Estoy empezando en 0. Luego tengo un bucle, que rompo con probabilidad 1 / (3 * 10 5 ). Dentro de ese ciclo agrego un número entero aleatorio entre -1 y 18 (inclusive) a mi total acumulado. Hay una probabilidad finita (aunque pequeña) de que cada número entero se genere, con números enteros positivos que son mucho más probables que los negativos (no creo que vea uno negativo en su vida). Romper con una probabilidad tan pequeña e incrementar la mayor parte del tiempo (y agregar mucho más que restar) asegura que usualmente iremos más allá de 1,000,000.
Alguna justificación matemática:
La probabilidad de que hagamos menos que este número de pasos es
que evalúa a
0.324402
. Por lo tanto, en aproximadamente dos tercios de los casos, daremos más 117,647 pasos, y fácilmente cada 1,000,000.9e9
sin agregar ningún byte (pero años de tiempo de ejecución).... o 11 bytes?
Finalmente, hay una versión de 11 bytes, que tampoco está limitada por el período del PRNG, pero que se quedará sin memoria casi siempre. Solo genera un número aleatorio (basado en la marca de tiempo) en cada iteración, y lo usa tanto para incrementar como para terminar. Los resultados de cada iteración permanecen en la pila y solo se resumen al final. Gracias a Dennis por esta idea:
fuente
Kmr
en un período todavía es probable que siempre sea un gran número positivo mayor que el período. Y no puede producir todos los números posibles en ese caso.Java,
133149Salidas de ejemplo
Sin golf
Respuesta anterior (antes del cambio de regla)
fuente
-
.Mathematica - 47
Básicamente solo genera un número aleatorio usando una distribución normal con una varianza igual a 1500000. Esto producirá un número entero entre -10 ^ 6 y 10 ^ 6 con una probabilidad del 49.5015%.
fuente
Python 2,
7569 bytesEs trivial comprobar que el ciclo while en el medio puede generar todos los enteros (aunque sesgados hacia cero). "12" se elige de modo que haya aproximadamente la mitad de los números que excedan ± 10 6 .
Solución anterior:
Python 2, 44 bytesBasado en la solución de Mathematica .Realmente no funciona porque Python
float
tiene solo una precisión finita.fuente
Rubí, 70
Para hacer posible la generación de números muy grandes, estoy devolviendo el número como
String
de una lambda. Si eso no está permitido, cuente 8 caracteres adicionales (paraputs f[]
) para que sea un programa en lugar de una función.Explicación
Genere un número entre
-1,000,000
y1,000,000
. Si el número es1
o mayor, el número se devuelve como aString
.Si el número es menor que
1
, la función se llama recursivamente para devolver el número fuera del rango de números. Para asegurarse de que también se pueden generar números negativos, a-
se antepone al resultado resultanteString
si el número inicial es mayor que-500,000
.¡Espero haber entendido el desafío correctamente!
fuente
R, 38
Sorteos de la distribución gaussiana con un promedio de 2,000,000, elegidos al azar, y una desviación estándar de 1,000,000, de modo que aproximadamente 2/3 de los sorteos se ubicarán entre 1,000,000 y 3,000,000. La distribución no tiene límites, por lo que en teoría esto puede generar cualquier número entero. El paquete Rmpfr reemplaza los R's flotantes dobles incorporados con precisión arbitraria.
fuente
sample(c(1,-1),1)
embargo , no creo que necesites todo el pensamiento. Centrarse en 1e6 debería ser suficiente ...Perl, 53 caracteres
Ciertamente no veo ninguna razón para trabajar con enteros al imprimir uno :)
Tiene la misma probabilidad de imprimir un número con o sin un "-" inicial.
Imprime un número de 1 dígito el 10% del tiempo, un número de 2 dígitos el 9% del tiempo, un número de 3 dígitos el 8,1% del tiempo, un número de 4 dígitos el 7,29% del tiempo, un número de 5 dígitos 6.56% del tiempo, un número de 6 dígitos 5.9% del tiempo, etc. Cualquier longitud es posible, con probabilidad decreciente. Los números de uno a cinco dígitos representan aproximadamente el 41.5% de los casos de salida, y el número 1,000,000 (o -1,000,000) solo 6 millonésimas de porcentaje, por lo que el número de salida estará fuera del rango -1,000,000 a 1,000,000 aproximadamente 54.6 % del tiempo.
Tanto "0" como "-0" son salidas posibles, lo que espero no sea un problema.
fuente
print int(rand(20)-10)||1
. Sin embargo, necesito una forma de generar 0 como salida. Tal vez || muere 0, si se permite la basura final después del cero. De lo contrario, se necesita un camino corto para imprimir el cero y salir sin más salida siint(rand(20)-10)==0
.Perl, 114 caracteres
Descompostura:
La probabilidad de obtener un valor entre -1.000.000 y 1.000.000 tiende a cero PERO es posible.
Perl, 25Genera un entero aleatorio dentro del rango de +/- 2 ^ 99.
Descompostura
Probado con 1 millón de muestras:
Esto cumple con todas las reglas:
Editar:
Tuve que aumentar el exponente para que se generen enteros más grandes. Elegí 99 porque mantiene el código lo más corto posible.fuente
-2^31
y+2^31-1
(32bits). Puede aumentar fácilmente los exponentes si desea generar enteros más grandes, pero puede fallar dependiendo de la implementación de Perl.1.#INF
para ser exactos)C#,
126107 bytesSin golf:
La posibilidad de generar un número de n dígitos es 1/2 ^ (n-10), que es mayor que 0 para todos los n positivos, y 1/2 para n = 11.
También crea ceros a la izquierda, que no parecen estar prohibidos en la pregunta original o en ninguno de sus comentarios.fuente
using System;
, no necesitaSystem.Random
dos veces, pero soloRandom
, ¿verdad?using
declaraciones. De todos modos, solo ahorraría 1 char.-1E6, 1E6+1
.Perl, 62 bytes
print $n=int rand(20)-10;while($n&&rand>.1){print int rand 10}
Tuve la misma idea que @Hobbs, de generar un dígito a la vez, pero su código no cumplía con el requisito agregado de cero a la izquierda. Generar el primer dígito en lugar de solo el signo lo resolvió. Y a menos que haya una forma más corta de salir si imprimimos un cero, o una forma más corta de generar los primeros -9 a 9, esto debería hacerlo por tamaño.
En un bucle de shell:
while perl -e '...'; do echo;done |less
Creo que este es uno de los más cortos que no requiere RAM infinita para satisfacer el problema. Como beneficio adicional, la salida no está fuertemente sesgada hacia nada, y el tiempo de ejecución es muy rápido.
Intenté usar bitwise y guardar un personaje en la condición while, pero creo que esto termina siendo cierto con más frecuencia, por lo que el ciclo termina antes. Necesitaría más caracteres para ajustar otras cosas para contrarrestar eso, para mantener la probabilidad de generar abdominales (salida)> 1M.
fuente
Javascript (73)
Esta solución utiliza que puede construir un número con base n multiplicando el número anterior con ny agregando un dígito en base n . Tenemos un adicional
..?..:..
allí para poder crear todos los enteros negativos. El siguiente código debe probarse en una consola del navegador.La probabilidad de obtener un número entero> =
2^1
(o <=-(2^1)
) es igual a la posibilidad de que el ciclo se ejecute 2 veces. La posibilidad de que eso suceda es(98/99)^2
. La posibilidad de obtener un número mayor que2^20
(o <=-(2^20)
) es, por lo tanto, del(98/99)^21 = 0.808
81%. Sin embargo, todo esto es en teoría, y suponiendo que Math.random es verdaderamente aleatorio. Obviamente no lo es.Fragmento de prueba de este código. También de una manera más legible.
Mostrar fragmento de código
fuente
GolfScript, 20 bytes
Sí, este también es un poco lento.
En comparación con lenguajes como CJam y Pyth, GolfScript sufre de una palabra clave detallada de generación de números aleatorios (
rand
). Para superar esta desventaja, necesitaba encontrar una manera de usarla solo una vez.Este código funciona seleccionando repetidamente un número aleatorio entre 0 y 8 8 −1 = 16,777,215 inclusive, e incrementando un contador hasta que el número aleatorio sea 0. El valor del contador resultante tiene una distribución geométrica con una mediana de aproximadamente -1 / log 2 (1 - 1/8 8 ) ≈ 11,629,080, por lo que cumple con la prueba "más de 1,000,000 al menos el 50% del tiempo".
Por desgracia, el número aleatorio así generado siempre es estrictamente positivo. Por lo tanto, la
.2&(*4/
parte adicional es necesaria para que sea negativa o cero. Funciona extrayendo el segundo bit más bajo del número (que es 0 o 2), decrementándolo para que sea -1 o 1, multiplicándolo con el número original y dividiendo el resultado entre 4 (para deshacerse de los dos bits más bajos, que ahora están correlacionados con el signo, y también para permitir que el resultado sea cero). Incluso después de la división por 4, el valor absoluto del número aleatorio todavía tiene una mediana de -1 / log 2 (1 - 1/8 8 ) / 4 ≈ 2,907,270, por lo que todavía pasa la prueba del 50%.fuente
JavaScript, 81 bytes
Este código cumple todas las reglas:
0
en la salidaComo beneficio adicional, el algoritmo se ejecuta con una complejidad temporal de O (log 10 n), por lo que devuelve el entero casi al instante.
Esto supone un entorno REPL. Intente ejecutar el código anterior en la consola de su navegador, o use el fragmento de pila a continuación:
algoritmo :
s
hasta que aMath.random() > 0.1
.Math.random() > 0.5
, haga que el número sea negativo (anteponiendo la cadenas
con-
).Este algoritmo no tiene una distribución uniforme entre todos los enteros. Los enteros con un conteo de dígitos más alto son menos probables que los más bajos. En cada iteración de bucle for, hay un 10% de posibilidades de que me detenga en el dígito actual. Solo tengo que asegurarme de parar después de 6 dígitos más del 50% del tiempo.
Esta ecuación de @nutki explica el valor máximo del porcentaje de probabilidad de frenado basado en la condición anterior:
Por lo tanto, 0.1 está dentro del rango para satisfacer las tres reglas de la pregunta.
fuente
TI-BASIC, 14 bytes
Similar a la respuesta R de @ssdecontrol, esto se basa en la distribución gaussiana con una media de -1,000,000 o 1,000,000, elegida al azar y desviación estándar 9. La distribución no tiene límites, por lo que en teoría esto puede generar cualquier número entero.
Explicacion :
fuente
:
significa "imprimir" debido a cómo se presenta la explicación). ¿Pero puede generar números de más de 20 dígitos?randNorm
?Bash, 66
Casi siempre imprime 5000000. Pero si encuentra un número válido
/dev/random
, imprimirá ese número en su lugar.Y este es más rápido:
fuente
/dev/urandom
que es menos aleatorio./dev/urandom
en un script de shell es básicamente lo mismo que llamarrand()
en otros idiomas. Aunque si realmente está usando bash, no POSIX sh, puede obtener números aleatorios deecho $RANDOM
. wiki.ubuntu.com/DashAsBinSh se ofrecehexdump /dev/urandom
como equivalente de bare-POSIX-mínimo/bin/dash
.C ++, 95 bytes
Expandido:
Explicación:
La función sigue imprimiendo dígitos aleatorios consecutivos hasta que un interruptor de valor aleatorio toma el valor requerido para detener la función. d es la variable que mantiene el valor del siguiente dígito a imprimir. s es la variable de cambio que toma valores enteros aleatorios en el intervalo [0, 9], si s == 9 entonces no se imprimen más dígitos y la función finaliza.
Las variables dys se inicializan para dar un tratamiento especial al primer dígito (tomándolo del intervalo [-9, 9] y si el primer dígito es cero, entonces la función debe finalizar para evitar los ceros iniciales). El valor de d podría asignarse como d = rand ()% 10 pero luego el primer dígito no podría ser negativo. d se asigna en su lugar como d = (rand ()% 19 + d + 9)% 10 y se inicializa en -18, por lo que el primer valor de d variará entre [-9, 9] y los siguientes valores siempre variarán desde [0 , 9].
La variable s varía aleatoriamente desde [0, 9], y si s es igual a 9, la función finaliza, por lo que después de imprimir el primer dígito, el siguiente se imprimirá con una probabilidad del 90% (suponiendo que rand () es verdaderamente aleatorio, y para satisfacer la tercera condición). s podría asignarse fácilmente como s = rand ()% 10, sin embargo, existe una excepción, si el primer dígito es cero, la función debe finalizar. Para manejar dicha excepción, s ha sido asignado como s = 9-rand ()% 10 * min (d * d + s + 1,1) e inicializado como -1. Si el primer dígito es cero, el mínimo devolverá 0 y s será igual a 9-0 = 9. La asignación de la variable s siempre oscilará entre [0, 9], por lo que la excepción solo puede ocurrir en el primer dígito.
Características (suponiendo que rand () es verdaderamente aleatorio)
El número entero se imprime dígito a dígito, con una probabilidad fija del 90% de imprimir otro dígito después de imprimir el último.
0 es el número entero con mayor probabilidad de ser impreso, con una probabilidad de aproximadamente 5.2%.
La probabilidad de imprimir un número entero en el intervalo [-10 ^ 6, 10 ^ 6] es aproximadamente del 44% (el cálculo no se escribe aquí).
Los enteros positivos y negativos se imprimen con la misma probabilidad (~ 47.4%).
No todos los dígitos se imprimen con la misma probabilidad. Por ejemplo: en medio de la impresión del número entero, si el último dígito fue 5, el dígito 3 tendrá una probabilidad ligeramente menor de imprimirse a continuación. En general, si el último dígito fue d, el dígito (d + 18)% 10 tendrá una probabilidad ligeramente menor de imprimirse a continuación.
Resultados de ejemplo (10 ejecuciones)
fuente
Bash, 42 bytes
printf "%d\n" 0x$(xxd -p -l5 /dev/random)
/ dev / random en OSX es solo bytes aleatorios, y
xxd -p -l5
convierte 5 de los caracteres ascii a hexadecimal, y loprintf
convierte en formato decimal.fuente
Pyth , 11 bytes
Nota: este programa probablemente se bloqueará con un error de memoria en cualquier computadora real. Para probarlo, intente reemplazarlo
G
por una cadena más corta, como en este código, que genera números con un promedio de alrededor de 28000:Este código se repite, agregando un número aleatorio de -1 a 8 a
Z
, con una probabilidad de 2 ^ -26 de salir del ciclo en cada repetición. La probabilidad de 2 ^ -26 se logra seleccionando un elemento aleatorio (O
) del conjunto de todos los subconjuntos (y
) del alfabeto (G
).Detalles técnicos y justificación:
La probabilidad 2 ^ -26 se deriva de dos hechos:
y
cuando se llama a secuencias, es la función de conjunto de potencia, construye la lista de todos los subconjuntos de la entrada. Dado que la entrada,G
tiene 26 caracteres de longitud, este conjunto de potenciayG
tiene 2 ^ 26 entradas.OyG
selecciona un elemento aleatorio de esas 2 ^ 26 entradas. Exactamente una de esas entradas, la cadena vacía, se evaluará como falsa cuando se pase aW
ciclo while. Por lo tanto, hay una probabilidad de 2 ^ -26 de salir del ciclo cada vez.En cualquier número fijo de ciclos de bucle K, la probabilidad de obtener el número K * 3.5 + my obtener K * 3.5 - m es igual, porque cada secuencia de sumandos que logra un total puede invertirse, -1 -> 8, 0 -> 7, etc., para lograr el otro. Además, los números más cercanos a K * 3.5 son claramente más probables que los números más lejanos. Por lo tanto, si K> 2000000 / 3.5 = 571428.5, la probabilidad de obtener un número por encima de 1000000 es mayor que 75%, porque algunos de los resultados por encima de ese número se pueden poner en una correspondencia uno a uno con todos los resultados a continuación. número, y la parte superior inferior a la mitad, se puede poner en una correspondencia uno a uno con los menores de 1000000. La probabilidad de obtener al menos 571429 bucles es (1-2 ^ -26) ^ 571429, que es no menos de (1-2 ^ -26 * 571429), el número esperado de veces que se abandona el ciclo durante los primeros 571429 intentos, que es 99.1%. Por lo tanto, en el 99.1% o más de las pruebas, hay un 75% o más de posibilidades de obtener al menos 1000000, por lo que hay más del 50% de posibilidades de obtener más de 1000000.
Este código se basa en un comportamiento de
O
dónde se introdujo un error accidentalmente hace 3 días y se corrigió hoy. Debería funcionar en cualquier versión de Pyth 3 antes del 22 de diciembre o después de hoy. El siguiente código es equivalente y siempre ha funcionado:fuente
Java, 113 bytes
Este programa imprime un número binario en la secuencia de salida estándar. Es posible que tenga que esperar un tiempo porque la probabilidad de que termine el número (o sea positivo) es aproximadamente 0. La idea de que el valor absoluto de un número generado es inferior a 1 millón es divertida, pero posible.
Sin golf:
Salida de muestra: se publicará cuando se haya generado un número.
fuente
Java (JDK) ,
140127 bytes-13 bytes
introduciendo más lógica en el encabezado del bucle, gracias a @ceilingcatPruébalo en línea!
fuente