逆FizzBuzz問題(linq)

asq を入れて、ちょっと書きなおしてみた.
order_by した後に、count して first すると empty sequence が出るという C# で出ない挙動がちょっとアレです.

from asq.initiators import query
from itertools import count, cycle, islice, ifilter

def FizzBuzz():
    seq = [None, None, "Fizz", None, "Buzz", "Fizz", None, None, "Fizz", "Buzz", None, "Fizz", None, None, "FizzBuzz"]
    for i, e in enumerate(cycle(seq)):
        if e == None:
            yield i + 1
        else:
            yield e

def InverseFizzBuzz(seq):
    count = len(seq)
    def work(start):
        i = start
        c = count
        a = []
        for x in query(FizzBuzz()).skip(start - 1):
            if c == 0:
                l = i - start
                return (a, l, range(start, start + l))
            if not isinstance(x, int):
                a += [x]
                c -= 1
            i += 1
    candidates = query([3, 5, 6, 9, 10, 12, 15]).select(work).where(lambda x: x[0] == seq).to_list()
    if len(candidates) == 0:
        return None
    else:
        return query(candidates).order_by(lambda x: x[1]).first()[2]

assert InverseFizzBuzz(["Fizz"]) == range(3, 4)
assert InverseFizzBuzz(["Buzz"]) == range(5, 6)
assert InverseFizzBuzz(["Fizz", "Buzz"]) == range(9, 11)
assert InverseFizzBuzz(["Buzz", "Fizz"]) == range(5, 7)
assert InverseFizzBuzz(["Fizz", "Buzz", "Fizz"]) == range(3, 7)
assert InverseFizzBuzz(["Buzz", "Fizz", "Buzz"]) == None
assert InverseFizzBuzz(["Fizz", "Fizz"]) == range(6, 10)
assert InverseFizzBuzz(["Fizz", "Fizz", "Buzz"]) == range(6, 11)