Random Golf of the Day # 7: un personaggio decisamente casuale


47

Informazioni sulla serie

Questa è una voce ospite per la serie Random Golf of the Day.

Prima di tutto, puoi trattarlo come qualsiasi altra sfida di golf del codice e rispondere senza preoccuparti della serie. Tuttavia, esiste una classifica in tutte le sfide. Puoi trovare la classifica insieme ad alcune ulteriori informazioni sulla serie nel primo post .

Ingresso

Nessun input ricevuto.

Produzione

Una singola lettera dell'alfabeto (caso irrilevante), con una nuova riga finale facoltativa. Ogni lettera deve avere una probabilità diversa da zero di essere scelta e tutte e 26 le probabilità devono essere distinte . Per rimuovere tutte le ambiguità: Distinto significa che non devono esserci due probabilità uguali tra loro.

punteggio

Questo è il codice golf. Vince il codice più breve in byte.

Una voce valida è un programma o una funzione completa che ha zero probabilità di non terminare.

Alfabeto

Per evitare confusione, l'alfabeto particolare da usare è l'alfabeto latino:

O

ABCDEFGHIJKLMNOPQRSTUVWXYZ

o

abcdefghijklmnopqrstuvwxyz

È possibile scegliere di visualizzare maiuscole o minuscole. In alternativa, è possibile scegliere di generare diversi casi su diverse esecuzioni se ciò aiuta. La probabilità per una data lettera è la probabilità che quella lettera compaia in entrambi i casi (superiore o inferiore).

Spiegazione

Poiché non sarà affatto ovvio dall'output, includi una chiara spiegazione di come hai raggiunto le 26 distinte probabilità.

Classifica

(da qui )

Il primo post della serie genera anche una classifica generale.

Per assicurarti che le tue risposte vengano visualizzate, inizia ogni risposta con un titolo, utilizzando il seguente modello Markdown:

## Language Name, N bytes

dov'è Nla dimensione del tuo invio. Se si migliora il punteggio, è possibile mantenere i vecchi punteggi nel titolo, colpendoli. Per esempio:

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

(La lingua non è attualmente mostrata, ma lo snippet richiede e analizza, e potrei aggiungere una classifica per lingua in futuro.)


come misureresti 26 probabilità distinte? eseguendo il programma 26 volte?
TU

1
@YOU dai un'occhiata alle soluzioni - ci sono alcuni approcci diversi con spiegazioni eccellenti
trichoplax

Se è una funzione deve stampare o può semplicemente restituire il valore del carattere?
Geoff Reedy,

@Geoff Secondo le nostre impostazioni predefinite per input e output , sia la stampa su STDOUT sia la restituzione di un carattere vanno bene.
trichoplax,

@Geoff nota che deve essere un personaggio, non solo un valore numerico che lo rappresenta. Ad esempio, Apiuttosto che 65.
trichoplax,

Risposte:


13

Pyth, 5

Os._G

Provalo qui

Calcola i prefissi dell'alfabeto, così: ["a", "ab", "abc", ..., "abcdefghijklmnopqrstuvwxyz"]. Quindi appiattisce l'elenco e seleziona un elemento casuale da esso uniformemente. Ciò significa che poiché aappare 26 volte, mentre bappare 25 volte, fino a un zsolo aspetto, ogni lettera ha una diversa possibilità di apparire. La stringa totale ha 351 caratteri.


1
Mi piace quella risposta. Molto intelligente.
Allen Fisher,

24

MATL, 6 personaggi

1Y2Xr)

Spiegazione:

XrPrendi un numero casuale normalmente distribuito )Usa questo per indicizzare in ... 1Y2L'alfabeto

La distribuzione è simmetrica intorno a 0 e la traduzione del numero in carattere è simmetrica intorno a 0,5. Pertanto le probabilità dovrebbero essere distinte.


2
Oh, ottima idea di usare una distribuzione gaussiana!
Luis Mendo,

1
linguaggio "migliore" per il lavoro, ancora battuto dalla gelatina. Ottima soluzione però.
Socratic Phoenix,

19

05AB1E , 6 byte

Codice

A.pJ.R

Spiegazione

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

Ora abbiamo la seguente stringa:

