¿Cuántos dados puedes tirar sin tirar el número más probable?


26

Problema

A partir de n=2dados:

  • Tira los ndados, con cada número del 1 al 6 igualmente probable en cada dado.
  • Compruebe si su suma es igual a la suma más probable para ndados, es decir 3.5*n.
    • Si son iguales, termina.
    • De lo contrario, imprima ny repita desde el principio con n+2dados

Su código no tiene que hacer este procedimiento exactamente, pero debería dar una salida aleatoria probabilísticamente equivalente a él, según nuestra definición de aleatoriedad .

Su programa debería generar todos los números en su propia línea; por ejemplo, si el programa obtuvo hasta 8 dados y sacó el número más probable con 8 dados, la salida sería:

2
4
6

Ejecución de ejemplo

En 2 dados, 7es la suma más probable. Digamos que los números obtenidos fueron 2y 3. Entonces, imprimirías 2.

En 4 dados, 14es la suma más probable. Digamos que los números rodados eran 3, 4, 2, y 5. Entonces, la suma es14 , entonces el programa terminaría aquí.

El resultado final en este caso es "2".

Reglas


Esta respuesta, tal como está, no está muy clara. ¿Hay entrada o está destinada a generar la salida de ninguna entrada como un bucle? ¿Hay alguna aleatoriedad? Parece que no veo ninguna aleatoriedad involucrada.
HyperNeutrino

Por cierto, ¡bienvenido a PPCG! :)
HyperNeutrino

Gracias, lo siento, soy muy nuevo en esto. ¿Qué lo haría más claro? No hay entrada, se supone que debes comenzar con un dado y subir lo más alto posible.
zoecarver

@pudility Entonces, si entiendo correctamente, ¿se supone que debo seguir lanzando 2, 4, 6, 8, ...tantos dados cada vez hasta que llegue al número más probable para esa iteración?
HyperNeutrino

55
¡Gracias por tomarse el tiempo para editar su desafío en función de nuestros comentarios! Para el registro, tenemos un lugar donde puede publicar desafíos para resolver algunos de los detalles antes de publicar: el sandbox .
FryAmTheEggman

Respuestas:


17

Python 2 , 70 bytes

from random import*
n=2
while eval("+randrange(6)-2.5"*n):print n;n+=2

Pruébalo en línea!

El truco consiste en calcular la suma mediante evaluna cadena que se parece

'+randrange(6)-2.5+randrange(6)-2.5'

con ncopias de la expresión concatenada. Las randrange(6)salidas de un número aleatorio a partir de [0,1,2,3,4,5], que se desplaza hacia abajo por 2.5tener promedio de 0. Cuando la suma si 0, la whilecondición falla y el ciclo termina.

Una alternativa que usaba mapera 4 bytes más:

from random import*
n=2
while sum(map(randrange,[6]*n))-2.5*n:print n;n+=2

He encontrado un montón de expresiones de igual longitud para un dado desplazado a cero, pero ninguno más corto

randrange(6)-2.5
randint(0,5)-2.5
randrange(6)*2-5
uniform(-3,3)//1

11
¡Me gusta este! Principalmente porque es el único que entiendo.
zoecarver

7

MATL , 13 bytes

`@E6y&Yrs@7*-

Pruébalo en línea!

Explicación

`       % Do...while top of the stack is truthy
  @E    %   Push 2*k, where k is the iteration index starting at 1
  6     %   Push 6
  y     %   Duplicate 2*k onto the top of the stack
  &Yr   %   Array of 2*k integers distributed uniformly in {1, 2, ..., 6}
  s     %   Sum
  @7*   %   Push 7*k
  -     %   Subtract
        % End (implicit). If the top of the stack is non-zero, the loop
        % proceeds with the next iteration. Else the loop is exited.
        % Display stack (implicit)

6

Jalea ,  19  14 bytes

-5 bytes con ayuda de Leaky Nun (pasando del conteo a la recursividad)

‘‘6ṗX_3.L⁶S?Ṅß

Un programa completo que imprime los resultados separados por nuevas líneas (también se imprime un espacio adicional y una nueva línea, y los errores del programa al final).

