Sobre la serie
Esta es una entrada invitada para la serie Random Golf of the Day.
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 .
Entrada
No se toma ninguna entrada.
Salida
Una sola letra del alfabeto (caso irrelevante), con una nueva línea final opcional. Cada letra debe tener una probabilidad distinta de cero de ser elegida, y las 26 probabilidades deben ser distintas . Para eliminar toda ambigüedad: Distinto significa que no debe haber dos probabilidades que sean iguales entre sí.
Puntuación
Este es el código de golf. El código más corto en bytes gana.
Una entrada válida es un programa o función completa que tiene una probabilidad cero de no terminar.
Alfabeto
Para evitar confusiones, el alfabeto particular que se utilizará es el alfabeto latino:
Ya sea
ABCDEFGHIJKLMNOPQRSTUVWXYZ
o
abcdefghijklmnopqrstuvwxyz
Puede optar por generar mayúsculas o minúsculas. Alternativamente, puede optar por generar diferentes casos en diferentes ejecuciones si eso ayuda. La probabilidad de una letra dada es la probabilidad de que esa letra aparezca en cualquier caso (superior o inferior).
Explicación
Como no será del todo obvio por el resultado, incluya una explicación clara de cómo logró las 26 probabilidades distintas.
Tabla de clasificación
(desde aquí )
La primera publicación de la serie también genera una tabla de clasificación general.
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 N
está 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 sí lo requiere y analiza, y puedo agregar una tabla de clasificación por idioma en el futuro).
A
lugar de65
.Respuestas:
Pyth, 5
Pruébalo aquí
Calcula los prefijos del alfabeto, así:
["a", "ab", "abc", ..., "abcdefghijklmnopqrstuvwxyz"]
. Luego aplana la lista y selecciona un elemento aleatorio de manera uniforme. Esto significa que, dado quea
aparece 26 veces, mientras queb
aparece 25 veces, hasta el finalz
con solo 1 aparición, cada letra tiene una posibilidad diferente de aparecer. La cadena total tiene 351 caracteres.fuente
MATL, 6 Personajes
Explicación:
Xr
Tome un número aleatorio normalmente distribuido)
Use esto para indexar en ...1Y2
El alfabetoLa distribución es simétrica alrededor de 0, y la traducción del número a char es simétrica alrededor de 0.5. Como tal, las probabilidades deben ser distintas.
fuente
05AB1E , 6 bytes
Código
Explicación
Ahora tenemos la siguiente cadena:
Después de eso, elegimos un elemento aleatorio usando
.R
.Las probabilidades
Pruébalo en línea! .
fuente
Jalea , 5 bytes
Pruébalo en línea!
Cómo funciona
Antecedentes
Let L 0 , ..., L 25 denota las letras del alfabeto en su orden natural, y S 0 , ..., s 25 una permutación aleatoria seleccionada de manera uniforme a de L . Defina la secuencia finita M por M n = max (L n , S n ) .
Arregle n en 0,… 25 y defina k como el índice tal que L n = S k .
Con probabilidad 1/26 , L n = S n y n = k , por lo que M n = L n y L n occurrs una vez en M .
Con probabilidad 25/26 , L n ≠ S n y n ≠ k . En este caso, sucede lo siguiente.
Con probabilidad n / 25 , S n es uno de L 0 , ..., L n - 1 , entonces L n > S n y M n = L n .
Independientemente, también con probabilidad n / 25 , k es uno de 0, ... n - 1 , entonces S k > L k y M k = S k = L n .
Por lo tanto, el número esperado de ocurrencias de L n en M es 1/26 + 25/26 · (n / 25 + n / 25) = (2n + 1) / 26 .
Finalmente, si ahora seleccionamos un término m de M de manera uniforme al azar, la letra L n se elegirá con probabilidad (2n + 1) / 26/26 = (2n + 1) / 676 .
Esto produce la siguiente distribución de probabilidades.
Puede verificar empíricamente la distribución llamando al enlace 100,000 veces (toma unos segundos).
fuente
MATL , 10 bytes
Pruébalo en línea!
El código genera una variable aleatoria uniforme en el intervalo (0,1) (
r
) y calcula su cuadrado (U
). Esto da como resultado una densidad de probabilidad decreciente no uniforme. Multiplicar por 26 (26*
) asegura que el resultado esté en el intervalo (0,26), y el redondeo hacia abajo (k
) produce los valores 0,1, ..., 25 con probabilidades decrecientes. El valor se usa como un índice ()
) en el alfabeto en mayúsculas (1Y2
). Dado que MATL usa indexación modular basada en 1, 0 corresponde a Z, 1 a A, 2 a B, etc.Como ilustración de que las probabilidades son distintas, aquí hay un histograma discreto resultante de 1000000 realizaciones aleatorias. El gráfico se produce al ejecutar esto en Matlab:
fuente
k
! Noté eso mientras intentaba codegolf.stackexchange.com/a/89648/11159Java 7,
625756 bytes5 bytes gracias a Poke.
1 byte gracias a trichoplax.
Ideone it!
Diagrama de frecuencia (1e6 carreras, factor de escala 1/1000)
fuente
sqrt(x*y*y) = sqrt(x)*y
Perl, 24 bytes
-4 bytes gracias a @Martin Ender
-1 byte gracias a @Dom Hastings
Necesita
-M5.010
o-E
correr:Ejecutar el siguiente código mostrará la aparición de cada letra:
Cómo funciona : supongo que el código es bastante explícito, pero aún así: elige un número aleatorio entre
0
yrand 26
. Por lo tanto, hay una probabilidad mucho mayor de que se elijan números cercanos a0
(letraA
).fuente
say+(A..Z)[rand rand 26]
(A..Z)[...]
y no funcionó, así que pensé que podría usar una matriz anónima como esa, pero eso fue solo porsay
... ¡gracias! :)PHP,
44362927 bytesTachado 44 sigue siendo regular 44; (
Gracias a insertusernamehere, Petah y Crypto por toda la ayuda
Elige un número aleatorio entre 0 y 675 (= 26 2 -1), toma su raíz cuadrada y la coloca (la
chr
función convierte su argumento en un entero). Dado que los cuadrados tienen diferentes intervalos entre ellos, la probabilidad de que cada número sea elegido es distinta. Cada n se elige con probabilidad (2n + 1) / 676.Agregar 65 a este número le da un carácter aleatorio de
A
aZ
.Ideona del código corriendo 1,000,000 veces
fuente
range(A,Z)
.chr()
.<s> 44 </s>
<?=chr(65+sqrt(rand(0,675)));
R,
4027 bytesEsto tomará el
1
número de los26
números generados con una probabilidad creciente haciaZ
, sin reemplazar, y mostrará una letra cuyo índice es este número, de la lista de letras mayúsculasLETTERS
.Los argumentos de la
sample
función son:fuente
> <> , 14 bytes
> <> es un lenguaje 2D toroidal, y la parte de las probabilidades distintas ocurre naturalmente debido a la única fuente de aleatoriedad del lenguaje. Pruébalo en línea!
Los comandos relevantes son:
Por lo tanto, las probabilidades de salida son:
fuente
Pitón 2,
5857 bytesExplicación: esto genera un número aleatorio de coma flotante en el intervalo
[0, 676)
, toma la raíz cuadrada y luego la coloca en el piso. Luego agrega 65 (el valor ascii de "A"), lo convierte en un carácter y lo imprime.Esto le da a cada número del 0 al 25 una probabilidad distinta. Para entender por qué, piénsalo así. ¿Cuántos números, ignorando los no enteros, cuando tomas la raíz cuadrada y el piso dan 0? Solo un número será (cero). Esto significa que cero tiene una probabilidad de
1/676
. ¿Cuántos números producirán 1? 3 will, 1, 2 y 3. Esto significa que uno tiene una probabilidad de3/676
. Se puede producir un dos con un 4, 5, 6, 7 u 8, lo que le da una probabilidad de 5, un tres tiene una probabilidad de 7, etc. a 25 (Z).¡1 byte guardado gracias a la monja con fugas!
fuente
chr(int(65+randint(676)**.5))
chr(int(65+random()**.5*26))
. Es lo mismo algebraicamente porque 26 == √676. y ahora el orden de las operaciones está de tu lado**2*26
podría usarse para la distribución inversa.1/random()%26
También debería funcionar.PowerShell v2 +,
3331 bytesToma un rango de
65
a90
(es decir, ASCIIA
aZ
), lo canaliza a través de un bucle. En cada iteración, utilizamos el operador de coma para crear una matriz de ese elemento multiplicado por ese número. Por ejemplo, esto generará 6565
s, 6666
s, 6767
s, etc. Esa gran matriz se canaliza a laGet-Random
que (uniformemente PRNG) seleccionará un elemento. Dado que hay diferentes cantidades de cada elemento, cada personaje tiene un porcentaje ligeramente diferente de ser elegido. Luego encapsulamos eso en parens y lo lanzamos como achar
. Eso queda en la tubería y la salida es implícita.(Gracias a @LeakyNun por jugar unos pocos bytes incluso antes de que se publicara.: D)
Las probabilidades
(leve redondeo para poder demostrar la
P
opción del-f
operador ormat)fuente
gal
output ([char[]]"uz$(gal|out-string)"-cmatch'[a-z]'|random
) llegó a 50 caracteres, luego 48, cambió a números y obtuvo 42, luego 31 y se detuvo allí; Miré en la tabla de clasificación para ver dónde me pondría. Aquí mismo. Carácter por personaje idéntico. Welp, probablemente no puedo superar eso.CJam,
211712 bytes¡Gracias a Martin Ender por salvarme 5 bytes!
Nueva versión
Esto forma una matriz de cadenas siguiendo el patrón
A
,AB
,ABC
, y así sucesivamente. Lo aplana y elige un personaje aleatorio. Como esta cadena contiene 26 A, 25 B, 24 C, etc., cada letra tiene una probabilidad distinta de ser elegida.Pruébalo en línea!
Explicación
Versión antigua
Obtiene probabilidades distintas al hacer una cadena en la que cada letra aparece varias veces igual a su posición en el alfabeto.
fuente
R, 23 bytes
Simplemente 'muestra' una carta de un builtin incorporado. El
1:26
es un vector de pesos que le da a cada letra una probabilidad diferente.fuente
1:26
es un vector de pesos para cada letraC, 35 bytes
Este programa asume que
RAND_MAX
es (2 ^ 32/2) - 1 ya que está en gcc por defecto. Compile con la-lm
bandera para vincular lasqrt
función. La salida se escribe en stdout como letras mayúsculas sin líneas nuevas.Opcionalmente, si
RAND_MAX
es (2 ^ 16/2) - 1, se puede usar una versión más corta de 32 bytes:Solo por diversión, también hice una versión que no usa la
sqrt
función o requiere la biblioteca matemática incluida (esta debe tenerRAND_MAX
como (2 ^ 32/2) - 1), pero terminó siendo más larga aunque pensé que era muy genial:Explicación
[Primer programa]
Para los dos primeros que usan
sqrt
, la función simplemente asigna el rango[0, RAND_MAX)
a[0, 25]
través de la división, y luego agrega 65 (ASCIIA
) al valor para cambiarlo al alfabeto ASCII antes de generarlo.[Segundo programa]
El segundo programa es un poco más complejo ya que hace una estrategia similar, pero sin el
sqrt
operador. Dado que los bits de exponente de un punto flotante se calculan automáticamente al asignar un número entero, pueden usarse efectivamente como una forma cruda de obtener el logaritmo de base 2 de un número.Como solo queremos que el rango
RAND_MAX
alcance un valor de exponente codificado de 25, el cálculo (2 ^ 32/2 - 1) / (2 ^ 25) nos da aproximadamente 64, que se usa durante la división derand
para mapearlo a esta nueva gama. También agregué 1 al valor ya que la representación de coma flotante de 0 es bastante extraña y rompería este algoritmo.A continuación, el flotante se escribe en un entero para permitir el desplazamiento de bits y otras operaciones similares. Dado que en los números de coma flotante IEEE 754 los bits de exponente son bits 30-23, el número se desplaza 23 bits a la derecha, cortando la mantisa y permitiendo que el valor de exponente bruto se lea como un entero. Tenga en cuenta que el bit de signo también está más allá de los bits de exponente, pero como nunca hay negativos, no es necesario enmascararlo.
Sin embargo, en lugar de sumar 65 a este resultado como lo hicimos antes, los exponentes de coma flotante se representan como un entero de 8 bits sin signo de 0 a 255, donde el valor de exponente de 0 es 127 (simplemente reste 127 para obtener el valor de exponente "firmado" real ) Dado que 127 - 65 es 62, simplemente restamos 62 para desplazarlo fuera de este rango de exponente de coma flotante al rango de alfabeto ASCII, todo en una sola operación.
Distribución
No soy un experto en matemáticas, así que no puedo decir con certeza la fórmula exacta para estas distribuciones, pero puedo (y probé) probar cada valor en el rango
[0, RAND_MAX)
para mostrar que la distancia entre el final del rango de una letra y la otra comienza nunca es la mismo. (Tenga en cuenta que estas pruebas suponen el (2 ^ 32/2) - 1) máximo aleatorio)[Primer programa]
[Segundo programa]
fuente
char
es un tipo integral en C, eso debería ser aceptable.Python 2, 72 bytes
Multiplica el carácter por su valor ascii, luego elige un carácter al azar de la cadena resultante.
Aquí están las probabilidades para cada letra seleccionada, en porcentajes:
Pruébalo: https://repl.it/Cm0x
fuente
Jalea , 5 bytes
(Puntuación igual, pero un método diferente , a una solución Jelly existente de Dennis).
La probabilidad de obtener cada letra es su índice basado en 1 en el alfabeto dividido por 351, el 26 ° número triangular:
A
) = 1/351, P (B
) = 2/351, ..., P (Z
) = 26/351.Como 1 + 2 + ... + 26 = 351, P (letra) = 1.
Implementación:
Pruébelo en TryItOnline u obtenga la distribución de 100K carreras (código de crédito para Dennis)
fuente
q, 38 bytes
No particularmente corto pero ...
La función de distribución acumulativa discreta es la secuencia
0.9 ^ 26, 0.9 ^ 25, ..., 0.9 ^ 0
Y simplemente tomamos muestras de la distribución.
fuente
JavaScript (ES6), 45 bytes
Logra una distribución no uniforme al cuadrar el valor aleatorio.
Math.random()
devuelve un flotador del rango,[0,1)
por lo que el resultado de cuadrar esto tiende hacia0
(oa
).Prueba
Mostrar fragmento de código
fuente
(n=Math.random(),10+26*n+n|0).toString(36)
Oracle SQL 11.2, 212 bytes
Usar la posición del personaje en el alfabeto como probabilidad
Sin golf
fuente
TI-Basic, 39 bytes
rand
genera un valor uniforme en (0,1]. Esto le da a 26 ^ rand una probabilidad diferente de igualar los enteros de 1 a 26.Versión anterior, 45 bytes.
La precisión limitada de los enteros TI-Basic limita las distribuciones normales para generar números dentro de µ ± 7.02σ (ver
randNorm(
). Entonces obtenemos el valor absoluto de un número aleatorio con µ 0 y σ 1, multiplicando por cuatro para aumentar el rango práctico mencionado anteriormente a µ ± 28.08σ. Luego, colocamos el valor en el piso y sumamos 1, ya quesub(
está indexado en 1, lo que nos da un rango de 1-29 con diferentes probabilidades de cada uno.fuente
PHP,
9284 bytesConstruye una cadena de todas las letras, repite el número de veces a través del bucle que estamos y luego elige una letra de esa cadena al azar. Las letras más adelante en el alfabeto tienen una mayor probabilidad como resultado
Gracias a insertusernamehere por eliminar bytes
probabilidades de resultado (ordenadas por%)
fuente
$x=0
que obviamente es necesario. Aquí hay una versión de 84 bytes :for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);
¿Alguna vez logró obtener un valor mayor queG
cuando ejecutó su código? De todos modos, siempre puedes ignorarnotice
s cuando juegas al golf.strlen
de$a
es 351, pero solo está eligiendo un carácter aleatorio de los primeros$x
(26) caracteres. Puede arreglarlo y mantener sus probabilidades con un cambio de la final$x
a350
+1 byte. Aquí hay una versión de 77 bytes que soluciona el problema pero también acerca las probabilidades mucho más juntas:for($i=65;$i<91;$a.=str_repeat(chr($i),$i++));echo substr($a,rand(0,2014),1);
Befunge
168164 bytesMás compacto que el primero, con probabilidades un poco diferentes: los primeros
?
tienen una probabilidad de 1/4 de imprimir una A en el "primer intento", 2/4 de posibilidad de volver a la misma?
y 1/4 de moverse al próximo. El resto de los?
s tienen 1/4 de posibilidades de imprimir la letra debajo de ellos, 1/4 para volver a intentarlo, 1/4 moviéndose a la siguiente letra, 1/4 moviéndose a la anterior. Nuevamente, la probabilidad de imprimir una A es mucho mayor que imprimir una Z.Befunge, 186 bytes
Obviamente no voy a ganar con esto, pero creo que es una respuesta interesante :)
v
y>
dirige el cursor respectivamente hacia abajo y hacia la derecha. El?
operador envía el cursor en una de las cuatro direcciones al azar. El primero?
está "bloqueado" porv
y>
en dos direcciones, por lo que solo tiene dos vías: imprimir la A o bajar a la siguiente?
. Entonces, desde el primero?
solo hay un 50% de posibilidades de imprimir una A.El siguiente
?
tiene una probabilidad de 1/3 de imprimir una B, 1/3 de volver a subir y 1/3 de bajar más. Etcétera etcétera.Debería ser bastante obvio que las letras más altas tienen muchas más posibilidades de ser impresas que las letras más bajas, pero no estoy exactamente seguro de cuáles son las posibilidades de cada letra.
Se agradecería un poco de ayuda con las matemáticas exactas :)
Al menos hay un 1/2 * 1/3 ^ 25 probabilidad de que el cursor se mueva hasta la Z en el primer intento, pero no estoy seguro de cómo las posibilidades de que el cursor se mueva hacia arriba y hacia abajo afecte a cada letra.
,@
imprime y termina.fuente
J,
2018 bytesIntérprete en línea
Mayúscula
La probabilidad de cada letra es su índice basado en 1 en el alfabeto.
fuente
zsh, 63 bytes
funciona creando esta cadena:
también conocido como 65 veces A, 66 veces B, 67 veces C ...
y luego elige un personaje aleatorio
fuente
A
en ascii. puede comenzar a partir de 1, pero entonces el bucle interno se convierte en{65..$[#i]}
lo que es 1 carácter más largoCJam, 11 bytes
o
Pruébalo en línea!
Esta solución es similar a la idea de Luis y crea una distribución no uniforme tomando la raíz cuadrada de la variable aleatoria.
fuente
Lote, 116 bytes
Funciona eligiendo la más grande o más pequeña (no recuerdo cuál) de dos variables aleatorias.
fuente
Matlab, 22
A menudo devolverá letras tempranas, ¡pero teóricamente puede tocarlas todas!
Toma uno dividido por un número aleatorio, lo limita a 26 y lo convierte en un personaje.
No muy corto, por supuesto, pero quizás el concepto pueda inspirar otras respuestas.
fuente
rand
Devuelve un valor en [0, 1)? Es decir, incluye cero pero no incluye uno. Si esto ocasionalmente resulta en 1/0, ¿min(1/0,26)
aún devolverá 26 o un error?rand
devuelve un valor en (0,1), por lo que no debería haber un problemarand
retorno 0 en la práctica, enmin(1/0,26)
realidad devuelve 26.CJam, 10 bytes
Enfoque CJam # 3 ...
Pruébalo en línea!
Esto crea un número aleatorio uniforme
x
entre 1 y 26 y luego lo usa para crear un número aleatorio uniforme entre0
y alx-1
cual se agregaA
. Este sesgo da como resultado caracteres más pequeños.fuente
Laberinto , 19 bytes
Pruébalo en línea!
Este es un ciclo que, en cada iteración, a) incrementa un contador que comienza en cero o b) termina, ambos con una probabilidad del 50%. Al final del ciclo, el contador se toma el módulo 26 y se agrega a 65 para dar una letra entre
A
yZ
.Esto da una probabilidad de
A
un poco más del 50%,B
un poco más del 25% y así sucesivamente hastaZ
un poco más del 1/2 26 . En teoría, existe la posibilidad de que esto se ejecute para siempre, pero este evento tiene una probabilidad cero según lo requerido por el desafío (en la práctica eso probablemente no sea posible de todos modos porque el PRNG devolverá ambos resultados posibles en algún momento durante su período).fuente