aababcabcdabcdeabcdefabcdefgabcdefghabcdefghiabcdefghijabcdefghijkabcdefghijklabcdefghijklmabcdefghijklmnabcdefghijklmnoabcdefghijklmnopabcdefghijklmnopqabcdefghijklmnopqrabcdefghijklmnopqrsabcdefghijklmnopqrstabcdefghijklmnopqrstuabcdefghijklmnopqrstuvabcdefghijklmnopqrstuvwabcdefghijklmnopqrstuvwxabcdefghijklmnopqrstuvwxyabcdefghijklmnopqrstuvwxyz

Successivamente, scegliamo un elemento casuale usando .R.

Le probabilità

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%

Provalo online! .


18

Gelatina , 5 byte

ØA»ẊX

Provalo online!

Come funziona

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

sfondo

Let L 0 , ..., L 25 denota le lettere dell'alfabeto nel loro ordine naturale, e S 0 , ..., S 25 un uniformemente a caso permutazione selezionata di L . Definire la sequenza finita M per M n = max (L n , S n ) .

Correggi n in 0,… 25 e definisci k come indice in modo tale che L n = S k .

Con probabilità 1/26 , L n = S n ed n = k , così M n = L n e L n occurrs volta in M .

Con probabilità 25/26 , L n ≠ S n e n ≠ k . In questo caso, si verifica quanto segue.

  • Con probabilità n / 25 , S n è uno di L 0 ,…, L n - 1 , quindi L n > S n e M n = L n .

  • Indipendentemente, anche con probabilità n / 25 , k è uno di 0,… n - 1 , quindi S k > L k e M k = S k = L n .

Pertanto, il numero previsto di occorrenze di L n in M è 1/26 + 25/26 · (n / 25 + n / 25) = (2n + 1) / 26 .

Infine, se ora selezioniamo un termine m di M uniformemente a caso, la lettera L n verremo scelti con probabilità (2n + 1) / 26/26 = (2n + 1) / 676 .

Ciò produce la seguente distribuzione di probabilità.

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

Puoi verificare empiricamente la distribuzione chiamando il link 100.000 volte (richiede alcuni secondi).


1
@RobertFraser il passaggio shuffle-and-yield produce un elenco con una A in qualsiasi punto una A è apparso in uno dei due elenchi, una B in cui è apparso un B in uno dei due elenchi e qualcosa di diverso da A nell'altro elenco, ... una Z in qualsiasi punto di Z è apparso in entrambe le liste. quindi nel risultato ci sono circa 52 volte più A che Z.
Sparr,

1
@RobertFraser Ho aggiunto una spiegazione.
Dennis,

2
@DennisJaheruddin In UTF-8, sì. Tuttavia, Jelly utilizza una codepage personalizzata che codifica tutti i caratteri che comprende come un singolo byte ciascuno. Il collegamento byte nell'intestazione punta ad esso.
Dennis,

2
Vedo, quando ho letto la spiegazione non è stato subito chiaro che non è possibile sfruttare anche la normale gamma UTF-8. Quindi, ho ragione a supporre che cambiando l'interprete e mappando tutti i caratteri su singoli caratteri UTF-8 avresti un codice completamente identico (solo meno leggibile / tipizzabile)? - In tal caso, considera di espandere la spiegazione per menzionare che un carattere deve essere conteggiato per un byte a fini di golf.
Dennis Jaheruddin,

2
@DennisJaheruddin Come spiegato nel README (primo link nell'intestazione), l'interprete ha due modalità (Jelly code page e UTF-8), quindi puoi salvare questo programma in un vero file a 5 byte. Potrei aggiungere tutte queste informazioni ad ogni risposta che scrivo, ma ce ne sono centinaia, quindi ho scelto invece il collegamento.
Dennis,

14

MATL , 10 byte

1Y2rU26*k)

Provalo online!

Il codice genera una variabile casuale uniforme sull'intervallo (0,1) ( r) e calcola il suo quadrato ( U). Ciò si traduce in una densità di probabilità decrescente non uniforme. Moltiplicando per 26 ( 26*) si assicura che il risultato sia sull'intervallo (0,26) e arrotondando per difetto ( k) si ottengono i valori 0,1, ..., 25 con probabilità decrescenti. Il valore viene utilizzato come indice ( )) nell'alfabeto maiuscolo ( 1Y2). Poiché MATL utilizza l'indicizzazione modulare basata su 1, 0 corrisponde a Z, 1 a A, 2 a B ecc.

A dimostrazione del fatto che le probabilità sono distinte, ecco un istogramma discreto derivante da 1000000 realizzazioni casuali. Il grafico viene prodotto eseguendo questo in Matlab:

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