Pruébalo en línea! - cada vez que se superan los 6 dados, TIO mata esto debido al uso de memoria, pero funciona en principio, también tarda unos 40 segundos en hacerlo.

Aquí está disponible una versión más amigable de 15 bytes que no lleva tanto tiempo o requiere tanta memoria .

¿Cómo?

Recurrentemente tira 2 dados más hasta que la suma de las caras cada una reducida en 3.5 sea cero, imprimiendo el número de dados a medida que avanza, cuando se alcanza el cero intenta usar un carácter de espacio causando un error de tipo.

‘‘6ṗX_3.L⁶S?Ṅß - Main link: no arguments (implicit left=zero)
‘              - increment (initial zero or the previous result)
 ‘             - increment  (= # of dice to roll, n)
  6            - literal 6
   ṗ           - Cartesian power - all possible rolls of n 6-sided dice with faces 1-6
    X          - pick one of them
      3.       - literal 3.5
     _         - subtract 3.5 from each of the roll results
           ?   - if:
          S    -          sum the adjusted roll results (will be 0 for most common)
        L      - ...then: length (number of dice that were rolled)
         ⁶     - ...else: literal ' ' (causes error when incremented in next step)
            Ṅ  - print that plus a newline
             ß - call this link with the same arity (as a monad with the result)

Wow, eso es muy pocos bytes. ¡Bien hecho! Espero a aceptarlo hasta que algunas personas más respondan.
zoecarver

Sí, es normal esperar un buen rato antes de aceptar, incluso si alguna vez lo haces. Muchas personas le dan una o dos semanas.
Jonathan Allan

Además, se supone que debe generar todas las iteraciones, no solo la última.
zoecarver

Ah, respondí a una edición anterior: eso la cambia por completo, no puedo usar este método de muchas maneras.
Jonathan Allan

Oh, espera un momento n, está bien, tal vez sea rescatable. Pensé que te referías a las sumas :)
Jonathan Allan

6

TI-BASIC, 28 bytes

