Question

In a recent interview one peculiar question has been asked

a[]= { 1,2,3,4,5,6,7,8,9,10}

When an array is given with specified starting index i have to iterate it till i traverse all elements.

I mean suppose the starting index is "5" i have to start from 6,7,8,9,10,5,4,3,2,1.Please carefully look at the sequence ,how can one create Reset(), Current,blah,blah...?.

But the interviewer executed the sequence as he asked.He did not show the code.

Can we really develop a logic for such a strange requirement?

Was it helpful?

Solution

Just use two loops.

IEnumerable<int> ForwardsBackwards(int[] a, int start) {
    for(int i=start; i<a.Length; i++) 
        yield return a[i];
    for(int i=start-1; i>=0; i--) 
        yield return a[i];
}

Edit: Even better with linq:

IEnumerable<int> ForwardBackward(int[] a, int start) {
    return a.Skip(start).Concat(a.Take(start).Reverse());
}

OTHER TIPS

Easier to maintain(?):

        int[] a= {1,2,3,4,5,6,7,8,9,10};

        int StartIndex=5;

        for (int iCount = StartIndex; iCount < a.Count() + StartIndex; iCount++)
        {
            Debug.WriteLine(a[(iCount + a.Count()) % a.Count()]);
        }

Output is:

6 7 8 9 10 1 2 3 4 5

Edit: just spotted your sequence, it reverses when you reach the upper limit. That's nasty if that was the specified question.

It's an old thread, but i had need of same algorithm, and came to a nice solution. Solution

  1. Can start from ANY element of array
  2. Can start iterate to ANY direction
  3. Will pass all elements, starting from NEXT in the direction of motion
  4. Will overlap to first/last, when border element is reached

All magic is in single line with for loop operator, other code is for preview convenience.

// Example program
#include <iostream>
#include <string>

int a[] = {0,1,2,3,4,5};
int Count = sizeof(a)/sizeof(int);

void LoopFromMidWithDirection ( int curIdx , int motion )
{
    std::cout << "\nNextFrom=" << curIdx << " motion =" << motion << "\n";
    curIdx +=motion;
    for (int i = curIdx; (i - curIdx) * motion < Count ; i += motion)
        std::cout << a[(i + Count) % Count] << " ";

    std::cout << "\n";
}

int main()
{
    LoopFromMidWithDirection(4, +1);
    LoopFromMidWithDirection(6, +1);
    LoopFromMidWithDirection(0, -1);
}

Output

NextFrom=4 motion =1
5 0 1 2 3 4 

NextFrom=6 motion =1
1 2 3 4 5 0 

NextFrom=0 motion =-1
5 4 3 2 1 0 

Solution is inspired from @Neil Kimber

Yes, you must implement the IEnumerator interface on a custom class. Write logic into the MoveNext method that detects end of array and then starts at the beginning of the array, remembering the mid-way start point.

Follow these code samples by Microsoft as a template.

(DEFINE (traverse length start call) 
  (DEFINE (flow index motion)
    (cond ((> index length) 
              (flow (- start 1) -1))
          ((> index -1) 
              ((call index) (flow (+ index motion) motion)))))
  (flow start +1))

(traverse 9 5 job)

I like the 9 to 5 aspect of the question. I wonder if they were alluding to something? Assuming job prints out the array index, this would produce 678954321.

In C i'd be tempted to use a for loop (not a while loop as I had it before the edit);

int a[]= { 1,2,3,4,5,6,7,8,9,10};
int length = 10;
int start = 5;
int motion = 1; //increment

for( int index = start; index >= 0; index += motion ) {
  if(index > (length-1)) {
    motion = -1; //decrement
    index = start -1;
  else {
    printf("%d", a[index]);
  }
}

The process is only finished after you print the zero index. The only time you're not traversing the array is when you've exceeded it. When that happens, you return to the start index (-1) and reverse the motion.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top