Golf Acak Hari Ini # 7: Karakter acak yang jelas


47

Tentang Seri

Ini adalah entri tamu untuk seri Golf Acak Hari ini.

Pertama, Anda dapat memperlakukan ini seperti tantangan golf kode lainnya, dan menjawabnya tanpa khawatir tentang seri sama sekali. Namun, ada papan peringkat di semua tantangan. Anda dapat menemukan papan peringkat bersama dengan beberapa informasi lebih lanjut tentang seri di posting pertama .

Memasukkan

Tidak ada input yang diambil.

Keluaran

Satu huruf alfabet (huruf tidak relevan), dengan baris tambahan opsional. Setiap huruf harus memiliki probabilitas bukan nol untuk dipilih, dan ke-26 probabilitas harus berbeda . Untuk menghapus semua ambiguitas: Perbedaan berarti bahwa tidak boleh ada dua probabilitas yang sama satu sama lain.

Mencetak gol

Ini kode golf. Kode terpendek dalam byte menang.

Entri yang valid adalah program atau fungsi lengkap yang memiliki probabilitas nol untuk tidak berakhir.

Alfabet

Untuk menghindari kebingungan, alfabet tertentu yang digunakan adalah alfabet Latin:

Antara

ABCDEFGHIJKLMNOPQRSTUVWXYZ

atau

abcdefghijklmnopqrstuvwxyz

Anda dapat memilih untuk menampilkan huruf besar atau kecil. Sebagai alternatif, Anda dapat memilih untuk menampilkan kasing yang berbeda pada run yang berbeda jika itu membantu. Probabilitas untuk huruf tertentu adalah probabilitas huruf itu muncul dalam kedua kasus (atas atau bawah).

Penjelasan

Karena tidak akan terlihat jelas dari output, harap sertakan penjelasan yang jelas tentang bagaimana Anda mencapai 26 probabilitas yang berbeda.

Papan peringkat

(dari sini )

Posting pertama dari seri ini juga menghasilkan leaderboard keseluruhan.

Untuk memastikan jawaban Anda muncul, mulailah setiap jawaban dengan tajuk utama, menggunakan templat Penurunan harga berikut:

## Language Name, N bytes

di mana Nukuran kiriman Anda. Jika Anda meningkatkan skor Anda, Anda bisa menyimpan skor lama di headline, dengan mencoretnya. Misalnya:

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

(Bahasa saat ini tidak ditampilkan, tetapi cuplikan memang membutuhkan dan menguraikannya, dan saya dapat menambahkan leaderboard berdasarkan bahasa di masa mendatang.)


bagaimana Anda mengukur 26 probabilitas yang berbeda? dengan menjalankan program 26 kali?
ANDA

1
@You melihat melalui solusi - ada beberapa pendekatan yang berbeda dengan penjelasan yang sangat baik
trichoplax

Jika itu adalah fungsi apakah perlu mencetak atau dapatkah itu hanya mengembalikan nilai karakter?
Geoff Reedy

@ Geoff Menurut standar kami untuk input dan output , baik mencetak ke STDOUT atau mengembalikan karakter baik-baik saja.
trichoplax

@ Geoff perhatikan bahwa itu harus berupa karakter, bukan hanya nilai angka yang mewakilinya. Misalnya, Abukan 65.
trichoplax

Jawaban:


13

Pyth, 5

Os._G

Coba di sini

Menghitung awalan abjad, sehingga: ["a", "ab", "abc", ..., "abcdefghijklmnopqrstuvwxyz"]. Kemudian ratakan daftar dan pilih elemen acak dari itu secara seragam. Ini berarti bahwa sejak amuncul 26 kali, sementara bmuncul 25 kali, semuanya zdengan hanya 1 penampilan, setiap huruf memiliki peluang berbeda untuk muncul. Total string memiliki 351 karakter.


1
Saya suka jawaban itu. Sangat pintar.
Allen Fisher

24

MATL, 6 Karakter

1Y2Xr)

Penjelasan:

XrAmbil nomor acak yang didistribusikan secara normal )Gunakan ini untuk mengindeks ke ... 1Y2Alfabet

