在Unity中独立比较值

问题描述 投票:0回答:1

假设我有三个整数

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关键字,但我找不到怎样的方法呢?

有人有个主意吗?

c#
1个回答
0
投票

让我们概括一下问题:它更容易解决(集合操作比使用3项目更容易)。到目前为止,每次迭代都很好

  1. 1添加到min项目;如果有几分钟的项目,请采取任意一项
  2. 从所有其他项目中减去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();
}

最后,我们实现了一个序列生成器(我们在其中添加了最终需求 - “迭代应该在至少两个整数等于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.
© www.soinside.com 2019 - 2024. All rights reserved.