找到2和3,使得总和是给定的数字

时间:2011-03-18 06:50:17

标签: actionscript-3 math

我需要将一个数字分解为由随机排序的2s和3s序列表示。

例如:

  • 5可以是3,2或2,3
  • 6可以是3,3

我目前正在使用ActionScript 3中的循环执行此操作,但一直在研究使用某种数学公式来节省几行代码的可能性。对于数学而言,我有点不高兴,我还没有找到合适的东西。

有人知道这样的事情是否存在?

谢谢,

Crung

4 个答案:

答案 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)

无法形成

1234只能以一种方式形成。其他方面,请随机选择23并继续。

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