Distribusi simetris sekitar 0, dan terjemahan angka ke char simetris sekitar 0,5. Dengan demikian probabilitasnya harus berbeda.


2
Oh, ide yang sangat bagus untuk menggunakan distribusi Gaussian!
Luis Mendo

1
bahasa "terbaik" untuk pekerjaan itu, masih dikalahkan oleh jelly. Solusi yang sangat baik.
Socratic Phoenix

19

05AB1E , 6 byte

Kode

A.pJ.R

Penjelasan

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

Kami sekarang memiliki string berikut:

aababcabcdabcdeabcdefabcdefgabcdefghabcdefghiabcdefghijabcdefghijkabcdefghijklabcdefghijklmabcdefghijklmnabcdefghijklmnoabcdefghijklmnopabcdefghijklmnopqabcdefghijklmnopqrabcdefghijklmnopqrsabcdefghijklmnopqrstabcdefghijklmnopqrstuabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvwabcdefghijklmnopqrstuvwxabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz

Setelah itu, kami memilih elemen acak menggunakan .R.

Peluangnya

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%

Cobalah online! .


18

Jelly , 5 byte

ØA»ẊX

Cobalah online!

Bagaimana itu bekerja

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

Latar Belakang

Biarkan L 0 , ..., L 25 menunjukkan huruf-huruf alfabet dalam rangka alami mereka, dan S 0 , ..., S 25 yang seragam di permutasi yang dipilih secara acak dari L . Tentukan urutan berhingga M oleh M n = maks (L n , S n ) .

Perbaiki n dalam 0, ... 25 dan tentukan k sebagai indeks sehingga L n = S k .

Dengan probabilitas 1/26 , L n = S n dan n = k , sehingga M n = L n dan L n occurrs sekali dalam M .

Dengan probabilitas 25/26 , L n ≠ S n dan n ≠ k . Dalam hal ini, berikut ini terjadi.

  • Dengan probabilitas n / 25 , S n adalah salah satu dari L 0 , ..., L n - 1 , jadi L n > S n dan M n = L n .

  • Secara independen, juga dengan probabilitas n / 25 , k adalah salah satu dari 0, ... n - 1 , jadi S k > L k dan M k = S k = L n .

Dengan demikian, jumlah kejadian yang diharapkan dari L n di M adalah 1/26 + 25/26 · (n / 25 + n / 25) = (2n + 1) / 26 .

Akhirnya, jika kita sekarang memilih istilah m dari M secara seragam secara acak, huruf L n kita dipilih dengan probabilitas (2n + 1) / 26/26 = (2n + 1) / 676 .

Ini menghasilkan distribusi probabilitas berikut.

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

Anda dapat secara empiris memverifikasi distribusi dengan menelepon tautan 100.000 kali (butuh beberapa detik).


1
@RobertFraser, langkah mengocok dan menghasilkan menghasilkan daftar dengan A di mana pun A muncul di salah satu daftar, B di mana B muncul di salah satu daftar dan apa pun selain A dalam daftar lainnya, ... Z di mana pun Z muncul di kedua daftar. jadi ada kira-kira 52x A sebanyak Z dalam hasil.
Sparr

1
@RobertFraser Saya sudah menambahkan penjelasan.
Dennis

2
@DennisJaheruddin Di UTF-8, ya. Namun, Jelly menggunakan halaman kode khusus yang mengkodekan semua karakter yang dipahami sebagai masing-masing byte tunggal. The byte link dalam poin sundulan untuk itu.
Dennis

2
Begitu, ketika saya membaca penjelasannya, tidak segera jelas bahwa Anda tidak dapat memanfaatkan rentang UTF-8 biasa juga. Jadi, apakah saya benar untuk berasumsi bahwa dengan mengubah juru bahasa dan memetakan semua karakter ke karakter UTF-8 individu Anda akan memiliki kode yang sama persis (hanya kurang dapat dibaca / diketik)? - Jika demikian, pertimbangkan untuk memperluas penjelasan dengan menyebutkan bahwa arang harus dihitung sebagai byte untuk keperluan golf.
Dennis Jaheruddin

