N 番目の要素を O(1) で取得する Cycle クラスを作る
数列 a = { 0, 1, 0, -1, 0, 1, 0, -1, 0, 1, 0, -1, ... } のような 4 周期で繰り返す数列で、かつ N 番目の要素を O(1) で取得する Cycle クラスを作ってみました。
// 0, 1, ... を繰り返す数列 var zeroOne = new Cycle<int>(new[] { 0, 1 }); Console.WriteLine(string.Join(", ", zeroOne.Take(5))); //=> 0, 1, 0, 1, 0 Console.WriteLine(string.Join(", ", new[] { 0, 1, 2, 3, 5 }.Select(e => zeroOne[e]))); //=> 0, 1, 0, 1, 1 // 0, 1, 0, -1, ... を繰り返す数列 var seq = new Cycle<int>(new[] { 0, 1, 0, -1 }); Console.WriteLine(string.Join(", ", seq.Take(8))); //=> 0, 1, 0, -1, 0, 1, 0, -1 Console.WriteLine(string.Join(", ", new[] { 0, 1, 2, 3, 5, 7 }.Select(e => seq[e]))); //=> 0, 1, 0, -1, 1, -1
Cycle クラス:
class Cycle<T> : IEnumerable<T> { private readonly T[] _array; public Cycle(T[] array) { if (array == null) throw new ArgumentNullException(nameof(array)); if (array.Length == 0) throw new ArgumentException(nameof(array)); _array = array; } public IEnumerator<T> GetEnumerator() { while (true) { foreach (var x in _array) yield return x; } } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public T this[int index] => _array[index % _array.Length]; }