您可以掷出多少个骰子而不掷出最可能的数字


26

问题

n=2骰子开始:

  • n骰子,与每个数为1〜6同样有可能在每个管芯上。
  • 检查它们的总和是否等于n骰子的最可能总和3.5*n
    • 如果相等,则终止。
    • 否则,打印n,并从一开始就重复n+2骰子

您的代码不必完全执行此过程,但应根据我们对randomness的定义,在概率上与之等效的随机输出。

您的程序应将所有数字单独输出。例如,如果程序最多有8个骰子,并用8个骰子掷出最可能的数字,则输出为:

2
4
6

示例运行

在2个骰子上,7是最可能的和。假设滚动的数字是23。然后,您将打印2

在4个骰子上,14是最可能的和。比方说推出的数字是342,和5。然后,总和为14,因此程序将在此处终止。

在这种情况下,最终输出为"2"

规则


就目前而言,这个答案还不清楚。有输入,还是要从无输入生成输出作为循环?有随机性吗?我似乎看不到任何随机性。
HyperNeutrino

顺便说一句,欢迎来到PPCG!:)
HyperNeutrino

谢谢,对不起,我对此很陌生。有什么会更清楚?没有输入,您应该从一个骰子开始,然后尽可能地提高。
zoecarver

@pudility因此,如果我理解正确,我应该2, 4, 6, 8, ...每次都输出一个骰子很多的骰子,直到我找到该迭代的最大可能数字为止?
HyperNeutrino

5
感谢您抽出宝贵的时间根据我们的反馈来编辑挑战!作为记录,我们在一个地方可以发布挑战,以在发布之前制定出一些详细信息:sandbox
FryAmTheEggman

Answers:


17

Python 2,70个字节

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

在线尝试!

诀窍是通过eval输入如下所示的字符串来计算总和

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

带有n连接的表达式副本。的randrange(6)输出从一个随机数[0,1,2,3,4,5],它由向下移位2.5以具有平均的0。当总和为if时0while条件失败,循环终止。

另一种使用方式map是长4个字节:

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

我发现了一堆等长的骰子等长表达式转移为零,但都不短

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

11
我喜欢这一个!主要是因为它是我所理解的唯一一个。
zoecarver

7

MATL,13字节

