Golf aleatorio del día # 7: un personaje claramente aleatorio


47

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 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 sí lo requiere y analiza, y puedo agregar una tabla de clasificación por idioma en el futuro).


¿Cómo medirías 26 probabilidades distintas? ejecutando el programa 26 veces?
USTED

1
@YOU eche un vistazo a las soluciones: hay algunos enfoques diferentes con excelentes explicaciones
trichoplax

Si es una función, ¿necesita imprimir o puede simplemente devolver el valor del carácter?
Geoff Reedy

@Geoff De acuerdo con nuestros valores predeterminados para entrada y salida , ya sea imprimir en STDOUT o devolver un carácter está bien.
trichoplax

@Geoff tenga en cuenta que debe ser un carácter, no solo un valor numérico que lo represente. Por ejemplo, en Alugar de 65.
trichoplax

Respuestas:


13

Pyth, 5

Os._G

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 que aaparece 26 veces, mientras que baparece 25 veces, hasta el final zcon solo 1 aparición, cada letra tiene una posibilidad diferente de aparecer. La cadena total tiene 351 caracteres.


1
Me gusta esa respuesta Muy inteligente.
Allen Fisher

24

MATL, 6 Personajes

1Y2Xr)

Explicación:

XrTome un número aleatorio normalmente distribuido )Use esto para indexar en ... 1Y2El alfabeto

La 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.


2
¡Oh, muy buena idea usar una distribución gaussiana!
Luis Mendo

1
"mejor" lenguaje para el trabajo, aún golpeado por la gelatina. Excelente solución sin embargo.
Phoenix Socrático

19

05AB1E , 6 bytes

Código

A.pJ.R

Explicación

A        # Pushes the alphabet
 .p      # Computes all prefixes
   J     # Join them together

Ahora tenemos la siguiente cadena:

aababcabcdabcdeabcdefabcdefgabcdefghabcdefghiabcdefghijabcdefghijkabcdefghijklabcdefghijklmabcdefghijklmnabcdefghijklmnoabcdefghijklmnopabcdefghijklmnopqabcdefghijklmnopqrabcdefghijklmnopqrsabcdefghijklmnopqrstabcdefghijklmnopqrstuabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvwabcdefghijklmnopqrstuvwxabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz

Después de eso, elegimos un elemento aleatorio usando .R.

Las probabilidades

a > 7.4074074074074066%
b > 7.122507122507122%
c > 6.837606837606838%
d > 6.552706552706553%
e > 6.267806267806268%
f > 5.982905982905983%
g > 5.698005698005698%
h > 5.413105413105414%
i > 5.128205128205128%
j > 4.843304843304843%
k > 4.5584045584045585%
l > 4.273504273504274%
m > 3.988603988603989%
n > 3.7037037037037033%
o > 3.418803418803419%
p > 3.133903133903134%
q > 2.849002849002849%
r > 2.564102564102564%
s > 2.2792022792022792%
t > 1.9943019943019944%
u > 1.7094017094017095%
v > 1.4245014245014245%
w > 1.1396011396011396%
x > 0.8547008547008548%
y > 0.5698005698005698%
z > 0.2849002849002849%

Pruébalo en línea! .


18

Jalea , 5 bytes

ØA»ẊX

Pruébalo en línea!

Cómo funciona

ØA«ẊX  Main link. No arguments.

ØA     Set argument and return value to the alphabet.
   Ẋ   Shuffle it.
  »    Yield the maximum of each letter in the sorted alphabet, and the
       corresponding character in the shuffled one.
    X  Pseudo-randomly select a letter of the resulting array.

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.

p(m = A) =  1/676 ≈ 0.00148
p(m = B) =  3/676 ≈ 0.00444
p(m = C) =  5/676 ≈ 0.00740
p(m = D) =  7/676 ≈ 0.01036
p(m = E) =  9/676 ≈ 0.01331
p(m = F) = 11/676 ≈ 0.01627
p(m = G) = 13/676 ≈ 0.01923
p(m = H) = 15/676 ≈ 0.02219
p(m = I) = 17/676 ≈ 0.02515
p(m = J) = 19/676 ≈ 0.02811
p(m = K) = 21/676 ≈ 0.03107
p(m = L) = 23/676 ≈ 0.03402
p(m = M) = 25/676 ≈ 0.03698
p(m = N) = 27/676 ≈ 0.03994
p(m = O) = 29/676 ≈ 0.04290
p(m = P) = 31/676 ≈ 0.04586
p(m = Q) = 33/676 ≈ 0.04882
p(m = R) = 35/676 ≈ 0.05178
p(m = S) = 37/676 ≈ 0.05473
p(m = T) = 39/676 ≈ 0.05769
p(m = U) = 41/676 ≈ 0.06065
p(m = V) = 43/676 ≈ 0.06361
p(m = W) = 45/676 ≈ 0.06657
p(m = X) = 47/676 ≈ 0.06953
p(m = Y) = 49/676 ≈ 0.07249
p(m = Z) = 51/676 ≈ 0.07544

