Rolagem Iterada de Dados

12

Dada uma entrada em nque 3 <= n <= 25, execute as seguintes etapas, começando com um ndado de um lado (faces no intervalo [1, n], inclusive):

  1. Imprima o resultado do lançamento dos ndados do lado atual em jogo, na forma kdn: X(onde Xé o resultado e ko número de dados em jogo).
  2. Se Xfor maior ou igual ao n/2número de dados em jogo, adicione um dado. Senão, remova um dado.
  3. Se o número de dados em jogo for igual a 0ou n, pare. Senão, vá para a etapa 1.

Execuções de exemplo (observe que a saída entre parênteses é para explicação e não é necessária):

6 lados:

1d6: 4 (avg: 3.0, add)
2d6: 6 (avg: 6.0, add)
3d6: 9 (avg: 9.0, add)
4d6: 16 (avg: 12.0, add)
5d6: 13 (avg: 15.0, remove)
4d6: 9 (avg: 12.0, remove)
3d6: 5 (avg: 9.0, remove)
2d6: 7 (avg: 6.0, add)
3d6: 11 (avg: 9.0, add)
4d6: 14 (avg: 12.0, add)
5d6: 17 (avg: 15.0, add)

9 lados:

1d9: 7 (avg: 4.5, add)
2d9: 14 (avg: 9.0, add)
3d9: 18 (avg: 13.5, add)
4d9: 18 (avg: 18.0, add)
5d9: 28 (avg: 22.5, add)
6d9: 26 (avg: 27.0, remove)
5d9: 28 (avg: 22.5, add)
6d9: 34 (avg: 27.0, add)
7d9: 33 (avg: 31.5, add)
8d9: 30 (avg: 36.0, remove)
7d9: 29 (avg: 31.5, remove)
6d9: 35 (avg: 27.0, add)
7d9: 32 (avg: 31.5, add)
8d9: 42 (avg: 36.0, add)

Regras

  • As saídas devem estar exatamente no formato kdn: X, com novas linhas separando cada rolo
  • Você deve simular rolando vários dados; simplesmente [1, n]não é permitido retornar um número inteiro aleatório no intervalo (inclusive) multiplicado pelo número de dados atualmente em jogo, pois isso não simula com precisão o lançamento de vários dados.
  • As brechas padrão são proibidas
  • Isso é , então a resposta mais curta em bytes vence

Entre os melhores

O snippet de pilha na parte inferior desta postagem gera o cabeçalho das respostas a) como uma lista da solução mais curta por idioma eb) como um cabeçalho geral.

Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:

## Language Name, N bytes

onde Nestá 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

Se você quiser incluir vários números no cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou deseja listar as penalidades do sinalizador de intérpretes separadamente), verifique se a pontuação real é o último número no cabeçalho:

## Perl, 43 + 2 (-p flag) = 45 bytes

Você também pode transformar o nome do idioma em um link que será exibido no snippet:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

Mego
fonte
Eu acho isso confuso. Resposta de exemplo, por favor?
precisa saber é o seguinte
Resposta de exemplo , pois os exemplos são concisos.
precisa saber é o seguinte
Sua edição foi esclarecida. Obrigado!
precisa saber é o seguinte
16
Você tem certeza da sua aritmética? Um d6 convencional tem um rolo médio de 3,5.
Peter Taylor
11
Todas as médias em seus exemplos parecem errado
edc65

Respostas:

3

Mathematica, 95 89 80 caracteres

For[k=1,0<k<#,If[Print[k,d,#,": ",x=Tr[{1,#}~RandomInteger~k]];x<k/2#,k--,k++]]&

Ungolfed

For[
  k = 1,
  0 < k < #,
  If[
    Print[k, d, #, ": ", x = Tr[{1, #}~RandomInteger~k]];
    x < k/2 #,
    k--,
    k++
  ]
] &
shrx
fonte
1
@ MartinBüttner obrigado por suas sugestões. Echoinfelizmente não pode receber uma sequência de entradas como Printfaz.
shrx
Oh, bom argumento.
27568 Martin Ender
3

PHP, 164 121 112 113 109 bytes

Versão final, eu prometo. Melhorado usando a sugestão de Titus:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$y+=$r/$y>$x/2?:-1;$y<$x&&$y?d($x,$y):0;}

EDIT: Adicionado um byte extra para formatação. Esqueceu que há um FI lá dentro que, graças à eliminação do texto "adicionar / sub", poderia ter sido um operador ternário:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}

A saída agora se parece com:

1d6: 5
2d6: 11
3d6: 8
2d6: 11
3d6: 7
2d6: 4
1d6: 5

EDIT: Graças a @Manatwork, me salvou muito! Versão nova e melhorada:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x=$r\n";if($r/$y>$x/2)$y++;else$y--;if($y<$x&&$y){d($x,$y);}}

Entrada anterior:

function d($x,$y){for($i=0;$i<$y;$i++)($r+=rand(1,$x));$s=$y."d$x=$r, ";if($r/$y>$x/2){$y++;$s.="add";}else{$y--;$s.="sub";}echo $s."\n";if($y<$x&&$y>0){d($x,$y);}}`

Rolos de matrizes separadas, produz isso:

1d6=6, add
2d6=7, add
3d6=11, add
4d6=14, add
5d6=15, sub
4d6=15, add
5d6=18, add

E é assim chamado: d(6, 1);

É obrigatório exibir o sufixo Adde Sub? Isso não está claro na sua pergunta.

steenbergh
fonte
O requisito diz "observe que a saída entre parênteses é para explicação e não é necessária". Dessa forma, parece mais curto:function d($x,$y=1){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x, $r↵";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}
manatwork
@manatwork Obrigado, você realmente ajudou muito!
precisa
O if ainda pode ser um ternário, economizando um byte. E a remodelação do aumento / diminuição pode salvar dois bytes:$y-=$r/$y>$x/2?:-1
Titus
2

Python 3, 125

Economizou 3 bytes graças ao DSM.

def x(d):
 import random;c=1
 while 0<c<d:r=sum(map(random.randint,[1]*c,[d]*c));print('%id%i: %i'%(c,d,r));c+=2*(r>=d*c/2)-1

Muito simples, lança um monte de dados e verifica a média. Nada muito chique aqui ainda.
Ele precisa ser chamado com um int. Então, x(6)produzirá algo como isto:

1d6: 5
2d6: 10
3d6: 8
2d6: 7
3d6: 11
4d6: 8
3d6: 13
4d6: 19
5d6: 13
4d6: 15
5d6: 22

.

Morgan Thrapp
fonte
2

JavaScript (ES6), 97 102 106 112 bytes

Obrigado @ user81655 e @Jupotter por me salvarem alguns bytes.

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// 102 bytes:
f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=0;++i<=k;)x+=1+Math.random()*n|0}

// Previous attempt, 112 bytes
f=n=>{k=1;while(k&&k!=n){for(x=i=0;i++<=k;)x+=1+~~(Math.random()*n);console.log(k+`d${n}: `+x);k+=x<k*n/2?-1:1}}

Demo

Isso funciona apenas em navegadores compatíveis com ES6 (no momento que inclui Firefox e Edge, possivelmente com Chrome e Opera com os recursos experimentais de JavaScript ativados):

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// Snippet stuff
console.log = x => {
  document.getElementById('O').innerHTML += x + `<br>`;
}

document.getElementById('F').addEventListener('submit', e => {
  document.getElementById('O').innerHTML = ``
  f(document.getElementById('I').valueAsNumber)
})
<form id=F action=# method=get>
  <label>
    Number of faces: 
    <input type=number min=3 max=25 value=9 required id=I>
  </label>
  <button>Play</button>
  
  <div>
    <output id=O></output>
  </div>
</form>

rink.attendant.6
fonte
Você pode alterar whilepara um forloop, arredondar para baixo em |0vez de ~~()e mover algumas instruções para remover os colchetes para economizar alguns bytes. Além disso, você pode torná-lo uma função anônima (não f=). 103 bytes:n=>{for(k=1;k&&k!=n;k+=x<k*n/2?-1:1)for(x=i=0;i++<=k;console.log(k+`d${n}: `+x))x+=1+Math.random()*n|0}
user81655
@ user81655 Obrigado. Por alguma razão, sua versão criou muita saída estranha, então mudei console.logpara o outro forloop (me custou 1 char a mais que o seu). Ainda assim,
baixei
Eu acabei de escrever isso sem testá-lo, então estou feliz que tenha funcionado principalmente. :)
user81655
Você pode ganhar um personagem substituindo a k&&k!=ncondição pela comparaçãok%n!=0
Jupotter
@Jupotter Obrigado, k%nfunciona ainda melhor;)
rink.attendant.6
1

CJam, 45 bytes

ri:M;{X__{Mmr+}*[X'dM':S5$N]o_+XM*<_+(-:XM%}g

Experimente online.

Implementa as especificações literalmente (incluindo a fórmula matematicamente incorreta "mean roll"). Como esperado, a portabilidade do programa GolfScript original abaixo para CJam salvou um monte de bytes, devido à menor built-in nomes de comandos ( mr, oe gem vez de rand, putse do).

GolfScript, 51 bytes

~:&;{1..{&rand+}*[1"d"&": "4$]puts.+1&*<.+(-:1&%}do

Aqui está minha entrada original do GolfScript. Truques de golfe notáveis ​​incluem o uso do número 1como uma variável convenientemente pré-inicializada para armazenar o número atual de dados a serem lançados. (Em vez disso X, a versão CJam usa , que CJam inicializa com o valor 1.)


Ps. Vendo o título, originalmente eu queria responder isso em AnyDice . Mas acaba sendo uma escolha horrível para esse desafio, e não acho que seja tecnicamente possível usá-lo para implementar essa especificação, conforme determinado.

O problema é que AnyDice é uma linguagem específica de domínio para escrever programas determinísticos para calcular estatísticas de rolagem de dados. Embora a inspeção dos possíveis resultados de um teste e a execução de testes condicionais com base neles sejam possíveis por recursão, não há como gerar aleatoriedade real. Portanto, embora você possa simular essa sequência de lançamentos de dados no AnyDice, tudo o que você pode obter como resultado são estatísticas sobre coisas como, por exemplo, o número de lançamentos até o término do processo ou a distribuição dos resultados em uma determinada etapa.

Tudo isso dito, aqui está o mais próximo que eu poderia chegar do AnyDice :

N: 6
K: 1
function: clip X:n { result: X * (X < N) }
function: adjust X:n { result: [clip X + ((XdN)*2 >= X*N)*2-1] * (X > 0) }
loop I over {1..20} {
  output K named "dice in roll [I]"
  output KdN named "outcome of roll [I]"
  K: [adjust K]
}

Este não é um código particularmente válido, já que parecia um exercício de futilidade. Os truques de golfe de linguagem padrão, como encurtar nomes de funções e eliminar espaços em branco desnecessários, devem esgotar a maior parte do potencial de golfe.

O truque principal usado aqui é que, quando você chama uma função que espera um número (conforme indicado :nna definição de função) no AnyDice e passa um dado (ou seja, uma distribuição de probabilidade), o AnyDice avalia automaticamente a função para todo o possível valores do dado e combina os resultados em um novo dado.

Aqui está uma captura de tela da saída (no formato de gráfico de barras) para os três primeiros rolos:

Captura de tela AnyDice

(Note-se que a coluna de "0" em cada gráfico indica a probabilidade de que a iteração parado, devido ao número de dados que batem quer 0 ou N, antes de o rolo de corrente. Isto acontece por ser uma forma conveniente para representar a condição de parada, pois é claro que rolar 0dN sempre produz 0.)

Ilmari Karonen
fonte
1

R, 103 bytes

Uma implementação bastante direta. Rolamentos de dados são feitos por sum(sample(n,i)).

i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}

Execução de teste

> i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}
1: 9
2: 
Read 1 item
1d9: 9
2d9: 14
3d9: 10
2d9: 14
3d9: 9
2d9: 9
3d9: 12
2d9: 7
1d9: 9
2d9: 11
3d9: 17
4d9: 18
5d9: 25
6d9: 29
7d9: 33
8d9: 43
9d9: 45
> 
MickyT
fonte
1

CoffeeScript, 106 99 bytes

f=(n,k=1)->(x=k;x+=Math.random()*n|0for[k..0];console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

# Previous attempt, 106 bytes
f=(n,k=1)->(x=i=0;x+=1+Math.random()*n//1while++i<=k;console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

Ungolfed

f = (n, k = 1) ->
 (x = k
 x += 1 + Math.random() * n | 0 for [k..0]
 console.log k + "d#{n}: " + x
 k += x < k * n / 2 && -1 || 1
 ) while k % n
rink.attendant.6
fonte
1

Julia, 77 bytes

n->(N=1;while 0<N<n k=sum(rand(1:n,N));print(N,"d$n: $k
");N+=1-2(2k<N*n)end)

A maior parte disso deve ser auto-explicativa - uma nova linha real está sendo usada na printstring em vez de ser usada printlnpara salvar um byte. rand(1:n,N)produz Nnúmeros inteiros aleatórios entre 1 e n.

Glen O
fonte
1

Ruby, 93 90 82 caracteres

->n{d=s=2
puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}

Exemplo de execução:

2.1.5 :001 > -->n{d=s=2;puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}[6]
1d6: 5
2d6: 10
3d6: 6
2d6: 5
1d6: 5
2d6: 8
3d6: 15
4d6: 18
5d6: 22
homem a trabalhar
fonte
0

QBIC , 83 bytes (não concorrente)

:c=a{e=0[1,q|e=e+_rq,a|]?!q$+@d|!+a$+@:|+!e$~e<c/2|q=q-1\q=q+1]c=q*a~q=a|_X]~q=0|_X

Explicação:

q                    Tracks the number of dice (is implicitly 1 at the start)
:                    Takes input from a CMD line parameter
[1,q|e=e+_rq,a|]     Rolls the dice separately
?!q$+@d|!+a$+@:|+!e$ Prints the roll result (requires an unfortunate amount of casting...)
~e<c/2|q=q-1\q=q+1]  Checks whether to increase or decrease
~q=a|_X]~q=0|_X      Tests the amount of dice and quits on either boundary.
steenbergh
fonte
0

PHP, 104 bytes

for($n=$argv[$k=1];$k&&$k<$n;print$k."d$n: $x\n",$k-=$x<$n*$k/2?:-1)for($x=$i=0;$i++<$k;)$x+=rand(1,$n);

Correr com php -r '<code>' <N>

demolir

for($n=$argv[$k=1];     // import input, init number of dice
    $k&&$k<$n;          // while 0<$k<$n
    print$k."d$n: $x\n",    // 2. print results
    $k-=$x<$n*$k/2?:-1      // 3. remove or add a die
)
    for($x=$i=0;$i++<$k;)   // 1. roll dice separately
        $x+=rand(1,$n);         // sum up results
Titus
fonte