Golf aléatoire du jour n ° 7: Un personnage distinctement aléatoire

47

A propos de la série

Ceci est une entrée d'invité pour la série Random Golf of the Day.

Tout d'abord, vous pouvez traiter cela comme n'importe quel autre défi de golf et y répondre sans vous soucier de la série. Cependant, il existe un classement pour tous les défis. Vous pouvez trouver le classement avec quelques informations supplémentaires sur la série dans le premier post .

Contribution

Aucune entrée n'est prise.

Sortie

Une seule lettre de l'alphabet (cas non pertinent), avec un retour à la ligne facultatif. Chaque lettre doit avoir une probabilité d’être choisie non nulle et les 26 probabilités doivent être distinctes . Pour lever toute ambiguïté: Distinct signifie qu'il ne doit pas y avoir deux probabilités égales.

Notation

C'est du code golf. Le code le plus court en octets gagne.

Une entrée valide est un programme complet ou une fonction qui a une probabilité nulle de ne pas se terminer.

Alphabet

Pour éviter toute confusion, l'alphabet à utiliser est l'alphabet latin:

Soit

ABCDEFGHIJKLMNOPQRSTUVWXYZ

ou

abcdefghijklmnopqrstuvwxyz

Vous pouvez choisir de produire des majuscules ou des minuscules. Vous pouvez également choisir de produire différents cas sur différentes exécutions, si cela vous aide. La probabilité pour une lettre donnée est la probabilité que cette lettre apparaisse dans les deux cas (supérieure ou inférieure).

Explication

Comme cela ne sera pas du tout évident à la sortie, veuillez inclure une explication claire de la manière dont vous avez réalisé les 26 probabilités distinctes.

Classement

(à partir d' ici )

Le premier article de la série génère également un classement général.

Pour vous assurer que vos réponses apparaissent, commencez chaque réponse par un titre, en utilisant le modèle Markdown suivant:

## Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores en les effaçant. Par exemple:

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

(La langue n'est pas affichée pour le moment, mais l'extrait de code nécessite une analyse syntaxique. Il se peut que j'ajoute un classement par langue ultérieurement.)

trichoplax
la source
Comment mesureriez-vous 26 probabilités distinctes? en exécutant le programme 26 fois?
VOUS
1
@YOU jetez un oeil à travers les solutions - il existe plusieurs approches différentes avec d'excellentes explications
trichoplax
S'il s'agit d'une fonction, faut-il imprimer ou peut-il simplement renvoyer la valeur du caractère?
Geoff Reedy
@ Geoff Selon nos valeurs par défaut pour les entrées et les sorties , imprimer sur STDOUT ou renvoyer un caractère convient.
Trichoplax
@ Geoff note qu'il doit s'agir d'un caractère, pas simplement d'une valeur numérique le représentant. Par exemple, Aplutôt que 65.
Trichoplax

Réponses:

13

Pyth, 5

Os._G

Essayez-le ici

Calcule les préfixes de l'alphabet, donc: ["a", "ab", "abc", ..., "abcdefghijklmnopqrstuvwxyz"]. Ensuite, aplatit la liste et en sélectionne un élément aléatoire de manière uniforme. Cela signifie que, puisque a26 fois apparaît, tandis que b25 fois, jusqu'à une zseule lettre, chaque lettre a une chance différente de paraître. La chaîne totale a 351 caractères.

FryAmTheEggman
la source
1
J'aime cette réponse. Très intelligent.
Allen Fisher
24

MATL, 6 caractères

1Y2Xr)

Explication:

XrPrendre un nombre aléatoire normalement distribué )Utilisez ceci pour ... 1Y2The alphabet

La distribution est symétrique autour de 0 et la traduction du nombre en caractères est symétrique autour de 0.5. En tant que telles, les probabilités doivent être distinctes.

Dennis Jaheruddin
la source
2
Oh, très bonne idée d'utiliser une distribution gaussienne!
Luis Mendo
1
"meilleur" langage pour le travail, toujours battu par la gelée. Excellente solution cependant.
Phoenix socratique
19

