Combien de dés pouvez-vous lancer sans lancer le nombre le plus probable


26

Problème

À partir des n=2dés:

  • Lancez des ndés, chaque chiffre de 1 à 6 étant également probable sur chaque dé.
  • Vérifiez si leur somme est égale à la somme la plus probable pour les ndés, c'est-à-dire 3.5*n.
    • S'ils sont égaux, mettez fin.
    • Sinon, imprimez net répétez depuis le début avec les n+2dés

Votre code n'a pas à effectuer cette procédure exactement, mais doit donner une sortie aléatoire probabilistiquement équivalente à celle-ci, basée sur notre définition de l'aléatoire .

Votre programme devrait sortir tous les numéros sur leur propre ligne; par exemple, si le programme a obtenu jusqu'à 8 dés et a lancé le nombre le plus probable avec 8 dés, le résultat serait:

2
4
6

Exemple d'exécution

Sur 2 dés, 7c'est la somme la plus probable. Disons que les chiffres obtenus étaient 2et 3. Ensuite, vous imprimeriez 2.

Sur 4 dés, 14c'est la somme la plus probable. Disons que les chiffres étaient roulés 3, 4, 2et 5. Ensuite, la somme est 14, donc le programme se terminerait ici.

La sortie finale dans ce cas est "2".

Règles


Cette réponse, en l'état, n'est pas très claire. Y a-t-il une entrée, ou est-il destiné à générer la sortie à partir d'aucune entrée sous forme de boucle? Y a-t-il un caractère aléatoire? Je ne pense pas qu'il y ait de hasard.
HyperNeutrino

Au fait, bienvenue chez PPCG! :)
HyperNeutrino

Merci, Désolé, je suis très nouveau dans ce domaine. Qu'est-ce qui le rendrait plus clair? Il n'y a aucune entrée, vous êtes censé commencer avec un dé et remonter le plus haut possible.
Zoecarver

@pudility Donc, si je comprends bien, je suis censé continuer à produire 2, 4, 6, 8, ...autant de dés à chaque fois jusqu'à ce que j'atteigne le nombre le plus probable pour cette itération?
HyperNeutrino

5
Merci d'avoir pris le temps de modifier votre défi en fonction de nos commentaires! Pour mémoire, nous avons un endroit où vous pouvez publier des défis pour travailler sur certains détails avant de publier: le bac à sable .
FryAmTheEggman

Réponses:


17

Python 2 , 70 octets

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

Essayez-le en ligne!

L'astuce consiste à calculer la somme en evaling une chaîne qui ressemble

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

avec des ncopies de l'expression concaténées. Les randrange(6)sorties un nombre aléatoire de [0,1,2,3,4,5], qui est décalé vers le bas 2.5pour avoir une moyenne de 0. Lorsque la somme si 0, la whilecondition échoue et la boucle se termine.

Une alternative utilisant mapétait de 4 octets de plus:

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

J'ai trouvé un tas d'expressions de longueur égale pour un dé décalé à zéro, mais aucune plus courte

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

11
J'aime celui la! Principalement parce que c'est le seul que je comprends.
Zoecarver

7

MATL , 13 octets

`@E6y&Yrs@7*-

Essayez-le en ligne!

Explication

`       % 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

Gelée ,  19  14 octets

-5 octets avec l'aide de Leaky Nun (passage du décompte à la récursivité)

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

Un programme complet imprimant les résultats séparés par des retours à la ligne (un espace supplémentaire et un retour à la ligne sont également imprimés, et les erreurs de programme à la fin).

Essayez-le en ligne! - chaque fois que 6 dés sont dépassés, TIO tue cela en raison de l'utilisation de la mémoire, mais cela fonctionne en principe - cela prend également ~ 40s pour le faire.

Une version plus conviviale de 15 octets qui ne prend pas autant de temps ou nécessite autant de mémoire est disponible ici .

Comment?

