Random Golf of the Day # 7: Wyraźnie losowa postać

47

O serii

To jest gościnny wpis do serii Random Golf of the Day.

Po pierwsze, możesz potraktować to jak każde inne wyzwanie związane z golfem i odpowiedzieć na nie, nie martwiąc się w ogóle serią. Istnieje jednak tabela wyników dla wszystkich wyzwań. Możesz znaleźć tabelę liderów wraz z kilkoma więcej informacji o serii w pierwszym poście .

Wejście

Brak danych wejściowych.

Wynik

Pojedyncza litera alfabetu (nie ma znaczenia wielkość liter), z opcjonalnym końcowym znakiem nowej linii. Każda litera musi mieć niezerowe prawdopodobieństwo wybrania, a wszystkie 26 prawdopodobieństw musi być odrębnych . Aby usunąć wszelką dwuznaczność: Wyraźny oznacza, że ​​nie mogą istnieć dwa prawdopodobieństwa, które są sobie równe.

Punktacja

To jest kod golfowy. Najkrótszy kod w bajtach wygrywa.

Poprawny wpis to pełny program lub funkcja, która ma zerowe prawdopodobieństwo, że nie zostanie zakończona.

Alfabet

Aby uniknąć nieporozumień, należy użyć alfabetu łacińskiego:

Zarówno

ABCDEFGHIJKLMNOPQRSTUVWXYZ

lub

abcdefghijklmnopqrstuvwxyz

Możesz wybrać wyświetlanie dużych lub małych liter. Alternatywnie możesz wybrać wyświetlanie różnych przypadków w różnych przebiegach, jeśli to pomoże. Prawdopodobieństwo dla danej litery to prawdopodobieństwo pojawienia się litery w obu przypadkach (górnej lub dolnej).

Wyjaśnienie

Ponieważ wynik nie będzie wcale oczywisty, dołącz jasne wyjaśnienie, w jaki sposób osiągnąłeś 26 różnych prawdopodobieństw.

Tabela liderów

( stąd )

Pierwszy post z serii generuje również ogólną tabelę wyników.

Aby mieć pewność, że Twoje odpowiedzi się pojawią, zacznij każdą odpowiedź od nagłówka, używając następującego szablonu Markdown:

## Language Name, N bytes

gdzie Njest rozmiar twojego zgłoszenia. Jeśli poprawić swój wynik, to może zachować stare porachunki w nagłówku, uderzając je przez. Na przykład:

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

(Język nie jest obecnie wyświetlany, ale fragment go wymaga i analizuje, a w przyszłości mogę dodać tabelę wyników według języków).

trichopaks
źródło
jak zmierzyłbyś 26 różnych prawdopodobieństw? uruchamiając program 26 razy?
TY
1
@YOU zapoznaj się z rozwiązaniami - istnieje kilka różnych podejść z doskonałymi wyjaśnieniami
trichoplax
Jeśli jest to funkcja, czy musi wydrukować, czy może po prostu zwrócić wartość znaku?
Geoff Reedy,
@Geoff Zgodnie z naszymi domyślnymi wartościami wejściowymi i wyjściowymi , drukowanie do STDOUT lub zwracanie znaku jest w porządku.
trichoplax
@Geoff pamiętaj, że musi to być znak, a nie tylko reprezentująca go liczba. Na przykład Azamiast 65.
trichoplax

Odpowiedzi:

13

Pyth, 5

Os._G

Wypróbuj tutaj

Oblicza prefiksy alfabetu, więc: ["a", "ab", "abc", ..., "abcdefghijklmnopqrstuvwxyz"]. Następnie spłaszcza listę i wybiera równomiernie z niej losowy element. Oznacza to, że ponieważ apojawia się 26 razy, a bpojawia się 25 razy, aż do zzaledwie jednego wyglądu, każda litera ma inną szansę pojawienia się. Łączny ciąg ma 351 znaków.

FryAmTheEggman
źródło
1
Podoba mi się ta odpowiedź. Bardzo mądry.
Allen Fisher
24

MATL, 6 znaków

1Y2Xr)

Wyjaśnienie:

XrWeź normalnie rozłożoną liczbę losową )Użyj tego, aby indeksować do ... 1Y2Alfabetu

