Skip to main content
10 of 12
edited body
ceilingcat
  • 7.7k
  • 2
  • 30
  • 30

#x86_64 machine language for Linux, 15 19 17 bytes

L1:
48 0f c7 f0             rdrand %rax
f3 48 0f b8 c0          popcnt %rax,%rax
3c 1a                   cmp    $0x1a,%al
7d f3                   jge    L1
8d 40 41                lea    0x41(%rax),%eax
c3                      retq

This requires support for the POPCNT and RDRAND instructions.

A uniform distributed random number is generated, the number of 1's in that number is counted, if that number is less than 26, a letter is returned. One will need to let the code run a long time before one sees a letter A.

To test, try something like

#include<stdio.h>
#define TEST "\x48\xf\xc7\xf0\xf3\x48\xf\xb8\xc0\x3c\x1a\x7d\xf3\x8d\x40\x41\xc3"
int main(){
  int hist[26]={0};
  for(int i=0;i<10000000;i++){
    hist[ ((int(*)())TEST)() - 'A' ]++;
  }
  for(int i=0;i<26;i++){
    printf("%c %d\n", 'A'+i, hist[i] );
  }
}

Sample output

A 0
B 0
C 0
D 0
E 0
F 0
G 0
H 0
I 0
J 0
K 0
L 8
M 32
N 137
O 511
P 1639
Q 5188
R 14475
S 37539
T 91670
U 205638
V 431381
W 842259
X 1536776
Y 2626524
Z 4206223

The analytical expression for the probability of each letter can be derived from the binomial distribution. The letter A is assigned index k=0, B is assigned k=1 and so on.

        /  \
       | 64 |
       | k  |
        \  /
p(k)=------------
      25
      --- /  \
      \  | 64 |
      /  | i  |
      --- \  /
      i=0

 p(A)~1.0483e-18
 p(B)~6.7093e-17
 p(C)~2.1134e-15
 p(D)~4.3678e-14
 p(E)~6.6608e-13
 p(F)~7.9930e-12
 p(G)~7.8598e-11
 p(H)~6.5124e-10
 p(I)~4.6401e-09
 p(J)~2.8872e-08
 p(K)~1.5879e-07
 p(L)~7.7953e-07
 p(M)~3.4429e-06
 p(N)~1.3772e-05
 p(O)~5.0169e-05
 p(P)~1.6723e-04
 p(Q)~5.1214e-04
 p(R)~1.4460e-03
 p(S)~3.7758e-03
 p(T)~9.1413e-03
 p(U)~2.0568e-02
 p(V)~4.3095e-02
 p(W)~8.4231e-02
 p(X)~1.5381e-01
 p(Y)~2.6276e-01
 p(Z)~4.2042e-01
ceilingcat
  • 7.7k
  • 2
  • 30
  • 30