Sobre a série
Esta é uma entrada para convidados da série Random Golf of the Day.
Primeiro, você pode tratar isso como qualquer outro desafio de código de golfe e respondê-lo sem se preocupar com a série. No entanto, existe uma tabela de classificação em todos os desafios. Você pode encontrar a tabela de classificação junto com mais informações sobre a série no primeiro post .
Entrada
Nenhuma entrada é recebida.
Resultado
Uma única letra do alfabeto (maiúsculas e minúsculas irrelevantes), com uma nova linha à direita opcional. Cada letra deve ter uma probabilidade diferente de zero de ser escolhida e todas as 26 probabilidades devem ser distintas . Para remover toda a ambiguidade: Distinto significa que não deve haver duas probabilidades iguais entre si.
Pontuação
Isso é código de golfe. O menor código em bytes vence.
Uma entrada válida é um programa ou função completo que tem probabilidade zero de não terminar.
Alfabeto
Para evitar confusão, o alfabeto específico a ser usado é o alfabeto latino:
Ou
ABCDEFGHIJKLMNOPQRSTUVWXYZ
ou
abcdefghijklmnopqrstuvwxyz
Você pode optar por imprimir maiúsculas ou minúsculas. Como alternativa, você pode optar por gerar casos diferentes em execuções diferentes, se isso ajudar. A probabilidade de uma determinada letra é a probabilidade dessa letra aparecer nos dois casos (superior ou inferior).
Explicação
Como não será nada óbvio a partir da saída, inclua uma explicação clara de como você alcançou as 26 probabilidades distintas.
Entre os melhores
( daqui )
O primeiro post da série também gera uma classificação geral.
Para garantir que suas respostas sejam exibidas, inicie todas as respostas com um título, usando o seguinte modelo de remarcação:
## Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
## Ruby, <s>104</s> <s>101</s> 96 bytes
(O idioma não é exibido no momento, mas o snippet exige e o analisa, e posso adicionar um cabeçalho por idioma no futuro.)
A
ao invés de65
.Respostas:
Pitão, 5
Experimente aqui
Calcula os prefixos do alfabeto, assim:
["a", "ab", "abc", ..., "abcdefghijklmnopqrstuvwxyz"]
. Em seguida, nivela a lista e seleciona um elemento aleatório dela uniformemente. Isso significa que, uma vez quea
aparece 26 vezes, enquantob
aparece 25 vezes, atéz
apenas com uma aparência, cada letra tem uma chance diferente de aparecer. A cadeia total possui 351 caracteres.fonte
MATL, 6 caracteres
Explicação:
Xr
Pegue um número aleatório distribuído normalmente)
Use-o para indexar em ...1Y2
O alfabetoA distribuição é simétrica em torno de 0 e a conversão de número em char é simétrica em torno de 0,5. Como tal, as probabilidades devem ser distintas.
fonte
05AB1E , 6 bytes
Código
Explicação
Agora temos a seguinte string:
Depois disso, escolhemos um elemento aleatório usando
.R
.As probabilidades
Experimente online! .
fonte
Gelatina , 5 bytes
Experimente online!
Como funciona
fundo
Vamos L 0 , ..., L 25 denota as letras do alfabeto em sua ordem natural, e S 0 , ..., S 25 a uniformemente em permutação selecionado aleatória de L . Defina a sequência finita M por M n = max (L n , S n ) .
Fixe n em 0,… 25 e defina k como o índice tal que L n = S k .
Com probabilidade 1/26 , G n = S n e n = k , então M n = L n e L n occurrs uma vez em H .
Com probabilidade 25/26 , L n ≠ S n e n ≠ k . Nesse caso, acontece o seguinte.
Com probabilidade n / 25 , S n é um de L 0 ,…, L n - 1 , então L n > S n e M n = L n .
Independentemente, também com probabilidade n / 25 , k é um de 0,… n - 1 , então S k > L k e M k = S k = L n .
Assim, o número esperado de ocorrências de L n em M é 1/26 + 25/26 · (n / 25 + n / 25) = (2n + 1) / 26 .
Finalmente, se agora selecionarmos um termo m de M uniformemente aleatoriamente, a letra L n será escolhida com probabilidade (2n + 1) / 26/26 = (2n + 1) / 676 .
Isso produz a seguinte distribuição de probabilidades.
Você pode verificar empiricamente a distribuição chamando o link 100.000 vezes (leva alguns segundos).
fonte
MATL , 10 bytes
Experimente online!
O código gera uma variável aleatória uniforme no intervalo (0,1) (
r
) e calcula seu quadrado (U
). Isso resulta em uma densidade de probabilidade decrescente não uniforme. Multiplicar por 26 (26*
) garante que o resultado esteja no intervalo (0,26) e arredondar para baixo (k
) produz os valores 0,1, ..., 25 com probabilidades decrescentes. O valor é usado como um índice ()
) no alfabeto maiúsculo (1Y2
). Como o MATL usa indexação modular baseada em 1, 0 corresponde a Z, 1 a A, 2 a B etc.Como uma ilustração de que as probabilidades são distintas, aqui está um histograma discreto resultante de 1000000 realizações aleatórias. O gráfico é produzido executando isso no Matlab:
fonte
k
! Notei que enquanto tentava codegolf.stackexchange.com/a/89648/11159 #Java 7,
625756 bytes5 bytes graças ao puxão.
1 byte graças ao trichoplax.
Ideone it!
Diagrama de frequência (1e6 é executado, fator de escala 1/1000)
fonte
sqrt(x*y*y) = sqrt(x)*y
Perl, 24 bytes
-4 bytes graças a @Martin Ender
-1 byte graças a @Dom Hastings
Precisa
-M5.010
ou-E
é executado:A execução do código a seguir mostrará a ocorrência de cada letra:
Como funciona : Eu acho que o código é bastante explícito, mas ainda assim: ele escolhe um número aleatório entre
0
erand 26
. Portanto, há uma probabilidade muito maior de que números próximos a0
(letraA
) sejam escolhidos.fonte
say+(A..Z)[rand rand 26]
(A..Z)[...]
e não funcionou, então pensei que poderia usar uma matriz anônima como essa, mas isso foi apenas por causa dosay
.. obrigado! :)PHP,
44362927 bytesO riscado 44 ainda é regular 44;
Obrigado a insertusernamehere, Petah e Crypto por toda a ajuda
Ele escolhe um número aleatório entre 0 e 675 (= 26 2 -1), pega sua raiz quadrada e a pavimenta (a
chr
função converte seu argumento em um número inteiro). Como os quadrados têm intervalos diferentes entre eles, a probabilidade de cada número escolhido é distinta. Todo n é escolhido com probabilidade (2n + 1) / 676.Adicionar 65 a este número fornece um caractere aleatório de
A
aZ
.Ideone do código executando 1.000.000 de vezes
fonte
range(A,Z)
.chr()
.<s> 44 </s>
<?=chr(65+sqrt(rand(0,675)));
R,
4027 bytesIsso levará o
1
número dos26
números gerados com crescente probabilidade paraZ
, sem substituir, e exibirá uma letra cujo índice é esse número, na lista de letras maiúsculasLETTERS
.Os argumentos da
sample
função são:fonte
> <> , 14 bytes
> <> é uma linguagem 2D toroidal, e a parte de probabilidades distintas acontece naturalmente devido à única fonte de aleatoriedade da linguagem. Experimente online!
Os comandos relevantes são:
Assim, as probabilidades de saída são:
fonte
Python 2,
5857 bytesExplicação: isso gera um número de ponto flutuante aleatório no intervalo
[0, 676)
, pega a raiz quadrada e depois a pavimenta. Em seguida, adiciona 65 (o valor ascii de "A"), converte-o em um caractere e o imprime.Isso dá a cada número de 0 a 25 uma probabilidade distinta. Para entender o porquê, pense assim. Quantos números, ignorando os não inteiros, quando você pega a raiz quadrada e o piso, obtém 0? Apenas um número será (zero). Isso significa que zero tem uma probabilidade de
1/676
. Quantos números produzirão 1? 3 vontade, 1, 2 e 3. Isso significa que se tem uma probabilidade de3/676
. Um dois pode ser produzido com um 4, 5, 6, 7 ou 8, dando probabilidade 5, um três com probabilidade 7, etc. e, como a diferença entre quadrados consecutivos aumenta constantemente em dois, esse padrão continua para cada número acima a 25 (Z).1 byte economizado graças à freira com vazamento!
fonte
chr(int(65+randint(676)**.5))
chr(int(65+random()**.5*26))
. É a mesma coisa algebricamente porque 26 == √676. e agora a ordem das operações está do seu lado**2*26
pode ser usado para a distribuição inversa.1/random()%26
também deve funcionar.PowerShell v2 +,
3331 bytesToma um intervalo de
65
até90
(ou seja, ASCIIA
aZ
), canaliza-o através de um loop. A cada iteração, usamos o operador vírgula para criar uma matriz desse elemento vezes esse número. Por exemplo, isso fará 6565
s, 6666
s, 6767
s, etc. Essa grande matriz é canalizada para aGet-Random
qual (PRNG uniformemente) seleciona um elemento. Como existem quantidades diferentes de cada elemento, cada personagem tem uma chance percentual ligeiramente distinta de ser escolhida. Em seguida, encapsulamos isso em parênteses e o definimos como achar
. Isso é deixado no pipeline e a produção está implícita.(Obrigado a @LeakyNun por jogar alguns bytes antes mesmo de ser publicado.: D)
As probabilidades
(ligeiro arredondamento para que eu pudesse demonstrar a
P
opção do-f
operador ormat)fonte
gal
saída ([char[]]"uz$(gal|out-string)"-cmatch'[a-z]'|random
) chegou a 50 caracteres, depois 48, mudou para números e conseguiu 42, depois 31 e parou por aí; olhou na tabela de classificação para ver onde isso me colocaria. Bem aqui. Caractere para caractere idêntico. Welp, provavelmente não posso superar isso.CJam,
211712 bytesObrigado a Martin Ender por me salvar 5 bytes!
Nova versão
Isto forma uma matriz de cadeias seguindo o padrão
A
,AB
,ABC
, e assim por diante. Nivela-o e escolhe um caráter aleatório. Como essa sequência contém 26 A, 25 B, 24 C e assim por diante, cada letra tem uma probabilidade distinta de ser escolhida.Experimente online!
Explicação
Versão antiga
Obtém probabilidades distintas criando uma sequência na qual cada letra aparece um número de vezes igual à sua posição no alfabeto.
fonte
R, 23 bytes
Apenas 'prova' uma carta de um builtin. a
1:26
é um vector de pesos dando a cada letra a probabilidade diferente.fonte
1:26
é um vetor de pesos para cada letraC, 35 bytes
Este programa assume que
RAND_MAX
é (2 ^ 32/2) - 1 como está no gcc por padrão. Compile com o-lm
sinalizador para vincular asqrt
função. A saída é gravada em stdout como letras maiúsculas sem deixar novas linhas.Opcionalmente, se
RAND_MAX
for (2 ^ 16/2) - 1, uma versão mais curta de 32 bytes pode ser usada:Apenas por diversão, eu também fiz uma versão que não usa a
sqrt
função ou requer a biblioteca de matemática incluída (esta deve terRAND_MAX
como (2 ^ 32/2) - 1), mas acabou sendo mais longa, embora eu achasse que era muito legal:Explicação
[Primeiro programa]
Para os dois primeiros a usar
sqrt
, a função simplesmente mapeia o intervalo[0, RAND_MAX)
para[0, 25]
a divisão direta e, em seguida, adiciona 65 (ASCIIA
) ao valor para alterá-lo para o alfabeto ASCII antes de produzi-lo.[Segundo programa]
O segundo programa é um pouco mais complexo, pois faz uma estratégia semelhante, mas sem o
sqrt
operador. Como os bits do expoente de um ponto flutuante são calculados automaticamente ao atribuir um número inteiro, eles podem ser efetivamente usados como uma maneira bruta de obter o logaritmo base 2 de um número.Como queremos que o intervalo
RAND_MAX
atinja apenas um valor de expoente codificado de 25, o cálculo (2 ^ 32/2 - 1) / (2 ^ 25) nos fornece apenas 64, que é usado durante a divisão derand
para mapeá-lo para esta nova gama. Também adicionei 1 ao valor, pois a representação de ponto flutuante de 0 é bastante estranha e quebraria esse algoritmo.Em seguida, o float é puncionado por um número inteiro para permitir o deslocamento de bits e outras operações desse tipo. Como nos números de ponto flutuante IEEE 754, os bits do expoente são os bits 30-23, o número é então deslocado para a direita 23 bits, cortando a mantissa e permitindo que o valor bruto do expoente seja lido como um número inteiro. Observe que o bit de sinal também está além dos bits do expoente, mas como nunca há negativos, ele não precisa ser mascarado.
Em vez de adicionar 65 a esse resultado, como fizemos anteriormente, os expoentes de ponto flutuante são representados como um número inteiro de 8 bits sem sinal de 0 a 255, onde o valor do expoente de 0 é 127 (basta subtrair 127 para obter o valor real do expoente "assinado" ) Como 127 - 65 é 62, simplesmente subtraímos 62 para ambos deslocá-lo para fora desse intervalo de expoente de ponto flutuante e para o intervalo do alfabeto ASCII, tudo em uma operação.
Distribuição
Como não sou especialista em matemática, não posso dizer com certeza a fórmula exata para essas distribuições, mas posso (e fiz) testar todos os valores no intervalo
[0, RAND_MAX)
para mostrar que a distância entre o ponto em que o intervalo de uma letra termina e o outro começa nunca é a mesma. mesmo. (Observe que esses testes assumem o máximo aleatório (2 ^ 32/2) - 1))[Primeiro programa]
[Segundo programa]
fonte
char
é um tipo integral em C, isso deve ser aceitável.Python 2, 72 bytes
Multiplica o caractere pelo seu valor ascii e, em seguida, escolhe um caractere aleatoriamente na sequência resultante.
Aqui estão as probabilidades de cada letra selecionada, em porcentagens:
Experimente: https://repl.it/Cm0x
fonte
Gelatina , 5 bytes
(Pontuação igual, mas um método diferente , a uma solução Jelly existente de Dennis.)
A probabilidade de gerar cada letra é o índice baseado em 1 no alfabeto dividido por 351 - o 26º número triangular:
A
) = 1/351, P (B
) = 2/351, ..., P (Z
) = 26/351.Como 1 + 2 + ... + 26 = 351, P (letra) = 1.
Implementação:
Teste-o no TryItOnline ou obtenha a distribuição de 100 mil execuções (crédito de código para Dennis)
fonte
q, 38 bytes
Não é particularmente curto, mas ...
A função de distribuição cumulativa discreta é a sequência
0.9 ^ 26, 0.9 ^ 25, ..., 0.9 ^ 0
E nós apenas provamos da distribuição.
fonte
JavaScript (ES6), 45 bytes
Atinge distribuição não uniforme ao quadrado do valor aleatório.
Math.random()
retorna um ponto flutuante do intervalo, de[0,1)
modo que o resultado do quadrado disso tende para0
(oua
).Teste
Mostrar snippet de código
fonte
(n=Math.random(),10+26*n+n|0).toString(36)
Oracle SQL 11.2, 212 bytes
Usando a posição do caractere no alfabeto como probabilidade
Sem golfe
fonte
TI-Basic, 39 bytes
rand
gera um valor uniforme em (0,1]. Isso dá 26 ^ e uma probabilidade diferente de igualar os números inteiros de 1 a 26.Versão antiga, 45 bytes
A precisão limitada dos números inteiros da TI-Basic limita as distribuições normais a gerar números dentro de µ ± 7,02σ (consulte
randNorm(
). Portanto, obtemos o valor absoluto de um número aleatório com µ 0 e σ 1, multiplicando por quatro para aumentar o intervalo prático mencionado anteriormente para µ ± 28,08σ. Em seguida, calculamos o valor e adicionamos 1, uma vez quesub(
é indexado a 1, fornecendo um intervalo de 1 a 29 com probabilidades diferentes de cada um.fonte
PHP,
9284 bytesConstrói uma sequência de todas as letras, repete o número de vezes no ciclo que somos e, em seguida, escolhe uma letra dessa sequência aleatoriamente. As letras mais tarde no alfabeto têm uma probabilidade mais alta como resultado
Obrigado a insertusernamehere por remover bytes
probabilidades de resultado (ordenadas por%)
fonte
$x=0
que é obviamente necessário. Aqui está uma versão de 84 bytes :for($i=65,$x=0;$i<91;$a.=str_repeat(chr($i++),$x))$x++;echo substr($a,rand(0,$x),1);
Você já conseguiu obter um valor maior do queG
quando executou seu código? De qualquer forma, você sempre pode ignorarnotice
s ao jogar golfe.strlen
de$a
é 351, mas você está apenas escolhendo um caractere aleatório dos primeiros$x
(26) caracteres. Você pode corrigi-lo e manter suas probabilidades com uma mudança da final$x
para350
para um byte. Aqui está uma versão de 77 bytes que corrige o problema, mas também aproxima as probabilidades:for($i=65;$i<91;$a.=str_repeat(chr($i),$i++));echo substr($a,rand(0,2014),1);
Befunge,
168164 bytesMais compacto que o primeiro, com probabilidades um pouco diferentes: os primeiros
?
têm 1/4 de chance de imprimir um A na "primeira tentativa", 2/4 de chance de voltar à mesma?
e 1/4 de volta para a Próximo. O restante dos itens?
tem 1/4 de chance de imprimir a letra abaixo deles, 1/4 para tentar novamente, 1/4 passa para a próxima letra, 1/4 passa para a anterior. Novamente, a probabilidade de imprimir um A é muito maior do que imprimir um Z.Anterior, 186 bytes
Obviamente, não vou ganhar com isso, mas acho que é uma resposta interessante, no entanto :)
v
e>
direciona o cursor respectivamente para baixo e para a direita. O?
operador envia o cursor em uma das quatro direções aleatoriamente. A primeira?
é "bloqueada" porv
e>
em duas direções; portanto, só há dois caminhos a seguir: para imprimir o A ou para o próximo?
. Portanto, desde o primeiro momento?
, há 50% de chance de imprimir um A.O próximo
?
tem 1/3 de chance de imprimir um B, 1/3 de voltar e 1/3 de descer mais. Etc etc.Deveria ser óbvio que as letras mais altas têm uma chance muito maior de serem impressas do que as letras mais baixas, mas não sei exatamente quais são as chances de cada letra.
Alguma ajuda com a matemática exata seria apreciada :)
Pelo menos, existe uma chance de 1/2 * 1/3 ^ 25 de que o cursor se mova até o Z na primeira tentativa, mas não tenho certeza de como as chances do cursor se mover para cima e para baixo afetam cada letra.
,@
imprime e sai.fonte
J,
2018 bytesIntérprete online
Maiúsculas.
A probabilidade de cada letra é o seu índice baseado em 1 no alfabeto.
fonte
zsh, 63 bytes
funciona criando esta string:
aka 65 vezes A, 66 vezes B, 67 vezes C ...
e então escolhe um caractere aleatório
fonte
A
em ascii. você pode começar a partir de 1, mas, em seguida, o loop interno torna-se{65..$[#i]}
o que é um caractere maisCJam, 11 bytes
ou
Experimente online!
Essa solução é semelhante à idéia de Luis e cria uma distribuição não uniforme, tomando a raiz quadrada da variável aleatória.
fonte
Lote, 116 bytes
Funciona escolhendo a maior ou a menor (esqueço qual) de duas variáveis aleatórias.
fonte
Matlab, 22
Retornará frequentemente as primeiras cartas, mas teoricamente pode tocar todas elas!
Pega um dividido por um número aleatório, limita isso a 26 e o transforma em um personagem.
Não muito curto, é claro, mas talvez o conceito possa inspirar outras respostas.
fonte
rand
um valor em [0, 1)? Ou seja, incluindo zero, mas não incluindo um. Se isso ocasionalmente resultar em 1/0,min(1/0,26)
ainda retornará 26 ou um erro?rand
retorna um valor em (0,1), de modo que não deve ser um problemarand
retornar 0, na prática,min(1/0,26)
realmente retorna 26.CJam, 10 bytes
Abordagem CJam # 3 ...
Experimente online!
Isso cria um número aleatoriamente uniforme
x
entre 1 e 26 e depois o usa para criar um número aleatório uniforme entre0
e aox-1
qual é adicionadoA
. Esse viés resulta em caracteres menores.fonte
Labirinto , 19 bytes
Experimente online!
Este é um loop que, a cada iteração, a) incrementa um contador que começa em zero ou b) termina, ambos com probabilidade de 50%. No final do loop, o contador é retirado do módulo 26 e adicionado a 65 para dar uma letra entre
A
eZ
.Isso dá uma probabilidade de
A
pouco mais de 50%,B
pouco mais de 25% e assim por diante atéZ
pouco mais de 1/2 26 . Em teoria, existe a possibilidade de que isso funcione para sempre, mas esse evento tem probabilidade zero, conforme exigido pelo desafio (na prática, provavelmente isso não é possível de qualquer maneira, porque o PRNG retornará os dois resultados possíveis em algum momento do período).fonte