Rozkład jest symetryczny wokół 0, a translacja liczby na char jest symetryczna wokół 0,5. Jako takie prawdopodobieństwa powinny być wyraźne.

Dennis Jaheruddin
źródło
2
Och, bardzo dobry pomysł, aby użyć rozkładu Gaussa!
Luis Mendo,
1
„najlepszy” język dla tej pracy, wciąż pobity galaretką. Jednak doskonałe rozwiązanie.
Socratic Phoenix,
19

05AB1E , 6 bajtów

Kod

A.pJ.R

Wyjaśnienie

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

Mamy teraz następujący ciąg:

aababcabcdabcdeabcdefabcdefgabcdefghabcdefghiabcdefghijabcdefghijkabcdefghijklabcdefghijklmabcdefghijklmnabcdefghijklmnoabcdefghijklmnopabcdefghijklmnopqabcdefghijklmnopqrabcdefghijklmnopqrsabcdefghijklmnopqrstabcdefghijklmnopqrstuabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvwabcdefghijklmnopqrstuvwxabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz

Następnie wybieramy losowy element za pomocą .R.

Prawdopodobieństwa

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%

Wypróbuj online! .

Adnan
źródło
18

Galaretka , 5 bajtów

ØA»ẊX

Wypróbuj online!

Jak to działa

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

tło

Niech L 0 , ..., L 25 oznacza litery alfabetu, w celu ich naturalnych i S 0 , ..., S 25 równomiernie losowo wybranych permutacji L . Zdefiniuj sekwencję skończoną M o M n = max (L n , S n ) .

Napraw n w 0,… 25 i zdefiniuj k jako indeks taki, że L n = S k .

Z prawdopodobieństwem 1/26 , l n = s n a n = k , tak M n = l n i L n occurrs raz M .

Z prawdopodobieństwem 25/26 , L n ≠ S n i n ≠ k . W takim przypadku dzieje się tak.

  • Z prawdopodobieństwem n / 25 , S n jest jednym z L 0 ,…, L n - 1 , więc L n > S n i M n = L n .

  • Niezależnie, również z prawdopodobieństwem n / 25 , k jest jednym z 0,… n - 1 , więc S k > L k i M k = S k = L n .

Zatem oczekiwana liczba wystąpień L n w M wynosi 1/26 + 25/26 · (n / 25 + n / 25) = (2n + 1) / 26 .

W końcu, jeśli teraz wybrać termin m o M równomiernie losowo litery L n , że wybiera się z prawdopodobieństwem (2N + 1) / 26/26 = (2n + 1) / 676 .

Daje to następujący rozkład prawdopodobieństw.

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

Możesz empirycznie zweryfikować dystrybucję, wywołując link 100 000 razy (zajmuje to kilka sekund).

Dennis
źródło
1
@RobertFraser krok losowania daje wydajność z listą A w dowolnym miejscu A pojawił się na jednej z list, B gdzie B pojawił się na jednej liście i cokolwiek innego niż A na drugiej liście, ... Z gdziekolwiek, gdzie Z pojawił się na obu listach. więc w wyniku jest około 52 razy więcej A niż Z.
Sparr,
1
@RobertFraser Dodałem wyjaśnienie.
Dennis,
2
@DennisJaheruddin In UTF-8, tak. Jednak Jelly używa niestandardowej strony kodowej, która koduje wszystkie znaki, które rozumie, jako jeden bajt każdy. Te bajty odwołuje się w punktach głowicy do niego.
Dennis
2
Rozumiem, że kiedy przeczytałem wyjaśnienie, nie było od razu jasne, że nie można również skorzystać ze zwykłego zakresu UTF-8. Czy mam więc prawo założyć, że zmieniając interpreter i mapując wszystkie znaki na poszczególne znaki UTF-8, otrzymalibyście całkowicie identyczny kod (tylko mniej czytelny / możliwy do wpisania)? - Jeśli tak, rozważ rozszerzenie wyjaśnienia, aby wspomnieć, że znak powinien być liczony jako bajt do celów golfowych.
Dennis Jaheruddin,
2
@DennisJaheruddin Jak wyjaśniono w README (pierwsze łącze w nagłówku), interpreter ma dwa tryby (strona kodowa Jelly i UTF-8), dzięki czemu można zapisać ten program w rzeczywistym pliku 5-bajtowym. Mógłbym dodać wszystkie te informacje do każdej odpowiedzi, którą piszę, ale są ich setki, więc wybrałem linkowanie.
Dennis
14

