I'm having trouble developing a for-loop that starts at a given integer (start) and then counts up and down from this starting point inside a given range (min to max). I want the result to be in order by distance to the given start. If a for-loop is not the right tool here, i am open for other suggestions!
Since this is hard to explain i have a example down below:
var start = 4;
var max = 10;
var min = 0;
var stepSize = 1;
for(var i=startIndex; i>=min && i<=max; ???) {
Console.WriteLine(i)
}
The result should look like this:
4 5 3 6 2 7 1 8 0 9 10
The really tricky part for me is the end where the alternation has to stop in order to reach the max value of 10 and not go below 0 in the meantime.
I started experimenting and had a solution that would work for the first bit:
const int start = 4;
const int stepSize = 1;
for (var (i,j,k) = (start,1,5); Math.Abs(j)<=11; k=(k j),j=-j-Math.Sign(j)*stepSize,i=(k (start-5))) {
Console.WriteLine(i);
}
This works fine for the first part where alternation is needed, but it breaks once the alternation needs to stop. The result from this experiment is:
4 5 3 6 2 7 1 8 0 9 -1
CodePudding user response:
A simple but elegant solution could generate the number sequence you want like so:
static IEnumerable<int>
UpDownCount(int start, int lower, int upper)
{
int i = start, j = start;
yield return start;
while (true)
{
bool ilimit = i <= upper,
jlimit = --j >= lower;
if (ilimit)
yield return i;
if (jlimit)
yield return j;
if (!(ilimit || jlimit))
yield break;
}
}
Then you can use that sequence with LINQ or a simple foreach
loop:
foreach (int i in UpDownCount(4, 0, 10))
Console.WriteLine(i);
CodePudding user response:
Here it is with a for
loop, but like others have already alluded to, I think other structures are better suited for your task:
public static void Main() {
int start = 4;
int max = 10;
int min = 0;
int stepSize = 1;
for(int i=start, j=start; i>=min || j<=max; i-=stepSize, j =stepSize) {
if (i==start) {
Console.Write(i " ");
}
else {
if (j <= max) {
Console.Write(j " ");
}
if (i >= min) {
Console.Write(i " ");
}
}
}
}
CodePudding user response:
The sequence you are after:
4 5 3 6 2 7 1 8 0 9 10
Could be specified as the following:
4 - 3 - 2 - 1 - 0
- 5 - 6 - 7 - 8 - 9 10
- - - - - - - - - - --
4 5 3 6 2 7 1 8 0 9 10
Which using something like MoreLinq, could be expressed like this:
Sequence(4, 0).Interleave(Sequence(5, 10))
Obviously, you control the start
, max
and min
by controlling the values of both sequences. So, say you want to start from 7, going up and down towards 1 as the minimum value, and 14 as the maximum. The call would be like:
Sequence(7, 1).Interleave(Sequence(8, 14))
Lastly, this also allows you to easily change from a "up-down" to a "down-up" by swapping the intervals. Using the example above:
Sequence(8, 14).Interleave(Sequence(7, 1))