命令式编程语言中的for循环在函数编程中如何实现?

时间:2022-01-01 16:04:25
最近在前学习scheme编程语言,知道函数编程语言没有常规编程语言的for循环,需要用尾递归来实现。
但是(凡事总有个但是)有时用用尾递归来实现循环来的不是很直接。比如“百鸡问题”用BASIC实现非常简单,用Java只时稍微麻烦一点。下面是“百鸡问题”的BASIC实现代码,请熟悉函数的编程的老大帮忙写出“百鸡问题”的Scheme或LISP实现代码。
PRINT "Cock", "Hen", "Chicken"
FOR x = 0 TO 20
    FOR y = 0 TO 33
        z = 100 - x - y
        IF x*5 + y*3 + z/3 = 100 THEN PRINT x, y, z
    NEXT
NEXT

6 个解决方案

#1


// lysee 1.1.1

= reduce(20, 0) {|int count, int x| 
  map(33) {|int y| 
    int z = 100 - x - y;
    if (x * 5 + y * 3 + z \ 3 == 100) {
      ++ count;
      = x, y, z, eol;
    }
  }
}, "found";

0 25 75
3 20 77
4 18 78
7 13 80
8 11 81
11 6 83
12 4 84
7 found

#2


1楼用的编程语言lysee看不懂,结果应该有四条,1楼有7条解的原因是小鸡的个数把77等不能被3整除的数也算在内了
0 25 75
4 18 78
8 11 81
12 4 84


#3


好高深的啊。
帮你顶,希望有人解答。

#4


俺是初学,写得可能不好,不简洁

(use srfi-1) ;;; import    functon: last  and  iota

;;;python haskell好像 容易实现这个函数的功能
(define (forfor lst1 lst2);;;; 返回列 (  (0 1)  (0 2) ... (0 33)... (20 0) (20 1) ...(20 33)  ) 
 (let [(l '())]  
  (do ( [x (first lst1) (add1 x)] )
      ( (> x (last lst1)) l )   
      (do ( [y (first lst2) (add1 y)] )
           ( (> y (last lst2)) #f )
          (set! l (append l (list (list x y)) ))  ))))


  
(define (baiji lst)
    (let* [(x (car lst))
          (y (last lst))
          (z (- 100 x y))]
        (if (= (+ (* 5 x) (* 3 y) (fx/ z 3)) 100)
          (print "x:" x " y:" y " z:" z))))
            
;  (iota 3 0) =>  (0 1 2) 类似python 的range函数
(for-each baiji (forfor (iota 21 0) (iota 34 0)))


---------------------------------------------------
x:0 y:25 z:75
x:3 y:20 z:77
x:4 y:18 z:78
x:7 y:13 z:80
x:8 y:11 z:81
x:11 y:6 z:83
x:12 y:4 z:84
        

#5


实现工具是 chicken scheme 
其他的工具除了(use srfi-1)不同外,其他应差不多的

#6


haskell:
[(x,y,(100-x-y)) | x<-[0..20],y<-[0..33],x*5+y*3+(100-x-y)/3==100]

返回:
[(0.0,25.0,75.0),(4.0,18.0,78.0),(8.0,11.0,81.0),(12.0,4.0,84.0)]

晕,除法不同?

#1


// lysee 1.1.1

= reduce(20, 0) {|int count, int x| 
  map(33) {|int y| 
    int z = 100 - x - y;
    if (x * 5 + y * 3 + z \ 3 == 100) {
      ++ count;
      = x, y, z, eol;
    }
  }
}, "found";

0 25 75
3 20 77
4 18 78
7 13 80
8 11 81
11 6 83
12 4 84
7 found

#2


1楼用的编程语言lysee看不懂,结果应该有四条,1楼有7条解的原因是小鸡的个数把77等不能被3整除的数也算在内了
0 25 75
4 18 78
8 11 81
12 4 84


#3


好高深的啊。
帮你顶,希望有人解答。

#4


俺是初学,写得可能不好,不简洁

(use srfi-1) ;;; import    functon: last  and  iota

;;;python haskell好像 容易实现这个函数的功能
(define (forfor lst1 lst2);;;; 返回列 (  (0 1)  (0 2) ... (0 33)... (20 0) (20 1) ...(20 33)  ) 
 (let [(l '())]  
  (do ( [x (first lst1) (add1 x)] )
      ( (> x (last lst1)) l )   
      (do ( [y (first lst2) (add1 y)] )
           ( (> y (last lst2)) #f )
          (set! l (append l (list (list x y)) ))  ))))


  
(define (baiji lst)
    (let* [(x (car lst))
          (y (last lst))
          (z (- 100 x y))]
        (if (= (+ (* 5 x) (* 3 y) (fx/ z 3)) 100)
          (print "x:" x " y:" y " z:" z))))
            
;  (iota 3 0) =>  (0 1 2) 类似python 的range函数
(for-each baiji (forfor (iota 21 0) (iota 34 0)))


---------------------------------------------------
x:0 y:25 z:75
x:3 y:20 z:77
x:4 y:18 z:78
x:7 y:13 z:80
x:8 y:11 z:81
x:11 y:6 z:83
x:12 y:4 z:84
        

#5


实现工具是 chicken scheme 
其他的工具除了(use srfi-1)不同外,其他应差不多的

#6


haskell:
[(x,y,(100-x-y)) | x<-[0..20],y<-[0..33],x*5+y*3+(100-x-y)/3==100]

返回:
[(0.0,25.0,75.0),(4.0,18.0,78.0),(8.0,11.0,81.0),(12.0,4.0,84.0)]

晕,除法不同?