重复骰子滚动


12

给定输入nwhere 3 <= n <= 25,请执行以下步骤,从单面n模具([1, n]包含在内的范围内的面)开始:

  1. 以以下形式打印n在游戏中滚动当前面骰子的结果kdn: X(其中X是结果,k是游戏中骰子的数量)。
  2. 如果X大于或等于n/2游戏中骰子数量的倍数,请添加骰子。否则,请移开骰子。
  3. 如果游戏中的骰子数量等于0n,请停止。否则,请转到步骤1。

运行示例(请注意,括号中的输出仅供参考,并非必需):

6面

1d6: 4 (avg: 3.0, add)
2d6: 6 (avg: 6.0, add)
3d6: 9 (avg: 9.0, add)
4d6: 16 (avg: 12.0, add)
5d6: 13 (avg: 15.0, remove)
4d6: 9 (avg: 12.0, remove)
3d6: 5 (avg: 9.0, remove)
2d6: 7 (avg: 6.0, add)
3d6: 11 (avg: 9.0, add)
4d6: 14 (avg: 12.0, add)
5d6: 17 (avg: 15.0, add)

9面:

1d9: 7 (avg: 4.5, add)
2d9: 14 (avg: 9.0, add)
3d9: 18 (avg: 13.5, add)
4d9: 18 (avg: 18.0, add)
5d9: 28 (avg: 22.5, add)
6d9: 26 (avg: 27.0, remove)
5d9: 28 (avg: 22.5, add)
6d9: 34 (avg: 27.0, add)
7d9: 33 (avg: 31.5, add)
8d9: 30 (avg: 36.0, remove)
7d9: 29 (avg: 31.5, remove)
6d9: 35 (avg: 27.0, add)
7d9: 32 (avg: 31.5, add)
8d9: 42 (avg: 36.0, add)

规则

  • 输出必须完全采用格式kdn: X,每行之间用换行符分隔
  • 您实际上必须模拟滚动多个骰子;[1, n]不允许简单地返回范围(含)范围内的随机整数乘以当前正在玩的骰子数量,因为这不能准确地模拟滚动多个骰子。
  • 禁止出现标准漏洞
  • 这是,因此最短答案以字节为单位

排行榜

这篇文章底部的堆栈摘录从答案a)生成排行榜,答案是每种语言的最短解决方案列表,而b)则是总体排行榜。

为了确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,可以将旧分数保留在标题中,方法是将它们打掉。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果您想在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes


我觉得这很混乱。请给出示例答案?
Hipe99

示例答案,因为示例很简洁。
Hipe99

您的修改已澄清。谢谢!
Hipe99

16
确定算术吗?常规d6的平均滚动为3.5。
彼得·泰勒

11
您示例中的所有平均值似乎都是错误的
edc65

Answers:



3

Mathematica,95 89 80个字符