MATL , 10 bajtów

1Y2rU26*k)

Wypróbuj online!

Kod generuje jednolitą zmienną losową na przedziale (0,1) ( r) i oblicza jej kwadrat ( U). Powoduje to nierównomierną, malejącą gęstość prawdopodobieństwa. Pomnożenie przez 26 ( 26*) zapewnia, że ​​wynik jest w przedziale (0,26), a zaokrąglenie w dół ( k) daje wartości 0,1, ..., 25 ze zmniejszającym się prawdopodobieństwem. Wartość jest używana jako indeks ( )) do wielkich liter alfabetu ( 1Y2). Ponieważ MATL stosuje modułowe indeksowanie 1, 0 odpowiada Z, 1 do A, 2 do B itd.

Jako ilustrację, że prawdopodobieństwa są różne, oto dyskretny histogram wynikający z 1000000 losowych realizacji. Wykres jest tworzony przez uruchomienie tego w Matlab:

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

wprowadź opis zdjęcia tutaj

Luis Mendo
źródło
1
Miły! Najlepsze rozwiązanie, jakie mogłem wymyślić, to 16 bajtów
DJMcMayhem
1
@DJMcMayhem Ładne podejście!
Luis Mendo,
Może, ale o wiele dłużej. : P
DJMcMayhem
Kolejna zabawna alternatywa: matl.suever.net/…
Suever,
W rzeczywistości nie potrzebujesz k! Zauważyłem, że podczas próby codegolf.stackexchange.com/a/89648/11159
Dennis Jaheruddin
13

Java 7, 62 57 56 bajtów

5 bajtów dzięki Poke.

1 bajt dzięki 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 to!

Wykres częstotliwości (przebiegi 1e6, współczynnik skalowania 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: ***************************************************************************
Leaky Nun
źródło
1
Nie sądzę, że musisz wybierać typ do gry int
Poke
@Poke Thanks, grał w golfa.
Leaky Nun
Czy możesz zapisać bajt, przesuwając 676 poza nawiasy?
trichoplax
@trichoplax Co masz na myśli?
Leaky Nun
2
sqrt(x*y*y) = sqrt(x)*y
trichoplax
10

Perl, 24 bajty

-4 bajty dzięki @Martin Ender
-1 bajt dzięki @Dom Hastings

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

Potrzebuje -M5.010lub -Euruchomić:

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

Uruchomienie następującego kodu pokaże występowanie każdej litery:

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


Jak to działa : Myślę, że kod jest dość wyraźny, ale nadal: wybiera losową liczbę między 0a rand 26. Istnieje więc znacznie większe prawdopodobieństwo, że wybrane zostaną liczby zbliżone do 0(litery A).

Dada
źródło
Wyjaśnienie ma dla mnie sens :)
trichoplax
Fajne rozwiązanie! Możesz zapisać 1 bajt, używając pustej listy i +:say+(A..Z)[rand rand 26]
Dom Hastings,
@DomHastings aarf, jestem głupi. Próbowałem (A..Z)[...]i to nie zadziałało, więc pomyślałem, że mogę użyć takiej anonimowej tablicy, ale to tylko z powodu say... dzięki! :)
Dada,
10

PHP, 44 36 29 27 bajtów

Przekreślone 44 jest nadal regularne 44; (

Dzięki inserttusernamehere, Petah i Crypto za całą pomoc

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

Wybiera liczbę losową z przedziału od 0 do 675 (= 26 2 -1), bierze pierwiastek kwadratowy i wykłada podłogę ( chrfunkcja przekształca argument na liczbę całkowitą). Ponieważ kwadraty mają różne odstępy między nimi, prawdopodobieństwo wybrania każdej liczby jest odrębne. Każdy n jest wybierany z prawdopodobieństwem (2n + 1) / 676.

Dodanie 65 do tej liczby daje losową postać od Ado Z.

Ideone kodu działającego 1 000 000 razy

Business Cat
źródło
Można wyłączyć golf 4 bajtów : range(A,Z).
inserttusernamehere
@insertusernamehere: Dziękuję za podpowiedź, ale udało mi się zagrać w 8 bajtów, nie używając w ogóle zasięgu i po prostu używając chr().
Business Cat
3
Nawet lepiej. Niestety skreślone 44 jest nadal regularne 44 . :)
inserttusernamehere
1
@insertusernamehere Za łatwo się <s>&nbsp;44&nbsp;</s>
poddajesz
<?=chr(65+sqrt(rand(0,675)));
Petah,
8

