逆FizzBuzz問題

近未来、2016年(・・・って、中途半端に近い未来ですね)では、
Googleの入社試験では、逆FizzBuzz問題を解くことになるそうな。

fizzbuzzした結果のリストから、それを生成するような最短の数値の範囲を求める、という問題です。

Pythonでやってみた感想は「やっぱり無名関数が欲しいなぁ」。名前を付けたほうが後々役立つのはそうなんでしょうが、こういった処理ではイマイチ良い名前が浮かばないことも多い。コードで言うと、candidatesとか。

#!python3
# -*- coding: ascii -*-
#invertfizzbuzz.py
"""
>>> from invertfizzbuzz import invert_fizzbuzz
>>> invert_fizzbuzz("fizz".split())
range(3, 4)
>>> invert_fizzbuzz("buzz".split())
range(5, 6)
>>> invert_fizzbuzz("fizz buzz".split())
range(9, 11)
>>> invert_fizzbuzz("buzz fizz".split())
range(5, 7)
>>> invert_fizzbuzz("fizz buzz fizz".split())
range(3, 7)
>>> invert_fizzbuzz("fizz fizz".split())
range(6, 10)
>>> invert_fizzbuzz("fizz fizz buzz".split())
range(6, 11)
"""

from iterutils import unique_everseen, count

def fizzbuzz(x):
    if x % 15 == 0:
        return "fizzbuzz"
    elif x % 3 == 0:
        return "fizz"
    elif x % 5 == 0:
        return "buzz"
    else:
        return x

def fizzbuzz_words_with_length(start, length):
    words = 
    for n in count(start):
        v = fb(n)
        if isinstance(v, str):
            words.append(v)
        if len(words) == length:
            return words, n + 1


def invert_fizzbuzz(words):
    words = list(words)
    if not words:
        return range(1,1)
    
    start_points = [3, 5, 6, 9, 10, 12, 15]
    invert_fizzbuzz = {}
    candidates = 
    for begin in start_points:
        fb, end = fizzbuzz_words_with_length(begin, len(words))
        if fb == words:
            candidates.append(range(begin, end))
    return min(candidates, key=len)

if __name__ == "__main__":
    import doctest
    doctest.testmod()

就職してから1回もブログを更新してないぜ。