05AB1E , 6 octets

Code

A.pJ.R

Explication

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

Nous avons maintenant la chaîne suivante:

aababcabcdabcdeabcdefabcdefgabcdefghabcdefghiabcdefghijabcdefghijkabcdefghijklabcdefghijklmabcdefghijklmnabcdefghijklmnoabcdefghijklmnopabcdefghijklmnopqabcdefghijklmnopqrabcdefghijklmnopqrsabcdefghijklmnopqrstabcdefghijklmnopqrstuabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvwabcdefghijklmnopqrstuvwxabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz

Après cela, nous sélectionnons un élément aléatoire en utilisant .R.

Les probabilités

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%

Essayez-le en ligne! .

Adnan
la source
18

Gelée , 5 octets

ØA»ẊX

Essayez-le en ligne!

Comment ça fonctionne

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

Contexte

Soit L 0 ,…, L 25 dénote les lettres de l'alphabet dans leur ordre naturel, et S 0 ,…, S 25 une permutation de L uniformément choisie au hasard . Définissez la séquence finie M par M n = max (L n , S n ) .

Fixez n dans 0,… 25 et définissez k en tant qu'indice tel que L n = S k .

Avec la probabilité 1/26 , L n = S n et n = k , de sorte que M n = L n et L n occurrs une fois dans M .

Avec probabilité 25/26 , L n ≠ S n et n ≠ k . Dans ce cas, les événements suivants se produisent.

  • Avec la probabilité n / 25 , S n est l’un des L 0 ,…, L n - 1 , donc L n > S n et M n = L n .

  • Indépendamment, également avec la probabilité n / 25 , k est l'un de 0,… n - 1 , donc S k > L k et M k = S k = L n .

Ainsi, le nombre attendu d’occurrences de L n dans M est égal à 1/26 + 25/26 · (n / 25 + n / 25) = (2n + 1) / 26 .

Enfin, si nous sélectionnons maintenant un terme m de M uniformément au hasard, nous choisissons la lettre L n avec une probabilité (2n + 1) / 26/26 = (2n + 1) / 676 .

Cela donne la distribution suivante des probabilités.

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

Vous pouvez vérifier empiriquement la distribution en appelant le lien 100 000 fois (cela prend quelques secondes).

Dennis
la source
1
@RobertFraser L'étape de mélange et de production produit une liste avec un A partout où un A est apparu dans l'une ou l'autre liste, un B où un B est apparu dans l'une ou l'autre liste et autre chose que A dans l'autre liste, ... un Z n'importe où que Z apparu dans les deux listes. il y a donc environ 52x autant de A que de Z dans le résultat.
Sparr
1
@ RobertFraser J'ai ajouté une explication.
Dennis
2
@DennisJaheruddin En UTF-8, oui. Cependant, Jelly utilise une page de code personnalisée qui code tous les caractères qu’elle comprend sous forme d’octet unique. Le lien d' octets dans l'en-tête pointe vers lui.
Dennis
2
Je vois que lorsque j'ai lu l'explication, il n'a pas été immédiatement clair que vous ne pouvez pas non plus tirer parti de la plage UTF-8 normale. Alors, ai-je raison de supposer qu'en changeant l'interprète et en mappant tous les caractères sur des caractères UTF-8 individuels, vous obtiendrez un code totalement identique (juste moins lisible / typable)? - Dans l'affirmative, envisagez d'élargir l'explication pour préciser qu'un personnage devrait compter pour un octet aux fins du golf.
Dennis Jaheruddin
2
@DennisJaheruddin Comme expliqué dans le fichier README (premier lien de l'en-tête), l'interpréteur dispose de deux modes (page de code Jelly et UTF-8). Vous pouvez donc enregistrer ce programme dans un fichier réel de 5 octets. Je pourrais ajouter toutes ces informations à chaque réponse que je rédigerai, mais il y en a des centaines et j'ai donc choisi de créer des liens.
Dennis
14

MATL , 10 octets

1Y2rU26*k)

Essayez-le en ligne!

