Re: [问题] 1-9位数不重复印出来 (Lisp)

楼主: hijkxyzuw (i,j,k) ×(x,y,z)   2017-05-25 01:27:46
最近在玩 lisp ,都只在 emacs 里执行而已。
这个问题想超久,自己也不知道卡在哪,
总之还是写出来了。
有 prolog 竟然没有 lisp !
好歹也算传奇又常见的语言。
不过这个板 prolog 文章好像比 lisp 多。
;; 因为需要巢状呼叫,所以变成 nest list,
;; 可以看成 tree 的结构。
;; 对一棵树所有元素执行 func,
;; 返回由返回值组成的树的副本。
(defun map-tree (func tree)
(if (atom tree)
(if (null tree)
nil
(funcall func tree))
(cons
(map-tree func (car tree))
(map-tree func (cdr tree)))))
;; 把数字 i 从 tree 中移除。(换成 nil。)
(defun filter-out-number (i tree)
(map-tree
(lambda (j)
(if (= i j) nil j))
tree))
;; 把一棵树除了 i 以外的值滤掉,
;; 再把每个元素乘十倍加上 i。
(defun multi-ten (i tree)
(map-tree
(lambda (j) (+ i (* j 10)))
tree))
;; 递回本体
;; 若 n = 1 则返回
(defun n-ten-list (n lst)
(if (= n 1)
lst
(map-tree
(lambda (i)
(multi-ten
i
(n-ten-list
(- n 1)
(filter-out-number i lst))))
lst)))
;; 包装函数
(defun n-ten (n)
(n-ten-list n '(0 1 2 3 4 5 6 7 8 9)))
结果大概像这样:
((nil (nil nil 210 310 410 510 610 710 810 910) (nil 120 nil 320 420 520 620 72\
0 820 920) (nil 130 230 nil 430 530 630 730 830 930) (nil 140 240 340 nil 540 6\
40 740 840 940) (nil 150 250 350 450 nil 650 750 850 950) (nil 160 260 360 460 \
...
还是长得像事后滤掉的。
还是 lisp 新手,
不知道怎么 print 或处理列表,
就变成很丑的巢状列表。
还有一些逻辑应该可以再优化,
等认识多一点函数后再来改进吧。

Links booklink

Contact Us: admin [ a t ] ucptt.com