R, 40 27 bajtów

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

Spowoduje to pobranie 1liczby z 26liczb generowanych z rosnącym prawdopodobieństwem w kierunku Z, bez zamiany, i wyświetlenie litery, której indeksem jest ta liczba, z listy wielkich liter LETTERS.

Argumenty samplefunkcji to:

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
źródło
Tak, to nie zadziała. To może być najmądrzejszy sposób!
Frédéric,
Cóż, zawsze gdzieś będzie podszewka! Muszę pomyśleć o tym ...
Frédéric,
1
Naprawiony i krótszy - imponujący :)
trichoplax
1
@trichoplax Thanks! Ładne wyzwanie btw!
Frédéric,
1
@AlbertMasclans: Może rzeczywiście, ale już to zrobiono w odpowiedzi innej osoby, więc nie chcę „kopiować”! Mimo wszystko dziękuję ! ;)
Frédéric
8

> <> , 14 bajtów

lx
;>dd+%'A'+o

> <> to toroidalny język 2D, a część prawdopodobieństwa po prostu dzieje się naturalnie ze względu na jedyne źródło losowości tego języka. Wypróbuj online!

Odpowiednie polecenia to:

[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

Zatem prawdopodobieństwa wyjściowe wynoszą:

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
źródło
7

Python 2, 58 57 bajtów

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

Objaśnienie: generuje losową liczbę zmiennoprzecinkową w przedziale [0, 676), pobiera pierwiastek kwadratowy, a następnie wprowadza go do podłogi. Następnie dodaje 65 (wartość ascii „A”), konwertuje go na char i drukuje.

Daje to każdemu numerowi od 0 do 25 wyraźne prawdopodobieństwo. Aby zrozumieć dlaczego, pomyśl o tym w ten sposób. Ile liczb, ignorując liczby całkowite, gdy weźmiesz pierwiastek kwadratowy i piętro, dajesz 0? Tylko jedna liczba będzie (zero). Oznacza to, że zero ma prawdopodobieństwo 1/676. Ile liczb da 1? 3 będzie, 1, 2 i 3. Oznacza to, że istnieje prawdopodobieństwo 3/676. Dwa mogą być produkowane z 4, 5, 6, 7 lub 8, co daje prawdopodobieństwo 5, trzy ma prawdopodobieństwo 7 itd., A ponieważ różnica między kolejnymi kwadratami stale rośnie o dwa, ten wzór jest kontynuowany przy każdym zwiększeniu liczby do 25 (Z).

1 bajt zapisany dzięki nieszczelnej zakonnicy!

DJMcMayhem
źródło
chr(int(65+randint(676)**.5))
Leaky Nun
1
Można to zrobić chr(int(65+random()**.5*26)). Jest to to samo algebraicznie, ponieważ 26 == √676. a teraz kolejność operacji jest po twojej stronie
Wheat Wizard
3
@EamonOlive Dla innego bajtu **2*26można zastosować odwrotny rozkład.
user81655,
1
1/random()%26powinien również działać.
xnor
1
@xnor, który czasami da 1/0% 26
trichoplax
5

PowerShell v2 +, 33 31 bajtów

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

Przyjmuje zakres od 65do 90(tj. ASCII Ado Z), przepuszcza go przez pętlę. W każdej iteracji używamy operatora przecinka, aby utworzyć tablicę tego elementu razy tę liczbę. Na przykład spowoduje to 65 65s, 66 66s, 67 67s itd. Ta duża tablica jest podłączona do potoku, do Get-Randomktórej (jednolicie PRNG) wybierze jeden element. Ponieważ istnieją różne ilości każdego elementu, każda postać ma nieco wyraźną procentową szansę na wybranie. Następnie enkapsulujemy to w pareny i rzucamy jako char. Pozostaje to w potoku, a dane wyjściowe są niejawne.

(Dzięki @LeakyNun za grę w golfa na kilka bajtów, jeszcze zanim został opublikowany.: D)


Prawdopodobieństwa

(niewielkie zaokrąglenie, dzięki czemu mógłbym zademonstrować Popcję -foperatora 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
źródło
1
Zacząłem bez patrzenia na żadną z odpowiedzi; próbował zbudować na galwyjściu ( [char[]]"uz$(gal|out-string)"-cmatch'[a-z]'|random) do 50 znaków, następnie 48, zmienił się na cyfry i dostał 42, a następnie 31 i zatrzymał się tam; spojrzałem na tabelę wyników, żeby zobaczyć, gdzie mnie to położy. Tutaj. Znak dla postaci identycznej. Welp, prawdopodobnie nie mogę tego pokonać.
TessellatingHeckler
5

CJam, 21 17 12 bajtów

Dzięki Martinowi Enderowi za uratowanie mnie 5 bajtów!

Nowa wersja

'\,:,s_el-mR

Tworzy tablicę ciągów poniższy wzór A, AB, ABC, i tak dalej. Spłaszcza go i wybiera losową postać. Ponieważ ten ciąg zawiera 26 A, 25 B, 24 C i tak dalej, każda litera ma wyraźne prawdopodobieństwo wyboru.

Wypróbuj online!

Wyjaśnienie

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

Stara wersja

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

Pobiera różne prawdopodobieństwa, tworząc ciąg, w którym każda litera pojawia się kilka razy równa jej pozycji w alfabecie.

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
Business Cat
źródło
5

R, 23 bajty

sample(LETTERS,1,,1:26)

Wystarczy „pobrać” próbkę z wbudowanego listu. 1:26jest wektorem wag dając każda litera inny prawdopodobieństwa.

użytkownik5957401
źródło
1
1:26jest wektorem wag dla każdej litery
użytkownik5957401
To sprawia, że ​​jest to poprawna odpowiedź. Warto edytować w objaśnieniu, aby osoby nieznające R mogły zrozumieć, jak to działa.
trichoplax
1
Miałem zamiar, a potem zdałem sobie sprawę, że facet nade mną zrobił dokładnie to samo w swoim kodzie i udzielił szczegółowego wyjaśnienia.
user5957401,
Dobrze, że dodałeś wyjaśnienie - kolejność, w jakiej rozwiązania pojawiają się na stronie, może się różnić w zależności od głosów, więc te „powyżej” mogą nie być później powyżej.
trichoplax
5

C, 35 bajtów

Ten program zakłada RAND_MAX(2 ^ 32/2) - 1 domyślnie na gcc. Skompiluj z -lmflagą, aby połączyć sqrtfunkcję. Dane wyjściowe są zapisywane na stdout jako wielkie litery bez końcowych znaków nowego wiersza.

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

Opcjonalnie, jeśli RAND_MAXjest (2 ^ 16/2) - 1, można użyć krótszej 32-bajtowej wersji:

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

Dla zabawy stworzyłem również wersję, która nie używa tej sqrtfunkcji ani nie wymaga dołączonej biblioteki matematycznej (ta musi mieć RAND_MAXjako (2 ^ 32/2) - 1), ale skończyła się na dłuższym czasie, chociaż myślałem, że to była całkiem fajne:

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

Wyjaśnienie

[Pierwszy program]

Przy pierwszych dwóch zastosowaniach sqrtfunkcja po prostu odwzorowuje zakres [0, RAND_MAX)na [0, 25]dzielenie przelotne, a następnie dodaje 65 (ASCII A) do wartości, aby przesunąć ją na alfabet ASCII przed wysłaniem.

[Drugi program]

Drugi program jest nieco bardziej złożony, ponieważ ma podobną strategię, ale bez sqrtoperatora. Ponieważ bity wykładnikowe zmiennoprzecinkowe są automatycznie obliczane po przypisaniu liczby całkowitej, można je skutecznie wykorzystać jako surowy sposób uzyskania logarytmu podstawowego 2 liczby.

Ponieważ chcemy, aby zakres RAND_MAXdo osiągnięcia zakodowanej wartości wykładniczej wynoszącej 25, obliczenia (2 ^ 32/2 - 1) / (2 ^ 25) dają nam tylko około 64, które jest używane podczas podziału randna mapowanie do tego nowego asortymentu. Dodałem również 1 do wartości, ponieważ reprezentacja zmiennoprzecinkowa 0 jest raczej dziwna i złamałaby ten algorytm.

Następnie liczba zmiennoprzecinkowa jest wpisywana na liczbę całkowitą, aby umożliwić przesunięcie bitów i inne tego typu operacje. Ponieważ w liczbach zmiennoprzecinkowych IEEE 754 bity wykładnikowe są bitami 30–23, liczba jest następnie przesuwana w prawo o 23 bity, odcinając mantysę i umożliwiając odczytanie wartości surowego wykładnika jako liczbę całkowitą. Zauważ, że bit znaku również wykracza poza bity wykładnikowe, ale ponieważ nigdy nie ma żadnych negatywów, nie trzeba go maskować.

Zamiast dodawać 65 do tego wyniku, jak to robiliśmy wcześniej, wykładniki zmiennoprzecinkowe są reprezentowane jako liczba całkowita bez znaku 8 bitów od 0 do 255, gdzie wartość wykładnika 0 wynosi 127 (po prostu odejmij 127, aby uzyskać rzeczywistą „wykładnik” wartości wykładnika ). Ponieważ 127 - 65 wynosi 62, zamiast tego po prostu odejmujemy 62, aby zarówno przesunąć go z tego zakresu zmiennoprzecinkowego wykładnika, jak i do zakresu alfabetu ASCII w jednej operacji.

Dystrybucja

Nie jestem ekspertem od matematyki, więc nie mogę z całą pewnością powiedzieć dokładnej formuły dla tych rozkładów, ale mogę (i zrobiłem) przetestować każdą wartość w zakresie, [0, RAND_MAX)aby wykazać, że odległość między miejscem, w którym kończy się zakres jednej litery, a drugim zaczyna się, nigdy nie jest podobnie. (Uwaga: testy te zakładają losowe maksimum (2 ^ 32/2) - 1)

[Pierwszy program]

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

[Drugi program]

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
Lemon Drop
źródło
Czy nie byłoby krótsze odesłanie porządkowego niż wydrukowanie go? Ponieważ charjest to typ integralny w C, powinno to być dopuszczalne.
Mego
@Mego No cóż, tak, jeśli możesz to zrobić, dopiero zaczynam grać w golfa, więc nie jestem zbyt zaznajomiony z tym, co uważa się za akceptowalne.
Lemon Drop
4

Python 2, 72 bajty

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

Mnoży znak przez jego wartość ascii, a następnie wybiera losowo jeden znak z otrzymanego ciągu.

Oto prawdopodobieństwa dla każdej wybranej litery w procentach:

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

Wypróbuj: https://repl.it/Cm0x

atlasolog
źródło
4

Galaretka , 5 bajtów

ØAxJX

(Równy wynik, ale inna metoda , niż istniejące rozwiązanie Jelly autorstwa Dennisa.)

Prawdopodobieństwo uzyskania każdej litery to indeks 1 w alfabecie podzielony przez 351 - 26 liczba trójkątna:

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

Ponieważ 1 + 2 + ... + 26 = 351, P (litera) = 1.

Realizacja:

Ø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

Przetestuj to na TryItOnline lub uzyskaj dystrybucję 100 000 przebiegów (kredyt do Dennisa)

Jonathan Allan
źródło
Gdzie nauczyłeś się być tak dobry w Jelly? Trudno mi uwierzyć, że Galaretka byłaby powszechną wiedzą poza PPCG.
Addison Crump
1
@Syxer Właśnie spojrzałem na wiki i wyrzuciłem - wciąż nie rozumiem wszystkiego :)
Jonathan Allan
1
No więc. Witamy w PPCG, oddaj głos.
Addison Crump
3

q, 38 bajtów

Niezbyt krótki, ale ...

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

Dyskretną funkcją rozkładu skumulowanego jest sekwencja

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

A my po prostu próbkujemy z dystrybucji.

skeevey
źródło
3

JavaScript (ES6), 45 bajtów

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

Osiąga nierównomierny rozkład poprzez podniesienie do kwadratu wartości losowej. Math.random()zwraca liczbę zmiennoprzecinkową zakresu, [0,1)więc wynik podniesienia do kwadratu zmierza w kierunku 0(lub a).

Test

użytkownik 81655
źródło
42 B,(n=Math.random(),10+26*n+n|0).toString(36)
Ephellon Dantzler,
3

Oracle SQL 11.2, 212 bajtów

Wykorzystanie pozycji znaku w alfabecie jako prawdopodobieństwa

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;

Bez golfa

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
źródło
3

TI-Basic, 39 bajtów

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

rand generuje jednolitą wartość w (0,1]. Daje to 26 ^ rand inne prawdopodobieństwo zrównania liczb całkowitych od 1 do 26.

Starsza wersja, 45 bajtów

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

Ograniczona precyzja liczb całkowitych TI-Basic ogranicza rozkład normalny do generowania liczb w granicach µ ± 7,02σ (patrz randNorm(). Otrzymujemy więc wartość bezwzględną liczby losowej z µ 0 i σ 1, mnożąc ją przez cztery, aby zwiększyć wspomniany wcześniej praktyczny zakres do µ ± 28,08σ. Następnie doliczamy wartość dolną i dodajemy 1, ponieważ sub(jest indeksowana 1, co daje nam zakres od 1-29 z różnymi prawdopodobieństwami dla każdego z nich.

Timtech
źródło
1
@trichoplax To był mój błąd, pozostało mi 30 ze starej wersji [0,29]. Naprawiłem to teraz.
Timtech,
Przedział (0,1) powinien wynosić [0,1).
kamoroso94,
@ kamoroso94 Sprawdziłeś? „Uwaga: Ze względu na specyfikę algorytmu generowania liczb losowych najmniejsza możliwa do wygenerowania liczba jest nieco większa niż 0. Największa możliwa liczba to w rzeczywistości 1” - cytowano na stronie tibasicdev.wikidot.com/rand
Timtech
3

PHP, 92 84 bajtów

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

Tworzy ciąg wszystkich liter, powtarzając liczbę razy przez pętlę, którą jesteśmy, a następnie losowo wybiera literę z tego ciągu. W rezultacie litery później w alfabecie mają większe prawdopodobieństwo

Dzięki inserttusernamehere do golenia bajtów

prawdopodobieństwa wyniku (uporządkowane według%)

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
źródło
1
zmieniono, aby faktycznie przestrzegać zasad. Mój błąd
gabe3886,
@insertusernamethere dostaję niezdefiniowane powiadomienia o zmiennych, gdy je uruchamiam i nie
wypisuję
Oh przepraszam. Myślę, że zostałem porwany i usunięty, $x=0co jest oczywiście konieczne. Oto wersja 84-bajtowa : for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);Czy kiedykolwiek udało ci się uzyskać wartość większą niż Gpodczas uruchamiania kodu? W każdym razie zawsze możesz zignorować notices podczas gry w golfa.
inserttusernamehere
1
Zrobiłem to, ale potrzeba czasu, żeby się pojawiło. Przebiegłem go przez około 100
000
strlenStanowi $ato 351, ale odbierają tylko losowy charakter z pierwszych $x(26) znaków. Można go naprawić i utrzymać prawdopodobieństw ze zmianą ostatecznej $xDo 350do +1 bajt. Oto 77-bajtowa wersja, która rozwiązuje problem, ale jednocześnie znacznie zbliża prawdopodobieństwo:for($i=65;$i<91;$a.=str_repeat(chr($i),$i++));echo substr($a,rand(0,2014),1);
Jo.
3

Befunge, 168 164 bajtów

Bardziej kompaktowy niż pierwszy, z nieco innymi prawdopodobieństwami: pierwsze ?mają 1/4 szansy wydrukowania A przy „pierwszej próbie”, 2/4 szansy na powrót do tego samego ?i 1/4 na przejście do Kolejny. Reszta ?każdego z nich ma 1/4 szansy wydrukowania litery pod nimi, 1/4 do ponownej próby, 1/4 przejścia do następnej litery, 1/4 przejścia do poprzedniej. Ponownie, prawdopodobieństwo wydrukowania A jest znacznie wyższe niż wydrukowanie Z.

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

Befunge, 186 bajtów

Oczywiście nie wygra z tym, ale myślę, że to jednak interesująca odpowiedź :)

vi >steruje kursorem odpowiednio w dół i w prawo. ?Operator wysyła kursor się w jednym z czterech kierunków losowy. Pierwszym ?jest „zablokowany” przez vi >w dwóch kierunkach, tak że ma tylko dwie drogi: albo pójść do wydrukowania A lub w dół do następnej ?. Tak więc od samego początku ?istnieje 50% szans na wydrukowanie A.

Następny ?ma 1/3 szansy na wydrukowanie B, 1/3 powrotu i 1/3 dalszego spadku. Itd itd.

Powinno być całkiem oczywiste, że wyższe litery mają znacznie większą szansę na wydrukowanie niż niższe, ale nie jestem do końca pewien, jakie są szanse każdej litery.

Będziemy wdzięczni za pomoc w dokładnej matematyce :)