Le code génère une variable aléatoire uniforme sur l'intervalle (0,1) ( r) et calcule son carré ( U). Il en résulte une densité de probabilité décroissante non uniforme. Multiplier par 26 ( 26*) garantit que le résultat est sur l'intervalle (0,26), et arrondir à la valeur inférieure ( k) produit les valeurs 0,1, ..., 25 avec des probabilités décroissantes. La valeur est utilisée comme index ( )) dans l'alphabet majuscule ( 1Y2). Puisque MATL utilise l'indexation modulaire basée sur 1, 0 correspond à Z, 1 à A, 2 à B, etc.

Pour illustrer le fait que les probabilités sont distinctes, voici un histogramme distinct résultant de 1 000 réalisations aléatoires. Le graphique est produit en exécutant ceci dans Matlab:

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

entrez la description de l'image ici

Luis Mendo
la source
1
Agréable! La meilleure solution que je puisse trouver est de 16 octets
DJMcMayhem
1
@DJMcMayhem Belle approche!
Luis Mendo
Peut-être, mais beaucoup plus longtemps. : P
DJMcMayhem
Une autre alternative amusante: matl.suever.net/…
Suever
En fait, vous n’avez pas besoin du k! Remarqué que tout en essayant codegolf.stackexchange.com/a/89648/11159
Dennis Jaheruddin
13

Java 7, 62 57 56 octets

5 octets grâce à Poke.

1 octet grâce à 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 ça!

Diagramme de fréquence (essais 1e6, facteur d'échelle 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: ***************************************************************************
Fuite Nun
la source
1
Je ne pense pas que vous ayez besoin de transtyper
Poke
@Poke Merci, joué au golf.
Leaky Nun
Pouvez-vous sauvegarder un octet en déplaçant le 676 en dehors des parenthèses?
Trichoplax
@ trichoplax Que voulez-vous dire?
Leaky Nun
2
sqrt(x*y*y) = sqrt(x)*y
Trichoplax
10

Perl, 24 octets

-4 octets grâce à @Martin Ender
-1 octet grâce à @Dom Hastings

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

Besoins -M5.010ou -Ecourir:

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

L'exécution du code suivant affichera l'occurrence de chaque lettre:

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


Comment ça marche : je suppose que le code est assez explicite, mais quand même: il choisit un nombre aléatoire entre 0et rand 26. Il y a donc une probabilité beaucoup plus élevée que des nombres proches de 0(lettre A) soient choisis.

Dada
la source
L'explication est logique pour moi :)
trichoplax
Belle solution! Vous pouvez enregistrer 1 octet en utilisant une liste nue et +:say+(A..Z)[rand rand 26]
Dom Hastings
@DomHastings aarf, je suis stupide. J'ai essayé (A..Z)[...]et cela n'a pas fonctionné, alors j'ai pensé que je pourrais utiliser un tableau anonyme comme ça, mais c'était juste à cause de la say.. merci! :)
Dada
10

PHP, 44 36 29 27 octets

44 barré est toujours régulier 44;

Merci à insertusernamehere, Petah et Crypto pour toute l'aide

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

Elle choisit un nombre aléatoire compris entre 0 et 675 (= 26 2 -1), prend sa racine carrée et la recouvre (la chrfonction convertit son argument en entier). Comme les carrés ont des intervalles différents entre eux, la probabilité que chaque nombre soit choisi est distincte. Chaque n est choisi avec une probabilité (2n + 1) / 676.

Ajouter 65 à ce nombre vous donne un caractère aléatoire de Aà Z.

Idée du code fonctionnant 1 000 000 fois

Chat d'affaires
la source
Vous pouvez jouer au golf de 4 octets : range(A,Z).
insertusernamehere
@insertusernamehere: Merci pour le conseil, mais j'ai pu jouer au golf 8 octets en n'utilisant pas la distance et en utilisant simplement chr().
Affaires Cat
3
Encore mieux. Malheureusement , 44 barrés sont toujours normaux 44 . :)
insertusernamehere
1
@insertusernamehere Vous abandonnez trop facilement :-)<s>&nbsp;44&nbsp;</s>
MonkeyZeus
<?=chr(65+sqrt(rand(0,675)));
Petah
8