inserisci qui la descrizione dell'immagine


1
Bello! La migliore soluzione che potrei trovare è di 16 byte
DJMcMayhem

1
@DJMcMayhem Bel approccio!
Luis Mendo,

Forse, ma molto di più. : P
DJMcMayhem

Un'altra alternativa divertente: matl.suever.net/…
Suever

In realtà non hai bisogno del k! Ho
Dennis Jaheruddin,

13

Java 7, 62 57 56 byte

5 byte grazie a Poke.

1 byte grazie a trichoplax.

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

Ideone esso!

Diagramma di frequenza (1e6 corse, fattore di scala 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
Non penso che sia necessario digitare in int
Poke

@Poke Grazie, golf.
Leaky Nun,

Puoi salvare un byte spostando il 676 fuori dalle parentesi?
trichoplax,

@trichoplax Che vuoi dire?
Leaky Nun,

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

10

Perl, 24 byte

-4 byte grazie a @Martin Ender
-1 byte grazie a @Dom Hastings

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

Necessità -M5.010o -Eesecuzione:

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

L'esecuzione del codice seguente mostrerà l'occorrenza di ogni lettera:

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


Come funziona : immagino che il codice sia piuttosto esplicito, ma comunque: sceglie un numero casuale tra 0e rand 26. Quindi c'è una probabilità molto più alta che vengano scelti i numeri vicini a 0(lettera A).


La spiegazione ha senso per me :)
trichoplax,

Bella soluzione! Puoi salvare 1 byte usando un elenco vuoto e +:say+(A..Z)[rand rand 26]
Dom Hastings

@DomHastings aarf, sono stupido. Ho provato (A..Z)[...]e non ha funzionato, quindi ho pensato di poter usare un array anonimo come quello, ma era solo per il say.. grazie! :)
Dada,

10

PHP, 44 36 29 27 byte

Cancellato 44 è ancora regolare 44; (

Grazie a insertusernamehere, Petah e Crypto per tutto l'aiuto

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

Sceglie un numero casuale tra 0 e 675 (= 26 2 -1), prende la sua radice quadrata e lo pavimenta (la chrfunzione converte il suo argomento in un numero intero). Poiché i quadrati hanno intervalli diversi tra loro, la probabilità di ciascun numero scelto è distinta. Ogni n è scelto con probabilità (2n + 1) / 676.

L'aggiunta di 65 a questo numero ti dà un carattere casuale da Aa Z.

Ideone del codice in esecuzione 1.000.000 di volte


Si può golf fuori 4 byte : range(A,Z).
inserire nomeutentequi

@inserireusernamehere: grazie per il suggerimento, ma sono stato in grado di giocare a golf a 8 byte non usando affatto il range e solo usando chr().
Business Cat


1
@inserireusernamehere Ti arrendi troppo facilmente :-)<s>&nbsp;44&nbsp;</s>
MonkeyZeus

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

8

R, 40 27 byte

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

Questo prenderà il 1numero dai 26numeri generati con crescente probabilità verso Z, senza sostituire, e visualizzerà una lettera il cui indice è questo numero, dall'elenco delle lettere maiuscole LETTERS.

Gli argomenti della samplefunzione sono:

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

Sì ", non funzionerà. Ci potrebbe essere un modo più intelligente!
Frédéric,

Bene, ci sarà sempre un rivestimento da qualche parte! Devo pensarci ...
Frédéric,

1
Risolto e più corto - impressionante :)
trichoplax

1
@trichoplax Grazie! Bella sfida tra l'altro!
Frédéric,

1
@AlbertMasclans: Può davvero, ma è già stato fatto nella risposta di qualcun altro, quindi non voglio "copiare"! Ma grazie comunque ! ;)
Frédéric,

8

> <> , 14 byte

lx
;>dd+%'A'+o

> <> è un linguaggio 2D toroidale e la parte delle probabilità distinte si verifica in modo naturale a causa dell'unica fonte di casualità del linguaggio. Provalo online!

I comandi rilevanti sono:

