Counting alternating numbers in an array

For an array of integers ...

var numbers = new int[] { 1,2,1,2,1,2,1,2,1,2,1,2,1,2,2,2,1,2,1 }; 

I need to determine the maximum sequence of numbers that alternate, then down or down, then up.

Not sure if the best way to get close to this is, the psuedo wise process amazes me as simple, but materializing code for it evades me.

The key is the fact that we are looking for the maximum sequence, therefore, although the above numbers can be interpreted differently, for example, a sequence of seven up and down, an important fact begins with the first number - this is a descending sequence whose length is 14.

Also, I should not assume that the first element, 121 is a sequence of length 3, it can be argued that the sequence does not start before the second digit, but does not allow to separate the hair.

+7
source share
6 answers

This seems to work, it is assumed that the length of the numbers is greater than 4 (in any case, this should be trivial):

 var numbers = new int[] { 1,2,1,2,1,2,1,2,1,2,1,2,1,2,2,2,1,2,1 }; int count = 2, max = 0; for (int i = 1; i < numbers.Length - 1; i++) { if ((numbers[i - 1] < numbers[i] && numbers[i + 1] < numbers[i]) || (numbers[i - 1] > numbers[i] && numbers[i + 1] > numbers[i])) { count++; max = Math.Max(count, max); } else if ((numbers[i - 1] < numbers[i]) || (numbers[i - 1] > numbers[i]) || ((numbers[i] < numbers[i + 1]) || (numbers[i] > numbers[i + 1]))) { max = Math.Max(max, 2); count = 2; } } Console.WriteLine(max); // 14 
+3
source

I'm not from a computer with a compiler right now, so just try:

 int max = 0; int aux =0; for(int i = 2 ; i < length; ++i) { if (!((numbers[i - 2] > numbers[i - 1] && numbers[i - 1] < numbers[i]) || numbers[i - 2] < numbers[i - 1] && numbers[i - 1] > numbers[i])) { aux = i - 2; } max = Math.Max(i - aux,max); } if (max > 0 && aux >0) ++max; 

Note: should work for a sequence of at least 3 elements.

+2
source

This is how i thought about it

  • First, you need to know if you are starting to start or starting from a low level. for example: 1-2-1 or 2-1-2 . You may not even have a familiar couple.
  • Then you count each number afterwards to see if it belongs in a sequence, taking into account the current direction.
  • Each time the sequence is interrupted, you need to start again by checking the direction.

I'm not sure if it is possible that from a number that you have already seen, choosing a different start number can POSSIBLY generate a longer sequence. Maybe there is a theorem that shows that this is impossible; perhaps this is obvious, and I'm thinking too much. But I donโ€™t think itโ€™s possible, because the reason the sequence is broken is because you have two high or two low, and there is no way around this.

I assumed the following cases

  • {} - no elements, returns 0
  • {1} - the only element, returns 0
  • {1, 1, 1} - there is no alternating sequence, returns 0

No input restrictions other than what C # expects. It can probably be compressed. Not sure if there is a way to capture the logic of changing directions without explicitly tracking the direction.

 static int max_alternate(int[] numbers) { int maxCount = 0; int count = 0; int dir = 0; // whether we're going up or down for (int j = 1; j < numbers.Length; j++) { // don't know direction yet if (dir == 0) { if (numbers[j] > numbers[j-1]) { count += 2; // include first number dir = 1; // start low, up to high } else if (numbers[j] < numbers[j-1]) { count += 2; dir = -1; // start high, down to low } } else { if (dir == -1 && numbers[j] > numbers[j-1]) { count += 1; dir = 1; // up to high } else if (dir == 1 && numbers[j] < numbers[j-1]) { count += 1; dir = -1; // down to low } else { // sequence broken if (count > maxCount) { maxCount = count; } count = 0; dir = 0; } } } // final check after loop is done if (count > maxCount) { maxCount = count; } return maxCount; } 

And some test cases with results based on my understanding of the issue and some assumptions.

 static void Main(string[] args) { int[] nums = { 1}; // base case == 0 int[] nums2 = { 2, 1 }; // even case == 2 int[] nums3 = { 1, 2, 1 }; // odd case == 3 int[] nums4 = { 2, 1, 2 }; // flipped starting == 3 int[] nums5 = { 2, 1, 2, 2, 1, 2, 1 }; // broken seqeuence == 4 int[] nums6 = { 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 1, 2, 1 }; // long sequence == 14 Console.WriteLine(max_alternate(nums)); Console.WriteLine(max_alternate(nums2)); Console.WriteLine(max_alternate(nums3)); Console.WriteLine(max_alternate(nums4)); Console.WriteLine(max_alternate(nums5)); Console.WriteLine(max_alternate(nums6)); Console.ReadLine(); } 
+2
source

There are probably many ways to approach this, but here is one option:

 var numbers = new int[] { 7,1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 1, 2, 1 }; int maxCount = 0; for (int j = 0; j+1 < numbers.Length; j++) { int count = 0; if (numbers[j] < numbers[j+1]) { count += 2; for (int i = j+2; i+1 < numbers.Length; i += 2) { if (numbers[i] < numbers[i + 1] ) { count += 2; } else { break; } } } if (maxCount < count) { maxCount = count; } } Console.WriteLine(maxCount); Console.ReadLine(); 

This solution assumes that you need a sequence of two variables. If this is not a requirement, you can change the second if .

Now that this is written out, it looks more complicated than I imagined ... Maybe someone else can come up with a better solution.

+1
source

Assumes at least 2 elements.

 int max = 1; bool expectGreaterThanNext = (numbers[0] > numbers[1]); int count = 1; for (var i = 0; i < numbers.Length - 1; i++) { if (numbers[i] == numbers[i + 1] || expectGreaterThanNext && numbers[i] < numbers[i + 1]) { count = 1; expectGreaterThanNext = (i != numbers.Length - 1) && !(numbers[i] > numbers[i+1]); continue; } count++; expectGreaterThanNext = !expectGreaterThanNext; max = Math.Max(count, max); } 
0
source

This works for any integers, it tracks low hi-low and hi-low hi, as you asked.

 int numbers[] = new int[] { 1,2,1,2,1,2,1,2,1,2,1,2,1,2,2,2,1,2,1 }; int count = 0; int updownup = 0; int downupdown = 0; for(int x = 0;x<=numbers.Length;x++) { if(x<numbers.Length - 2) { if(numbers[x]<numbers[x+1]) { if(numbers[x+1]>numbers[x+2]) { downupdown++; } } } } count = 0; for(x=0;x<=numbers.Length;x++) { if(x<numbers.Length - 2) { if(numbers[x]>numbers[x+1] { if(numbers[x+1]<numbers[x+2]) { updownup++; } } } } 
-2
source

All Articles