Vamos ver o quão boa é a sua linguagem de escolha na aleatoriedade seletiva.
Dado 4 caracteres, A
, B
, C
, e D
, ou uma cadeia de 4 caracteres ABCD
como entrada , um dos caracteres, com as seguintes probabilidades de saída:
A
deve ter 1/8 (12,5%) de chance de ser escolhidoB
deve ter uma chance de 3/8 (37,5%) de ser escolhidoC
deve ter 2/8 (25%) de chance de ser escolhidoD
deve ter 2/8 (25%) de chance de ser escolhido
Isso está alinhado com o seguinte layout da máquina Plinko :
^
^ ^
^ ^ ^
A B \ /
^
C D
Sua resposta deve fazer uma tentativa genuína de respeitar as probabilidades descritas. Uma explicação adequada de como as probabilidades são computadas em sua resposta (e por que elas respeitam as especificações, desconsiderando problemas de pseudo-aleatoriedade e grandes números) é suficiente.
Pontuação
Isso é código-golfe, e o menor número de bytes em cada idioma vence!
ceil(abs(i - 6)/ 2.0)
vai mapear um índice a partir0-7
de um índice a partir0-3
com a distribuição apropriada (0 111 22 33
) para este desafio ...Respostas:
Máquina de Feijão Lean Mean ,
554342 bytes-13 bytes graças a Alex Varga
Espero que vocês não se importem de eu responder minha própria pergunta após apenas 2 horas, mas duvido que alguém planejasse postar uma resposta no LMBM.
Isso literalmente reflete apenas o layout do Plinko mostrado no OP, invertido horizontalmente para reduzir o espaço em branco desnecessário.
fonte
Gelatina , 6 bytes
Um link monádico que pega uma lista de quatro caracteres e retorna um com a distribuição de probabilidade descrita.
Experimente online!
Quão?
fonte
ṁ
!Cubix ,
3924222119 bytesVeja no intérprete online!
Isso mapeia a seguinte rede de cubos:
Explanação de implementação de distribuição aleatória
Cubix é uma linguagem na qual um ponteiro de instrução viaja pelas faces de um cubo, executando os comandos que encontra. A única forma de aleatoriedade é o comando
D
, que envia o IP em uma direção aleatória: uma chance igual em1/4
cada sentido.No entanto, podemos usar isso para gerar as probabilidades ponderadas corretas: usando
D
duas vezes. O primeiroD
tem um1/4
de ir para um segundoD
. Este segundoD
, no entanto, tem duas direções bloqueadas com setas (> D <
) que enviam o ponteiro de instruções de volta para aD
para escolher outra direção. Isso significa que existem apenas duas direções possíveis a partir daí, cada uma com uma1/8
chance geral de acontecer. Isso pode ser usado para gerar o caractere correto, conforme mostrado no diagrama abaixo:(Observe que, no código real, a seta à direita é substituída por um espelho
|
)Código Explicação
O ponteiro de instruções começa à direita, no personagem
i
, voltada para a direita. Ele executa issoi
, pegando o primeiro caractere como entrada e depois passa para oD
, iniciando o processo aleatório mostrado acima.Caractere A: No caso em que o primeiro
D
nos envie para o leste e o segundo para o sul, precisamos imprimir o caractere A. Isso já está na pilha do primeiroi
. O seguinte é executado:\
- Reflita o IP para o lestei;
- Pegue uma entrada e clique novamente (sem opção)U
- Faça uma inversão de marcha, virando o IP duas vezes para a esquerdao
- Saída do TOS, caractere A@
- Encerrar o programaCaractere B: Se o primeiro ou o segundo se
D
dirigirem ao norte, precisamos gerar o caractere B, que será a próxima entrada. Ambos os caminhos executam os seguintes comandos:^
- Siga para o norte<
- Vá para o oeste, embrulhando para ...i
- Pegue outra entrada, caractere Bo
- Saída do TOS, caractere B;
- Faça o TOS@
- Encerrar o programaCaractere C: Se o primeiro
D
nos enviar para o oeste, o seguinte será executado:i
- Pegue outra entrada, caractere Bi
- Pegue outra entrada, caractere Co
- Saída TOS, caractere C@
- Encerrar o programaCaractere D: Se o primeiro
D
nos enviar para o sul, o seguinte será executado:i
- Pegue outra entrada, caractere B..
- Duas no-opsi
- Pegue outra entrada, caractere C|
- Esse espelho reflete leste-oeste, mas o IP está indo para o norte, então passamos por ele.^
- Isso se une ao caminho adotado para o caractere B. No entanto, como já pegamos duas entradas, o quarto caractere (caractere D) acabará sendo impresso.fonte
Python , 50 bytes
Uma função sem nome, que recebe e retorna seqüências de caracteres (ou listas de caracteres).
Experimente online!
Quão?
random.choice
escolhe um elemento aleatório de uma lista, de modo que a função forma uma string com a distribuição correta, ou seja, dada"ABCD"
,"ABCD"[:2] = "AB"
mais"ABCD"[1:]*2 = "BCD"*2 = "BCDBCD"
qual é"ABBCDBCD"
.fonte
R , 31 bytes
Lê os caracteres
stdin
separados por espaços.sample
extrai amostras aleatórias de sua primeira entrada em quantidade da segunda entrada (so1
), (argumento de substituição opcional), com pesos dados pelo último argumento.Experimente online!
Experimente
n
vezes!Para o último código, eu amostro os
n
tempos (definidosn
no cabeçalho) com a substituição definida comoT
rue (é falso por padrão), tabulo os resultados e dividon
para ver as probabilidades relativas das entradas.fonte
PHP, 28 bytes
Corra como cano com
-nR
.01112233
na base-4 está5551
em decimal ...fonte
7030
está entre os meus favoritos pessoais.Java 8,
5344 bytesIsto é um
Function<char[], Character>
.Experimente online! (este programa de teste executa a função acima 1.000.000 vezes e emite as probabilidades experimentais de escolher
A
,B
,C
, eD
).A idéia geral aqui é encontrar uma maneira de mapear ,
0-7
para0-3
que0
apareça1/8
horas,1
apareça3/8
horas,2
apareça2/8
horas e3
apareça2/8
horas.round(abs(k - 6) / 2.0))
funciona para isso, ondek
é um número inteiro aleatório no intervalo[0,8)
. Isso resulta no seguinte mapeamento:Que, como você pode ver, os resultados dos índices
0 111 22 33
, que produz as probabilidades desejados de1/8
,3/8
,2/8
e2/8
.Mas espere! Como o mundo
-~Math.abs(k-6)/2
alcança o mesmo resultado (novamente, ondek
está um número inteiro aleatório no intervalo[0,8]
)? É bem simples, na verdade ...(x+1)/2
(divisão inteira) é a mesma coisa queround(x/2)
, ex + 1
é a mesma coisa que-~x
. Emborax+1
e-~x
tenham o mesmo comprimento, na função acima é melhor usar,-~x
pois-~
tem precedência e, portanto, não requer parênteses.fonte
Math.abs
também aceita dobra como parâmetro):s->s[-~(int)Math.abs(Math.random()*8-6)/2]
( 42 bytes ).APL, 14 bytes
Entrada como uma string.
Quão?
1 3 2 2\⊢
- repita cada letra x vezes ('ABCD'
→'ABBBCCDD'
)⊃
- pegue o elemento no índice(?8)
- aleatório 1-8fonte
⎕U2378
.Carvão , 11 bytes
Experimente online! Link é uma versão detalhada do código, embora você dificilmente precise dele;
‽
escolhe um elemento aleatório,⟦⟧
cria uma lista e as variáveis são aquelas que recebem as letras de entrada apropriadas (na ordem inversa, porque eu queria).fonte
Pitão ,
87 bytesUsa exatamente o mesmo algoritmo da minha resposta em Python.
Experimente aqui!
Pitão ,
108 bytesUsa exatamente o mesmo algoritmo da resposta Python de Jonathan Allan.
Experimente aqui!
Explicação
O
- Pega um elemento aleatório da String criado anexando (com+
):<Q2
- Os dois primeiros caracteres da String.*2t
Duplique a String completa (*2
), exceto o primeiro caractere (t
).Aplicando este algoritmo para
ABCD
:<Q2
levaAB
.*2t
levaBCD
e dobra-lo:BCDBCD
.+
une as duas cordas:ABBCDBCD
.O
leva um caractere aleatório.-2 graças a Leaky Nun (segunda solução)
-1 graças a mnemônico (primeira solução)
fonte
>Q1
torna-setQ
, o que se tornat
.*2
por+
e usando a entrada implícita duas vezes.y
vez disso, o que não funciona para strings ...Geléia , 8 bytes
Experimente online!
Remova o
X
para ver"ABBBCCDD"
. OX
escolhe um elemento aleatório.fonte
C # (.NET Core) ,
7655 bytesExperimente online!
Minha primeira resposta foi escrita diretamente no TIO usando meu telefone celular. Upar!
Explicação: se a sequência original for "ABCD", a função criará a sequência "ABCDBBCD" e extrairá dela um elemento aleatório.
fonte
Javascript 35 bytes
Toma uma string
ABCD
como entrada, geraA
1/8 do tempo,B
3/8 do tempo,C
1/4 do tempo eD
1/4 do tempo.Explicação
fonte
05AB1E , 5 bytes
Experimente online!
Explicação
fonte
> <> ,
252219 bytesExperimente online! , ou assista ao parque infantil !
Uma breve visão geral de> <>: é uma linguagem 2D com um peixe que nada através do código, executando instruções conforme ele é executado. Se atingir a borda do código, será envolto para o outro lado. O peixe começa no canto superior esquerdo, movendo-se para a direita. A aleatoriedade é complicada em> <>: a única instrução aleatória é
x
, que define a direção do peixe aleatoriamente para cima, para baixo, esquerda e direita (com igual probabilidade).No início do programa, o peixe lê em dois caracteres de entrada com
i_i
(cadai
um lê um caractere de STDIN para a pilha e_
é um espelho horizontal, que o peixe ignora agora). Em seguida, atinge umx
.Se o
x
peixe envia para a direita, ele lê mais um caractere (o terceiro), o imprime como
e para com;
. A direção esquerda é semelhante: o peixe lê mais dois caracteres (então chegamos ao quarto), gira para a direita, imprime o quarto caractere e pára. Se o peixe nada, ele envolve e imprime o segundo caractere, antes de ser refletido/
e interrompido. Se nada, é refletido à esquerda pelo/
e bate em outrox
.Desta vez, duas direções apenas enviam o peixe de volta para
x
(à direita com uma seta,<
, e para cima com um espelho_
). O peixe, portanto, tem 1/2 chance de escapar dissox
em cada uma das outras duas direções. Para a esquerda, imprime o caractere superior da pilha, que é o segundo, mas, para baixo, primeiro troca os dois elementos da pilha por$
, portanto, essa direção imprime o primeiro caractere.Em resumo, o terceiro e o quarto caracteres são impressos com probabilidade de 1/4 cada; o primeiro caractere tem probabilidade 1/2 x 1/4 = 1/8; e o segundo caractere tem probabilidade 1/4 + 1/2 x 1/4 = 3/8.
fonte
05AB1E , 8 bytes
Experimente online!
fonte
MATL ,
1210 bytesExperimente online! Ou execute-o 1000 vezes (código ligeiramente modificado) e verifique o número de vezes que cada caractere aparece.
Explicação
Alterações no código modificado:
1000:"Gl3HH4$vY"1Zr]vSY'
1000:"...]
é um loop para repetir1000
vezes.G
garante que a entrada seja enviada no início de cada iteração.v
precisa ser substituído por4$v
para concatenar apenas os4
números principais .v
concatena os1000
resultados em um vetor,S
classifica eY'
codifica na duração. Isso fornece as quatro letras e o número de vezes que elas apareceram.fonte
05AB1E , 6 bytes
Experimente online!
Explicação
Funciona para listas e seqüências de caracteres.
fonte
C (gcc) ,
5049 bytesExperimente online!
fonte
ABCD
é exemplo de entrada, seu código deve ter 4 caracteres (ou uma cadeia de comprimento 4) como entradaRuby,
34332927 bytesEconomizou 2 bytes graças a @Value Inc
Introduzir como quatro caracteres
construa uma matriz
[B,B,C,D,A,B,C,D]
e faça uma amostra.experimente online!
tente
n
vezes! (Eu converti para uma função para repeti-lo mais facilmente, mas o algoritmo é o mesmo)fonte
$*
é um alias paraARGV
.Pitão, 7 bytes
Suíte de teste
O8
gera um número aleatório de 0 a 7.| ... 1
aplica um lógico ou com 1, convertendo o 0 em 1 e deixando tudo o mesmo. O número nesse estágio é 1/2 / 8 do tempo e 2, 3, 4, 5, 6, 7 ou 8 1/8 do tempo.@z
indexa na sequência de entrada nessa posição. A indexação é realizada modulando o comprimento da string, então 4 indexam na posição 0, 5 na posição 1 e assim por diante.As probabilidades são:
Posição 0: Número aleatório 4. 1/8 do tempo.
Posição 1: Número aleatório 0, 1 ou 5. 3/8 do tempo.
Posição 2: Número aleatório 2 ou 6. 2/8 do tempo.
Posição 3: Número aleatório 3 ou 7. 2/8 do tempo.
fonte
Javascript,
3130 bytes / 23 bytesVer a resposta Javascript anterior da asgallant me levou a pensar em JS. Como ele disse:
O meu é:
Explicação:
De
Math.random()*8&7
se decompõe da seguinte forma:Versão 2, 23 bytes
Mas então, graças a Arnauld, que postou depois de mim, quando ele disse:
que, se é realmente permitido, me levou a:
em que
new Date%8
usa a mesma tabela de detalhamento acima.E
%8
também poderia ser&7
; faça sua escolha. Mais uma vez obrigado, Arnauld.fonte
ngn / apl, 10 bytes
?2 4
escolhe aleatoriamente um par de números - o primeiro entre 0 1 e o segundo entre 0 1 2 3⌈/
é "max reduzir" - encontre o número maior⎕a
é o alfabeto maiúsculo[ ]
indexaçãoobserve o gráfico para max (a, b) quando a∊ {0,1} e b∊ {0,1,2,3}:
se a e b são escolhidos aleatoriamente e independentemente, podemos substituir 0123 = ABCD para obter a distribuição de probabilidade desejada
fonte
Python 3 ,
64 5551 bytes-9 bytes graças a @ovs
Experimente online!
Explicação
random.choice()
obtém um caractere aleatório da String, enquanto(s*2)[1:]+s[1]
criaBCDABCDB
para uma entrada deABCD
, que possui 1/8A
s, 2/8C
s, 2/8 seD
3/8B
s.fonte
random.choice
para 55 bytes:lambda s:choice((s[0]+s[1:]*3)[:8])
choice()
mesmo.QBIC , 27 bytes
Explicação
fonte
> <>, 56 bytes
Experimente online!
fonte
Chip , 60 bytes
Experimente online!
?
Cada um dos três produz um bit aleatório. No primeiro ciclo, esses bits são executados nos comutadores acima (/
's\
') para determinar qual valor vamos gerar a partir desta tabela:(onde
_
pode ser0
ou1
). Caminhamos pela entrada conforme necessário, imprimindo e finalizando quando o valor correto é atingido.O grande blob alfabético no final é copiado por atacado do programa cat; essa solução simplesmente suprime a saída e termina para obter o efeito pretendido.
fonte
Ruby, 32 bytes
Bem direto..?
Experimente online!
fonte
Applesoft,
29oops, 32 bytesUm pequeno exemplo de "retrocomputação". Tenha paciência comigo, sou novo nisso. Entendo que o que é designado como "entrada" não precisa ser contado em bytes. Conforme declarado no OP, a entrada seria fornecida como "ABCD". (Inicialmente, não percebi que precisava especificar a entrada obtida, o que acrescentou 4 bytes, enquanto eu deduzia o restante em um byte.)
Os termos INPUT, RND, PRINT e MID $ são codificados internamente como tokens de byte único.
Primeiro, X é atribuído a um valor aleatório no intervalo 0 <X <4. Isso é usado para escolher um dos caracteres de I $, de acordo com (X <.5) + X + 1. O valor da posição do caracter é tomado como avaliação truncada da expressão. X <0,5 adiciona 1 se X for menor que 0,5, caso contrário, adicione 0. Os resultados de X são divididos da seguinte forma:
fonte
Lisp comum , 198 bytes
Experimente online!
Legível:
fonte