Puede verificar empíricamente la distribución llamando al enlace 100,000 veces (toma unos segundos).


1
@RobertFraser, el paso de barajar y ceder produce una lista con una A en cualquier lugar donde aparece una A en cualquiera de las listas, una B donde aparece una B en cualquier lista y cualquier otra cosa que no sea A en la otra lista, ... una Z en cualquier lugar donde Z apareció en ambas listas. así que hay aproximadamente 52 veces más A que Z en el resultado.
Sparr

1
@RobertFraser He agregado una explicación.
Dennis

2
@DennisJaheruddin En UTF-8, sí. Sin embargo, Jelly usa una página de códigos personalizada que codifica todos los caracteres que entiende como un solo byte cada uno. El enlace de bytes en el encabezado apunta a él.
Dennis

2
Ya veo, cuando leí la explicación, no estaba claro de inmediato que tampoco se puede aprovechar el rango UTF-8 normal. Entonces, ¿estoy en lo cierto al suponer que al cambiar el intérprete y asignar todos los caracteres a caracteres UTF-8 individuales, tendría un código completamente idéntico (simplemente menos legible / tipificable)? - Si es así, considere expandir la explicación para mencionar que un carbón debe contar para un byte para fines de golf.
Dennis Jaheruddin

2
@DennisJaheruddin Como se explica en el archivo README (primer enlace en el encabezado), el intérprete tiene dos modos (página de códigos Jelly y UTF-8), por lo que puede guardar este programa en un archivo real de 5 bytes. Podría agregar toda esa información a cada respuesta que escribo, pero hay cientos de ellas, así que elegí vincular en su lugar.
Dennis

14

MATL , 10 bytes

1Y2rU26*k)

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:

bar(0:25, histc(floor(26*rand(1,1e6).^2), 0:25))

ingrese la descripción de la imagen aquí


1
¡Agradable! La mejor solución que se me ocurre es 16 bytes
DJMcMayhem

1
@DJMcMayhem ¡Buen enfoque!
Luis Mendo

Quizás, pero mucho más. : P
DJMcMayhem

Otra alternativa divertida: matl.suever.net/…
Suever

En realidad no necesitas el k! Noté eso mientras intentaba codegolf.stackexchange.com/a/89648/11159
Dennis Jaheruddin

13

Java 7, 62 57 56 bytes

5 bytes gracias a Poke.

1 byte gracias a trichoplax.

char r(){return(char)(65+(int)Math.sqrt(Math.random()*676));}
char r(){return(char)(65+Math.sqrt(Math.random()*676));}
char r(){return(char)(65+Math.sqrt(Math.random())*26);}

Ideone it!

Diagrama de frecuencia (1e6 carreras, factor de escala 1/1000)

A: *
B: ****
C: *******
D: **********
E: *************
F: ****************
G: *******************
H: **********************
I: *************************
J: ***************************
K: ******************************
L: **********************************
M: ************************************
N: ***************************************
O: *******************************************
P: *********************************************
Q: ************************************************
R: ***************************************************
S: ******************************************************
T: *********************************************************
U: ************************************************************
V: ***************************************************************
W: ******************************************************************
X: *********************************************************************
Y: ************************************************************************
Z: ***************************************************************************

1
No creo que necesites escribir en int
Poke

@Poke Gracias, golf.
Leaky Nun

¿Puedes guardar un byte moviendo el 676 fuera del paréntesis?
trichoplax

@trichoplax ¿Qué quieres decir?
Leaky Nun

2
sqrt(x*y*y) = sqrt(x)*y
trichoplax

10

Perl, 24 bytes

-4 bytes gracias a @Martin Ender
-1 byte gracias a @Dom Hastings

say+(A..Z)[rand rand 26]

Necesita -M5.010o -Ecorrer:

perl -E 'say+(A..Z)[rand rand 26]'

Ejecutar el siguiente código mostrará la aparición de cada letra:

perl -MData::Printer -E '$h{(A..Z)[rand rand 26]}++ for 1 .. 1_000_000;$h{$_} = int($h{$_} / 100) / 100 for A .. Z;p %h;'
A 16.4
B 11.02
C 8.99
...
Z 0.07


Cómo funciona : supongo que el código es bastante explícito, pero aún así: elige un número aleatorio entre 0y rand 26. Por lo tanto, hay una probabilidad mucho mayor de que se elijan números cercanos a 0(letra A).


La explicación tiene sentido para mí :)
trichoplax

Buena solución! Puede guardar 1 byte usando una lista simple y +:say+(A..Z)[rand rand 26]
Dom Hastings

@DomHastings aarf, soy estúpido. Lo intenté (A..Z)[...]y no funcionó, así que pensé que podría usar una matriz anónima como esa, pero eso fue solo por say... ¡gracias! :)
Dada

10

PHP, 44 36 29 27 bytes

Tachado 44 sigue siendo regular 44; (

Gracias a insertusernamehere, Petah y Crypto por toda la ayuda

<?=chr(65+rand(0,675)**.5);

Elige un número aleatorio entre 0 y 675 (= 26 2 -1), toma su raíz cuadrada y la coloca (la chrfunció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 Aa Z.

Ideona del código corriendo 1,000,000 veces


Puede jugar al golf de 4 bytes : range(A,Z).
insertusernamehere

@insertusernamehere: Gracias por el consejo, pero pude jugar al golf 8 bytes al no usar el rango y solo usarlo chr().
Business Cat

3
Aun mejor. Lamentablemente tachado 44 sigue siendo regular 44 . :)
insertusernamehere

1
@insertusernamehere Te rindes demasiado fácilmente :-)<s>&nbsp;44&nbsp;</s>
MonkeyZeus

<?=chr(65+sqrt(rand(0,675)));
Petah

8

R, 40 27 bytes

LETTERS[sample(26,1,,1:26)]

Esto tomará el 1número de los 26números generados con una probabilidad creciente hacia Z, sin reemplazar, y mostrará una letra cuyo índice es este número, de la lista de letras mayúsculas LETTERS.

Los argumentos de la samplefunción son:

sample(
       26, #How many numbers to generate
        1, #How many numbers to sample
         , #Replacing ? Here, no by default
     1:26, #Weight of probabilities
       )

Sí, eso no funcionará. ¡Podría haber una forma más inteligente!
Frédéric

Bueno, ¡siempre habrá un forro en alguna parte! Tengo que pensar en eso ...
Frédéric

1
Fijo y más corto - impresionante :)
trichoplax

1
@trichoplax ¡Gracias! Bonito desafío por cierto!
Frédéric

1
@AlbertMasclans: De hecho, puede, pero ya se ha hecho en la respuesta de otra persona, ¡así que no quiero "copiar"! Pero gracias de todos modos ! ;)
Frédéric

8

> <> , 14 bytes

lx
;>dd+%'A'+o

> <> 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:

[Row 1]
l          Push length of stack
x          Change the instruction pointer direction to one of up/down/left/right
           This gives a 50/50 chance of continuing on the first row (moving
           left/right) or going to the next row (moving up/down, wrapping if up)

[Row 2]
>          Change IP direction to right
dd+%       Take top of stack mod 26 (dd+ = 13+13 = 26)
'A'+       Add 65
o          Output as character
;          Halt

Por lo tanto, las probabilidades de salida son:

A:  1/2^1  + 1/2^27 + 1/2^53 + ... = 33554432 / 67108863 ~ 0.50000000745
B:  1/2^2  + 1/2^28 + 1/2^54 + ... = half of chance for A
C:  1/2^3  + 1/2^29 + 1/2^55 + ... = half of chance for B
...
Z:  1/2^26 + 1/2^52 + 1/2^78 + ... = half of chance for Y

7

Pitón 2, 58 57 bytes

from random import*
print chr(int(65+(random()*676)**.5))

Explicació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 de1/676 . ¿Cuántos números producirán 1? 3 will, 1, 2 y 3. Esto significa que uno tiene una probabilidad de 3/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!


chr(int(65+randint(676)**.5))
Leaky Nun

1
Usted podría hacer chr(int(65+random()**.5*26)). Es lo mismo algebraicamente porque 26 == √676. y ahora el orden de las operaciones está de tu lado
Wheat Wizard