`@E6y&Yrs@7*-

在线尝试!

说明

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

果冻 19  14 字节

在Leaky Nun的帮助下-5字节(从计数到递归)

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

完整的程序将打印结果,并以换行符分隔(还会打印多余的空格和换行符,并在末尾显示程序错误)。

在线尝试! -每次超过6个骰子,TIO都会由于占用内存而将其杀死,但是从原理上讲,它的工作原理-大约需要40秒钟。

不这么长时间,或需要这么多的内存更友好的15字节的版本可以在这里

怎么样?

递归滚动2个骰子,直到每张减少3.5的面的总和为零,并随即打印骰子的数量,当达到零时,它尝试使用空格字符,导致类型错误。

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

哇,那是很少的字节。做得好!我推迟接受它,直到有更多人回答。
zoecarver

是的,即使接受,通常要等待一段时间才能接受。很多人给它一两个星期。
乔纳森·艾伦,

同样,您应该输出所有迭代-不仅是最后一个。
zoecarver

哦,我回答了一个旧的编辑-完全更改了它,我无法以许多方式使用此方法。
乔纳森·艾伦,

哦,等等n,好吧,也许它是可挽救的。我以为你的意思是::
乔纳森·艾伦

6

TI-BASIC,28个字节

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

说明

  • randInt(1,6,N) 生成从1到6的N个随机数的列表
  • mean(randInt(1,6,N)-3.5 滚动平均下降3.5
  • While 继续直到平均表达式等于零(最可能的和)

5

R,49个字节

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

sample(6,n,T)生成具有替换n范围的(伪)随机样本1:6sum如果且仅当它是最常见的值时,从每个元素中减去3.5会得出结果为0(假)。

在线尝试!

跳过奇数骰子。


这似乎为我每次输出80,可能是bug?
zoecarver

@pudility,您可以在末尾添加空格以再次尝试;每次都缓存输入/代码段
Giuseppe

3
@Giuseppe您可以在“设置”下的TIO中禁用缓存。
xnor

在像@xnor一样禁用缓存后,它工作得很好。感谢您的回答!
zoecarver

知道的@xnor!很高兴将来知道。
朱塞佩

4

爪哇8,123 149 113 108个字节

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

107字节,如果我们使用Object null是未使用的参数来代替。

+26字节的错误修复程序,由@Jules在注释中正确指出。
-41字节感谢@OliverGrégoire的出色思考!

说明:

在这里尝试。

()->{                           // 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
我认为该功能有误。如果r相等,3.5*n则程序应直接终止。但是,如果我正确理解该功能,它将n在终止之前最后一次打印。
raznagul

@raznagul实际上,它并没有打印额外的时间。但是它被窃听了。之前的操作:随机1-12(错误1:应该是2-12);检查是否等于7:如果是:我们无需打印即可完成;如果不是,则再次掷出2个骰子(错误2,应该是4个骰子,而不是2个)。然后打印2,然后加n2。所以它确实包含两个错误(1-12,而不是2-12;以及滚动骰子,例如2-> 2-> 4-> 6-> ...,而不是2-> 4-> 6-> ...)。但是,它可以正确打印,因为System.out.println(n),n+=2如果r确实等于,则不会打印3.5*n
Kevin Cruijssen

2
“通过从2-12中选择一个随机数来一次滚动两个骰子” –概率上不等同于滚动两个骰子并按问题中的要求添加数字,因此不是正确的解决方案。
Jules

1
短了几个字节(113),但可能仍可打高尔夫球:()->{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);}}。另外,请正确对待朱尔斯的评论和我的解释。n是骰子,s是总和,e是预期,i是索引。最后,总和开头n避免+1n时间和s!=e重复,因为我只是不知道如何避免这种情况。
奥利维尔·格雷戈尔(OlivierGrégoire),

1
我又打了一次;)()->{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);}}
奥利维尔·格雷戈雷(

3

05AB1E22 20字节

-2字节归功于Emigna

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

在线尝试!

说明

[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
如果您移动O.R可以将)和删除s
Emigna

3

R,48 44 42字节

朱塞佩的答案提高了5个字节。

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

这(ab)利用了以下事实:F默认情况下,FALSE该变量是分配给该变量的变量,0然后可以递增该变量,从而节省了初始化计数器变量的需要。


1
当然,您可以通过调用sample(6)而不是sample(1:6)但可以省掉两个字节,但划掉的44仍然是44。... codegolf.stackexchange.com/a/82343/67312
Giuseppe

@Giuseppe当然,谢谢!我已经编辑了答案。
rturnbull

2

的PHP,75字节

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

在线尝试!


1
5^2/++$i*$d+=rand()%6是循环的条件略短。我还认为,如果滚动的第一个“骰子”为“ 1”,则当前循环会错误地退出(它为initial生成0 $d)。
user59178

@ user59178好主意,但它可以被零错误除以,所以我必须对其进行修改。你是对的,我的解决方案在这种情况下停止之前是对的。
约尔格Hülsermann

您的45字节答案无效,因为结果分配与问题中的分配不一样,请参见此处。我认为您的42字节答案也使用了错误的分配;例如,似乎假设两个骰子的总和等于2和7。

@Pakk是45字节答案无效。我认为您的想法是错误的,在42字节版本中会发生什么。查看扩展版本,在线尝试!
约尔格Hülsermann

@JörgHülsermann扩展版本证实了我的观点。在适当的实现中,对于较大的$ i,$ r / $ i的值应接近3.5,但我完全看不到这种情况。我得到9984个骰子的平均值为1.16,在统计上这是极不可能的。


1

Mathematica,47个字节

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

LLlAMnYP中的-5个字节


1

05AB1E,17个字节

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

在线尝试!

说明

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

批次,109个字节

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

令人讨厌的random是,它是一个神奇的环境变量,因此它仅在环境扩展过程中被替换为随机值,通常在for循环开始之前发生。call使其在每次循环中都发生,但是您需要加倍%符号以防止在循环之前发生扩展。有趣的开始是因为我们想将结果乘以6,这需要一个实数%,现在必须将其加倍两次。结果是六个连续的%s。


1

JavaScript(ES2015),75 78字节

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

输出以换行符分隔的结果字符串

编辑:感谢Shaggy,保存了一个字节,添加了4个字节以从2开始功能

说明

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
使用反引号内的文字换行符(而不是)来保存字节'\n'
毛茸茸的

它不是以开头n=2,而是在调用函数时必须指定骰子的起始编号。
MT0

1

php-89个字符

$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.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.