我需要将一个数字分解为由随机排序的2s和3s序列表示。
例如:
我目前正在使用ActionScript 3中的循环执行此操作,但一直在研究使用某种数学公式来节省几行代码的可能性。对于数学而言,我有点不高兴,我还没有找到合适的东西。
有人知道这样的事情是否存在?
谢谢,
Crung
答案 0 :(得分:3)
要保存几行代码?当你有函数时,你可以在一行代码中执行任何: - )
的伪代码:
def makelist (n):
list = []
if n is less than 2:
return list
while n > 0:
select case n is 4 or 2:
list.append (2)
n = n - 2
select case n is 3:
list.append (3)
n = n - 3
select case random() is odd:
list.append (2)
n = n - 2
select otherwise:
list.append (3)
n = n - 3
return list
然后,您只需要一行代码就可以使用它:
list = makelist (62)
答案 1 :(得分:2)
假设您尝试分解为2a+3b
的数字为n
。拆分:
n = 6*(n/6-1) + 6+(n%6)
其中%
为模,/
为整数除法。第一部分可以被6整除,因此可以写成一系列2 + 2 + 2或3 + 3。对于第二部分,使用某种表格进行选择。因为它总是在6到11之间,所以可以制作所有数字。
6+(n%6) | sum
--------+----
6 | 3+3
7 | 2+2+3
8 | 2+3+3
9 | 3+3+3
10 | 3+3+2+2
11 | 3+3+3+2
这样做的好处包括你可以改变3和2的数量,并且你不必使用任何类型的低效循环。
答案 2 :(得分:2)
1
。 2
,3
和4
只能以一种方式形成。其他方面,请随机选择2
或3
并继续。
private function TwoThree_v2(n : Number) : Array {
// Initialize the count array
// It is a simple recurrence relation a(n) = a(n-2) + a(n-3)
// saying how many sequences with sum n there are.
var counts = new Array();
counts.push(1);
counts.push(0);
counts.push(1);
for (var i = 3; i <= n; i++) {
counts.push(counts[i-2] + counts[i-3]);
}
var result = new Array();
while (n > 4) {
var w2 = counts[n-2];
var w3 = counts[n-3];
// Branch according to how many sequences that continues
// with 2 and 3, respectively.
if (Math.random()*(w2+w3) < w2) {
result.push(2);
n -= 2;
}
else {
result.push(3);
n -= 3;
}
}
// Add the last 1-2 digits.
if (n == 2 || n == 3) {
result.push(n);
}
else if (n == 4) {
result.push(2);
result.push(2);
}
else {
throw new Error("Can't form " + n.ToString());
}
return result;
}
现在每个序列将以相同的概率返回:
With n = 10:
[2, 2, 2, 2, 2] 14414
[2, 2, 3, 3] 14271
[2, 3, 2, 3] 14061
[2, 3, 3, 2] 14452
[3, 2, 2, 3] 14191
[3, 2, 3, 2] 14278
[3, 3, 2, 2] 14333
答案 3 :(得分:1)
假设您必须使用最少的位数:
var number = 1000;
var threes = number / 3;
var twos = ((number % 3) == 0) ? 0 :
((number % 3) == 1) ? 2 : 1;
// Account for case of four left at the end.
if (twos == 2) {
--threes;
}
现在你只需要形成一个列表:
// First start with all threes.
var list = [];
for(var i = 0; i < threes; ++i) {
list.push(i);
}
// Now randomly pick locations to add the two.
for(i = 0; i < twos; ++i) {
list.splice(Math.round(Math.random() * list.length), 2);
}
不幸的是,三三两两的随机分布使得一个简单的公式变得不可能。你能做的最好的事情是确定两个到三个的随机比率,然后找到适合给定数字。
var ratio = Math.random(); //Ratio of twos to threes.
// number = 2a + 3b; a = ratio * b;
// number = 2(ratio * b) + 3b;
// number = (2 * ratio + 3) * b;
// number / (2 * ratio + 3) = b;
var threes = number / (2 * ratio + 3);
var twos = ratio * threes;
// At this point, need to round threes and twos...
threes = Math.round(threes);
twos = Math.round(twos);
// Then adjust to ensure that rounded total equals number.
// Note that diff will be in range [-5, 5].
// Probably tighter even but I'm too lazy to figure out the true maximum.
var diff = number - (3 * threes + 2 * twos);