美文网首页
函数式编程解百鸡问题

函数式编程解百鸡问题

作者: redexpress | 来源:发表于2022-06-07 08:23 被阅读0次

    问题

    百鸡问题来自《张邱建算经》,原文:今有鸡翁一直钱五,鸡母一直前三,鸡雏三直钱一,凡百钱买百鸡。问:鸡翁、母、雏各几何?

    这个问题有三个未知数,但却只能列两个方程。属于不确定方程问题。如果直接推算比较复杂,可以参考“百鸡问题”史话,而用编程实现比较直接。

    命令式编程

    用命令式编程有两种解法,下面是Python程序

    方法一:多重循环

    for x in range(0, 21):
        for y in range(0, 34):
            z = 100 - x - y
            if x * 5 + y * 3 + z / 3 == 100:
                print(x, y, z)
    

    方法二:列表演算

    思路同方法一,Python 等编程语言支持列表演算,可以用一行代码写完

    [print(x, y, 100 - x - y) for x in range(21) for y in range(34) if x*5+y*3+(100-x-y)/3 == 100]
    

    方法三:单循环加逻辑推理

    只循环公鸡,剩下的钱买小鸡,鸡的总量超过100的,每超过8只就把9只小鸡换成1只母鸡,这样总量就是100。

    for x in range(21):
        z = (20 - x) * 15
        y = (x + z - 100) // 8
        if (x + z - 100) % 8 == 0 and (x + z >= 100):
            print(x, y, 100-x-y)
    

    函数式编程

    函数式编程语言没有for/while循环语句,可以通过递归实现,下面是Scheme代码:

    (define (chicken)
      (chicken-iter 0 0))
    
    (define (chicken-iter a b)
      (cond [(eq? 100 (+ (* a 5) (* b 3) (/ (- 100 a b) 3)))
             (printf "~s ~s ~s\n" a b (- 100 a b))])
      (cond [(and (eq? a (truncate 100/5)) (eq? b (truncate 100/3)))
             (display "")]
            [else (if (eq? b (truncate 100/3))
              (chicken-iter (+ a 1) 0)
              (chicken-iter a (+ b 1)))]))
    
    (chicken)
    

    而Haskell支持列表演算,代码可以很简短:

    [(x, y, 100-x-y) | x <- [0..20], y<-[0..33], x*5+y*3+(100-x-y) `div` 3 == 100, (100-x-y) `mod` 3==0]
    

    即使你不了解Haskell,代码也不难理解。第三种方法的函数式编程感兴趣读者可以自行完成。

    相关文章

      网友评论

          本文标题:函数式编程解百鸡问题

          本文链接:https://www.haomeiwen.com/subject/exnsmrtx.html