Przynajmniej przy pierwszej próbie istnieje szansa 1/2 * 1/3 ^ 25, że kursor przesunie się w dół do litery Z. Nie jestem jednak pewien, jak szanse na przesuwanie kursora w górę i w dół wpływają na każdą literę.

,@ odciski i rezygnuje.

 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
źródło
2

J, 20 18 bajtów

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

Tłumacz online

Duże litery.

Prawdopodobieństwo każdej litery jest indeksem 1 w alfabecie.

Leaky Nun
źródło
2

zsh, 63 bajty

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

działa, tworząc ten ciąg:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

czyli 65 razy A, 66 razy B, 67 razy C ...

a następnie wybiera losową postać

izabera
źródło
Dlaczego zacząłeś w wieku 65 lat?
gcampbell
1
@gcampbell 65 jest Aw ascii. możesz zacząć od 1, ale wtedy wewnętrzna pętla staje się {65..$[#i]}dłuższa o 1 char
izabera,
2

CJam, 11 bajtów

4.mrmqC*'A+

lub

676.mrmq'A+

Wypróbuj online!

To rozwiązanie jest podobne do pomysłu Luisa i tworzy nierównomierny rozkład, biorąc pierwiastek kwadratowy zmiennej losowej.

Martin Ender
źródło
2

Partia, 116 bajtów

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

Działa poprzez wybranie większej lub mniejszej (zapominam która) dwóch zmiennych losowych.

Neil
źródło
2

Matlab, 22

Często zwraca wczesne litery, ale teoretycznie może je wszystkie dotknąć!

Bierze jedną podzieloną przez liczbę losową, ogranicza ją do 26 i zamienia na postać.

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

Oczywiście nie bardzo krótko, ale być może ta koncepcja może zainspirować inne odpowiedzi.

Dennis Jaheruddin
źródło
Czy randzwraca wartość w [0, 1)? To znaczy, włączając zero, ale nie włączając jednego. Jeśli czasami powoduje to 1/0, min(1/0,26)nadal zwróci 26 lub błąd?
trichoplax
O ile wiem, randzwraca wartość w (0,1), więc nie powinno być problemu
paul.oderso
1
@trichoplax Nawet jeśli nie zobaczysz randzwrotu 0 w praktyce, min(1/0,26)faktycznie zwraca 26.
Dennis Jaheruddin
W takim razie fajne rozwiązanie :)
trichoplax
2

CJam, 10 bajtów

Podejście CJam # 3 ...

26mr)mr'A+

Wypróbuj online!

Spowoduje to utworzenie jednolicie losowej liczby xmiędzy 1 a 26, a następnie wykorzysta tę liczbę do utworzenia równomiernie losowej liczby między 0i do x-1której zostanie dodana A. To tendencyjność prowadzi do mniejszych postaci.

Martin Ender
źródło
2

Labirynt , 19 bajtów

__v6%_65+.@
" )
"^2

Wypróbuj online!

Jest to pętla, która przy każdej iteracji albo a) zwiększa licznik rozpoczynający się od zera lub b) kończy się, oba z prawdopodobieństwem 50%. Na końcu pętli licznik jest pobierany modulo 26 i dodawany do 65, aby dać literę między Ai Z.

Daje to prawdopodobieństwo Anieco ponad 50%, Bnieco ponad 25% i tak dalej do Znieco ponad 1/2 26 . Teoretycznie istnieje możliwość takiego działania na zawsze, ale to zdarzenie ma zerowe prawdopodobieństwo zgodnie z wymaganiami wyzwania (w praktyce prawdopodobnie nie jest to możliwe, ponieważ PRNG zwróci oba możliwe wyniki w pewnym momencie w tym okresie).

Martin Ender
źródło