Rollo de dados iterados

12

Dada una entrada ndonde 3 <= n <= 25, realice los siguientes pasos, comenzando con un ndado de un solo lado (caras en el rango [1, n], inclusive):

  1. Imprima el resultado de tirar los ndados del lado actual en juego, en la forma kdn: X(donde Xestá el resultado y kes el número de dados en juego).
  2. Si Xes mayor o igual que n/2el número de dados en juego, agrega un dado. De lo contrario, retire un dado.
  3. Si el número de dados en juego es igual a 0o n, pare. De lo contrario, vaya al paso 1.

Ejecuciones de ejemplo (tenga en cuenta que el resultado entre paréntesis es para explicación y no es obligatorio):

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)

Reglas

  • Las salidas deben estar exactamente en el formato kdn: X, con nuevas líneas que separen cada rollo
  • En realidad, debes simular lanzar múltiples dados; simplemente [1, n]no está permitido devolver un número entero aleatorio en el rango (inclusive) multiplicado por el número de dados actualmente en juego, ya que eso no simula con precisión el lanzamiento de múltiples dados.
  • Las lagunas estándar están prohibidas
  • Este es el , por lo que gana la respuesta más corta en bytes

Tabla de clasificación

El Fragmento de pila al final de esta publicación genera la tabla de clasificación a partir de las respuestas a) como una lista de la solución más corta por idioma yb) como una tabla de clasificación general.

Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:

## Language Name, N bytes

¿Dónde Nestá el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:

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

Si desea incluir varios números en su encabezado (por ejemplo, porque su puntaje es la suma de dos archivos o desea enumerar las penalizaciones de la bandera del intérprete por separado), asegúrese de que el puntaje real sea el último número en el encabezado:

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

También puede hacer que el nombre del idioma sea un enlace que luego aparecerá en el fragmento:

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

Mego
fuente
Esto me parece confuso. Ejemplo de respuesta, por favor?
Hipe99
Ejemplo de respuesta , ya que los ejemplos son concisos.
Hipe99
Tu edición aclarada. ¡Gracias!
Hipe99
16
¿Estás seguro de tu aritmética? Un d6 convencional tiene un rollo promedio de 3.5.
Peter Taylor
11
Todos los promedios en sus ejemplos parecen mal
edc65

Respuestas:

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++]]&

Sin golf

For[
  k = 1,
  0 < k < #,
  If[
    Print[k, d, #, ": ", x = Tr[{1, #}~RandomInteger~k]];
    x < k/2 #,
    k--,
    k++
  ]
] &
shrx
fuente
1
@ MartinBüttner gracias por sus sugerencias. Echodesafortunadamente no puede tomar una secuencia de entradas como lo Printhace.
shrx
Oh, buen punto.
Martin Ender
3

PHP, 164 121 112 113 109 bytes

Versión final, lo prometo. Mejorado usando la sugerencia 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;}

EDITAR: se agregó un byte adicional para formatear. Olvidé que hay un IF allí que, gracias a soltar el texto "agregar / sub", podría haber sido un operador ternario:

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

La salida ahora se ve así:

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