R, 40 27 octets

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

Cela prendra un 1nombre parmi les 26nombres générés avec une probabilité croissante vers Z, sans le remplacer, et affichera une lettre dont l’indice est ce nombre, dans la liste des lettres majuscules LETTERS.

Les arguments de la samplefonction sont:

sample(
       26, #How many numbers to generate
        1, #How many numbers to sample
         , #Replacing ? Here, no by default
     1:26, #Weight of probabilities
       )
Frédéric
la source
Oui, ça ne marchera pas. Il pourrait y avoir une façon des plus intelligente!
Frédéric
Eh bien, il y aura toujours une doublure quelque part! Il faut que j'y pense ...
Frédéric
1
Fixe et plus court - impressionnant :)
trichoplax
1
@ trichoplax Merci! Beau défi d'ailleurs!
Frédéric
1
@ AlbertMasclans: C'est effectivement le cas, mais cela a déjà été fait dans la réponse de quelqu'un d'autre, alors je ne veux pas "copier"! Mais merci quand même ! ;)
Frédéric
8

> <> , 14 octets

lx
;>dd+%'A'+o

> <> est un langage 2D toroïdal, et la partie des probabilités distinctes se produit naturellement en raison de la seule source d’aléatoire du langage. Essayez-le en ligne!

Les commandes pertinentes sont:

[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

Ainsi, les probabilités de sortie sont:

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
Sp3000
la source
7

Python 2, 58 57 octets

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

Explication: ceci génère un nombre aléatoire dans l’intervalle [0, 676), prend la racine carrée, puis la recouvre. Ensuite, il ajoute 65 (la valeur ascii de "A"), le convertit en caractère et l’imprime.

Cela donne à chaque nombre de 0 à 25 une probabilité distincte. Pour comprendre pourquoi, réfléchis comme ça. Combien de nombres, en ignorant les non-entiers, quand vous prenez la racine carrée et le plancher donnent 0? Un seul nombre sera (zéro). Cela signifie que zéro a une probabilité de 1/676. Combien de nombres vont produire 1? 3 volonté, 1, 2 et 3. Cela signifie qu'on a une probabilité de 3/676. Un deux peut être produit avec un 4, 5, 6, 7 ou 8, ce qui lui donne une probabilité de 5, un trois a une probabilité de 7, etc. Et puisque la différence entre les carrés consécutifs augmente régulièrement de deux, cette tendance se poursuit pour chaque nombre croissant à 25 (Z).

1 octet économisé grâce à une nonne qui fuit!

DJMcMayhem
la source
chr(int(65+randint(676)**.5))
Leaky Nun
1
Tu pourrais faire chr(int(65+random()**.5*26)). C'est la même chose algébriquement parce que 26 == √676. et maintenant, l'ordre des opérations est de votre côté
Wheat Wizard
3
@EamonOlive Pour un autre octet **2*26pourrait être utilisé pour la distribution inverse.
user81655
1
1/random()%26devrait aussi fonctionner.
xnor
1
@xnor qui donnera parfois 1/0% 26
trichoplax
5

PowerShell v2 +, 33 31 octets

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

Prend une plage allant de 65à 90(c.- à -d., ASCII Aà Z), le transfère via une boucle. A chaque itération, nous utilisons l'opérateur virgule pour créer un tableau de cet élément multiplié par ce nombre. Par exemple, cela fera 65 65s, 66 66s, 67 67s, etc. Ce grand tableau est acheminé vers Get-Randomlequel un (élément uniformément PRNG) sélectionnera un élément. Puisqu'il existe différentes quantités de chaque élément, chaque personnage a un pourcentage légèrement différent de chances d'être choisi. Nous encapsulons ensuite cela par parens et le lançons comme char. Cela reste sur le pipeline et la sortie est implicite.

(Merci à @LeakyNun pour avoir joué au golf quelques octets avant même qu’il ait été posté.: D)


Les probabilités

(léger arrondi pour que je puisse démontrer l' Poption de l' -fopérateur 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 %
AdmBorkBork
la source
1
J'ai commencé sans regarder aucune des réponses; essayé de construire sur la galsortie ( [char[]]"uz$(gal|out-string)"-cmatch'[a-z]'|random) a 50 caractères, puis 48, passe aux nombres et obtient 42, puis 31 et s’arrête là; regardé dans le classement pour voir où cela me mettrait. Ici. Caractère de caractère identique. Welp, je ne peux probablement pas battre ça.
TessellatingHeckler
5

CJam, 21 17 12 octets

Merci à Martin Ender de m'avoir sauvé 5 octets!

Nouvelle version

'\,:,s_el-mR

Cela forme un tableau de chaînes suivant le modèle A, AB, ABCet ainsi de suite. Il l'aplatit et choisit un caractère aléatoire. Comme cette chaîne contient 26 A, 25 B, 24 C, etc., chaque lettre a une probabilité distincte d'être choisie.

Essayez-le en ligne!

Explication

'\,          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

Ancienne version

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

Obtient des probabilités distinctes en créant une chaîne dans laquelle chaque lettre apparaît un nombre de fois égal à sa position dans l'alphabet.

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
Chat d'affaires
la source
5

R, 23 octets

sample(LETTERS,1,,1:26)

Juste "échantillons" une lettre d'un incorporé. le 1:26est un vecteur de poids donnant à chaque lettre une probabilité différente.

utilisateur5957401
la source
1
1:26est un vecteur de poids pour chaque lettre
user5957401
Cela en fait une réponse valable. Cela vaut la peine d’éditer une explication pour que les personnes qui ne connaissent pas R puissent comprendre comment cela fonctionne.
Trichoplax
1
J'allais le faire, puis je me suis rendu compte que le gars au-dessus de moi avait fait à peu près la même chose dans son code et avait fourni un explicateur détaillé.
user5957401
Il est bon que vous ayez ajouté une explication - l'ordre dans lequel les solutions apparaissent sur la page peut varier selon les votes, de sorte que ceux "ci-dessus" risquent de ne pas l'être plus tard.
Trichoplax
5

C, 35 octets

Ce programme suppose RAND_MAXest (2 ^ 32/2) - 1 comme il est sur gcc par défaut. Compilez avec le -lmdrapeau pour lier la sqrtfonction. La sortie est écrite sur stdout en majuscules sans fin de nouvelle ligne.

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

Facultativement, si RAND_MAXest (2 ^ 16/2) - 1, une version plus courte de 32 octets peut être utilisée:

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

Juste pour le plaisir, j’ai aussi créé une version qui n’utilise pas la sqrtfonction et ne nécessite pas la bibliothèque mathématique incluse (celle-ci doit avoir le RAND_MAXformat (2 ^ 32/2) - 1), mais elle a fini par être plus longue même si j’ai pensé que c’était plutôt cool:

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

Explication

[Premier programme]

Pour les deux premiers utilisateurs sqrt, la fonction mappe simplement la plage [0, RAND_MAX)à [0, 25]travers la division, puis ajoute 65 (ASCII A) à la valeur pour la déplacer dans l'alphabet ASCII avant de la générer.

[Deuxième programme]

Le deuxième programme est un peu plus complexe car il fait une stratégie similaire, mais sans l' sqrtopérateur. Etant donné que les bits d'exposant d'une virgule flottante sont automatiquement calculés lors de l'attribution d'un entier, ils peuvent en fait être utilisés comme moyen grossier d'obtenir le logarithme en base 2 d'un nombre.

Puisque nous voulons seulement que la plage jusqu’à RAND_MAXatteindre une valeur d’exposant codée de 25, le calcul (2 ^ 32/2 - 1) / (2 ^ 25) nous en donne à peu près 64, qui est utilisé lors de la division de randpour le mapper. à cette nouvelle gamme. J'ai également ajouté 1 à la valeur car la représentation en virgule flottante de 0 est plutôt étrange et casserait cet algorithme.

Ensuite, le float est typé en un entier pour permettre le transfert de bits et autres opérations du même genre. Etant donné que dans les nombres à virgule flottante IEEE 754, les bits d'exposant sont les bits 30 à 23, le nombre est alors décalé de 23 bits vers la droite, ce qui élimine la mantisse et permet la lecture de la valeur de l'exposant brut en tant qu'entier. Notez que le bit de signe est également au-delà des bits d'exposant, mais comme il n'y a jamais de négatif, il n'est pas nécessaire de le masquer.

Plutôt que d’ajouter 65 à ce résultat comme auparavant, les exposants à virgule flottante sont représentés par un entier non signé de 8 bits compris entre 0 et 255, où la valeur de l’exposant égale à 0 est 127 (il suffit de soustraire 127 pour obtenir la valeur réelle de l’exposant "signé"). ). Étant donné que 127 - 65 correspond à 62, nous soustrayons simplement 62 pour le décaler en dehors de cette plage d’exposants en virgule flottante et dans la plage d’alphabets ASCII en une seule opération.

Distribution

Je ne suis pas un expert en mathématiques, je ne peux donc pas affirmer avec certitude la formule exacte de ces distributions, mais je peux (et ai fait) tester toutes les valeurs de la plage [0, RAND_MAX)pour montrer que la distance entre le point où commence la plage d'une lettre et l'autre commence n'est jamais la même. même. (Notez que ces tests supposent le maximum aléatoire (2 ^ 32/2) - 1))

[Premier programme]

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

[Deuxième programme]

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
Goutte de citron
la source
Ne serait-il pas plus rapide de retourner l'ordinal que de l'imprimer? Puisque charest un type entier en C, cela devrait être acceptable.
Mego
@ Mego Oh, ben oui, si vous pouvez le faire, je suis novice en golf, donc je ne connais pas trop ce qui est considéré comme une production acceptable.
Lemon Drop
4

Python 2, 72 octets

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

Multiplie le caractère par sa valeur ascii, puis choisit un caractère au hasard dans la chaîne résultante.

Voici les probabilités pour chaque lettre sélectionnée, en pourcentages:

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

Essayez-le: https://repl.it/Cm0x

atlasologue
la source
4

Gelée , 5 octets

ØAxJX

(Score égal, mais méthode différente , par rapport à une solution Jelly existante de Dennis.)

La probabilité de donner chaque lettre est son index basé sur 1 dans l'alphabet divisé par 351 - le 26ème nombre triangulaire:

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

Depuis 1 + 2 + ... + 26 = 351, P (lettre) = 1.

La mise en oeuvre:

Ø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

Testez-le sur TryItOnline ou obtenez la distribution de 100 000 exécutions (crédit de code à Dennis)

Jonathan Allan
la source
Où as-tu appris à être aussi doué avec Jelly? J'ai du mal à croire que Jelly serait une connaissance commune en dehors de PPCG.
Addison Crump
1
@Syxer Je viens juste de regarder le wiki et de m'éloigner - je ne comprends toujours pas tout :)
Jonathan Allan
1
Eh bien. Bienvenue au PPCG, votez à la hausse.
Addison Crump
3

q, 38 octets

Pas particulièrement court mais ...

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

La fonction de distribution cumulative discrète est la séquence

0.9 ^ 26, 0.9 ^ 25, ..., 0.9 ^ 0

Et nous ne faisons qu'échantillonner à partir de la distribution.

Skeevey
la source
3

JavaScript (ES6), 45 octets

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

Obtient une distribution non uniforme en quadrillant la valeur aléatoire. Math.random()renvoie un float de la plage de [0,1)sorte que le résultat de la quadrature tend vers 0(ou a).

Tester

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

Oracle SQL 11.2, 212 octets

Utilisation de la position du caractère dans l'alphabet comme probabilité

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;

Non-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
Jeto
la source
3

TI-Basic, 39 octets

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

rand génère une valeur uniforme dans (0,1], ce qui donne à 26 ^ Rand une probabilité différente d'être égale aux nombres entiers compris entre 1 et 26.

Ancienne version, 45 octets

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

La précision limitée des entiers TI-Basic limite les distributions normales à générer des nombres compris dans µ ± 7.02σ (voir randNorm(). Nous obtenons donc la valeur absolue d'un nombre aléatoire avec µ 0 et σ 1, en multipliant par quatre pour augmenter la plage pratique mentionnée précédemment à µ ± 28.08σ. Ensuite, nous calculons la valeur et ajoutons 1, car sub(est indexé sur 1, ce qui nous donne une plage allant de 1 à 29 avec des probabilités différentes pour chacune.

Timtech
la source
1
@trichoplax Ce fut mon erreur, il me restait 30 de l'ancienne version qui était [0,29]. Je l'ai corrigé maintenant.
Timtech
L'intervalle (0,1] est supposé être [0,1].
kamoroso94
@ kamoroso94 Avez-vous vérifié? "Remarque: en raison de particularités de l'algorithme de génération de nombres aléatoires, le plus petit nombre possible à générer est légèrement supérieur à 0. Le plus grand nombre possible est actuellement de 1" - extrait de tibasicdev.wikidot.com/rand
Timtech
3

PHP, 92 84 octets

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

Construit une chaîne de toutes les lettres, répète le nombre de fois que nous sommes dans la boucle, puis sélectionne une lettre de cette chaîne de manière aléatoire. En conséquence, les lettres plus tard dans l'alphabet ont une probabilité plus élevée

Merci à insertusernamehere pour avoir réduit les octets

Probabilités de résultat (classées par%)

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%

gabe3886
la source
1
changé pour effectivement respecter les règles. Mon erreur
gabe3886
@ insertusernamehere J'obtiens des avis de variable non définis lorsque j'exécute cette opération et aucune sortie de lettre
gabe3886
Oh je suis désolé. Je pense que je me suis emporté et enlevé $x=0ce qui est évidemment nécessaire. Voici une version de 84 octets : for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);Avez-vous déjà réussi à obtenir une valeur plus grande que Glorsque vous exécutez votre code? Quoi qu'il en soit, vous pouvez toujours ignorer le notices lorsque vous jouez au golf.
insertusernamehere
1
Je l’ai fait, mais il a fallu un certain temps pour revenir. Je l'ai couru à travers environ 100k itérations pour vérifier
gabe3886
Le strlenof $aest 351, mais vous ne choisissez qu'un caractère aléatoire parmi les $x26 premiers . Vous pouvez le fixer et de garder vos probabilités d'un changement de la finale $xà 350de 1 octet. Voici une version de 77 octets qui résout le problème mais rapproche également les probabilités:for($i=65;$i<91;$a.=str_repeat(chr($i),$i++));echo substr($a,rand(0,2014),1);
Jo.
3

Befunge, 168 164 octets

Plus compact que le premier, avec des probabilités un peu différentes: les premiers ?ont 1/4 de chance d’imprimer un A au premier essai, 2/4 de chance de revenir au même ?, et 1/4 de passer au suivant. Les autres ?ont chacun 1/4 de chances d'imprimer la lettre en dessous, 1/4 pour réessayer, 1/4 pour passer à la lettre suivante, 1/4 pour passer à la précédente. Encore une fois, la probabilité d'imprimer un A est beaucoup plus élevée que d'imprimer un Z.

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

Befunge, 186 octets

Évidemment, je ne gagnerai pas avec ça, mais je pense que c'est quand même une réponse intéressante :)

vet >dirige le curseur respectivement vers le bas et vers la droite. L' ?opérateur envoie le curseur dans l'une des quatre directions au hasard. Le premier ?est "bloqué" par vet >dans les deux sens. Il ne peut donc y avoir que deux solutions: soit imprimer le A, soit descendre au suivant ?. Donc, à partir du premier ?seul, il y a 50% de chances d'imprimer un A.

La suivante ?a 1/3 de chance d’imprimer un B, 1/3 de remonter et 1/3 de descendre. Etc.

Il devrait être évident que les lettres les plus hautes ont beaucoup plus de chances d'être imprimées que les lettres les plus basses, mais je ne sais pas exactement quelles sont les chances de chaque lettre.

Un peu d'aide avec le calcul exact serait apprécié :)

Au moins il y a un 1/2 * 1/3 de 25 ^ chance que le curseur se déplace tout le chemin jusqu'à Z sur le premier essai, mais je ne suis pas certain comment les chances du curseur se déplaçant vers le haut et vers le bas affecte chaque lettre.

,@ imprime et quitte.

 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">,@
Daniero
la source
2

J, 20 18 octets

({~? @ #) u: 64 + # ~ 1 + i.26
({~? @ #) u: 64 + # ~ i.27

Interprète en ligne

Majuscule.

La probabilité de chaque lettre est son index basé sur 1 dans l'alphabet.

Fuite Nun
la source
2

zsh, 63 octets

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

cela fonctionne en créant cette chaîne:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

aka 65 fois A, 66 fois B, 67 fois C ...

et puis il choisit un caractère aléatoire

Izabera
la source
Pourquoi as-tu commencé à 65 ans?
Gcampbell
1
@gcampbell 65 est Aen ascii. vous pouvez commencer à partir de 1, mais alors la boucle interne devient {65..$[#i]}ce qui est 1 caractère plus long
izabera
2

CJam, 11 octets

4.mrmqC*'A+

ou

676.mrmq'A+

Essayez-le en ligne!

Cette solution est similaire à l'idée de Luis et crée une distribution non uniforme en prenant la racine carrée de la variable aléatoire.

Martin Ender
la source
2

Lot, 116 octets

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

Fonctionne en choisissant la plus grande ou la plus petite (j'oublie laquelle) de deux variables aléatoires.

Neil
la source
2

Matlab, 22 ans

Reviendra souvent les premières lettres, mais peut théoriquement toutes les toucher!

Prend une divisée par un nombre aléatoire, limite celle-ci à 26 et la transforme en personnage.

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

Pas très court bien sûr, mais le concept peut peut-être inspirer d'autres réponses.

Dennis Jaheruddin
la source
Renvoie-t-il randune valeur dans [0, 1)? C'est-à-dire incluant zéro mais pas un. Si cela aboutit parfois à 1/0, min(1/0,26)retournera- t-il toujours 26 ou une erreur?
Trichoplax
Pour autant que je sache, randrenvoie une valeur dans (0,1), il ne devrait donc pas y avoir de problème
paul.oderso
1
@trichoplax Même si vous ne verrez pas le randretour 0 en pratique, min(1/0,26)retourne le 26.
Dennis Jaheruddin
Dans ce cas, bonne solution :)
trichoplax
2

CJam, 10 octets

Approche CJam # 3 ...

26mr)mr'A+

Essayez-le en ligne!

Cela crée un nombre uniformément aléatoire xentre 1 et 26 et l’utilise ensuite pour créer un nombre uniformément aléatoire entre 0et x-1qui est ajouté A. Cela polarise les résultats vers des personnages plus petits.

Martin Ender
la source
2

Labyrinthe , 19 octets

__v6%_65+.@
" )
"^2

Essayez-le en ligne!

Il s’agit d’une boucle qui, à chaque itération, a) incrémente un compteur qui commence à zéro ou b) se termine, les deux avec une probabilité de 50%. À la fin de la boucle, le compteur est pris modulo 26 et ajouté à 65 pour donner une lettre entre Aet Z.

Cela donne une probabilité d' Aun peu plus de 50%, d' Bun peu plus de 25% et ainsi de suite jusqu'à Zun peu plus de 1/2 26 . En théorie, il y a une possibilité que cela dure éternellement, mais cet événement a une probabilité égale à zéro, comme l'exige le défi (en pratique, ce n'est probablement pas possible de toute façon, car le PRNG renverra les deux résultats possibles à un moment donné de sa période).

Martin Ender
la source