2
@DennisJaheruddin Seperti dijelaskan dalam README (tautan pertama di header), penerjemah memiliki dua mode (halaman kode Jelly dan UTF-8), sehingga Anda dapat menyimpan program ini dalam file 5-byte yang sebenarnya. Saya bisa menambahkan semua informasi itu ke setiap jawaban yang saya tulis, tetapi ada ratusan, jadi saya memilih menautkan.
Dennis

14

MATL , 10 byte

1Y2rU26*k)

Cobalah online!

Kode menghasilkan variabel acak seragam pada interval (0,1) ( r) dan menghitung kuadratnya ( U). Ini menghasilkan kepadatan probabilitas yang tidak seragam dan menurun. Mengalikan dengan 26 ( 26*) memastikan bahwa hasilnya ada pada interval (0,26), dan pembulatan ke bawah ( k) menghasilkan nilai 0,1, ..., 25 dengan penurunan probabilitas. Nilai ini digunakan sebagai indeks ( )) ke dalam huruf besar ( 1Y2). Karena MATL menggunakan pengindeksan modular berbasis 1, 0 berkorespondensi dengan Z, 1 ke A, 2 ke B dll.

Sebagai ilustrasi bahwa probabilitasnya berbeda, inilah histogram diskrit yang dihasilkan dari 10.00000 realisasi acak. Grafik diproduksi dengan menjalankan ini di Matlab:

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

masukkan deskripsi gambar di sini


1
Bagus! Solusi terbaik yang bisa saya dapatkan adalah 16 byte
DJMcMayhem

1
@DJMcMayhem Pendekatan yang bagus!
Luis Mendo

Mungkin, tapi jauh lebih lama. : P
DJMcMayhem

Alternatif lain yang menyenangkan: matl.suever.net/…
Suever

Sebenarnya kamu tidak butuh itu k! Memperhatikan hal itu ketika
Dennis Jaheruddin

13

Java 7, 62 57 56 byte

5 byte berkat Poke.

1 byte berkat 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);}

Ide itu!

Diagram frekuensi (berjalan 1e6, faktor penskalaan 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
Saya tidak berpikir Anda perlu mengetikkan ke int
Poke

@ Poke Terima kasih, bermain golf.
Leaky Nun

Bisakah Anda menyimpan byte dengan memindahkan 676 di luar tanda kurung?
trichoplax

@trichoplax Apa maksudmu?
Leaky Nun

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

10

Perl, 24 byte

-4 byte terima kasih kepada @Martin Ender
-1 byte terima kasih kepada @Dom Hastings

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

Perlu -M5.010atau -Euntuk dijalankan:

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

Menjalankan kode berikut akan menunjukkan kemunculan setiap huruf:

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


Cara kerjanya : Saya kira kode ini cukup eksplisit, tetapi tetap: ia memilih nomor acak antara 0dan rand 26. Jadi ada kemungkinan yang jauh lebih tinggi bahwa angka yang dekat dengan 0(huruf A) dipilih.


Penjelasannya masuk akal bagi saya :)
trichoplax

Solusi bagus! Anda dapat menyimpan 1 byte menggunakan daftar kosong dan +:say+(A..Z)[rand rand 26]
Dom Hastings

@HomHastings aarf, aku bodoh. Saya mencoba (A..Z)[...]dan tidak berhasil, jadi saya pikir saya bisa menggunakan array anonim seperti itu, tapi itu hanya karena say.. terima kasih! :)
Dada

10

PHP, 44 36 29 27 byte

Dicoret 44 masih teratur 44; (

Terima kasih untuk menyisipkan nama pengguna di sini, Petah, dan Crypto untuk semua bantuannya

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

Ia memilih angka acak antara 0 dan 675 (= 26 2 -1), mengambil akar kuadratnya, dan menempatkannya ( chrfungsi mengubah argumennya menjadi bilangan bulat). Karena kuadrat memiliki interval yang berbeda di antara mereka, probabilitas setiap nomor yang dipilih berbeda. Setiap n dipilih dengan probabilitas (2n + 1) / 676.

Menambahkan 65 ke nomor ini memberi Anda karakter acak dari Ahingga Z.

Gagasan kode dijalankan 1.000.000 kali


Anda dapat golf off 4 bytes : range(A,Z).
insertusernamehere

@insertusernamehere: Terima kasih atas tipnya, tapi saya bisa bermain golf 8 byte dengan tidak menggunakan rentang sama sekali dan hanya menggunakan chr().
Business Cat

3
Bahkan lebih baik. Sayangnya dicoret 44 masih teratur 44 . :)
insertusernamehere

