Looping in a spiral

前端 未结 30 2669
独厮守ぢ
独厮守ぢ 2020-11-22 15:07

A friend was in need of an algorithm that would let him loop through the elements of an NxM matrix (N and M are odd). I came up with a solution, but I wanted to see if my fe

30条回答
  •  醉梦人生
    2020-11-22 15:17

    Here's c#, linq'ish.

    public static class SpiralCoords
    {
      public static IEnumerable> GenerateOutTo(int radius)
      {
        //TODO trap negative radius.  0 is ok.
    
        foreach(int r in Enumerable.Range(0, radius + 1))
        {
          foreach(Tuple coord in GenerateRing(r))
          {
            yield return coord;
          }
        }
      }
    
      public static IEnumerable> GenerateRing(int radius)
      {
        //TODO trap negative radius.  0 is ok.
    
        Tuple currentPoint = Tuple.Create(radius, 0);
        yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
    
        //move up while we can
        while (currentPoint.Item2 < radius)
        {
          currentPoint.Item2 += 1;
          yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
        }
        //move left while we can
        while (-radius < currentPoint.Item1)
        {
          currentPoint.Item1 -=1;
          yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);    
        }
        //move down while we can
        while (-radius < currentPoint.Item2)
        {
          currentPoint.Item2 -= 1;
          yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
        }
        //move right while we can
        while (currentPoint.Item1 < radius)
        {
          currentPoint.Item1 +=1;
          yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);    
        }
        //move up while we can
        while (currentPoint.Item2 < -1)
        {
          currentPoint.Item2 += 1;
          yield return Tuple.Create(currentPoint.Item1, currentPoint.Item2);
        }
      }
    
    }
    

    The question's first example (3x3) would be:

    var coords = SpiralCoords.GenerateOutTo(1);
    

    The question's second example (5x3) would be:

    var coords = SpiralCoords.GenerateOutTo(2).Where(x => abs(x.Item2) < 2);
    

提交回复
热议问题