在Unity中独立比较值

时间:2019-04-26 07:09:25

标签: c#

假设我有三个整数

int A = 43;
int B = 33;
int C = 23;

我希望每次迭代都使用我的代码:

  1. 取两个个最高整数,并从中减去1
  2. 取其余(最低)个,然后添加1
  3. 领带(如果我们有几个最低的物品)应该随机解决
  4. 当至少2个整数等于0时,迭代应该结束

例如对于A = 43; B = 33; C = 23,序列应为

A       B       C

43      33      23
42      32      24
41      31      25
40      30      26
39      29      27
38      28      28 
37      27      29 <- may vary since we resolve tie at random: {37, 29, 27} is valid
36      28      28
...

我的当前尝试是:

using System;

public class Program
{
    int A = 43;
    int B = 33;
    int C = 23;

    public static void Main()
    {
        Console.WriteLine(A + "\t" + B + "\t" + C);

        do
        {
            Iteration(A, B, C);
            Console.WriteLine(A + "\t" + B + "\t" + C);
        }
        while (...); //At least two variables are bigger than 0
    }

    private void Iteration(ref int A, ref int B, ref int C)
    {
        /*
        Increase the smallest variable by 1.
        Decrease the two bigger variables by 1.

        When the two smallest variables are the same, 
        choose one at random and increase it by 1.
        Add 1 to the other smallest variable and the bigger one.
        */
    }
}

我希望我的结果看起来像这样:

A       B       C

43      33      23
42      32      24
41      31      25
40      30      26
39      29      27
38      28      28
37      27      29
36      28      28
35      29      27
34      28      28
33      27      29
32      28      28
31      27      29
...     ...     ...

我已经尝试过进行很多比较,但是我希望代码更简洁。例如,我曾考虑过使用ref关键字,但是找不到方法来实现它?

有人知道吗?

1 个答案:

答案 0 :(得分:0)

让我们一般化这个问题:更容易解决(与3项目相比, collection 操作更容易)。到目前为止,每次迭代都很好

  1. 1添加到 min 项;如果有多个最小项,则任意取一个
  2. 从所有 rest 项目中
  3. 1减去

我们可以借助 Linq 轻松实现这些规则:

代码:

// Simplest, not thread-safe
private static Random s_Random = new Random(); 

private static int[] NextIteration(int[] value) {
  int minValue = value.Min();

  int[] minIndexes = value
    .Select((item, index) => item == minValue 
       ? index 
       : -1)
    .Where(index => index >= 0)
    .ToArray();

  int minIndex = minIndexes.Length == 1
    ? minIndexes[0]
    : minIndexes[s_Random.Next(minIndexes.Length)]; // 

  return value
    .Select((item, index) => index == minIndex 
       ? item + 1  // increment an item at chosen minIndex
       : item - 1) // decrement all the other items
    .ToArray();
}

最后,我们实现了序列 generator (在其中添加了最终要求-“迭代应在至少两个整数等于0时结束”):

  private static IEnumerable<int[]> AllIterations(int[] value) {
    for (int[] data = value; 
               data.Count(item => item == 0) < value.Length - 1; 
               data = NextIteration(data))
      yield return data;
  } 

演示:

var result = AllIterations(new[] {43, 33, 23})
  .Take(20)                                  // Let's have a look at top 20 items
  .Select(line => string.Join("\t", line));

Console.WriteLine(string.Join(Environment.NewLine, result));

// How many iterations does it take to come to the end?
Console.WriteLine(""); 
Console.WriteLine($"{AllIterations(new[] {43, 33, 23}).Count()} iterations required."); 

结果 :(可能会变化,因为我们在领带上放置了任意项)

43  33  23
42  32  24
41  31  25
40  30  26
39  29  27
38  28  28
37  27  29
36  28  28
35  29  27
34  28  28
33  27  29
32  28  28
31  27  29
30  28  28
29  27  29
28  28  28
29  27  27
28  26  28
27  27  27
28  26  26  

97 iterations required.