Jogo de dados não transitivo

10

Aqueles de vocês que gostam de Numberphile estariam familiarizados com o Dr. James Grime, que descreveu um jogo de dados não transitivo em seu canal .

O jogo consiste em três dados de 6 faces:

  • Morrer 1: 3,3,3,3,3,6
  • Die 2: 2,2,2,5,5,5
  • Die 3: 1,4,4,4,4,4

Dois jogadores selecionam um dado para usar. Eles os rolam e o dado mais alto ganha, o melhor de tudo.

Probabilisticamente, o dado 1 vence o dado 2 com uma chance> 50%. Da mesma forma, os dados 2 batimentos morrem 3 e, curiosamente, dados 3 batimentos morrem 1.

Escrever uma tomada de programa 1, 2ou 3como entrada. Isso indica o dado que o usuário escolhe. O programa escolhe o dado que venceria o usuário e produziria os resultados de 21 rolos e " Computer/User wins with x points"

Regras

  • Code-golf, votos como desempate
  • Você deve usar o RNG (ou similares) para simular os lançamentos de dados.
  • Eu não sou muito rigoroso no formato de saída. Tudo bem, desde que você mostre os dados, de alguma forma separe entre as 21 jogadas (de uma maneira diferente de como você separa os dados na mesma jogada) e solte a frase acima.
  • A entrada pode ser stdin, argumento de linha de comando, na tela etc.

Exemplo

Entrada

1

Resultado

4 3
4 3
4 3
4 3
4 3
4 3
4 3
4 3
4 3
4 6
1 3
4 3
4 3
1 3
4 3
1 3
4 3
4 3
4 3
4 3
4 6
 Computer wins with 16 points

Aqui, o usuário escolhe o dado 1 e seus rolos são mostrados na coluna da direita. O programa escolhe o dado 3 e o vence.

TwiNight
fonte

Respostas:

1

GolfScript, 112 105 caracteres

3,21*{..+6rand<3*+)}%3/\{)\.+-1%>2<.p~<}+,,"User
Computer"n/1$11<=" wins with "+\[.~22+]$1>~+" points"+

Execute-o online .

O script espera a entrada no STDIN e, em seguida, imprime o resultado dos dados (computador da primeira coluna, segundo usuário) e as estatísticas finais em STDOUT.

Howard
fonte
4

APL ( 106 114)

'Computer' 'User'[1+X],'wins with','points',⍨|Z-21×X←11>Z←+/>/⎕←⍉↑{⍵[{?6}¨⍳21]}¨(↓5 6⍴545170074510753⊤⍨18⍴7)[⎕+⍳2]

Explicação:

  • (↓5 6⍴545170074510753⊤⍨18⍴7)[⎕+⍳2]: O grande número é uma representação de base 7 dos dados. Criamos uma matriz 6x5 contendo os valores dos dados na ordem: 2 3 1 2 3. Peça a entrada do usuário e adicione-a ao vetor 1 2, e selecione essas linhas da matriz. Como a lista de dados é alterada, o usuário agora obtém o que ele selecionou (à direita) e o computador, o mais forte.
  • {⍵[{?6}¨⍳21]}¨: faça 21 jogadas para cada um desses dois dados.
  • ⎕←⍉↑: coloque os rolos na forma de matriz e os produza.
  • Z←+/>/: obtém a pontuação do computador (quantidade de vezes que o valor do computador foi superior ao do usuário)
  • X←11>Z: defina Xse o usuário venceu (se 11 for maior que a pontuação do computador).
  • 'Computer' 'User'[1+X]. Xé se o usuário ganhou.
  • 'wins with','points',⍨|Z-21×X: Zé a pontuação do computador; portanto, se o computador for exibido Z, será exibido 21-Z.
marinus
fonte
A pontuação não é a diferença dos totais (que deve ser 0 para todos os pares de dados); em vez disso, o vencedor de cada uma das 21 jogadas recebe 1 ponto. No exemplo, o usuário possui 5 pontos (de 5 vitórias consecutivas: 4-6, 1-3, 1-3, 1-3, 4-6) e o computador obtém os 16 pontos restantes.
TwiNight 10/01
@TwiNight: fix it
marinus
Pontos negativos quando o usuário ganha. Você pode consertar o |Z-21×Xque não altera a contagem de caracteres
TwiNight
2

R - 228

d=matrix(rep(c(rep(3,5),6,2,2,2,5,5,5,1,rep(4,5)),2),6)
x=scan()
r=expand.grid(Computer=d[,x+2],User=d[,x])[sample(36,21,T),]
print(r)
s=summary.factor(names(r)[max.col(r)])
cat(names(which.max(s)),"wins with",max(s),"points\n")

Exemplo de execução:

> source('ntd.R')
1: 2
2: 
Read 1 item
     Computer User
28          3    5
31          3    5
36          6    5
18          6    2
11          3    2
31.1        3    5
14          3    2
8           3    2
9           3    2
17          3    2
2           3    2
29          3    5
3           3    2
16          3    2
4           3    2
21          3    5
14.1        3    2
23          3    5
16.1        3    2
17.1        3    2
19          3    5
Computer wins with 14 points
Geoff Reedy
fonte
Você pode substituir summary.factorpor table, salvando 9 caracteres.
Brian Diggs
2

Mathematica 208 172 166 159

Espaços adicionados para maior clareza