[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

Pertanto le probabilità di uscita sono:

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

Spiegazione: questo genera un numero in virgola mobile casuale nell'intervallo [0, 676), prende la radice quadrata e quindi la pavimenta. Quindi aggiunge 65 (il valore ASCII di "A"), lo converte in un carattere e lo stampa.

Questo dà ad ogni numero da 0 a 25 una probabilità distinta. Per capire il perché, pensaci in questo modo. Quanti numeri, ignorando i non numeri interi, quando prendi la radice quadrata e il floor danno 0? Sarà solo un numero (zero). Ciò significa che zero ha una probabilità di 1/676. Quanti numeri produrrà 1? 3 will, 1, 2 e 3. Ciò significa che si ha una probabilità di 3/676. Un due può essere prodotto con un 4, 5, 6, 7 o 8, dandogli probabilità 5, un tre ha probabilità 7, ecc. E poiché la differenza tra i quadrati consecutivi aumenta costantemente di due, questo schema continua per ogni numero in su a 25 (Z).

1 byte salvato grazie alla suora che perde!


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

1
Si potrebbe fare chr(int(65+random()**.5*26)). È la stessa cosa algebricamente perché 26 == √676. e ora l'ordine delle operazioni è dalla tua parte
Mago del grano

3
@EamonOlive Per un altro byte **2*26potrebbe essere utilizzato per la distribuzione inversa.
user81655

1
1/random()%26dovrebbe anche funzionare.
xnor

1
@xnor che a volte darà 1/0% 26
trichoplax

5

PowerShell v2 +, 33 31 byte

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

Prende un intervallo da 65a 90(cioè, ASCII Aa Z), lo convoglia attraverso un ciclo. Ogni iterazione, usiamo l'operatore virgola per creare una matrice di quell'elemento per quel numero. Ad esempio, ciò comporterà 65 65s, 66 66s, 67 67s, ecc. Quel grande array viene convogliato al Get-Randomquale (uniformemente PRNG) selezionerà un elemento. Poiché ci sono diverse quantità di ciascun elemento, ogni personaggio ha una probabilità percentuale leggermente distinta di essere scelto. Quindi incapsuliamo quello in parentesi e lo lanciamo come a char. Rimane in cantiere e l'output è implicito.

(Grazie a @LeakyNun per aver giocato a golf pochi byte anche prima che fosse pubblicato.: D)


Le probabilità

(leggero arrotondamento in modo da poter dimostrare l' Popzione -fdell'operatore 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
Ho iniziato senza guardare nessuna delle risposte; ha provato a costruire su galoutput ( [char[]]"uz$(gal|out-string)"-cmatch'[a-z]'|random) ha ottenuto 50 caratteri, quindi 48, è passato a numeri e ha ottenuto 42, quindi 31 e si è fermato lì; guardò la classifica per vedere dove mi avrebbe messo. Giusto qui. Carattere per carattere identico. Welp, probabilmente non posso batterlo.
TessellatingHeckler,

5

CJam, 21 17 12 byte

Grazie a Martin Ender per avermi salvato 5 byte!

Nuova versione

'\,:,s_el-mR

Questo forma una matrice di stringhe seguendo il modello A, AB, ABC, e così via. Lo appiattisce e sceglie un personaggio casuale. Poiché questa stringa contiene 26 A, 25 B, 24 C e così via, ogni lettera ha una netta probabilità di essere scelta.

Provalo online!

Spiegazione

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

Vecchia versione

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

Ottiene probabilità distinte creando una stringa in cui ogni lettera appare un numero di volte uguale alla sua posizione nell'alfabeto.

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

5

R, 23 byte

sample(LETTERS,1,,1:26)

Basta "campionare" una lettera da un builtin. il 1:26è un vettore di pesi che danno ogni lettera una probabilità diversa.


1
1:26è un vettore di pesi per ogni lettera
user5957401

Questo lo rende una risposta valida. Vale la pena modificarlo in una spiegazione in modo che le persone che non hanno familiarità con R possano capire come funziona.
trichoplax,

1
Stavo per farlo, e poi mi sono reso conto che il ragazzo sopra di me aveva fatto più o meno la stessa cosa nel suo codice e aveva dato un approfondimento esplicativo.
user5957401

È positivo che tu abbia aggiunto una spiegazione: l'ordine in cui le soluzioni vengono visualizzate nella pagina può variare in base al voto, quindi quelli "sopra" potrebbero non essere sopra in seguito.
trichoplax,

5

C, 35 byte

Questo programma presuppone che RAND_MAXsia (2 ^ 32/2) - 1 come è su gcc di default. Compilare con il -lmflag per collegare la sqrtfunzione. L'output viene scritto su stdout come maiuscolo senza trascinare le nuove righe.

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

Facoltativamente, se RAND_MAXè (2 ^ 16/2) - 1, è possibile utilizzare una versione di 32 byte più corta:

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

Solo per divertimento, ho anche realizzato una versione che non utilizza la sqrtfunzione o richiede la libreria matematica inclusa (questa deve avere RAND_MAXcome (2 ^ 32/2) - 1), ma alla fine è stata più lunga anche se pensavo fosse piuttosto interessante:

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

Spiegazione

[Primo programma]

Per i primi due usi sqrt, la funzione mappa semplicemente l'intervallo [0, RAND_MAX)sulla [0, 25]divisione passante, quindi aggiunge 65 (ASCII A) al valore per spostarlo nell'alfabeto ASCII prima di emetterlo.

[Secondo programma]

Il secondo programma è un po 'più complesso in quanto fa una strategia simile, ma senza l' sqrtoperatore. Poiché i bit esponenti di un punto mobile vengono calcolati automaticamente al momento dell'assegnazione di un numero intero, possono essere effettivamente utilizzati come un modo grezzo per ottenere il logaritmo di base 2 di un numero.

Poiché vogliamo solo che l'intervallo fino a RAND_MAXraggiungere un valore esponente codificato di 25, il calcolo (2 ^ 32/2 - 1) / (2 ^ 25) ci fornisce solo circa 64, che viene utilizzato durante la divisione di randper mapparlo a questa nuova gamma. Ho anche aggiunto 1 al valore poiché la rappresentazione in virgola mobile di 0 è piuttosto strana e romperebbe questo algoritmo.

Successivamente, il float viene punzonato con un tipo intero per consentire lo spostamento dei bit e altre operazioni simili. Poiché in IEEE 754 numeri in virgola mobile i bit dell'esponente sono i bit 30-23, il numero viene quindi spostato a destra di 23 bit, tagliando la mantissa e consentendo di leggere il valore dell'esponente grezzo come intero. Si noti che anche il bit di segno è oltre i bit di esponente, ma poiché non ci sono mai negativi, non è necessario mascherarlo.

Invece di aggiungere 65 a questo risultato come abbiamo fatto prima, tuttavia, gli esponenti in virgola mobile sono rappresentati come un numero intero a 8 bit senza segno da 0 a 255, dove il valore esponente di 0 è 127 (Sottrai semplicemente 127 per ottenere il valore esponente effettivo "firmato" ). Poiché 127 - 65 è 62, invece sottraggiamo semplicemente 62 per spostarlo da questo intervallo di esponente in virgola mobile e nell'intervallo di alfabeto ASCII in un'unica operazione.

Distribuzione

Non sono un esperto di matematica, quindi non posso dire con certezza la formula esatta per queste distribuzioni, ma posso (e ho fatto) testare ogni valore dell'intervallo [0, RAND_MAX)per mostrare che la distanza tra dove finisce l'intervallo di una lettera e l'inizio dell'altra non è mai la stesso. (Nota che questi test assumono il (2 ^ 32/2) - 1) massimo casuale)

[Primo programma]

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

[Secondo programma]

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

Non sarebbe più breve restituire l'ordinale che stamparlo? Poiché charè un tipo integrale in C, dovrebbe essere accettabile.
Mego

@Mego Oh, sì, se riesci a farlo, sono solo un principiante del golf, quindi non ho troppa familiarità con ciò che è considerato un risultato accettabile.
Lemon Drop

4

Python 2, 72 byte

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

Moltiplica il carattere per il suo valore ASCII, quindi seleziona un carattere a caso dalla stringa risultante.

Ecco le probabilità per ogni lettera selezionata, in percentuale:

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

Provalo: https://repl.it/Cm0x


4

Gelatina , 5 byte

ØAxJX

(Pari punteggio, ma un metodo diverso , rispetto a una soluzione Jelly esistente di Dennis.)

La probabilità di dare ciascuna lettera è il suo indice in base a 1 nell'alfabeto diviso per 351 - il 26 ° numero triangolare:

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

Dal 1 + 2 + ... + 26 = 351, P (lettera) = 1.

Implementazione:

Ø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

Provalo su TryItOnline o ottieni la distribuzione di 100K run (accredita il codice a Dennis)


Dove hai imparato ad essere così bravo con Jelly? Trovo difficile credere che Jelly sarebbe una conoscenza comune al di fuori di PPCG.
Addison Crump

1
@Syxer Ho appena guardato il wiki e mi sono scagliato via - ancora non capisco tutto :)
Jonathan Allan