3
@EamonOlive Para otro byte **2*26podría usarse para la distribución inversa.
user81655

1
1/random()%26También debería funcionar.
xnor

1
@xnor que a veces dará 1/0% 26
trichoplax

5

PowerShell v2 +, 33 31 bytes

[char](65..90|%{,$_*$_}|Random)

Toma un rango de 65a 90(es decir, ASCII Aa Z), 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á 65 65s, 66 66s, 67 67s, etc. Esa gran matriz se canaliza a la Get-Randomque (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 a char. 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 Popción del -foperador ormat)

PS C:\Tools\Scripts\golfing> 65..90|%{"$([char]$_): {0:P}"-f($_/2015)}
A: 3.23 %
B: 3.28 %
C: 3.33 %
D: 3.37 %
E: 3.42 %
F: 3.47 %
G: 3.52 %
H: 3.57 %
I: 3.62 %
J: 3.67 %
K: 3.72 %
L: 3.77 %
M: 3.82 %
N: 3.87 %
O: 3.92 %
P: 3.97 %
Q: 4.02 %
R: 4.07 %
S: 4.12 %
T: 4.17 %
U: 4.22 %
V: 4.27 %
W: 4.32 %
X: 4.37 %
Y: 4.42 %
Z: 4.47 %

1
Empecé sin mirar ninguna de las respuestas; trató de construir en galoutput ( [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.
TessellatingHeckler

5

CJam, 21 17 12 bytes

¡Gracias a Martin Ender por salvarme 5 bytes!

Nueva versión

'\,:,s_el-mR

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

'\,          e# Push the range of all characters up to 'Z'
   :,        e# For each one, take the range of all characters up to it
     s       e# Convert the array of ranges to one string
      _el-   e# Subtract the lower case version of the string from itself
             e# This leaves only capital letters in the string
          mR e# Take a random character from it

Versión antigua

26,:)'[,'A,- .*M*mr0=

Obtiene probabilidades distintas al hacer una cadena en la que cada letra aparece varias veces igual a su posición en el alfabeto.

26,:)                 e# Push 1, 2, ... 26
     '[,'A,-          e# Push 'A', 'B', ... 'Z'
             .*       e# Vectorize: repeat each letter the corresponding number of times
               M*     e# Join with no separator
                 mr   e# Shuffle the string
                   0= e# Get the first character

5

R, 23 bytes

sample(LETTERS,1,,1:26)

Simplemente 'muestra' una carta de un builtin incorporado. El 1:26es un vector de pesos que le da a cada letra una probabilidad diferente.


1
1:26es un vector de pesos para cada letra
user5957401

Eso lo convierte en una respuesta válida. Vale la pena editar una explicación para que las personas que no estén familiarizadas con R puedan entender cómo funciona.
trichoplax

1
Iba a hacerlo, y luego me di cuenta de que el tipo que estaba encima de mí había hecho casi lo mismo en su código y me dio un explicador en profundidad.
user5957401

Es bueno que haya agregado una explicación: el orden en que aparecen las soluciones en la página puede variar a medida que se reciben los votos, por lo que los "anteriores" podrían no ser posteriores.
trichoplax

5

C, 35 bytes

Este programa asume que RAND_MAXes (2 ^ 32/2) - 1 ya que está en gcc por defecto. Compile con la -lmbandera para vincular la sqrtfunción. La salida se escribe en stdout como letras mayúsculas sin líneas nuevas.

f(){putchar(sqrt(rand())/1783+65);}

Opcionalmente, si RAND_MAXes (2 ^ 16/2) - 1, se puede usar una versión más corta de 32 bytes:

f(){putchar(sqrt(rand())/7+65);}

Solo por diversión, también hice una versión que no usa la sqrtfunción o requiere la biblioteca matemática incluida (esta debe tener RAND_MAXcomo (2 ^ 32/2) - 1), pero terminó siendo más larga aunque pensé que era muy genial:

f(){float r=rand()/64+1;putchar((*(int*)&r>>23)-62);}

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 (ASCII A) 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 sqrtoperador. 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_MAXalcance 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 de randpara 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]

Letter - Starting Location
A - 0
B - 3179089
C - 12716356
D - 28611801
E - 50865424
F - 79477225
G - 114447204
H - 155775361
I - 203461696
J - 257506209
K - 317908900
L - 384669769
M - 457788816
N - 537266041
O - 623101444
P - 715295025
Q - 813846784
R - 918756721
S - 1030024836
T - 1147651129
U - 1271635600
V - 1401978249
W - 1538679076
X - 1681738081
Y - 1831155264
Z - 1986930625

