函数式编程真好用,
优化是啥, 能吃么2333
(如果有点兴趣, 后面我稍微给出了解释)
#lang racket
(define (co sym number)
(cons sym number))
(define (get_sym s)
(if (number? s)
s
(car s)))
(define (get_number s)
(if (number? s)
s
(cdr s)))
(define (gen f a b)
(co (list
(cond ((eq? f +) '+)
((eq? f -) '-)
((eq? f *) '*)
((eq? f /) '/))
(get_sym a) (get_sym b))
(f (get_number a) (get_number b))))
(define (f0 a b)
(if (or (eq? a 'err) (eq? b 'err))
(list 'err)
(list
(gen + a b)
(gen - a b)
(gen - b a)
(gen * a b)
(if (= (get_number b) 0)
'err
(gen / a b))
(if (= (get_number a) 0)
'err
(gen / b a)))))
(define (f1 a l)
(if (null? l)
'()
(append (f0 a (car l))
(f1 a (cdr l)))))
(define (f2 l1 l2)
(if (null? l1)
'()
(append (f1 (car l1) l2)
(f2 (cdr l1) l2))))
(define (c n)
(cond
((= n 1) '(1 2 3 4)) ; 把这里改成想要的4个数字就行
((= n 2) (f2 (c 1) (c 1)))
((= n 3) (f2 (c 1) (c 2)))
((= n 4)
(append (f2 (c 1) (c 3))
(f2 (c 2) (c 2))))))
; 这就是答案了
(filter (lambda (x) (= (get_number x) 24))
(filter (lambda (x) (not (eq? x 'err)))
(c 4)))
直接算1 2 3 4有474种答案, 当然有很多是重复的
(((* 1 (* 2 (* 3 4))) . 24)
((/ (* 2 (* 3 4)) 1) . 24)
((* 1 (* 2 (* 4 3))) . 24)
((/ (* 2 (* 4 3)) 1) . 24)
((* 1 (* 3 (* 2 4))) . 24)
((/ (* 3 (* 2 4)) 1) . 24)
((* 1 (* 3 (* 4 2))) . 24)
((/ (* 3 (* 4 2)) 1) . 24))
要是有人看的话, 我再写点,
基本思路是生成abcd与+-*/的所有结果, 再筛选出需要的结果,
上面有八个函数, co, get_sym, get_number, gen, f0, f1, f2, c,
递归地想, 四个数字的结果表可以由三个数字的结果表和一个数字得出(简称3+1)或者2+2,
同理, 3=1+2, 2=1+1,
这就是c函数干的事: 初次分解,
然后, 用两个结果表生成一个结果表, 这就是个双重循环,
然后我拆成三个函数: 列表对列表, 列表对元素, 元素对元素,
就是f2, f1, f0三个函数,
拿着ab, 如何生成(a+b, a-b, b-a, a*b, a/b, b/a), 应该就不用我说了吧,
co, get_sym, get_number, 就是一数据抽象之类的对象, 无需在意,
最后, gen函数应该改成搜索列表之类的, 而不是一个情况判断, 有空再说吧, 下次一定2333