1
@insertusernamehere Anda terlalu mudah menyerah :-)<s>&nbsp;44&nbsp;</s>
MonkeyZeus

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

8

R, 40 27 byte

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

Ini akan mengambil 1angka dari 26angka-angka yang dihasilkan dengan probabilitas yang semakin besar menuju Z, tanpa mengganti, dan menampilkan huruf yang indeksnya adalah angka ini, dari daftar huruf besar LETTERS.

Argumen samplefungsi adalah:

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

Ya, itu tidak akan berhasil. Mungkin saya cara yang paling pintar!
Frédéric

Yah, akan selalu ada garis di suatu tempat! Harus berpikir tentang itu ...
Frédéric

1
Diperbaiki dan lebih pendek - mengesankan :)
trichoplax

1
@trichoplax Terima kasih! Tantangan bagus btw!
Frédéric

1
@AlbertMasclans: Memang bisa, tetapi sudah dilakukan dalam jawaban orang lain, jadi saya tidak ingin "menyalin"! Tapi Terimakasih ! ;)
Frédéric

8

> <> , 14 byte

lx
;>dd+%'A'+o

> <> adalah bahasa 2D toroidal, dan bagian probabilitas yang berbeda secara alami terjadi karena satu-satunya sumber keacakan dari bahasa tersebut. Cobalah online!

Perintah yang relevan adalah:

[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

Dengan demikian probabilitas output adalah:

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

Python 2, 58 57 byte

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

Penjelasan: ini menghasilkan angka floating point acak dalam interval [0, 676), mengambil akar kuadrat dan kemudian lantai itu. Kemudian ia menambahkan 65 (nilai ascii dari "A"), mengubahnya menjadi char, dan mencetaknya.

Ini memberikan setiap angka dari 0 hingga 25 probabilitas yang berbeda. Untuk memahami mengapa, pikirkan seperti ini. Berapa banyak angka, mengabaikan non-bilangan bulat, ketika Anda mengambil akar kuadrat dan lantai memberi 0? Hanya satu angka yang akan (nol). Ini berarti nol memiliki probabilitas 1/676. Berapa angka yang akan menghasilkan 1? 3 akan, 1, 2, dan 3. Ini berarti seseorang memiliki probabilitas 3/676. Dua dapat diproduksi dengan 4, 5, 6, 7, atau 8, memberikan probabilitas 5, tiga memiliki probabilitas 7, dll. Dan karena perbedaan antara kuadrat berurutan meningkat terus dengan dua, pola ini berlanjut untuk setiap angka ke atas hingga 25 (Z).

1 byte disimpan berkat biarawati bocor!


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

1
Anda bisa melakukannya chr(int(65+random()**.5*26)). Hal yang sama secara aljabar karena 26 == √676. dan sekarang urutan operasi ada di pihak Anda
Wheat Wizard

3
@EamonOlive Untuk byte lain **2*26dapat digunakan untuk distribusi terbalik.
user81655

1
1/random()%26juga harus bekerja.
xnor

1
@ xnor yang kadang-kadang akan memberikan 1/0% 26
trichoplax

5

PowerShell v2 +, 33 31 byte

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

Mengambil rentang dari 65ke 90(yaitu, ASCII Ake Z), menyalurkannya melalui loop. Setiap iterasi, kami menggunakan operator koma untuk membuat larik elemen tersebut dikali angka tersebut. Sebagai contoh, ini akan menghasilkan 65 65s, 66 66s, 67 67s, dll. Array besar itu disalurkan ke Get-Randommana (secara seragam PRNG) akan memilih satu elemen. Karena ada jumlah yang berbeda dari setiap elemen, setiap karakter memiliki peluang persentase yang sedikit berbeda untuk dipilih. Kami kemudian merangkum bahwa dalam parens dan melemparkannya sebagai char. Yang tersisa pada pipa dan output tersirat.

(Terima kasih kepada @LeakyNun untuk bermain golf beberapa byte bahkan sebelum diposting.: D)


Peluangnya

(sedikit pembulatan sehingga saya bisa menunjukkan Popsi dari -foperator 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
Saya mulai tanpa melihat jawaban apa pun; mencoba membangun berdasarkan galkeluaran ( [char[]]"uz$(gal|out-string)"-cmatch'[a-z]'|random) mencapai 50 karakter, kemudian 48, beralih ke angka dan mendapat 42, kemudian 31 dan berhenti di sana; memandang ke papan peringkat untuk melihat di mana itu akan menempatkan saya. Disini. Karakter untuk karakter identik. Nah, saya mungkin tidak bisa mengalahkan itu.
TessellatingHeckler

5

CJam, 21 17 12 byte

Terima kasih kepada Martin Ender karena telah menyelamatkan saya 5 byte!

Versi baru

'\,:,s_el-mR

Ini membentuk sebuah array dari string mengikuti pola A, AB, ABC, dan sebagainya. Ini mendatar dan memilih karakter acak. Karena string ini mengandung 26 A, 25 B, 24 C, dan seterusnya, setiap huruf memiliki kemungkinan berbeda untuk dipilih.

Cobalah online!

Penjelasan

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

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

Mendapat probabilitas berbeda dengan membuat string di mana setiap huruf muncul beberapa kali sama dengan posisinya dalam alfabet.

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 byte

sample(LETTERS,1,,1:26)

Hanya 'sampel' surat dari builtin. yang 1:26merupakan vektor bobot memberikan setiap huruf probabilitas yang berbeda.


1
1:26adalah vektor bobot untuk setiap huruf
user5957401

Itu membuatnya menjadi jawaban yang valid. Perlu diedit dalam penjelasan sehingga orang yang tidak terbiasa dengan R dapat memahami cara kerjanya.
trichoplax

1
Saya akan, dan kemudian saya menyadari bahwa orang di atas saya telah melakukan banyak hal yang sama dalam kode dan memberikan penjelasan yang mendalam.
user5957401

Ada baiknya Anda menambahkan penjelasan - urutan di mana solusi muncul di halaman dapat bervariasi saat suara masuk sehingga yang "di atas" mungkin tidak di atas nanti.
trichoplax

5

C, 35 byte

Program ini mengasumsikan RAND_MAXadalah (2 ^ 32/2) - 1 karena pada gcc secara default. Kompilasi dengan -lmbendera untuk menautkan sqrtfungsi. Output ditulis ke stdout sebagai huruf kapital tanpa tertinggal baris baru.

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

Secara opsional, jika RAND_MAX(2 ^ 16/2) - 1, versi 32 byte yang lebih pendek dapat digunakan:

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

Hanya untuk bersenang-senang, saya juga membuat versi yang tidak menggunakan sqrtfungsi atau memerlukan perpustakaan matematika yang disertakan (yang ini harus memiliki RAND_MAX(2 ^ 32/2) - 1), tetapi akhirnya menjadi lebih lama meskipun saya pikir itu adalah cukup keren:

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

Penjelasan

[Program Pertama]

Untuk dua yang pertama menggunakan sqrt, fungsi hanya peta kisaran [0, RAND_MAX)untuk [0, 25]melalui divisi, dan kemudian menambahkan 65 (ASCII A) untuk nilai bergeser ke dalam alfabet ASCII sebelum keluaran itu.

[Program Kedua]

Program kedua sedikit lebih rumit karena melakukan strategi yang sama, tetapi tanpa sqrtoperator. Karena bit eksponen floating point dihitung secara otomatis setelah menetapkan bilangan bulat, mereka dapat secara efektif digunakan sebagai cara kasar untuk mendapatkan logaritma basis 2 dari angka.

Karena kita hanya ingin rentang hingga RAND_MAXmencapai nilai eksponen yang dikodekan dari 25, perhitungan (2 ^ 32/2 - 1) / (2 ^ 25) memberi kita hanya sekitar 64, yang digunakan selama pembagian randuntuk memetakannya ke rentang baru ini. Saya juga menambahkan 1 ke nilai karena representasi floating point 0 agak aneh dan akan merusak algoritma ini.

Selanjutnya, float diketik dengan tipe integer untuk memungkinkan bithifting dan operasi lainnya. Karena dalam angka floating point IEEE 754 bit eksponen adalah bit 30-23, angka tersebut kemudian bergeser ke kanan 23 bit, memotong mantissa dan membiarkan nilai eksponen mentah dibaca sebagai integer. Perhatikan bahwa bit tanda juga di luar bit eksponen, tetapi karena tidak pernah ada negatif itu tidak harus ditutup.

Daripada menambahkan 65 ke hasil ini seperti yang kami lakukan sebelumnya, eksponen floating point direpresentasikan sebagai integer 8 bit yang tidak ditandatangani dari 0 hingga 255, di mana nilai eksponen 0 adalah 127 (Cukup kurangi 127 untuk mendapatkan nilai eksponen "ditandatangani" yang sebenarnya ). Karena 127 - 65 adalah 62, kami hanya mengurangi 62 untuk menggesernya keluar dari rentang eksponen titik mengambang ini dan ke dalam rentang alfabet ASCII semuanya dalam satu operasi.

Distribusi

Saya bukan ahli matematika jadi saya tidak bisa mengatakan dengan pasti rumus yang tepat untuk distribusi ini, tetapi saya dapat (dan memang) menguji setiap nilai pada rentang [0, RAND_MAX)untuk menunjukkan bahwa jarak antara di mana rentang satu huruf berakhir dan yang lainnya dimulai tidak pernah menjadi sama. (Perhatikan tes ini menganggap (2 ^ 32/2) - 1) maksimum acak)

[Program Pertama]

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

[Program Kedua]

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

Bukankah lebih pendek untuk mengembalikan ordinal daripada mencetaknya? Karena charmerupakan tipe integral dalam C, itu harus dapat diterima.
Mego

@Mego Oh well ya jika Anda bisa melakukannya, saya baru bermain golf jadi saya tidak terlalu terbiasa dengan apa yang dianggap sebagai output yang dapat diterima.
Lemon Drop

4

Python 2, 72 byte

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

Mengalikan karakter dengan nilai ascii-nya, lalu mengambil satu karakter secara acak dari string yang dihasilkan.

Berikut adalah probabilitas untuk setiap huruf yang dipilih, dalam persentase:

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

Cobalah: https://repl.it/Cm0x


4

Jelly , 5 byte

ØAxJX

(Skor yang sama, tetapi metode yang berbeda , untuk solusi Jelly yang ada oleh Dennis.)

Peluang menghasilkan setiap huruf adalah indeks berbasis-1 dalam alfabet dibagi dengan 351 - angka segitiga ke-26:

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

Karena 1 + 2 + ... + 26 = 351, P (huruf) = 1.

Penerapan:

Ø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

Uji di TryItOnline atau dapatkan distribusi 100 ribu berjalan (kode kredit ke Dennis)


Dari mana Anda belajar menjadi jeli di Jelly? Saya merasa sulit untuk percaya bahwa Jelly akan menjadi pengetahuan umum di luar PPCG.
Addison Crump

1
@Syxer Saya baru saja melihat wiki dan dihancurkan - masih belum mengerti semuanya :)
Jonathan Allan