2→N
While mean(randInt(1,6,N)-3.5
Disp N
N+2→N
End

Explicación

  • randInt(1,6,N) genera una lista de N números aleatorios del 1 al 6
  • mean(randInt(1,6,N)-3.5 obtiene el promedio de los rollos desplazado hacia abajo por 3.5
  • While continúa hasta que la expresión promedio sea igual a cero (la suma más probable)

5

R , 49 bytes

n=2
while(sum(sample(6,n,T)-3.5)){print(n)
n=n+2}

sample(6,n,T)genera n(pseudo) muestras aleatorias del rango 1:6con reemplazo. Restar 3.5 de cada elemento produce un resultado cuyo sumes 0 (falsey) si y solo si es el valor más común.

Pruébalo en línea!

Omite las tiradas de dados impares.


Esto parece producir 80 cada vez para mí, ¿posible error?
zoecarver

@pudility puedes agregar espacios al final para volver a intentarlo; está almacenando en caché las entradas / fragmento de código cada vez
Giuseppe

3
@Giuseppe Puede deshabilitar el caché en TIO en Configuración.
xnor

después de deshabilitar el caché como @xnor dijo, funcionó muy bien. ¡Gracias por la respuesta!
zoecarver

@xnor que sabía! Es bueno saberlo en el futuro.
Giuseppe

4

Java 8, 123 149 113 108 bytes

()->{for(int n=0,s=1,i;s!=n*7;){for(i=s=++n*2;i-->0;s+=Math.random()*6);if(s!=n*7)System.out.println(n*2);}}

O 107 bytes si usamos un Object nullparámetro no utilizado no lugar.

+26 bytes para una corrección de errores, señalado correctamente por @Jules en los comentarios.
-41 bytes gracias al gran pensamiento de @ OliverGrégoire !

Explicación:

Pruébalo aquí

()->{                           // Method without parameter nor return-type
  for(int n=0,                  //  Amount of dice
          s=1,                  //  Sum
          i;                    //  Index
      s!=n*7;){                 //  Loop (1) as long as the sum doesn't equal `n`*7,
                                //  because we roll the dice per two, and 3.5*2=7
    for(i=s=++n*2;              //   Reset both the index and sum to `n`*2,
                                //   so we can use random 0-5, instead of 1-6
                                //   and we won't have to use `+1` at `Math.random()*6`
        i-->0;                  //   Inner loop (2) over the amount of dice
        s+=Math.random()*6      //    And increase the sum with their random results
    );                          //   End of inner loop (2)
    if(s!=n*7)                  //   If the sum doesn't equal `n`*7
      System.out.println(n*2);  //    Print the amount of dice for this iteration 
  }                             //  End of loop (1)
}                               // End of method

1
Creo que hay un error en la función. Si res igual, 3.5*nel programa debe terminar directamente. Pero, si entiendo la función correctamente, se imprimiría nuna última vez antes de finalizar.
raznagul

@raznagul En realidad, no estaba imprimiendo un tiempo adicional. Sin embargo, fue molestado. Lo que hizo antes: aleatorio 1-12 (error 1: debería haber sido 2-12); compruebe si esto es igual a 7: si es así: hemos terminado sin imprimir; si no es así: tira 2 dados nuevamente (error 2, debería haber sido 4 dados en lugar de 2 nuevamente); luego imprime 2 y sube nen 2. Entonces contenía dos errores (1-12 en lugar de 2-12; y tira dados como 2 -> 2 -> 4 -> 6 -> ..., en lugar de 2 -> 4 -> 6 -> ...). Sin embargo, se estaba imprimiendo correctamente, porque no se habría utilizado System.out.println(n),n+=2si rfuera realmente igual a 3.5*n.
Kevin Cruijssen

2
"Tira dos dados a la vez, escogiendo un número aleatorio del 2 al 12". Esto no es probabilísticamente equivalente a tirar dos dados y sumar los números como se requiere en la pregunta, por lo tanto, no es una solución correcta.
Jules

1
Más corto por unos pocos bytes (113), pero probablemente todavía golfable: ()->{for(int n=2,s=0,e=7,i;s!=e;n+=2,e+=7){for(i=n,s=n;i-->0;)s+=Math.random()*6;if(s!=e)System.out.println(n);}}. También, correcto en lo que respecta al comentario de Jules y mi explicación. nes dados, ses suma, ese espera, ies índice. Finalmente, la suma comienza npara evitar a +1, nveces, y s!=ese repite porque simplemente no sé cómo evitar ese caso.
Olivier Grégoire

1
Lo jugué un poco más;)()->{for(int i=0,s=1,j;s!=i*7;){for(j=s=++i*2;j-->0;)s+=Math.random()*6;if(s!=i*7)System.out.println(i*2);}}
Olivier Grégoire

3

05AB1E , 22 20 bytes

-2 Bytes gracias a Emigna

[YF6L.RO}7Y*;ïQ#Y=ÌV

Pruébalo en línea!

Explicación

[YF6L.RO}7Y*;ïQ#Y=ÌV
[                    # Infinite loop start
 YF     }            # Y times... (Y defaults to 2)
   6L.R               # Push a random number between 1 and 6 (why does this have to be so looooong ._.)
       O              # Sum
         7Y*;ï       # Push 3.5 * Y as an int
              Q      # Is it equal to 3.5 * Y?
               #     # If so: Quit
                Y    # Push Y
                 =   # Print without popping
                  ÌV # Set Y to Y + 2

1
Si te mueves Odespués .Rpuedes eliminar )y s.
Emigna

3

R, 48 44 42 bytes

Una mejora de 5 bytes en la respuesta de Giuseppe .

while(sum(sample(6,F<-F+2,1)-3.5))print(F)

Esto (ab) utiliza el hecho de que Fes una variable asignada de forma predeterminada a la FALSEque coacciona 0y que luego puede incrementarse, lo que nos ahorra la necesidad de inicializar una variable de contador.


1
por supuesto, puede guardar dos bytes llamando en sample(6)lugar de sample(1:6)pero tachado 44 sigue siendo 44 .... codegolf.stackexchange.com/a/82343/67312
Giuseppe

