Functional programming leads to deep insights into the nature of computation. – Martin Odersky
近日软件匠艺小组的朋友用函数式编程的方式重新实现了一个古老的Kata练习题:FizzBuzzWhizz,用了很多种语言及其特性,非常精妙。这是一个软件匠艺的文艺复兴时代。
原帖见https://codingstyle.cn/topics/100
题目
FizzBuzzWhizz详细描述请自行查阅相关资料。此处以3, 5, 7为例,形式化地描述一下问题。
r1
+ times(3) -> Fizz
+ times(5) -> Buzz
+ times(7) -> Whizz
r2
+ times(3) && times(5) && times(7) -> FizzBuzzWhizz
+ times(3) && times(5) -> FizzBuzz
+ times(3) && times(7) -> FizzWhizz
+ times(5) && times(7) -> BuzzWhizz
r3
+ contains(3) -> Fizz
+ the priority of contains(3) is highest
rd
+ others -> others
Python实现
借助原帖的测试用例,我用python语言也练习了一把。本来想引入Pipe库用管道式的方式写,可能会取得一些方便,但想想还是用原生的语法来做吧。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| def times(n, s): return lambda x: s if x % n == 0 else '' time3 = times(3, 'Fizz') time5 = times(5, 'Buzz') time7 = times(7, 'Whizz')
def allof(*rules): return lambda x: reduce(lambda s, rule: s + rule(x), rules, '')
def anyof(*rules): def lmb(x): for rule in rules: if rule(x): return rule(x) return lmb
r1 = anyof(time3, time5, time7) r2 = anyof(allof(time3, time5, time7), allof(time3, time5), allof(time3, time7), allof(time5, time7)) r3 = lambda x: 'Fizz' if str(x).count('3') else '' rd = lambda x: str(x) lord_of_the_rule = anyof(r3, r2, r1, rd)
|
这里是测试用例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import unittest
class FizzBuzzWhizzTest(unittest.TestCase):
def test_rule_1(self): self.assertEqual('Fizz', lord_of_the_rule(3)) self.assertEqual('Buzz', lord_of_the_rule(5)) self.assertEqual('Whizz', lord_of_the_rule(7))
def test_rule_2(self): self.assertEqual('FizzBuzzWhizz', lord_of_the_rule(3 * 5 * 7)) self.assertEqual('FizzBuzz', lord_of_the_rule(3 * 5)) self.assertEqual('BuzzWhizz', lord_of_the_rule((5 * 7) * 2))
def test_rule_3(self): self.assertEqual('Fizz', lord_of_the_rule(13))
def test_priority_of_r3_greater_than_r2(self): self.assertEqual('Fizz', lord_of_the_rule(35))
def test_rule_d(self): self.assertEqual('2', lord_of_the_rule(2))
if __name__ == "__main__": unittest.main()
|
源代码见 https://github.com/mebusw/fizz-buzz-whizz/blob/master/python/FizzBuzzWhizzTest.py