1
Bene allora. Benvenuto in PPCG, vota per favore.
Addison Crump

3

q, 38 byte

Non particolarmente breve ma ...

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

La funzione di distribuzione cumulativa discreta è la sequenza

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

E ci limitiamo a campionare dalla distribuzione.


3

JavaScript (ES6), 45 byte

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

Raggiunge una distribuzione non uniforme quadrando il valore casuale. Math.random()restituisce un float dell'intervallo [0,1)quindi il risultato della quadratura tende verso 0(o a).

Test


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

3

Oracle SQL 11.2, 212 byte

Usando la posizione del personaggio nell'alfabeto come 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;

Un-golfed

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 genera un valore uniforme in (0,1]. Ciò dà a 26 ^ una probabilità diversa di eguagliare gli interi da 1 a 26.

Versione precedente, 45 byte

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

La precisione limitata degli interi TI-Basic limita le distribuzioni normali alla generazione di numeri entro µ ± 7.02σ (vedi randNorm(). Quindi otteniamo il valore assoluto di un numero casuale con µ 0 e σ 1, moltiplicando per quattro per aumentare l'intervallo pratico menzionato prima a µ ± 28.08σ. Quindi, calcoliamo il valore e aggiungiamo 1, poiché sub(è 1-indicizzato, dandoci un intervallo da 1-29 con diverse probabilità di ciascuno.


1
@trichoplax Questo è stato il mio errore, ne avevo rimasti 30 dalla versione precedente che era [0,29]. L'ho risolto ora.
Timtech,

L'intervallo (0,1] dovrebbe essere [0,1).
kamoroso94

@ kamoroso94 Hai controllato? "Nota: a causa delle specifiche dell'algoritmo di generazione di numeri casuali, il numero più piccolo possibile da generare è leggermente maggiore di 0. Il numero più grande possibile è in realtà 1" - citato da 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);