@Giuseppe Por supuesto, gracias! He editado la respuesta ahora.
rturnbull

2

PHP , 75 bytes

for($d=2;(++$i*7/2-$r+=rand(1,6))||$i<$d;)$i%$d?:$d+=1+print"$d
".$r=$i="";

Pruébalo en línea!


1
5^2/++$i*$d+=rand()%6Es una condición ligeramente más corta para el bucle. También creo que el ciclo actual sale incorrectamente si el primer "dado" lanzado es un "1" (genera un 0 para la inicial $d).
user59178

@ user59178 Buena idea, pero podría ser una división por cero error, por lo que debo modificarla. Tienes razón, mi solución antes se detiene en este caso, que está mal.
Jörg Hülsermann

Su respuesta de 45 bytes no es válida porque la distribución resultante no es la misma que en la pregunta, consulte aquí . Creo que su respuesta de 42 bytes también está usando la distribución incorrecta; parece suponer, por ejemplo, que para dos dados, es igualmente probable que tenga 2 y 7 como suma.

@Pakk Sí, la respuesta de 45 bytes no es válida. Creo que su pensamiento es falso lo que sucede en la versión de 42 bytes. Mira una versión ampliada ¡ Pruébalo en línea!
Jörg Hülsermann

@ JörgHülsermann Esa versión ampliada confirma lo que digo. En una implementación adecuada, el valor de $ r / $ i debería acercarse a 3.5 para valores mayores de $ i, pero no veo que eso suceda en absoluto. Obtuve un promedio de 1.16 por 9984 dados, que es estadísticamente extremadamente improbable.


1

Mathematica, 47 bytes

For[n=1,Tr@RandomInteger[5,2n++]!=5n,Print[2n]]

-5 bytes de LLlAMnYP


1

05AB1E , 17 bytes