1
Baiklah kalau begitu. Selamat datang di PPCG, pilih suara.
Addison Crump

3

q, 38 byte

Tidak terlalu pendek tapi ...

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

Fungsi distribusi kumulatif diskrit adalah urutannya

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

Dan kami hanya mengambil sampel dari distribusi.


3

JavaScript (ES6), 45 byte

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

Mencapai distribusi tidak seragam dengan mengkuadratkan nilai acak. Math.random()mengembalikan float dari rentang [0,1)sehingga hasil kuadrat ini cenderung ke arah 0(atau a).

Uji


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

3

Oracle SQL 11.2, 212 byte

Menggunakan posisi karakter dalam alfabet sebagai probabilitas

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;

Tidak bermain 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 byte

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

rand menghasilkan nilai seragam dalam (0,1) .Ini memberikan 26 ^ rand probabilitas yang berbeda untuk sama dengan bilangan bulat dari 1 hingga 26.

Versi yang lebih lama, 45 byte

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

Ketepatan terbatas dari bilangan bulat TI-Basic membatasi distribusi normal untuk menghasilkan angka dalam μ ± 7.02σ (lihat randNorm(). Jadi kita mendapatkan nilai absolut dari angka acak dengan μ 0 dan σ 1, dikalikan empat untuk meningkatkan rentang praktis yang disebutkan sebelumnya menjadi μ ± 28.08σ. Kemudian, kami memberi nilai dan menambahkan 1, karena sub(1-diindeks, memberi kami kisaran 1-29 dengan probabilitas masing-masing yang berbeda.


1
@trichoplax Itu adalah kesalahan saya, saya memiliki 30 yang tersisa dari versi lama yaitu [0,29]. Saya memperbaikinya sekarang.
Timtech

Interval (0,1) seharusnya [0,1).
kamoroso94

@ kamoroso94 Sudahkah Anda memeriksa? "Catatan: Karena spesifik dari algoritma penghasil angka acak, jumlah terkecil yang mungkin dihasilkan sedikit lebih besar dari 0. Angka terbesar yang mungkin sebenarnya adalah 1" - dikutip dari tibasicdev.wikidot.com/rand
Timtech

3

PHP, 92 84 byte

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

Buat string dari semua huruf, ulangi berapa kali melalui loop kita, dan kemudian ambil surat dari string itu secara acak. Surat-surat kemudian dalam alfabet memiliki probabilitas yang lebih tinggi sebagai hasilnya

Terima kasih untuk menyisipkan nama pengguna di sini untuk memotong byte

probabilitas hasil (dipesan oleh%)

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,44% T => 5,68%
U => 6.06%
V => 6.13%
W => 6.60%
X => 6.95%
Y => 7.17%
Z => 7.38%


1
diubah untuk benar-benar mematuhi aturan. Kesalahan saya
gabe3886

@insertusernamedi sini saya mendapatkan pemberitahuan variabel yang tidak terdefinisi ketika saya menjalankannya dan tidak ada keluaran surat
gabe3886

Oh maafkan saya. Saya pikir saya terbawa dan dihilangkan $x=0yang jelas diperlukan. Berikut adalah versi 84 byte : for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);Apakah Anda pernah berhasil mendapatkan nilai lebih besar daripada Gsaat menjalankan kode Anda? Lagi pula, Anda selalu dapat mengabaikan noticesaat bermain golf.
insertusernamehere

1
Ya, tapi butuh beberapa saat untuk muncul. Saya menjalankannya melalui sekitar iterasi 100k untuk memeriksa
gabe3886

The strlenof $aadalah 351, tetapi Anda hanya memilih karakter acak dari yang pertama $x(26) karakter. Anda dapat memperbaikinya dan menjaga probabilitas Anda dengan perubahan final $xmenjadi 350+1 byte. Berikut adalah versi 77 byte yang memperbaiki masalah tetapi juga membawa probabilitas lebih dekat:for($i=65;$i<91;$a.=str_repeat(chr($i),$i++));echo substr($a,rand(0,2014),1);
Jo.

3

Befunge, 168 164 byte

Lebih ringkas daripada yang pertama, dengan probabilitas yang sedikit berbeda: Yang pertama ?memiliki peluang 1/4 untuk mencetak nilai A pada "percobaan pertama", peluang 2/4 untuk kembali ke yang sama ?, dan 1/4 untuk pindah ke lanjut. Sisanya ?masing-masing memiliki 1/4 peluang untuk mencetak surat di bawahnya, 1/4 untuk mencoba lagi, 1/4 pindah ke surat berikutnya, 1/4 pindah ke yang sebelumnya. Sekali lagi, probabilitas mencetak huruf A jauh lebih tinggi daripada mencetak huruf Z.

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

Befunge, 186 byte

Jelas tidak akan menang dengan ini, tapi saya pikir ini adalah jawaban yang menarik :)