Crea una stringa di tutte le lettere, ha ripetuto il numero di volte attraverso il ciclo che siamo e quindi sceglie una lettera da quella stringa in modo casuale. Di conseguenza, le lettere più avanti nell'alfabeto hanno una probabilità maggiore

Grazie a insertusernamehere per la rasatura dei byte

probabilità di risultato (ordinate per%)

A => 0,29%
B => 0,62%
C => 0,82%
D => 1,15%
E => 1,50%
F => 1,65%
G => 2,00%
H => 2,27%
I => 2,52%
J => 2,80%
K => 3,13%
L => 3,47%
M => 3,72%
N => 3,93%
O => 4,15%
P => 4,59%
Q => 4,81%
R => 5,17%
S => 5,44%
T => 5,68%
U => 6,06%
V => 6,13%
W => 6,60%
X => 6,95%
Y => 7,17%
Z => 7,38%


1
modificato per aderire effettivamente alle regole. Il mio errore
gabe3886,

@inserireusernamehere ricevo avvisi variabili non definiti quando eseguo questo e nessuna emissione di lettere
gabe3886

Oh mi dispiace. Penso di essere stato portato via e rimosso, il $x=0che è ovviamente necessario. Ecco una versione di 84 byte : for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);sei mai riuscito a ottenere un valore maggiore di Gquando hai eseguito il tuo codice? Ad ogni modo, puoi sempre ignorare notices quando giochi a golf.
insertusernamehere

1
L'ho fatto, ma ci vuole un po 'per spuntare. Ho controllato circa
100.000

Il strlenof $aè 351, ma stai scegliendo solo un personaggio casuale tra i primi $x(26) caratteri. Puoi risolverlo e mantenere le tue probabilità con una modifica del finale $xa 350per +1 byte. Ecco una versione da 77 byte che risolve il problema ma avvicina anche molto le probabilità:for($i=65;$i<91;$a.=str_repeat(chr($i),$i++));echo substr($a,rand(0,2014),1);
Jo.

3

Befunge, 168 164 byte

Più compatto del primo, con probabilità un po 'diverse: i primi ?hanno 1/4 di possibilità di stampare una A al "primo tentativo", 2/4 di probabilità di tornare allo stesso ?e 1/4 di passaggio al Il prossimo. Il resto della ?s ha ciascuna 1/4 possibilità di stampare la lettera sottostante, 1/4 per riprovare, 1/4 per passare alla lettera successiva, 1/4 per passare alla precedente. Ancora una volta, la probabilità di stampare una A è molto più alta rispetto alla stampa di una Z.

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

