Su tarea es hacer un programa que tome un número entero n > 1y ngenere el resultado de un dado de un solo lado. Sin embargo, este dado sigue las reglas para explotar dados .
Cuando tires el dado, verifica qué valor arrojaste. Si obtuviste el máximo para ese tipo de dado (en un d4 estándar que sería 4, o 6 en un d6, etc.), lanza nuevamente y agrega el nuevo lanzamiento a ese total. Cada lanzamiento continúa sumando al total, hasta que ya no obtengas el número máximo. Sin embargo, ese número final todavía se agrega.
Su programa debe tener un solo número entero ny tirar el ndado que explota. Aquí hay una distribución de ejemplo para mostrar cómo debería ser n=4. Tenga en cuenta que nunca debe generar ningún múltiplo de n, ya que siempre explotarán.
Puede suponer que el tamaño de la pila para cualquier recursividad que haga es infinito, y su función aleatoria debe cumplir con nuestros estándares de aleatoriedad (generador aleatorio incorporado o hora / fecha ). Su función aleatoria también debe ser lo más uniforme posible, en comparación con una distribución geométrica, ya que estamos hablando de dados.

Respuestas:
Código de máquina x86 (para Intel Ivy Bridge y posterior), 17 bytes
Los bytes de código anteriores definen una función que simula un dado explosivo. Se necesita una sola entrada, pasada en el
ESIregistro, que indica el número máximo de dados. Devuelve un solo valor en elECXregistro, que es el resultado de los rollos.Internamente, utiliza la
RDRANDinstrucción para generar un número aleatorio. Utiliza un generador de números aleatorios (RNG) integrado en el hardware de los procesadores Intel Ivy Bridge y posteriores (algunas CPU AMD también admiten esta instrucción).La lógica de la función es bastante sencilla. El número aleatorio generado se escala para ubicarse dentro del rango deseado utilizando la técnica estándar (
(rand % dieSize) + 1), y luego se verifica para ver si debería causar una explosión. El resultado final se mantiene en un registro acumulador.Aquí hay una versión anotada que muestra la mnemotecnia en lenguaje ensamblador:
Estoy haciendo trampa un poco . Todas las convenciones de llamadas estándar x86 devuelven el resultado de una función en el
EAXregistro. Pero, en el verdadero código de máquina, no hay convenciones de llamadas. Puede usar cualquier registro que desee para entrada / salida. El usoECXpara el registro de salida me ahorró 1 byte. Si desea usarEAX, inserte unaXCHG eax, ecxinstrucción de 1 byte inmediatamente antes de laretinstrucción. Esto intercambia los valores de los registrosEAXyECX, copiando efectivamente el resultado deECXenEAX, y desechandoECXcon el valor anterior deEAX.Pruébalo en línea!
Aquí está la función equivalente transcrita en C, usando el
__builtin_ia32_rdrand32_stepintrínseco soportado por GCC, Clang e ICC para generar laRDRANDinstrucción:Curiosamente, GCC con la
-Osbandera transforma esto en casi exactamente el mismo código de máquina . Toma la entrada enEDIlugar deESI, lo cual es completamente arbitrario y no cambia nada sustancial sobre el código. Debe devolver el resultadoEAX, como mencioné anteriormente, y utiliza laMOVinstrucción más eficiente (pero más grande) para hacer esto inmediatamente antes delRET. De lo contrario, samezies. Siempre es divertido cuando el proceso es completamente reversible: ¡escriba el código en ensamblado, transcríbalo a C, ejecútelo a través de un compilador de C y recupere su ensamblaje original!fuente
Python 2 ,
666461 bytes-3 bytes gracias a xnor
Pruébalo en línea!
El rollo anterior se almacena
c, lo que nos permite acceder a él varias veces sin tener que almacenarlo en una variable, que no se puede hacer en una Python lambda. En cada recursión, verificamos si lanzamos dados explosivos.cse inicializa a cero, porc%nlo que falsey está allí. En las próximas iteraciones, solo será falsey si se tiraron los dados explosivos.Python 2 , 55 bytes
Pruébalo en línea!
Mi otra respuesta parece estar un poco sobredimensionada, ya que esto parece funcionar también ... Lo dejaré de todos modos.
fuente
c*(c<n)puede serc%n.R , 39 bytes
Pruébalo en línea!
Explicación: esta solución evita los bucles recursivos / while calculando directamente la distribución del número de explosiones que ocurrirán. Seanorte el número de lados en el dado. Si Usted indica que el éxito como rodar una norte y el fracaso como rodar cualquier otra cosa, entonces usted tiene probabilidad 1norte de éxito. El número total de explosiones es el número de éxitos antes del primer fracaso. Esto corresponde a unG e o m e t r i c ( 1 - 1norte) distribución (consulte lapágina de wikipedia, que define el éxito y el fracaso al revés). Cada explosión traenorte al total. La tirada final sigue unadistribuciónU n i fo r m (1,2,…,n-1) que sumamos al total.
fuente
samplecon los estándares de aleatoriedad, dado su sesgo ?sampleconduce a una falta de uniformidad que da una relación de probabilidad máxima a mínima tan alta como 1.03 ... ¡Sorprendente, no es así!samplecon ? ;-)Perl 6 , 26 bytes
Pruébalo en línea!
Explicación
fuente
{sum roll(*,1..$_)...$_>*}J ,
1611 bytesPruébalo en línea!
Explicación
TL; DR
1+?realiza el lanzamiento del dado,(+$:)^:=reitera solo cuando es igual a la entrada.La función es un tren de 4 verbos:
Un tren es cuando 2 o más verbos se concatenan. Aquí, la respuesta es de la forma
f g h j:Un llamado "tren 4" se analiza como un gancho y un tenedor:
Por lo tanto, la respuesta es equivalente a:
Ganchos:
(f g) xyx (f g) yUn gancho monádico (un argumento) de dos verbos, dado un argumento
x, se cumple la siguiente equivalencia:Por ejemplo,
(* -) 5evalúa a5 * (- 5), que evalúa a_25.Esto significa que nuestro 4-tren, un gancho de
fy(g h j), es equivalente a:¿Pero qué hace
faquí?(+$:)^:=es una conjunción de dos verbos que usan la conjunción Power^:: otro hook ((+$:)) y un verbo (=). Tenga en cuenta que estofes diádico: tiene dos argumentos (xy(g h j) x). Entonces tenemos que ver cómo se^:comporta. La conjunción de poderf^:otoma un verbofy un verbo o un sustantivoo(un sustantivo es solo un dato) y aplicafotiempos. Por ejemplo, tomao = 3. Se cumplen las siguientes equivalencias:Si
oes un verbo, la conjunción de potencia simplemente evaluaráolos argumentos y usará el resultado del sustantivo como recuento repetido.Para nuestro verbo,
oes=, el verbo de igualdad. Se evalúa0para diferentes argumentos y1para argumentos iguales. Repetimos el gancho(+$:)una vez para argumentos iguales y no para los diferentes. Para facilitar la notación de la explicación, dejemosy ⇔ ((g h j) x). Recuerde que nuestro gancho inicial es equivalente a esto:Expandiendo la conjunción, esto se convierte en:
Si
xyyson lo mismo, esto se convierte en:De lo contrario, esto se convierte en:
Ahora, hemos visto tenedores monádicos. Aquí tenemos un tenedor diádico:
Entonces, cuando
xyyson lo mismo, obtenemos:¿Qué es
$:? Se refiere al verbo completo y permite la recursividad. Esto significa que, cuandoxy yare the same, we apply the verb toyand addx`.Tenedores:
(g h j) xAhora, ¿qué hace la horquilla interna? Esto fue
yen nuestro último ejemplo. Para una bifurcación monádica de tres verbos, dado un argumentox, se cumple la siguiente equivalencia:Para el siguiente ejemplo, supongamos que hemos llamado verbos
SUM,DIVIDEyLENGTHque haga lo que supongo que podría hacerlo. Si concatenamos los tres en una bifurcación, obtenemos:Esta bifurcación evalúa el promedio de
x(suponiendo quexsea una lista de números). En J, realmente escribiríamos esto como ejemplo como+/ % #.Una última cosa sobre tenedores. Cuando el "diente" más a la izquierda (en nuestro caso simbólico anterior
g) es un sustantivo, se trata como una función constante que devuelve ese valor.Con todo esto en su lugar, ahora podemos entender el tenedor anterior:
?Poniendolo todo junto
Dadas todas estas cosas, nuestro verbo es equivalente a:
Esto expresa la funcionalidad deseada.
fuente
(+$:)^:=1+?Jalea , 7 bytes
Pruébalo en línea!
Utiliza la recursividad. Ejecuta el programa nuevamente (
ß) y agrega (+) si (¡) el número aleatorio (X) es igual (=) a la entrada del programa.}haceßactuar sobre la entrada del programa y se¥combina+ß}en un solo enlace para¡consumir.Aquí una distribución de 1000 salidas para n = 6 que recolecté usando este programa. Trazado con python / matplotlib.
Aquí hay 5000 puntos de datos de n = 3 en un gráfico de semilog que muestra la distribución exponencial (¿aproximadamente?).
fuente
Pyth -
1211 bytesUtiliza funcional mientras. Siento que debería haber una respuesta más inteligente que simplemente simule la distribución.
Pruébalo en línea .
fuente
Python 3 , 80 bytes
Pruébalo en línea!
fuente
r.random()devuelve 0.1-r.random()debería funcionar.import ... as _es más corto!05AB1E , 10 bytes
Pruébelo en línea o verifique las listas .
Alternativa de 10 bytes:
Pruébelo en línea o verifique las listas .
Aunque me gusta más el primero porque tiene la "palabra"
DIÊ, que se adapta al desafío.Explicación:
fuente
.Γo algo.Wolfram Language (Mathematica) , 50 bytes
Pruébalo en línea!
fuente
R ,
4742 bytesPruébalo en línea!
Crédito al enfoque de ArBo .
Aún un byte más largo que el de Robin Ryder , ¡vota el suyo!
fuente
ifpara 46 bytes, pero terminé obteniendo un 52 en un rollo que no debería ser posible con n = 4, por lo que no sé si está sucediendo algo extraño de límite de recursión baja, pero yo creo que puede tener errores. Pruébalo en línea!Ruby , 35 bytes
Pruébalo en línea!
fuente
xvariable: ¡ Pruébelo en línea!APL (Dyalog Unicode) ,
1514 bytesPruébalo en línea!
fuente
Haskell ,
7776 bytesPruébalo en línea!
Gracias a killmous por un byte.
Si
<|>estuviéramos en el preludio, podríamos mejorar conMonadComprehensions:Haskell , no competidor, 66 bytes
Pruébalo en línea!
fuente
Python 2 , 53 bytes
Pruébalo en línea!
Utiliza la
oridea de cortocircuito de la respuesta de ArBo . La expresiónrandom()*n//1genera un número desde0hastan-1,0tomando el lugar de un rollo den. Elortoma el número que, excepto si se trata de cero (Falsey-) que sigue an+f(n).fuente
Japt , 13 bytes
Intentalo
La respuesta del puerto de Arnauld . Descubrí cómo hacer una llamada recursiva;)
JS transpuesto:
fuente
N.g(f):)U. Saltar una línea parece funcionar también. Ese es un buen truco :)Japt , 12 bytes
Puede ser más corto que la solución de dana, pero es mucho más feo. Solo lo estoy publicando porque parece una eternidad ya que teníamos una solución Japt que comenzó con una línea vacía.
Intentalo
fuente
PowerShell , 49 bytes
Pruébalo en línea!
Método iterativo Ajusta la entrada
$argsa$ay el$lrodillo ast (hecho hasta entrar en el bucle al menos una vez). Luego, mientras el último lanzamiento sea-equal a la entrada, seguimos rodando. Dentro del bucle, acumulamos en$oel último rollo, que se actualiza creando un rango de1entrada$ay seleccionando unRandomelemento del mismo. (Honestamente, estoy un poco sorprendido de que$o+=$l=funcione). Una vez que estamos fuera del ciclo, nos vamos$oa la tubería y la salida es implícita.fuente
Adelante (gforth) , 72 bytes
Pruébalo en línea!
Explicación del Código
fuente
Lote, 70 bytes.
Toma la entrada
ncomo un parámetro de línea de comando%1.des el rollo actual,tel total acumulado. Simplemente sigue rodando hastadque no sea igual an.fuente
Jalea , 9 bytes
Pruébalo en línea!
Una alternativa que no tiene esta limitación es:
Jalea , 10 bytes
Pruébalo en línea!
Tenga en cuenta que ambos enlaces TIO generan 400 números para mostrar la distribución.
fuente
Python 3 ,
8172 bytesPruébalo en línea!
-9 bytes gracias a ArBo
Explicación
fuente
from random import*lugar.TI-BASIC,
2823 bytes-5 bytes gracias a esta meta publicación!
La entrada está adentro
Ans.La salida está en
Ansy se imprime implícitamente.Ejemplos:
Explicación:
Notas:
fuente
startTmrya no es necesario, este envío ahora funcionará para versiones de TI-BASIC anteriores a la TI-84 +SmileBASIC 3, 49 bytes
La función
D N OUT Rimplementa tiradas de dados explosivas de forma recursiva.Sin golf
Tenga en cuenta que en SmileBASIC, las funciones pueden tener múltiples valores de retorno. Si una función tiene un valor de retorno, entonces
fun in OUT varyvar = fun(in)son exactamente iguales, es por eso que podemos definir la función enOUTforma y también llamarla en una expresión en el cuerpo de la función. Si hubiera definido la función comoDEF D(N)tendría que declarar explícitamenteRETURN Ren el cuerpo de la función; mezclar ambas sintaxis me ahorró bytes.fuente
Potencia Shell , 43 bytes (método iterativo)
Pruébalo en línea!
PowerShell , 48 bytes (método recursivo)
Pruébalo en línea!
fuente
Jalea , 7 bytes
Un enlace monádico que acepta un número entero
n, que produce un número entero.¿Cómo?
fuente
SmileBASIC, 41 bytes
Despues de leer:
Me di cuenta de que, en lugar de verificar si era una tirada de dados
n, puedes repetir mientras la suma es un múltiplo den.fuente
AnyDice , 36 bytes
Casi incorporado en el idioma:
Para que esto sea correcto, tengo que abusar del supuesto de profundidad de recursión infinita. AnyDice limita la profundidad de recursión con una profundidad de función máxima de propiedad global. el estallido incorporado, sin embargo, usa el suyo propio; profundidad de explosión, que por defecto es 2.
Agregaría otros 25 bytes; y realmente no cumpliría con los requisitos ya que es teóricamente posible que un dado explote más de 99 veces.
La salida de la función es un dado, es decir. un tipo incorporado de AnyDice que es una combinación de resultados y probabilidades para el resultado.
fuente
CJam , 19 bytes
Explicación:
O en seudocódigo:
Como un diagrama de flujo:
Pruébalo en línea!
fuente
Excel VBA, 46 bytes
Gracias a @TaylorScott
Ejecutado en la ventana de comandos.
Como una función definida por el usuario.
Excel VBA,
10867 bytesfuente
do..loop whiley convirtiendo la función en una función de ventana inmediata. -Do:v=-Int(-[A1]*Rnd):t=t+v:Loop While[A1]=v:?t- 46 Bytes