[Segundo programa]

Letter - Starting Location
A - 0
B - 64
C - 192
D - 448
E - 960
F - 1984
G - 4032
H - 8128
I - 16320
J - 32704
K - 65472
L - 131008
M - 262080
N - 524224
O - 1048512
P - 2097088
Q - 4194240
R - 8388544
S - 16777152
T - 33554368
U - 67108800
V - 134217664
W - 268435392
X - 536870848
Y - 1073741760
Z - 2147483520

¿No sería más corto devolver el ordinal que imprimirlo? Como chares un tipo integral en C, eso debería ser aceptable.
Mego

@Mego Bueno, sí, si puedes hacer eso, soy nuevo en el golf, así que no estoy muy familiarizado con lo que se considera una producción aceptable.
Lemon Drop

4

Python 2, 72 bytes

from random import*
print choice(''.join(i*chr(i)for i in range(65,91)))

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:

A 3.23
B 3.28
C 3.33
D 3.37
E 3.42
F 3.47
G 3.52
H 3.57
I 3.62
J 3.67
K 3.72
L 3.77
M 3.82
N 3.87
O 3.92
P 3.97
Q 4.02
R 4.07
S 4.12
T 4.17
U 4.22
V 4.27
W 4.32
X 4.37
Y 4.42
Z 4.47

Pruébalo: https://repl.it/Cm0x


4

Jalea , 5 bytes

ØAxJX

(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:

  • PAGS(A ) = 1/351, P ( B) = 2/351, ..., P ( Z) = 26/351.

Como 1 + 2 + ... + 26 = 351, P (letra) = 1.

Implementación:

ØAxJX    - no input taken
ØA       - yield the alphabet: 'ABC...Z'
   J     - yield [1,...,len(Left)]: [1,2,3,...26]
  x      - Left times Right: 'abbccc...zzzzzzzzzzzzzzzzzzzzzzzzzz'
    X    - choose random element from Left

Pruébelo en TryItOnline u obtenga la distribución de 100K carreras (código de crédito para Dennis)


¿Dónde aprendiste a ser tan bueno en Jelly? Me resulta difícil creer que Jelly sea de conocimiento común fuera de PPCG.
Addison Crump

1
@Syxer Acabo de mirar la wiki y me alejé, todavía no entiendo todo :)
Jonathan Allan

1
Bien entonces. Bienvenido a PPCG, tenga un voto positivo.
Addison Crump

3

q, 38 bytes

No particularmente corto pero ...

.Q.A(reverse 0.9 xexp til 26)binr 1?1f

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.


3

JavaScript (ES6), 45 bytes

_=>(n=Math.random(),10+n*n*26|0).toString(36)

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 hacia 0(o a).

Prueba


42 B,(n=Math.random(),10+26*n+n|0).toString(36)
Ephellon Dantzler

3

Oracle SQL 11.2, 212 bytes

Usar la posición del personaje en el alfabeto como probabilidad

SELECT c FROM(SELECT dbms_random.value(0,351)v FROM DUAL),(SELECT c,e,LAG(e,1,0)OVER(ORDER BY c)s FROM(SELECT CHR(LEVEL+64)c,SUM(LEVEL)OVER(ORDER BY LEVEL)e FROM DUAL CONNECT BY LEVEL<27))WHERE v BETWEEN s AND e;

Sin golf

SELECT c FROM
  (SELECT dbms_random.value(0,351)v FROM DUAL), -- random value
  (
    SELECT c,e,LAG(e,1,0)OVER(ORDER BY c)s -- Mapping each character to its interval 
    FROM   (
             -- Each char has it's position in the alphabet as probability
             SELECT CHR(LEVEL+64)c,SUM(LEVEL)OVER(ORDER BY LEVEL)e 
             FROM   DUAL 
             CONNECT BY LEVEL<27
           )  
  )
WHERE v BETWEEN s AND e -- match the random value to an interval

3

TI-Basic, 39 bytes