b=Boole;{#, Row@{
         If[# > 10, "Play", "Comput"], "er wins with ",
         Max[#, 21 - #], " points"} &@ Total[b[#1 > #2] & @@@ #]} &@
   Table[1 + i + 3 b[6 Random[] > 2 i + 1],{21}, {i, {#, Mod[# + 1, 3]}}] &
Dr. belisarius
fonte
Acho que a saída deve listar os valores de cada lançamento dos dados.
DavidC
@ cara sim, eu perdi durante o teste. Fiz uma correção rápida apenas para manter a bola correndo. Vou pensar mais tarde como melhorá-lo.
Dr. belisarius
Agora parece estar funcionando bem.
DavidC
@dude Muito melhor agora
Dr. belisarius
Muito legal. 1)
Mr.Wizard 13/01
1

Rubi 1.8, 165

i,s,*d=getc,21,[4]*5<<1,[3]*5<<6,[2,5]*3
puts"#{s.times{p r=[i,i-1].map{|o|d[o%3][rand 6]};s+=r[0]<=>r[1]}>s?"Human":"Computer"} wins with #{[s/=2,21-s].max} points"

getc obtém o valor ascii da entrada (somente ruby ​​1.8), que felizmente é o módulo 3 congruente em relação ao seu valor inteiro.

sinicia às 21, então s.times{code}executa code21 vezes e retorna 21. A cada iteração, o loop adiciona ou subtrai 1 de s, dependendo de quem vence, para que possamos ver quem venceu, verificando se sterminou abaixo de 21. Limpo até agora , mas preciso da expressão desajeitada [s/=2,21-s].maxpara extrair o número real de pontos. Há muito tempo eu queria fazer aritmética com o valor de retorno <=>, então estou feliz de qualquer maneira.

histocrata
fonte
1

Mathematica 234 247

Código

g@n_ := {t = RandomChoice[{{5, 25, 1, 5}/36 -> {{3, 1}, {3, 4}, {6, 1}, {6, 4}}, 
         {5, 1, 5, 1}/12 -> {{2, 3}, {2, 6}, {5, 3}, {5, 6}},
         {1, 1, 5, 5}/12 -> {{1, 2}, {1, 5}, {4, 2}, {4, 5}}}[[n]], 21], 
         Row[{If[(c = Count[t, {x_, y_} /; y > x]) > 10, "Computer ", "Player "], 
         "wins with ", If[c > 10, c, 21 - c], " points"}]}

Uso

{Lista do jogador, Lista do computador}

g[1]
g[2]
g[3]

resultados


Explicação

né o número 1, 2 ou 3 que corresponde ao dado do jogador. Como n também determina (mas não é igual) o dado do computador, podemos gerar todos os lançamentos possíveis dos dados quando n = 1, n = 2, n = 3. Também podemos determinar suas respectivas probabilidades.

Examine os dados logo após RandomChoice:

{5, 25, 1, 5} / 36 -> {{3, 1}, {3, 4}, {6, 1}, {6, 4}}

Se o jogador empata o dado 1, os únicos resultados possíveis são os seguintes 4 pares

{{3, 1}, {3, 4}, {6, 1}, {6, 4}}

As respectivas probabilidades desses pares são

{5, 25, 1, 5}/36, isso é,

{5/36, 25/36, 1/36, 5/36}

RandomChoice[<data>, 21] produz 21 jogadas dos dois dados.

DavidC
fonte
1

C, 205 191

p;r(c){return 1+c+3*(rand()%6>2*c);}main(i,c,q,s){for(c=51-getchar();++i<23;printf("%u %u\n",q,s))q=r(c),p+=(s=r(-~c%3))<q;printf("%ser wins with %u points",p<11?"Comput":"Us",p<11?21-p:p);}

Lê a escolha do usuário em stdin.

deixou de girar contra-relógio
fonte
Algumas dicas: for(c=51-getchar(p=0);, printf("%ser wins), expressão de reabastecimento em rcomeçar com (e economizar espaço.
ugoren
E mais: (c+1)%3-> -~c%3, faça pestático (inicializado com 0), remova {}depois for( ;-> ,dentro deles), use p<11?:duas vezes dentro em printfvez de atribuir p,q.
Ugoren
E você pode definir s,qno loop printfe incrementar pdepois, economizando parênteses. Altere também a catribuição para usar %3or %7, fornecendo uma ordem diferente de 0,1,2.
ugoren
1

Fator

Com inclui: 388

Sem: 300

USING: arrays formatting io kernel math math.parser prettyprint random sequences ;
IN: N
CONSTANT: d { { 3 3 3 3 3 6 } { 2 2 2 5 5 5 } { 1 4 4 4 4 4 } }
: p ( -- ) 1 read string>number [ 3 mod 1 + ] keep [ 1 - d nth ] bi@ 2array 21 iota [ drop first2 [ random ] bi@ [ 2array . ] 2keep < ] with map [ ] count [ 11 > "Comput" "Play" ? ] [ "er wins with %d points" sprintf ] bi append print ;

Sim, o Factor não é realmente o idioma a ser usado no golfe, mas é legal.

Matthew Rolph
fonte
0

Python 182

from random import*
u=2+input()
r=[eval("int(choice(`0x1d67e987c0e17c9`[i%3::3])),"*21)for i in(u,u-1)]
U,C=map(sum,r)
print r,['Us','Comput'][U<C]+'er wins with %d points'%abs(U-C)
daniero
fonte
0

R 206

u=scan()
D=list(c(rep(3,5),6),c(2,5),c(1,rep(4,5)))
S=sample
U=S(D[[u]],21,T)
C=S(D[[(u+1)%%3+1]],21,T)
print(cbind(U,C))
W=sum(U>C)
I=(W>10)+1
cat(c("Computer","User")[I],"wins with",c(21-W,W)[I],"points")
modelo
fonte