Lance récursivement 2 dés supplémentaires jusqu'à ce que la somme des faces réduites chacune de 3,5 soit nulle, imprimant le nombre de dés au fur et à mesure, lorsque le zéro est atteint, il tente d'utiliser un caractère espace provoquant une erreur de type.

‘‘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, c'est très peu d'octets. Bien joué! Je retiens de l'accepter jusqu'à ce que quelques personnes de plus répondent.
Zoecarver

Oui, il est normal d'attendre un bon moment avant d'accepter, même si c'est le cas. Beaucoup de gens lui donnent une semaine ou deux.
Jonathan Allan

De plus, vous êtes censé produire toutes les itérations - pas seulement la dernière.
Zoecarver

Oh, j'ai répondu à un vieux montage - qui le change complètement, je ne peux pas utiliser cette méthode à bien des égards.
Jonathan Allan

Oh attend juste le ns, OK peut-être que c'est récupérable. Je pensais que vous vouliez les sommes :)
Jonathan Allan

6

TI-BASIC, 28 octets

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

Explication

  • randInt(1,6,N) génère une liste de N nombres aléatoires de 1 à 6
  • mean(randInt(1,6,N)-3.5 obtient la moyenne des rouleaux réduite de 3,5
  • While continue jusqu'à ce que l'expression moyenne soit égale à zéro (la somme la plus probable)

5

R , 49 octets

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

sample(6,n,T)génère ndes échantillons (pseudo) aléatoires à partir de la plage 1:6avec remplacement. La soustraction de 3,5 de chaque élément donne un résultat dont la valeur sumest 0 (falsey) si et seulement si c'est la valeur la plus courante.

Essayez-le en ligne!

Saute les jets de dés impairs.


Cela semble produire 80 à chaque fois pour moi, bug possible?
Zoecarver

@pudility vous pouvez ajouter des espaces à la fin pour réessayer; il met en cache les extraits de code / entrées à chaque fois
Giuseppe

3
@Giuseppe Vous pouvez désactiver le cache dans TIO sous Paramètres.
xnor

après avoir désactivé le cache comme @xnor l'a dit, cela a très bien fonctionné. Merci d'avoir répondu!
Zoecarver

@xnor qui savait! Bon à savoir à l'avenir.
Giuseppe

4

Java 8, 123 149 113 113 108 octets

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

Ou 107 octets si nous utilisons à la place un Object nullparamètre as .

+26 octets pour une correction de bogue, correctement signalé par @Jules dans les commentaires.
-41 octets grâce à la grande pensée de @ OliverGrégoire !

Explication:

Essayez-le ici.

()->{                           // 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
Je pense qu'il y a une erreur dans la fonction. Si régal à, 3.5*nle programme doit se terminer directement. Mais, si je comprends bien la fonction, elle s'imprimerait nune dernière fois avant de se terminer.
raznagul

@raznagul En fait, il n'imprimait pas une fois de plus. Il a cependant été buggé. Ce qu'il faisait avant: aléatoire 1-12 (bug 1: aurait dû être 2-12); vérifiez si cela est égal à 7: si c'est le cas: nous avons terminé sans imprimer; si ce n'est pas le cas: lancez à nouveau 2 dés (bug 2, aurait dû être à nouveau 4 dés au lieu de 2); puis imprimez 2 et augmentez nde 2. Il contenait donc deux bugs (1-12 au lieu de 2-12; et lancer des dés comme 2 -> 2 -> 4 -> 6 -> ..., au lieu de 2 -> 4 -> 6 -> ...). Cependant, il s'imprimait correctement, car il ne serait pas allé System.out.println(n),n+=2s'il rétait en effet égal à 3.5*n.
Kevin Cruijssen

2
"Lancez deux dés à la fois, en choisissant un nombre aléatoire entre 2 et 12" - ce n'est pas probablement équivalent à lancer deux dés et à ajouter les nombres requis dans la question, ce n'est donc pas une bonne solution.
Jules

1
Shorter par quelques octets (113), mais probablement encore 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);}}. Aussi, correct en ce qui concerne le commentaire de Jules et mon explication. nest dés, sest somme, eest attendu, iest index. Enfin, la somme commence par néviter un +1, nfois, et s!=eest répétée parce que je ne sais tout simplement pas comment éviter ce cas.
Olivier Grégoire