For[k=1,0<k<#,If[Print[k,d,#,": ",x=Tr[{1,#}~RandomInteger~k]];x<k/2#,k--,k++]]&

不打高尔夫球

For[
  k = 1,
  0 < k < #,
  If[
    Print[k, d, #, ": ", x = Tr[{1, #}~RandomInteger~k]];
    x < k/2 #,
    k--,
    k++
  ]
] &

1
@MartinBüttner感谢您的建议。Echo不幸的是,不能像Print这样进行一系列输入。
shrx 2015年

哦,好点。
马丁·恩德

3

PHP,164个 121 112 113 109字节

我保证是最终版本。使用Titus的建议进行了改进:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$y+=$r/$y>$x/2?:-1;$y<$x&&$y?d($x,$y):0;}

编辑:添加了一个额外的字节用于格式化。忘了那里有一个IF,由于删除了“ add / sub”文本,本来可以是三元运算符:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x: $r\n";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}

现在输出如下:

1d6: 5
2d6: 11
3d6: 8
2d6: 11
3d6: 7
2d6: 4
1d6: 5

编辑:感谢@Manatwork,为我节省了很多!新的和改进的版本:

function d($x,$y){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x=$r\n";if($r/$y>$x/2)$y++;else$y--;if($y<$x&&$y){d($x,$y);}}

上一个条目:

function d($x,$y){for($i=0;$i<$y;$i++)($r+=rand(1,$x));$s=$y."d$x=$r, ";if($r/$y>$x/2){$y++;$s.="add";}else{$y--;$s.="sub";}echo $s."\n";if($y<$x&&$y>0){d($x,$y);}}`

滚动单独的模具,输出以下内容:

1d6=6, add
2d6=7, add
3d6=11, add
4d6=14, add
5d6=15, sub
4d6=15, add
5d6=18, add

因此,它被称为: d(6, 1);

显示AddSub后缀是强制性的吗?您的问题尚不清楚。


要求说:“请注意,括号中的输出是解释性的,不是必需的”。这种方式似乎更短:function d($x,$y=1){for($i=$y;$i--;)$r+=rand(1,$x);echo$y."d$x, $r↵";$r/$y>$x/2?$y++:$y--;if($y<$x&&$y)d($x,$y);}
manatwork

@manatwork谢谢,您真的提供了很多帮助!
steenbergh

if仍然可以是三进制,节省一个字节。重新建模增加/减少可以节省两个字节:$y-=$r/$y>$x/2?:-1
Titus

2

Python 3、125

DSM节省了3个字节。

def x(d):
 import random;c=1
 while 0<c<d:r=sum(map(random.randint,[1]*c,[d]*c));print('%id%i: %i'%(c,d,r));c+=2*(r>=d*c/2)-1

非常简单,掷出一堆骰子并检查平均值。这里还没有什么花哨的。
需要使用一个int调用它。因此,x(6)将产生如下内容:

1d6: 5
2d6: 10
3d6: 8
2d6: 7
3d6: 11
4d6: 8
3d6: 13
4d6: 19
5d6: 13
4d6: 15
5d6: 22


2

的JavaScript(ES6),97个102 106 112字节

感谢@ user81655和@Jupotter为我节省了一些字节。

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// 102 bytes:
f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=0;++i<=k;)x+=1+Math.random()*n|0}

// Previous attempt, 112 bytes
f=n=>{k=1;while(k&&k!=n){for(x=i=0;i++<=k;)x+=1+~~(Math.random()*n);console.log(k+`d${n}: `+x);k+=x<k*n/2?-1:1}}

演示版

这仅在兼容ES6的浏览器中有效(目前包括Firefox和Edge,可能启用了实验性JavaScript功能的Chrome和Opera):

f=n=>{for(k=1;k%n;console.log(k+`d${n}: `+x),k+=x<k*n/2?-1:1)for(x=i=k;i--;)x+=Math.random()*n|0}

// Snippet stuff
console.log = x => {
  document.getElementById('O').innerHTML += x + `<br>`;
}

document.getElementById('F').addEventListener('submit', e => {
  document.getElementById('O').innerHTML = ``
  f(document.getElementById('I').valueAsNumber)
})
<form id=F action=# method=get>
  <label>
    Number of faces: 
    <input type=number min=3 max=25 value=9 required id=I>
  </label>
  <button>Play</button>
  
  <div>
    <output id=O></output>
  </div>
</form>


您可以将更while改为for循环,用|0代替,~~()然后舍入并移动一些语句,以便可以删除方括号以节省一些字节。另外,您还可以将其设为匿名函数(否f=)。103字节:n=>{for(k=1;k&&k!=n;k+=x<k*n/2?-1:1)for(x=i=0;i++<=k;console.log(k+`d${n}: `+x))x+=1+Math.random()*n|0}
user81655

@ user81655谢谢。由于某种原因,您的版本创建了许多无关的输出,因此我将其console.log移至另一个for循环(比您多花了1个字符)。仍然下降到106
rink.attendant.15年

我只是在没有测试的情况下编写了此代码,因此很高兴它可以正常工作。:)
user81655

您可以通过用k&&k!=n比较代替条件来获得一个字符k%n!=0
Jupotter 2015年

@Jupotter谢谢,k%n工作得更好;)
rink.attendant.15年6

1

CJam,45个字节

ri:M;{X__{Mmr+}*[X'dM':S5$N]o_+XM*<_+(-:XM%}g

在线尝试。

从字面上实现规范(包括数学上不正确的“平均滚动”公式)。正如预期的那样,移植下面CJam原GolfScript程序保存一堆字节由于较短的内置命令的名称(mrog代替randputsdo)。

GolfScript,51个字节

~:&;{1..{&rand+}*[1"d"&": "4$]puts.+1&*<.+(-:1&%}do

这是我最初的GolfScript条目。著名的高尔夫技巧包括使用数字1作为方便的预初始化变量来存储要掷骰子的当前数量。(CJam版本使用X,而CJam初始化为值1。)


附言看到标题,我本来想在AnyDice中回答这个问题。但是事实证明,应对这一挑战是一个可怕的选择,而且我认为使用它来实现给定的规范在技术上也不可行。

问题是AnyDice是一种特定于领域的语言,用于编写 确定性程序来计算骰子滚动统计信息。在考察一个卷可能的结果,做基于这些条件辊通过递归可能,有没有办法产生任何实际的随机性。因此,尽管您可以在AnyDice中模拟骰子掷骰的顺序,但输出所能获得的只是统计信息,例如直到过程结束为止的掷骰数或给定步骤的结果分配。

这么说 这是我在AnyDice中可以得到的最接近的东西

N: 6
K: 1
function: clip X:n { result: X * (X < N) }
function: adjust X:n { result: [clip X + ((XdN)*2 >= X*N)*2-1] * (X > 0) }
loop I over {1..20} {
  output K named "dice in roll [I]"
  output KdN named "outcome of roll [I]"
  K: [adjust K]
}

这并不是特别适用的代码,因为这似乎是徒劳的。无论如何,标准的括号语言高尔夫技巧,例如缩短功能名称和消除不必要的空格,都应该耗尽大多数高尔夫潜力。

这里使用的关键技巧是,当您:n在AnyDice中调用一个期望有数字的函数(如函数定义中的指示),并将其传递给模具(即概率分布)时,AnyDice会自动评估所有可能的函数,并将结果合并到一个新的模具中。

这是前三卷的输出屏幕截图(条形图格式):

AnyDice屏幕截图

(注意,在每一个曲线图中的“0”栏表示迭代停止,由于骰子击中的数量的概率或者 0或N,现有的卷筒之前,这恰好是代表停止条件的便利方式,由于当然,滚动0dN总是会产生0。)


1

R,103字节

一个相当直接的实现。骰子掷骰由来完成sum(sample(n,i))

i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}

测试运行

> i=1;n=scan();while(i&i<=n){cat(i,'d',n,': ',s<-sum(sample(n,i)),'\n',sep='');i=ifelse(s<i*n/2,i-1,i+1)}
1: 9
2: 
Read 1 item
1d9: 9
2d9: 14
3d9: 10
2d9: 14
3d9: 9
2d9: 9
3d9: 12
2d9: 7
1d9: 9
2d9: 11
3d9: 17
4d9: 18
5d9: 25
6d9: 29
7d9: 33
8d9: 43
9d9: 45
> 

1

CoffeeScript,106 99字节

f=(n,k=1)->(x=k;x+=Math.random()*n|0for[k..0];console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

# Previous attempt, 106 bytes
f=(n,k=1)->(x=i=0;x+=1+Math.random()*n//1while++i<=k;console.log k+"d#{n}: "+x;k+=x<k*n/2&&-1||1)while k%n

不打高尔夫球

f = (n, k = 1) ->
 (x = k
 x += 1 + Math.random() * n | 0 for [k..0]
 console.log k + "d#{n}: " + x
 k += x < k * n / 2 && -1 || 1
 ) while k % n

1

朱莉娅77字节

n->(N=1;while 0<N<n k=sum(rand(1:n,N));print(N,"d$n: $k
");N+=1-2(2k<N*n)end)

其中大多数应该是不言自明的- print字符串中使用了实际的换行符,而不是println保存字节。rand(1:n,N)产生N介于1和之间的随机整数n


1

Ruby,93 90 82个字符

->n{d=s=2
puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}

样品运行:

2.1.5 :001 > -->n{d=s=2;puts"#{d}d#{n}: #{s=eval'+rand(n)+1'*d}"while(d+=s<d*n/2.0?-1:1)>0&&d<n}[6]
1d6: 5
2d6: 10
3d6: 6
2d6: 5
1d6: 5
2d6: 8
3d6: 15
4d6: 18
5d6: 22

0

QBIC,83个字节(非竞争)

:c=a{e=0[1,q|e=e+_rq,a|]?!q$+@d|!+a$+@:|+!e$~e<c/2|q=q-1\q=q+1]c=q*a~q=a|_X]~q=0|_X

说明:

q                    Tracks the number of dice (is implicitly 1 at the start)
:                    Takes input from a CMD line parameter
[1,q|e=e+_rq,a|]     Rolls the dice separately
?!q$+@d|!+a$+@:|+!e$ Prints the roll result (requires an unfortunate amount of casting...)
~e<c/2|q=q-1\q=q+1]  Checks whether to increase or decrease
~q=a|_X]~q=0|_X      Tests the amount of dice and quits on either boundary.

0

PHP,104字节

for($n=$argv[$k=1];$k&&$k<$n;print$k."d$n: $x\n",$k-=$x<$n*$k/2?:-1)for($x=$i=0;$i++<$k;)$x+=rand(1,$n);

与运行 php -r '<code>' <N>

分解

for($n=$argv[$k=1];     // import input, init number of dice
    $k&&$k<$n;          // while 0<$k<$n
    print$k."d$n: $x\n",    // 2. print results
    $k-=$x<$n*$k/2?:-1      // 3. remove or add a die
)
    for($x=$i=0;$i++<$k;)   // 1. roll dice separately
        $x+=rand(1,$n);         // sum up results
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.