понедельник, 18 августа 2014 г.

BurdoBordo как генерализация FizzBuzz

Многим известно  тестовое задание FizzBuzz. Возникла (а почему бы и нет?) идея решить более общую задачу. Будут заданы два делителя и две соответствующих им строки. Результатом будет вывод исходного числа или строки в зависимости от делимости числа. Наивный, понятный, хорошо поддерживаемый первый вариант:

def BurdoBordo(x,BURDO="BURDO",burdo=3,BORDO="BORDO",bordo=5):
    if x%burdo==0 and x%bordo==0:
        return BURDO+BORDO
    elif x%burdo==0:
        return BURDO
    elif x%bordo==0:
        return BORDO
    else:
        return str(x)
FizzBuzz=lambda x: BurdoBordo(x,BURDO="Fizz",burdo=3,BORDO="Buzz",bordo=5)
for x in xrange(1,101):
    print FizzBuzz(x)


Следующий вариант, в котором более активно используются особенности python.

def BurdoBordo(x,BURDO="BURDO",burdo=3,BORDO="BORDO",bordo=5):
    return ((BURDO,)+('',)*burdo)[x%burdo]+((BORDO,)+('',)*bordo)[x%bordo] or str(x)

FizzBuzz=lambda x: BurdoBordo(x,BURDO="Fizz",burdo=3,BORDO="Buzz",bordo=5)
for x in xrange(1,101):
    print FizzBuzz(x)

И, наконец, последний вариант, с индексами и short-circuit evaluation.

def BurdoBordo(x,BURDO="BURDO",burdo=3,BORDO="BORDO",bordo=5):
    return (BURDO+BORDO)[x%burdo and len(BURDO):x%bordo and len(BURDO) or len(BURDO+BORDO)] or str(x)

FizzBuzz=lambda x: BurdoBordo(x,BURDO="Fizz",burdo=3,BORDO="Buzz",bordo=5)
for x in xrange(1,101):
    print FizzBuzz(x)