1
Je l'ai revu un peu;)()->{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 octets

-2 octets grâce à Emigna

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

Essayez-le en ligne!

Explication

[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 vous déménagez Oaprès, .Rvous pouvez supprimer )et s.
Emigna

3

R, 48 44 42 octets

Une amélioration de 5 octets sur la réponse de Giuseppe .

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

Cette (ab) utilise le fait qu'il Fs'agit d'une variable par défaut affectée à FALSElaquelle contraint 0et peut ensuite être incrémentée, ce qui nous évite d'avoir à initialiser une variable de compteur.


1
bien sûr, vous pouvez enregistrer deux octets en appelant sample(6)au lieu de sample(1:6)mais barré 44 est toujours 44 .... codegolf.stackexchange.com/a/82343/67312
Giuseppe

@Giuseppe Bien sûr, merci! J'ai édité la réponse maintenant.
rturnbull

2

PHP , 75 octets

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

Essayez-le en ligne!


1
5^2/++$i*$d+=rand()%6est une condition légèrement plus courte pour la boucle. Je pense aussi que la boucle actuelle se termine incorrectement si le tout premier "dé" lancé est un "1" (il génère un 0 pour l'initiale $d).
user59178

@ user59178 Belle idée mais cela pourrait être une division par zéro erreur donc je dois la modifier. Vous avez raison ma solution avant de vous arrêter dans ce cas qui est faux.
Jörg Hülsermann

Votre réponse de 45 octets n'est pas valide car la distribution résultante n'est pas la même que dans la question, voir ici . Je pense que votre réponse de 42 octets utilise également la mauvaise distribution; il semble supposer, par exemple, que pour deux dés, il est également susceptible d'avoir 2 et 7 comme somme.

@Pakk Oui, la réponse à 45 octets n'est pas valide. Je pense que votre pensée est fausse ce qui se passe à la version 42 octets. Regardez une version élargie Essayez-le en ligne!
Jörg Hülsermann

@ JörgHülsermann Cette version étendue confirme ce que je dis. Dans une implémentation correcte, la valeur de $ r / $ i devrait se rapprocher de 3,5 pour des valeurs plus élevées de $ i, mais je ne vois pas du tout cela se produire. J'ai obtenu une moyenne de 1,16 pour 9984 dés, ce qui est statistiquement extrêmement improbable.


1

Mathematica, 47 octets

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

-5 octets de LLlAMnYP


1

05AB1E , 17 octets

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

Essayez-le en ligne!

Explication

[                   # 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

Lot, 109 octets

@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%

Plutôt ennuyeux, il randoms'agit d'une variable d'environnement magique, elle n'est donc remplacée que par une valeur aléatoire lors de l'expansion de l'environnement, ce qui se produit normalement avant le début de la boucle for. callle fait se produire à chaque fois dans la boucle, mais vous devez ensuite doubler les %signes pour empêcher l'expansion de se produire avant la boucle. Le plaisir commence car nous voulons moduler le résultat par 6, ce qui nécessite un vrai %signe, qui doit maintenant être doublé deux fois. Le résultat est six %s consécutifs .


1

JavaScript (ES2015), 75 78 octets

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

Produit une chaîne de résultats séparés par des retours à la ligne

Edit: enregistré un octet grâce à Shaggy, ajouté 4 octets pour démarrer la fonction à 2

Explication

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
Enregistrez un octet en utilisant un saut de ligne littéral entre guillemets, au lieu de '\n'.
Shaggy

Cela ne commence pas par n=2, au lieu de cela, vous devez spécifier le nombre de dés de départ lorsque la fonction est appelée.
MT0

1

php - 89 caractères

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

vous n'avez pas besoin de la première $r=0;utilisation echoau lieu de print $n."peut être écrit au fur "$net à mesure des boucles au lieu de tandis que permet de faire quelque chose dans la boucle après ou avant pour enregistrer quelques octets
Jörg Hülsermann


1

Haskell 133 132 octets

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)

Nous remercions @Laikoni pour les suggestions dans les commentaires ci-dessous.


1.) Les importations doivent être comptées dans le nombre d'octets. 2.) return()peut être raccourci pure()et putStrLn$showraccourci print.
Laikoni