EDITAR: ¡Gracias a @Manatwork, me salvó mucho! Versión nueva y mejorada:

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);}}`

Tira los troqueles separados, genera esto:

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

Y se llama así: d(6, 1);

¿Es obligatorio mostrar el sufijo Addy Sub? Esto no está claro en su pregunta.

Steenbergh
fuente
El requisito dice "tenga en cuenta que el resultado entre paréntesis es para explicación y no es obligatorio". De esta manera parece más corto: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 Gracias, ¡realmente ayudaste mucho!
steenbergh
El if todavía puede ser un ternario, ahorrando un byte. Y remodelar el aumento / disminución puede ahorrar dos bytes:$y-=$r/$y>$x/2?:-1
Titus
2

Pitón 3, 125

Guardado 3 bytes gracias a 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

Bastante simple, tira un montón de dados y verifica el promedio. Nada demasiado lujoso aquí todavía.
Necesita ser llamado con un int. Entonces, x(6)producirá algo como esto:

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

.

Morgan Thrapp
fuente
2

JavaScript (ES6), 97 102 106 112 bytes

Gracias @ user81655 y @Jupotter por salvarme unos pocos 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}}

Manifestación

Esto solo funciona en navegadores compatibles con ES6 (en este momento incluye Firefox y Edge, posiblemente con Chrome y Opera con funciones experimentales de JavaScript habilitadas):

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
fuente
Puede cambiar el whilea un forbucle, redondear hacia abajo en |0lugar de ~~()y mover algunas declaraciones para que pueda eliminar los corchetes para guardar algunos bytes. También se le permite convertirlo en una función anónima (no 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 Gracias. Por alguna razón, su versión creó una gran cantidad de resultados extraños, así que moví console.logel otro forbucle (me costó 1 char más que el suyo). Todavía lo bajé a 106
rink.attendant.6
Acabo de escribir esto sin probarlo, así que me alegro de que haya funcionado. :)
user81655
Puedes ganar un personaje reemplazando la k&&k!=ncondición por la comparaciónk%n!=0
Jupotter
@Jupotter Gracias, k%nfunciona aún mejor;)
rink.attendant.6
1

CJam, 45 bytes

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

Pruébalo en línea.

Implementa la especificación de forma bastante literal (incluida la fórmula matemáticamente incorrecta de "balance medio"). Como se esperaba, portar el programa GolfScript original a continuación a CJam ahorró un montón de bytes debido a nombres de comando integrados más cortos ( y mr, en lugar de , y ).ograndputsdo

GolfScript, 51 bytes

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

Aquí está mi entrada original de GolfScript. Entre los trucos de golf más notables se incluyen el uso del número 1como una variable convenientemente preinicializada para almacenar el número actual de dados que se lanzarán. (En su lugar X, utiliza la versión de CJam , que CJam se inicializa con el valor 1.)


PD. Al ver el título, originalmente quería responder esto en AnyDice . Pero resulta ser una elección horrible para este desafío, y no creo que sea técnicamente posible usarlo para implementar esta especificación como se indica.

El problema es que AnyDice es un lenguaje específico de dominio para escribir programas deterministas para calcular estadísticas de lanzamiento de dados. Al inspeccionar los posibles resultados de un rollo y hacer rollos condicionales basados en ellos es posible a través de la repetición, no hay manera de generar cualquier aleatoriedad real. Entonces, si bien podría simular esta secuencia de tiradas de dados en AnyDice, todo lo que puede obtener como resultado son estadísticas sobre cosas como, por ejemplo, el número de tiradas hasta que finalice el proceso, o la distribución de resultados en un paso dado.

Dicho todo esto, aquí está lo más cerca que pude llegar a 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 no es un código particularmente golfizado, ya que parecía un ejercicio inútil. Los trucos estándar de golf en el lenguaje de llaves, como acortar los nombres de las funciones y eliminar espacios en blanco innecesarios, deberían agotar la mayor parte del potencial de golf de todos modos.

El truco clave utilizado aquí es que, cuando llama a una función que espera un número (como se indica :nen la definición de la función) en AnyDice, y le pasa un dado (es decir, una distribución de probabilidad), AnyDice evalúa automáticamente la función para todos los posibles valores del dado, y combina los resultados en un nuevo dado.

Aquí hay una captura de pantalla de la salida (en formato de gráfico de barras) para los primeros tres rollos:

Captura de pantalla de AnyDice

(Nota que el "0" columna en cada gráfico indica la probabilidad de que la iteración se detuvo, debido al número de dados que golpean ya sea 0 o N, antes de que el rollo actual. Esto pasa a ser una manera conveniente de representar la condición de parada, ya por supuesto, rodar 0dN siempre produce 0.)

Ilmari Karonen
fuente
1

R, 103 bytes

Una implementación bastante sencilla. Los dados se hacen por rollos 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)}

Prueba de funcionamiento

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

Sin golf

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

La mayor parte de esto debería explicarse por sí mismo: se está utilizando una nueva línea real en la printcadena en lugar de usarla printlnpara guardar un byte. rand(1:n,N)produce Nenteros aleatorios entre 1 y n.

Glen O
fuente
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}

Ejecución de muestra:

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
hombre trabajando
fuente
0

QBIC , 83 bytes (no competitivos)

: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

Explicación:

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

Corre con php -r '<code>' <N>

Descompostura

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
fuente