vdan >mengarahkan kursor masing-masing ke bawah dan ke kanan. The ?Operator mengirimkan kursor off di salah satu dari empat arah secara acak. Yang pertama ?"diblokir" oleh vdan >dalam dua arah, sehingga hanya memiliki dua cara untuk pergi: Baik untuk mencetak A, atau turun ke yang berikutnya ?. Jadi, dari yang pertama ?saja ada kemungkinan 50% untuk mencetak A.

Yang berikutnya ?memiliki peluang 1/3 untuk mencetak B, 1/3 untuk kembali ke atas, dan 1/3 untuk lebih jauh ke bawah. Dll.

Seharusnya cukup jelas bahwa huruf-huruf yang lebih tinggi memiliki peluang lebih besar untuk dicetak daripada huruf-huruf yang lebih rendah, tetapi saya tidak begitu yakin dengan peluang masing-masing huruf.

Beberapa bantuan dengan matematika pasti akan dihargai :)

Setidaknya ada peluang 1/2 * 1/3 ^ 25 bahwa kursor bergerak ke Z pada percobaan pertama, tapi saya tidak yakin bagaimana peluang kursor bergerak ke atas dan ke bawah memengaruhi setiap huruf.

,@ cetakan dan berhenti.

 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 byte

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

ini bekerja dengan membuat string ini:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

