На днях мне нужен был алгоритм для превращения 2D-сетки в алмаз (путем эффективного поворота на 45 градусов), поэтому я мог бы рассматривать диагональные последовательности как плоские перечислимые числа, например:
1 2 3 1
4 5 6 => 4 2
7 8 9 7 5 3
8 6
9
Мой алгоритм выглядит следующим образом:
public static IEnumerable<IEnumerable<T>> RotateGrid<T>(IEnumerable<IEnumerable<T>> grid)
{
int bound = grid.Count() - 1;
int upperLimit = 0;
int lowerLimit = 0;
Collection<Collection<T>> rotated = new Collection<Collection<T>>();
for (int i = 0; i <= (bound * 2); i++)
{
Collection<T> row = new Collection<T>();
for (int j = upperLimit, k = lowerLimit; j >= lowerLimit || k <= upperLimit; j--, k++)
{
row.Add(grid.ElementAt(j).ElementAt(k));
}
rotated.Add(row);
if (upperLimit == bound)
lowerLimit++;
if (upperLimit < bound)
upperLimit++;
}
return rotated;
}
Можно ли это сделать в более сжатом формате с использованием LINQ?
.. или даже просто более сжатый формат?:)