En muhtemel sayıyı atmadan kaç zar alabilirsin


26

Sorun

Zardan başlayarak n=2:

  • Rulo nher sayı 1 ila 6 eşit ölçüde muhtemel her bir kalıp üzerinde zar.
  • nToplamlarının zar için en muhtemel toplama eşit olup olmadığını kontrol edin , yani 3.5*n.
    • Eşitlerse, sonlandırın.
    • Aksi takdirde, zardan nbaşlayarak yazdırın ve tekrarlayınn+2

Kodunuz tam olarak bu prosedürü uygulamak zorunda değildir, ancak rastgelelik tanımımıza dayanarak, olasılıkla buna eşdeğer rastgele bir çıktı vermelidir .

Programınız tüm numaraları kendi satırlarında vermelidir; örneğin, program 8 zar attığında ve 8 zar ile en muhtemel sayıyı atarsa, çıktı şöyle olacaktır:

2
4
6

Örnek Çalıştırma

2 zarda, 7en muhtemel toplamı. Diyelim ki haddelenmiş sayılar 2ve 3. Ardından, yazdırırsınız 2.

4 zarda, 14en muhtemel toplamıdır. Diyelim haddelenmiş numaralar söylemek 3, 4, 2, ve 5. O zaman, toplam, 14program burada sonlandırılacak.

Bu durumda son çıktı "2".

kurallar


Bu cevap, olduğu gibi, çok belirsiz. Girdi var mı, yoksa döngü olarak girdi içermeyen çıktı üretmek mi gerekiyor? Herhangi bir rastgelelik var mı? İçinde rastgele rastgele herhangi bir şey görmüyorum.
HyperNeutrino

Bu arada, PPCG'ye hoş geldiniz! :)
HyperNeutrino

Teşekkürler, üzgünüm bu konuda çok yeniyim. Bunu daha net yapan ne? Girdi yok, bir ölüme başlamanız ve mümkün olduğu kadar yükseğe çıkmanız gerekiyor.
zoecarver

Pudility Yani doğru anlarsam, 2, 4, 6, 8, ...bu yineleme için en muhtemel sayıya ulaşana kadar her seferinde bu kadar zar attığımı mı düşünüyorsun?
HyperNeutrino

5
Geri bildirimimize dayanarak zorluklarınızı düzenlemek için zaman ayırdığınızdan dolayı teşekkür ederiz! Kayıt için, göndermeden önce bazı ayrıntıları çözmek için zorluk gönderebileceğiniz bir yerimiz var: sanal alan .
FryAmTheEggman

Yanıtlar:


17

Python 2,70 bayt

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

Çevrimiçi deneyin!

İşin püf noktası eval, bir dize gibi görünerek toplamı hesaplamaktır.

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

ile nifade kopyaları Zincirleme. randrange(6)Çıkışları bir rasgele sayı [0,1,2,3,4,5]ile düşürülmüştür, 2.5ortalama olması 0. Toplam varsa 0, whilekoşul başarısız olur ve döngü sona erer.

Alternatif bir mapkullanım 4 bayt daha uzundu:

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

Sıfır anlamına gelen bir kalıba eşit uzunlukta ifadeler demet buldum, ancak hiçbiri daha kısa değil

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

11
Bunu beğendim! Esas olarak, anladığım tek şey bu.
zoecarver

7

MATL , 13 bayt

