如何解决骰子组合总数
试图找到一个很好的算法来计算总共 d4 个骰子组合。例如 3 个四个面的骰子,组成 4 的所有组合都会给出:004 013 112 022
我将使用 c#,但 python 或伪代码会很棒。只是需要一些算法的帮助。始终是四面骰子,但骰子总数和数量是参数。
任何想法都会很棒。谢谢。
解决方法
您可以使用递归。
例如,在 Python 中它看起来像这样:
def combis(num_dice,target,minval=1):
if target == 0:
return [""] # solution
if num_dice < 1 or target < 0:
return [] # no solution
res = []
for side in range(minval,min(5,target + 1)):
for combi in combis(num_dice - 1,target - side,side):
res.append(str(side) + combi)
return res
print(combis(3,4))
如果这真的必须在 Python 中完成,那么人们会使用像 itertools
这样的库。
输出是一个字符串列表,其中字符串中的每个字符都是代表骰子边的数字。字符串永远不会长于第一个参数 (num_dice
),但它们可以更短,这意味着涉及的骰子更少。如果需要,您可以用“0”填充它们。
在 C# 中实现
using System;
using System.Collections;
class MainClass {
public static ArrayList combis(int numDice,int target,int minval=1) {
var res = new ArrayList();
if (target == 0) {
res.Add(""); // solution
} else if (numDice > 0 && target > 0) {
for (int side = minval; side < 5 && side <= target; side++) {
foreach (var combi in combis(numDice - 1,side)) {
res.Add(side.ToString() + combi);
}
}
}
return res;
}
public static void Main (string[] args) {
// Example run
foreach (var combi in combis(3,4)) {
Console.WriteLine (combi);
}
}
}
,
这是对 trincot 的 answer 的一个调整,它不需要创建中间列表,并且计算当前骰子的最小值,从而减少浪费的调用 (.Net Fiddle)。>
public static ArrayList combos(int nDice,int tot,int max)
{
var res = new ArrayList();
combos(res,"",nDice,tot,max);
return res;
}
private static void combos(ArrayList res,String sol,int nDice,int max)
{
if(tot == 0)
{
res.Add(sol);
return;
}
for(int side = 1+(tot-1)/nDice; side <= Math.Min(tot,max); side++)
combos(res,sol+side,nDice-1,tot-side,side);
}
测试:
public static void Main (string[] args) {
int nDice = 3;
int nFaces = 4;
for(int tot=1; tot<=nDice*nFaces+1; tot++)
{
Console.WriteLine ("\nTot: " + tot);
foreach (var combo in combos(nDice,nFaces)) {
Console.WriteLine (combo);
}
}
}
输出:
tot: 1
1
tot: 2
11
2
tot: 3
111
21
3
tot: 4
211
22
31
4
tot: 5
221
311
32
41
tot: 6
222
321
33
411
42
tot: 7
322
331
421
43
tot: 8
332
422
431
44
tot: 9
333
432
441
tot: 10
433
442
tot: 11
443
tot: 12
444
tot: 13
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。