Searching a sequence for a pattern
Personally, here is how I would do it. I think this is pretty straight-forward. I think it is also no less efficient than the other (longer, more complex) answer. The method Subarray is something I wrote before, I didn’t write it just for this.

/// &lt;summary&gt;Similar to &lt;see cref="string.Substring(int,int)"/&gt;, only for arrays. Returns a new
/// array containing &lt;paramref name="length"/&gt; items from the specified
/// &lt;paramref name="startIndex"/&gt; onwards.&lt;/summary&gt;
public static T[] Subarray&lt;T&gt;(this T[] array, int startIndex, int length)
{
    if (array == null)
        throw new ArgumentNullException("array");
    if (startIndex &lt; 0)
        throw new ArgumentOutOfRangeException("startIndex", "startIndex cannot be negative.");
    if (length &lt; 0 || startIndex + length &gt; array.Length)
        throw new ArgumentOutOfRangeException("length", "length cannot be negative or extend beyond the end of the array.");
    T[] result = new T[length];
    Array.Copy(array, startIndex, result, 0, length);
    return result;
}

public static IEnumerable&lt;T[]&gt; SearchPattern&lt;T&gt;(this IEnumerable&lt;T&gt; seq, params Func&lt;T[], T, bool&gt;[] matches)
{
    Contract.Requires(seq != null);
    Contract.Requires(matches != null);
    Contract.Requires(matches.Length &gt; 0);

    // No need to create a new array if seq is already one
    var seqArray = seq as T[] ?? seq.ToArray();

    // Check every applicable position for the matching pattern
    for (int j = 0; j &lt;= seqArray.Length - matches.Length; j++)
    {
        // If this position matches...
        if (Enumerable.Range(0, matches.Length).All(i =&gt;
            matches[i](seqArray.Subarray(j, i), seqArray[i + j])))
        {
            // ... yield it
            yield return seqArray.Subarray(j, matches.Length);

            // and jump to the item after the match so we don’t get overlapping matches
            j += matches.Length - 1;
        }
    }
}