假设我有三个整数
int A = 43;
int B = 33;
int C = 23;
我希望每次迭代都使用我的代码:
1
1
。 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
关键字,但是找不到方法来实现它?
有人知道吗?
答案 0 :(得分:0)
让我们一般化这个问题:更容易解决(与3
项目相比, collection 操作更容易)。到目前为止,每次迭代都很好
1
添加到 min 项;如果有多个最小项,则任意取一个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.