Je vais le réparer tout de suite. Merci
Davide Spataro

Quelques petites choses supplémentaires: div k 2 thenpeuvent être div k 2thenet do print k;s(k+2)sont print k>>s(k+2).
Laikoni

1

Octave 55 octets

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

Inspiré par la réponse d'Andrewarchi. Si quelqu'un a des conseils pour le raccourcir, il est le bienvenu.


Wow, TI-BASIC et Octave ont des syntaxes étonnamment similaires
andrewarchi

@andrewarchi Octave (la version en ligne est ce que j'utilise) n'est que la base des bases en matière de programmation.
Michthan

1

Pyth , 20 octets

K2WnsmhO6K*K3.5K=+K2

Essayez-le en ligne!


Bienvenue chez PPCG!
Martin Ender

Merci! Je viens de terminer le didacticiel Pyth et je me suis dit que je pourrais essayer, bien que cela soit probablement encore améliorable. Toutes les suggestions sont appréciées.
qwertz

0

QBIC , 40 octets

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

Cela fait à peu près littéralement ce que le défi demande; semble le moyen le plus court pour obtenir la bonne distribution.

Explication

{          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 caractères

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

Explication :

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

et:

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 octets

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

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

Je pourrais me passer de Math.Int () mais malheureusement en 0.7 les fonctions Random (). Next () ont un bug où elles retournent toutes des doubles au lieu des ints. Il a été corrigé mais seulement après que cette question a été publiée. Je ne gagnerai rien, mais bon, belle preuve de concept.

Modifier:

  • suppression de l'espace inutile entre l'utilisation et le "runtime" (-1 octet)

Edit2:

  • supprimé var r et créer un nouveau aléatoire là où il est nécessaire (-4 octets)

  • changé i = 0, d = 0 en i = d = 0 (-2 octets)

  • incrémenté i après vérification (-1 octet)


0

Rubis , 52 octets

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

Explication

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

Essayez-le en ligne!


@Pakk note the s=0 at the front of the loop and the use of x.times. This means the sum is reset every time and then x dice are rolled, which should be the correct distribution. I'll write up an explanation of my code.
Value Ink

You are correct, I was too fast with my conclusion.

0

Javascript, 87 chars

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

Test with console.log instead of 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)

Or the more readable version

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

A more cheaty version for 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)

This pretty much works the same as the first but reuses the rolls from earlier calls. Because of this I can remove the for loop. Both are tested in lua 5.2



-1

PHP, 51 bytes

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

If your output is always 2, then this is not a valid answer...

If we print $n inside while loop, then it will print the following : 2,4,6,8,10.....
Shiva

2
Still, I don't see how this follows the requirements in the question. You use two variables: "$n" and "n". "n" is undefined, so will be set to zero. So effectively, what you do is print an even number, and have a chance of 5/6 of printing the next even number. This is mathematically not equivalent to the distribution in the question.

Typo, that n should be always 2, updated the code.
Shiva

Still not what the question asks... Now you are throwing a die, check if it is five (=2*2.5); if the die is five, you stop, and if it is not five, you write the next even number and continue. Mathematically effectively the same as what you did in the previous version of the code.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.