fork download
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. static class Program
  6. {
  7. public static void Main(string[] args)
  8. {
  9. var list1 = new int?[] { 1, 2, 3, 4, 5 };
  10. var list2 = new int?[] { 3, 4, 5, 6, 7 };
  11. var list3 = new int?[] { 6, 9, 9 };
  12.  
  13. var lockstep = LockStepSequences(new[] { list1, list2, list3 });
  14.  
  15. foreach (var step in lockstep)
  16. Console.WriteLine(string.Join("\t", step.Select(i => i.HasValue ? i.Value.ToString() : "null").ToArray()));
  17. }
  18.  
  19. public static IEnumerable<IEnumerable<T>> LockStepSequences<T>(this IEnumerable<IEnumerable<T>> sequences)
  20. {
  21. var iters = sequences
  22. .Select((s, index) => new { active=true, index, enumerator = s.GetEnumerator() })
  23. .ToArray();
  24.  
  25. var isActive = iters.Select(it => it.enumerator.MoveNext()).ToArray();
  26. var numactive = isActive.Count(flag => flag);
  27.  
  28. try
  29. {
  30. while (numactive > 0)
  31. {
  32. T min = iters
  33. .Where(it => isActive[it.index])
  34. .Min(it => it.enumerator.Current);
  35.  
  36. var row = new T[iters.Count()];
  37.  
  38. for (int j = 0; j < isActive.Length; j++)
  39. {
  40. if (!isActive[j] || !Equals(iters[j].enumerator.Current, min))
  41. continue;
  42.  
  43. row[j] = min;
  44. if (!iters[j].enumerator.MoveNext())
  45. {
  46. isActive[j] = false;
  47. numactive -= 1;
  48. }
  49. }
  50. yield return row;
  51. }
  52. }
  53. finally
  54. {
  55. foreach (var iter in iters) iter.enumerator.Dispose();
  56. }
  57. }
  58. }
  59.  
  60.  
Success #stdin #stdout 0.06s 37288KB
stdin
Standard input is empty
stdout
1	null	null
2	null	null
3	3	null
4	4	null
5	5	null
null	6	6
null	7	null
null	null	9
null	null	9