sub("ABCDEFGHIJKLMNOPQRSTUVWXYZ",int(26^rand),1

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.

sub("ABCDEFGHIJKLMNOPQRSTUVWXYZAAA",1+int(4abs(invNorm(rand))),1

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 que sub(está indexado en 1, lo que nos da un rango de 1-29 con diferentes probabilidades de cada uno.


1
@trichoplax Ese fue mi error, me quedaban 30 de la versión anterior que era [0,29]. Lo arreglé ahora.
Timtech

El intervalo (0,1] se supone que es [0,1).
kamoroso94

@ kamoroso94 ¿Lo has comprobado? "Nota: Debido a los detalles del algoritmo de generación de números aleatorios, el número más pequeño posible para generar es ligeramente mayor que 0. El número más grande posible es en realidad 1" - citado por tibasicdev.wikidot.com/rand
Timtech

3

PHP, 92 84 bytes

for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);

Construye 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%)

A => 0.29%
B => 0.62%
C => 0.82%
D => 1.15%
E => 1.50%
F => 1.65%
G => 2.00%
H => 2.27%
I => 2.52%
J => 2.80%
K => 3.13%
L => 3.47%
M => 3.72%
N => 3.93%
O => 4.15%
P => 4.59%
Q => 4.81%
R => 5.17%
S => 5.44%
T => 5.68%
U => 6.06%
V => 6.13%
W => 6.60%
X => 6.95%
Y => 7.17%
Z => 7.38%


1
cambiado para adherirse a las reglas. Mi error
gabe3886

@insertusernameaquí recibo avisos de variables indefinidas cuando ejecuto eso y no hay salida de letras
gabe3886

Oh lo siento. Creo que me dejé llevar y eliminé, lo $x=0que 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 que Gcuando ejecutó su código? De todos modos, siempre puedes ignorar notices cuando juegas al golf.
insertusernamehere

1
Lo hice, pero lleva un tiempo recortar. Lo
revisé

El strlende $aes 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 $xa 350+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);
Jo.

3

Befunge 168 164 bytes

Má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.

??????????????????????????>
""""""""""""""""""""""""""
ABCDEFGHIJKLMNOPQRSTUVWXYZ
""""""""""""""""""""""""""
>>>>>>>>>>>>>>>>>>>>>>>>>>,@
##########################

Befunge, 186 bytes

Obviamente no voy a ganar con esto, pero creo que es una respuesta interesante :)

vy >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" por vy> 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.

 v
>?"A"v
>?"B"v
>?"C"v
>?"D"v
>?"E"v
>?"F"v
>?"G"v
>?"H"v
>?"I"v
>?"J"v
>?"K"v
>?"L"v
>?"M"v
>?"N"v
>?"O"v
>?"P"v
>?"Q"v
>?"R"v
>?"S"v
>?"T"v
>?"U"v
>?"V"v
>?"W"v
>?"X"v
>?"Y"v
>?"Z">,@


2

zsh, 63 bytes

for i in {A..Z};for j in {1..$[#i]};s+=$i;echo $s[RANDOM%$#s+1]

funciona creando esta cadena:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

también conocido como 65 veces A, 66 veces B, 67 veces C ...

y luego elige un personaje aleatorio


¿Por qué empezaste a los 65?
gcampbell

1
@gcampbell 65 está Aen 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 largo
izabera

2

CJam, 11 bytes

4.mrmqC*'A+

o

676.mrmq'A+

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.


2

Lote, 116 bytes

@set/ar=%random%%%676,s=r/26,r%%=26,s-=(r-s)*(r-s^>^>31)
@set a=ABCDEFGHIJKLMNOPQRSTUVWXYZ
@call echo %%a:~%s%,1%%

Funciona eligiendo la más grande o más pequeña (no recuerdo cuál) de dos variables aleatorias.


2

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.

['' 96+min(1/rand,26)]

No muy corto, por supuesto, pero quizás el concepto pueda inspirar otras respuestas.


¿ randDevuelve 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?
trichoplax

Por lo que sé, randdevuelve un valor en (0,1), por lo que no debería haber un problema
paul.oderso

1
@trichoplax Aunque no verá el randretorno 0 en la práctica, en min(1/0,26)realidad devuelve 26.
Dennis Jaheruddin

En ese caso, buena solución :)
trichoplax

2

CJam, 10 bytes

Enfoque CJam # 3 ...

26mr)mr'A+

Pruébalo en línea!

Esto crea un número aleatorio uniforme xentre 1 y 26 y luego lo usa para crear un número aleatorio uniforme entre 0y al x-1cual se agrega A. Este sesgo da como resultado caracteres más pequeños.


2

Laberinto , 19 bytes

__v6%_65+.@
" )
"^2

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 Ay Z.

Esto da una probabilidad de Aun poco más del 50%, Bun poco más del 25% y así sucesivamente hasta Zun 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).

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.