alias 65 kali A, 66 kali B, 67 kali ...

dan kemudian memilih karakter acak di dalamnya


Mengapa Anda mulai dari 65?
gcampbell

1
@gcampbell 65 ada Adi ascii. Anda bisa mulai dari 1, tetapi kemudian loop batin menjadi {65..$[#i]}yang 1 char lagi
izabera

2

CJam, 11 byte

4.mrmqC*'A+

atau

676.mrmq'A+

Cobalah online!

Solusi ini mirip dengan ide Luis dan menciptakan distribusi yang tidak seragam dengan mengambil akar kuadrat dari variabel acak.


2

Batch, 116 byte

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

Bekerja dengan memilih yang lebih besar atau lebih kecil (saya lupa yang mana) dari dua variabel acak.


2

Matlab, 22

Akan sering mengembalikan surat awal, tetapi secara teoritis dapat menyentuh semuanya!

Membawa satu yang dibagi dengan angka acak, membatasi ini hingga 26 dan mengubahnya menjadi karakter.

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

Tentu saja tidak terlalu singkat, tetapi mungkin konsepnya dapat menginspirasi jawaban lain.


Apakah randmengembalikan nilai dalam [0, 1)? Yaitu, termasuk nol tetapi tidak termasuk satu. Jika ini sesekali menghasilkan 1/0, apakah min(1/0,26)masih akan mengembalikan 26, atau kesalahan?
trichoplax

Sejauh yang saya tahu randmengembalikan nilai dalam (0,1), jadi seharusnya tidak ada masalah
paul.oderso

1
@trichoplax Meskipun Anda tidak akan melihat randkembali 0 dalam praktek, min(1/0,26)sebenarnya mengembalikan 26.
Dennis Jaheruddin

Dalam hal ini, solusi yang bagus :)
trichoplax

2

CJam, 10 byte

Pendekatan CJam # 3 ...

26mr)mr'A+

Cobalah online!

Ini membuat angka acak seragam xantara 1 dan 26 dan kemudian menggunakannya untuk membuat angka acak seragam antara 0dan x-1yang ditambahkan A. Bias ini menghasilkan karakter yang lebih kecil.


2

Labirin , 19 byte

__v6%_65+.@
" )
"^2

Cobalah online!

Ini adalah loop yang, pada setiap iterasi, baik a) menambah penghitung yang dimulai dari nol atau b) berakhir, keduanya dengan probabilitas 50%. Pada akhir loop, penghitung diambil modulo 26 dan ditambahkan ke 65 untuk memberikan surat antara Adan Z.

Ini memberikan kemungkinan Ahanya sedikit di atas 50%, Bhanya sedikit di atas 25% dan seterusnya hingga Zhanya sedikit di atas 1/2 26 . Secara teori, ada kemungkinan ini berjalan selamanya, tetapi acara ini memiliki probabilitas nol seperti yang dipersyaratkan oleh tantangan (dalam praktiknya itu mungkin tidak mungkin karena PRNG akan mengembalikan kedua hasil yang mungkin di beberapa titik selama periode tersebut).

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.