Befunge, 186 byte

Ovviamente non vincerò con questo, ma penso che sia comunque una risposta interessante :)

ve >dirige il cursore rispettivamente verso il basso e verso destra. L' ?operatore invia il cursore in una delle quattro direzioni in modo casuale. Il primo ?è "bloccato" da ve >in due direzioni, quindi ha solo due strade da percorrere: o stampare la A, o giù alla successiva ?. Quindi dal primo ?solo c'è una probabilità del 50% di stampare una A.

Il prossimo ?ha una probabilità 1/3 di stampare una B, 1/3 di risalire e 1/3 di scendere ulteriormente. Ecc. Ecc.

Dovrebbe essere abbastanza ovvio che le lettere più alte hanno una probabilità molto più grande di essere stampate rispetto a quelle inferiori, ma non sono esattamente sicuro di quali siano le possibilità di ciascuna lettera.

Qualche aiuto con l'esatta matematica sarebbe apprezzato :)

Almeno c'è una possibilità 1/2 * 1/3 ^ 25 che il cursore si sposti completamente verso il basso sulla Z al primo tentativo, ma non sono sicuro di come le probabilità che il cursore si muova su e giù influenzino ogni lettera.

,@ stampa e termina.

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

2

J, 20 18 byte

(? {~ @ #) U: 64 + # ~ 1 + I.26
(? {~ @ #) U: 64 + # ~ I.27

Interprete online

Maiuscolo.

La probabilità di ogni lettera è il suo indice basato su 1 nell'alfabeto.


2

zsh, 63 byte

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

funziona creando questa stringa:

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

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

e quindi sceglie un personaggio casuale in esso


Perché hai iniziato a 65 anni?
gcampbell,

1
@gcampbell 65 è Ain ascii. puoi iniziare da 1, ma poi il ciclo interno diventa {65..$[#i]}che è più lungo di 1 carattere
izabera

2

CJam, 11 byte

4.mrmqC*'A+

o

676.mrmq'A+

Provalo online!

Questa soluzione è simile all'idea di Luis e crea una distribuzione non uniforme prendendo la radice quadrata della variabile casuale.


2

Lotto, 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%%

Funziona selezionando la più grande o più piccola (dimentico quale) di due variabili casuali.


2

Matlab, 22

Restituirà spesso lettere iniziali, ma in teoria può toccarle tutte!

Prende uno diviso per un numero casuale, lo limita a 26 e lo trasforma in un personaggio.

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

Naturalmente non molto breve, ma forse il concetto può ispirare altre risposte.


Non randrestituire un valore in [0, 1)? Cioè, incluso zero ma non incluso uno. Se ciò si traduce occasionalmente in 1/0, min(1/0,26)restituirà comunque 26 o un errore?
trichoplax,

Per quanto ne so randrestituisce un valore in (0,1), quindi non dovrebbe esserci un problema
paul.oderso

1
@trichoplax Anche se randin pratica non vedrai il ritorno 0, in min(1/0,26)realtà restituisce 26.
Dennis Jaheruddin

In tal caso, bella soluzione :)
trichoplax,

2

CJam, 10 byte

Approccio n. 3 di CJam ...

26mr)mr'A+

Provalo online!

Questo crea un numero uniformemente casuale xtra 1 e 26 e quindi lo utilizza per creare un numero uniformemente casuale tra 0e al x-1quale viene aggiunto A. Questo distorce i risultati verso personaggi più piccoli.


2

Labirinto , 19 byte

__v6%_65+.@
" )
"^2

Provalo online!

Questo è un ciclo che, ad ogni iterazione, a) incrementa un contatore che inizia da zero o b) termina, entrambi con probabilità 50%. Alla fine del ciclo, il contatore viene preso modulo 26 e aggiunto a 65 per dare una lettera tra Ae Z.

Questo dà una probabilità di Apoco più del 50%, Bpoco più del 25% e così via fino a Zpoco più di 1/2 26 . In teoria, esiste la possibilità che questo si svolga per sempre, ma questo evento ha probabilità zero come richiesto dalla sfida (in pratica ciò non è probabilmente possibile perché il PRNG restituirà entrambi i risultati possibili ad un certo punto nel suo periodo).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.