[N·ÌD6Lã.R7;-O_#,

Pruébalo en línea!

Explicación

[                   # loop over N in 0...
 N·Ì                # push N*2+2
    D               # duplicate
     6L             # push range [1 ... 6]
       ã            # cartesian product (combinations of N*2+2 elements in range)
        .R          # pick one at random
          7;-       # subtract 3.5 from each dice roll
             O_#    # if sum == 0 exit loop
                ,   # otherwise print the copy of N*2+2

1

Lote, 109 bytes

@set/an=%1+2,s=n*5/2
@for /l %%i in (1,1,%n%)do @call set/as-=%%random%%%%%%6
@if %s% neq 0 echo %n%&%0 %n%

De manera bastante molesta, randomes una variable de entorno mágico, por lo que solo se reemplaza con un valor aleatorio durante la expansión del entorno, que normalmente ocurre antes de que comience el ciclo for. callhace que suceda cada vez a través del ciclo, pero luego debe duplicar los %signos para evitar que la expansión ocurra antes del ciclo. La diversión comienza porque queremos modular el resultado en 6, lo que requiere un %signo real , que ahora debe duplicarse dos veces. El resultado es seis consecutivos.% s .


1

JavaScript (ES2015), 75 78 bytes

f=(n=2)=>[...Array(n)].reduce(a=>a+Math.random()*6|0,n)==3.5*n?'':n+`
`+f(n+2)

Emite una cadena de resultados separados por nuevas líneas

Editar: guardó un byte gracias a Shaggy, agregó 4 bytes para iniciar la función a las 2

Explicación

f=n=>
  [...Array(n)]                // Array of size n
    .reduce(                   // Combine each item
      a=>a+Math.random()*6|0,  // Add a random roll between 0 and 5 for each item
    n)                         // Start at n to correct rolls to between 1 and 6
    ==3.5*n                    // Compare total to most probable roll total
  ? ''                         // If true, end
  : n+'\n'+f(n+2)              // Otherwise, output n and continue

f=(n=2)=>[...Array(n)].reduce(a=>a+Math.random()*6|0,n)==3.5*n?'':n+`
`+f(n+2)

let roll = _ => document.getElementById('rolls').innerHTML = f();
document.getElementById('roll-button').onclick = roll;
roll();
<button id="roll-button">Roll</button>
<pre id="rolls"></pre>


2
Guarde bytes utilizando una nueva línea literal encerrada en comillas invertidas, en lugar de '\n'.
Shaggy

Esto no comienza con n=2, sino que debe especificar el número inicial de dados cuando se llama a la función.
MT0

1

php - 89 caracteres

$r=0;$n=2;while($r!=$n*3.5){$r=$i=0;while($i<$n){$r+=rand(1,6);$i++;}print $n."
";$n+=2;}

no necesita el primer $r=0;uso en echolugar de print $n."puede escribirse como"$n y para bucles en lugar de mientras permite hacer algo en el bucle posterior o antes para guardar algunos bytes
Jörg Hülsermann


1

Haskell 133 132 bytes

import System.Random;import Control.Monad
s k=do n<-replicateM k$randomRIO(1,6);if sum n==7*div k 2 then pure()else do print k;s(k+2)

Gracias a @Laikoni por las sugerencias en los comentarios a continuación.


1.) Las importaciones deben contarse en el recuento de bytes. 2.) return()se puede acortar pure()y putStrLn$showse puede acortar a print.
Laikoni

Lo arreglaré de inmediato. Gracias
Davide Spataro

Algunas cosas más pequeñas: div k 2 thenpueden ser div k 2theny do print k;s(k+2)son print k>>s(k+2).
Laikoni

1

Octava 55 bytes

n=2;
while mean(randi(6,n,1))-3.5!=0
n
n=n+2;
end

Inspirado por la respuesta de Andrewarchi. Si alguien tiene algunos consejos para acortarlo, son bienvenidos.


Wow, TI-BASIC y Octave tienen sintaxis sorprendentemente similares
andrewarchi

@andrewarchi Octave (la versión en línea es lo que uso) es solo lo básico de lo básico cuando se trata de programación.
Michthan


0

QBIC , 40 bytes

{[1,r|g=g+_r1,6|]~g=r*3.5|_X\g=0?r┘r=r+2

Esto casi literalmente hace lo que pide el desafío; Parece la forma más corta de obtener la distribución correcta.

Explicación

{          DO infinitely
[1,r|      FOR a=1, a<=r (at start, r == 2), a++
g=g+       Add to g (0 at start)
  _r1,6|   a random number between 1 and 6 incl.
]          NEXT
~g=r*3.5   IF the result of all dice rolls equals the expected value
|_X        THEN quit
\g=0       ELSE, reset the dice total
?r┘        PRINT the number of dice used
r=r+2      and add 2 dice.
           END IF and LOOP are courtiously provided by QBIC at EOF.


0

JavaScript (ES6) - 69 caracteres

r=n=>n?r(n-1)+(Math.random()*6|0)-2.5:0;f=(n=2)=>r(n)?n+`
`+f(n+2):""

console.log(f())

Explicacion :

r=n=>                                     # Roll n dice
     n?                                   # If there is a dice left to roll
       r(n-1)                             #   Roll n-1 dice
             +(Math.random()*6|0)         #   Add a random number from 0 .. 5
                                 -2.5     #   Subtract 2.5 so sum of average is 0
                                     :0   # Else total is 0

y:

f=(n=2)=>                                 # Start with n = 2
         r(n)                             # Roll n dice
             ?n+"\n"+f(n+2)               # If non-zero then concatenate n, newline and
                                          #    result for n+2 dice
                           :""            # If zero (average) terminate.

0

Calc2 0.7, 119 118 111 bytes

using"runtime";for(n=2,d=0;d!=3.5*n;Console.WriteLine(n),n+=2)for(i=d=0;i++<n;)d+=Math.Int(Random().Next(1,7));

sin golf:

using "runtime";
var d = 0;
var r = Random();
for(var n = 2; d != 3.5 * n; Console.WriteLine(n), n += 2)
{
    d = 0;
    for(var i = 0; i < n; i++)
        d += Math.Int(r.Next(1,7));
}

Podría prescindir de Math.Int () pero desafortunadamente en 0.7 las funciones Random (). Next () tienen un error en el que todos devuelven dobles en lugar de ints. Se ha solucionado, pero solo después de que se publicó esta pregunta. No voy a ganar nada, pero bueno, buena prueba de concepto.

Editar:

  • Se eliminó el espacio innecesario entre el uso y el "tiempo de ejecución" (-1 byte)

Edit2:

  • eliminó var r y creó un nuevo Random donde es necesario (-4 byte)

  • cambiado i = 0, d = 0 a i = d = 0 (-2 bytes)

  • i incrementado después de la verificación (-1 byte)


0

Ruby , 52 bytes

s=x=2;(s=0;p x.times{s+=rand(6)-2.5};x+=2)while s!=0

Explicación

s=x=2;                                                # sum=2, x=2
      (                                  )while s!=0  # while sum != 0:
       s=0;                                           #  reset the sum
           p                                          #  print
             x.times{              };                 #  repeat x times:
                     s+=                              #   Add to sum:
                        rand(6)                       #    random int in 0..5
                               -2.5                   #    subtract average
                                                      #  (implicitly return x for printing)
                                     x+=2             #  Increment x by 2

Pruébalo en línea!


@Pakk tenga s=0en cuenta la parte frontal del bucle y el uso de x.times. Esto significa que la suma se reinicia cada vez y luego xse lanzan los dados, que debería ser la distribución correcta. Escribiré una explicación de mi código.
Value Ink

Tienes razón, fui demasiado rápido con mi conclusión.

0

Javascript, 87 caracteres

for(n=2;eval('+'.repeat(n).replace(/./g,x=>x+(Math.random()*6|0)))!=2.5*n;n+=2)alert(n)

Prueba con en console.loglugar de alert:

for(n=2;eval('+'.repeat(n).replace(/./g,x=>x+(Math.random()*6|0)))!=2.5*n;n+=2)console.log(n)
console.log('Done')


0

lua, 102 bytes

function r(n,t) for d=1,n do t=t+math.random(1,6)end return t==n*3.5 or print(n)or r(n+2,0)end r(2,0)

O la versión más legible

function r(n,t) --recursive function does its magic, t is given to safe usage bytes(no local)
    for d=1,n do --roll n dice and count them up to the total (t)
         t =t+math.random(1,6)
    end 
    return t==n*3.5 or --check if t==n*3.5. If it is then it ends
           print(n) or --t != n*3.5 thus print n. print returns nil
           r(n+2,0) --both the check and the return value from print are false thus r gets executed.
end 
r(2,0) --start the process

Una versión más atractiva para 96 ​​bytes.

function r(n,t,m)t=t+m(1,6)+m(1,6)return t==n*3.5 or print(n)or r(n+2,t,m)end r(2,0,math.random)

Esto funciona más o menos igual que el primero, pero reutiliza los rollos de llamadas anteriores. Debido a esto, puedo eliminar el bucle for. Ambos se prueban en lua 5.2



-1

PHP, 51 bytes

$r=2;$n=2;while(rand(0,6)-2.5*$r){print $n;$n=$n+2;}

Si su salida es siempre 2, entonces esta no es una respuesta válida ...

Si imprimimos $ n dentro del bucle while, imprimirá lo siguiente: 2,4,6,8,10 .....
Shiva

2
Aún así, no veo cómo esto sigue los requisitos de la pregunta. Utiliza dos variables: "$ n" y "n". "n" no está definido, por lo que se establecerá en cero. Así que efectivamente, lo que haces es imprimir un número par, y tienes la posibilidad de 5/6 de imprimir el siguiente número par. Esto no es matemáticamente equivalente a la distribución en la pregunta.

Typo, que n debería ser siempre 2, actualizó el código.
Shiva

Todavía no es lo que la pregunta pregunta ... Ahora está tirando un dado, verifique si es cinco (= 2 * 2.5); si el dado es cinco, se detiene, y si no es cinco, escribe el siguiente número par y continúa. Matemáticamente es lo mismo que lo que hiciste en la versión anterior del código.
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.