`@E6y&Yrs@7*-

Çevrimiçi deneyin!

açıklama

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

Jöle ,  19  14 bayt

- Sızdıran Rahibe'nin yardımıyla 5 bayt (sayımdan özyinelemeye geçiş)

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

Sonuçları yeni satırlarla ayıran tam bir program (ekstra bir boşluk ve yeni satır da yazdırılır ve sonunda program hataları).

Çevrimiçi deneyin! - 6 zar atıldığında herhangi bir zamanda TIO bunu hafıza kullanımı nedeniyle öldürür, ancak prensip olarak çalışır - aynı zamanda ~ 40 saniye sürer.

Burada çok uzun sürmeyen veya çok fazla bellek gerektiren daha kolay 15 byte'lık bir sürüm var .

Nasıl?

Her biri 3.5 değerinde azaltılmış yüzlerin toplamı sıfır olana kadar tekrarlı bir şekilde 2 zar atılır, gider sırasındaki zar sayısını yazdırır, sıfıra ulaştığında bir tür hatasına neden olan bir boşluk karakteri kullanmaya çalışır.

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

Vay, bu çok az bayt. Aferin! Birkaç kişi cevap verene kadar kabul etmeye devam ediyorum.
zoecarver

Evet, kabul etmeden önce bir süre beklemek normaldir, öyle olsa bile. Birçok insan bir iki hafta verir.
Jonathan Allan,

Ayrıca, tüm yinelemelerin çıktısını almanız gerekir - yalnızca sonuncuyu değil.
zoecarver

Oh, eski bir düzenlemeyi cevapladım - tamamen değiştirdi, bu yöntemi pek çok şekilde kullanamıyorum.
Jonathan Allan,

Oh sadece ns bekle , tamam belki kurtarılabilir. Toplamları kastediyorsun sanmıştım :)
Jonathan Allan

6

TI-BASIC, 28 bayt

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

açıklama

  • randInt(1,6,N) 1 ile 6 arasında bir N rasgele sayı listesi oluşturur
  • mean(randInt(1,6,N)-3.5 3,5 puan aşağı kaydırılan ruloların ortalamasını alır
  • While Ortalama ifade sıfıra eşit olana kadar devam eder (en olası toplam)

5

R , 49 bayt

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

sample(6,n,T)replasman ile naralıktan rastgele örnekler üretir (sözde) 1:6. Her elemandan 3.5 çıkartmak, bir sonuç verir.sum , eğer (sadece en yaygın değerse) 0 (falsey) .

Çevrimiçi deneyin!

Tek zar atmalarını atlar.


Bu benim için her zaman 80 çıktı gibi görünüyor, olası hata?
zoecarver

@pudility sonunda tekrar denemek için boşluk ekleyebilirsiniz; her seferinde girişleri / kod pasajını önbelleğe alıyor
Giuseppe

3
@Giuseppe Önbelleği, Ayarlar altındaki TIO'da devre dışı bırakabilirsiniz.
xnor

@xnor gibi önbelleği devre dışı bıraktıktan sonra, Çok iyi çalıştı. Cevap için teşekkürler!
zoecarver

@xnor kim biliyordu! Gelecekte bilmek güzel.
Giuseppe

4

Java 8, 123 149 113 108 bayt

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

Veya bunun yerine kullanılmayan bir parametre kullanırsak , 107 bayt .Object null

Bir hata düzeltme için +26 bayt , yorumlarda @Jules tarafından doğru bir şekilde belirtilmiş . @ OliverGrégoire
sayesinde -41 bayt 'in harika düşüncesi !

Açıklama:

Burada dene.

()->{                           // 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
İşlevde bir hata olduğunu düşünüyorum. Eğer reşit 3.5*nprogramı doğrudan sonlandırmak gerekir. Ancak, işlevi doğru anlarsam, nsonlandırmadan önce son bir kez basar.
raznagul

@raznagul Aslında, ek bir zaman basmıyordu. Ancak tıkanmıştı. Daha önce ne yaptı: rastgele 1-12 (hata 1: 2-12 olmalıydı); Bunun 7'ye eşit olup olmadığını kontrol edin: öyleyse: yazdırmadan bitirdik; eğer değilse: tekrar 2 zar atın (2. böcek, tekrar 2 yerine 4 zar olmalıydı); sonra 2'ye yazdırın ve n2'ye yükseltin . Böylece iki böcek (2-12 yerine 1-12; ve 2 -> 2 -> 4 -> 6 -> ... gibi, 2 -> 4 -> 6 -> ...). Ancak doğru şekilde yazdırıyordu, çünkü gerçekten de eşit System.out.println(n),n+=2olsaydı rgitmezdi 3.5*n.
Kevin Cruijssen

2
"Bir defada iki zar at, 2-12 arasında rastgele bir sayı seçerek" - bu muhtemelen iki zar atmaya ve soruda gereken sayıları eklemeye olasılıkla eşdeğer değildir, bu nedenle doğru bir çözüm değildir.
Jules

1
Birkaç bayt (113) tarafından kısa ama muhtemelen hala 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);}}. Ayrıca, Jules'un yorumuna ve açıklamama göre düzeltin. ndices, stoplamı, ebeklenen, iendeksidir. Sonunda toplam , birkaç kez nönlemek için başlar ve tekrarlanır, çünkü bu davadan nasıl kaçınılacağımı bilmiyorum. +1ns!=e
Olivier Grégoire

1
Yine biraz golf oynadım;)()->{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 bayt

-2 Emigna sayesinde bayt

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

Çevrimiçi deneyin!

açıklama

[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
OSonra hareket .Rederseniz )ve kaldırabilirsiniz s.
Emigna

3

R, 48 44 42 bayt

Giuseppe'nin cevabında 5 baytlık bir gelişme .

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

Bu (ab), zorlayan ve sonra artırılabilen , Fvarsayılan olarak atanmış bir değişken olan gerçeği kullanır , böylece bir sayaç değişkenini başlatma ihtiyacını bize bildirir.FALSE0


1
Tabii ki, iki bayt sample(6)yerine arayarak kaydedebilirsiniz sample(1:6)ama çarpı işareti
Giuseppe

@Giuseppe Elbette, teşekkürler! Şimdi cevabı değiştirdim.
rturnbull

2

PHP , 75 bayt

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

Çevrimiçi deneyin!


1
5^2/++$i*$d+=rand()%6 is a slightly shorter condition for the loop. Also I think the current loop incorrectly exits if the very first "dice" rolled is a "1" (it generates a 0 for the initial $d).
user59178

@user59178 Nice Idea but it could be make a division by zero error so I must modified it. You are right my solution before stops in this case which is wrong.
Jörg Hülsermann

Your 45-byte answer is invalid because the resulting distribution is not the same as in the question, see here. Your 42-byte answer is, I think, also using the wrong distribution; it seems to assume for example that for two dice, it is equally likely to have 2 and 7 as the sum.

@Pakk Yes the 45 Byte answer is invalid. I think your thinking is false what happens at the 42 Byte Version. Look at am expanded version Try it online!
Jörg Hülsermann

@JörgHülsermann That expanded version confirms what I say. In a proper implementation, the value of $r/$i should become closer to 3.5 for bigger values of $i, but I don't see that happening at all. I got an average of 1.16 for 9984 dice, that is statistically extremely unlikely.


1

Mathematica, 47 bytes

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

-5 bytes from LLlAMnYP


1

05AB1E, 17 bytes

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

Try it online!

Explanation

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

Batch, 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%

Rather annoyingly, random is a magic environment variable, so it only gets replaced with a random value during environment expansion, which normally happens before the for loop starts. call makes it happen each time through the loop, but then you need to double the % signs to prevent the expansion from happening before the loop. The fun starts because we want to modulo the result by 6, which requires a real % sign, which now has to be doubled twice. The result is six consecutive %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)

Outputs a string of results separated by newlines

Edit: saved a byte thanks to Shaggy, added 4 bytes to start function at 2

Explanation

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
Save a bytes by using a literal newline enclosed in backticks, instead of '\n'.
Shaggy

This does not start with n=2, instead you have to specify the starting number of dice when the function is called.
MT0

1

php - 89 Characters

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

you need not the first $r=0; use echo instead of print $n." can be write as "$n and for loops instead of while allows do to something in the after loop or before to save some 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)

Credit to @Laikoni for the suggestions in the comments below.


1.) Imports should be counted in the byte count. 2.) return() can be shortened to pure() and putStrLn$show can be shortened to print.
Laikoni

I will fix it right away. Thanks
Davide Spataro

Some further small things: div k 2 then can be div k 2then and do print k;s(k+2) is print k>>s(k+2).
Laikoni

1

Octave 55 bytes

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

Inspired by Andrewarchi's answer. If someone has any pointers to even shorten it, they are welcome.


Wow, TI-BASIC and Octave have surprisingly similar syntaxes
andrewarchi

@andrewarchi Octave (the online version is what I use) is just the basics of the basics when it comes to programming.
Michthan

1

Pyth, 20 bytes

K2WnsmhO6K*K3.5K=+K2

Try it online!


Welcome to PPCG!
Martin Ender

Thanks! Just finished the Pyth tutorial and figured I might give it a try, although this is probably still improvable. Any suggestions are appreciated.
qwertz

0

QBIC, 40 bytes

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

Thispretty much literally does what the challenge asks for; seems the shortest way to get the distribution right.

Explanation

{          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 Characters

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

Explanation:

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

and:

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

ungolfed:

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

I could do without the Math.Int() but unfortunately in 0.7 the Random().Next() functions have a bug where they all return doubles instead of ints. It has been fixed but only after this question was posted. I'm not gonna win anything, but hey, nice proof of concept.

Edit:

  • removed unnecessary space between using and "runtime" (-1 byte)

Edit2:

  • removed var r and create a new Random where it's needed (-4 byte)

  • changed i=0,d=0 to i=d=0 (-2 byte)

  • incremented i after check (-1 byte)


0

Ruby, 52 bytes

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

Explanation

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

Try it online!


@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.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.