FizzBuzz — это известная задачка на программирование, которую обычно дают в технической части собеседований. Она формулируется примерно так:
Напишите функцию, выводящую список целых чисел от 1 до 100, но вместо каждого числа, кратного 3, она должна выводить «Fizz», а вместо каждого числа, кратного 5, выводить «Buzz». Вместо чисел, кратных и 3, 5, программа должна выводить «FizzBuzz»; все остальные числа должны выводиться без изменений.
Можно написать функцию, вообще не использующую условную логику и вместо этого разделяющую целые числа на 4 возможные категории (обычное решение оставим в качестве упражнения заинтересованному читателю):
- Имеющие делитель 3, но не 5
- Имеющие делитель 5, но не 3
- Имеющие делитель и 3, и 5
- Не имеющие делитель 3 и 5
Нам нужна функция, которая будет возвращать:
- «Fizz», если и является взаимно простым с 5
- «Buzz», если и является взаимно простым с 3
- «FizzBuzz», если и
- во всех остальных случаях.
Рассмотрим реализацию такой функции на Python:
[(lambda n: { 1: n, 6: "Fizz", 10: "Buzz", 0: "FizzBuzz" }[n**4%15])(n+1) for n in range(100)]
Та же функция на Ruby:
(1..100).map{|n| {1 => n, 6 => "Fizz", 10 => "Buzz", 0 => "FizzBuzz"}[n**4%15] }
Как мы и ожидали, каждая из этих функций возвращает список целых чисел от 1 до 100 с подставленными в нужные места «Fizz», «Buzz» и «FizzBuzz».
Но почему? Откуда взялись постоянные значения 0, 6, 10 и 1? Почему
возвращает 6 для чисел, кратных 3, но не 5, 10 для чисел, кратных 5, но не 3, 0 для чисел, кратных 5 и 3 и 1 во всех остальных случаях? И самое важное — справедливо ли это для любого
, которое мы выберем?