Красиво вывести дерево - Lisp
Формулировка задачи:
Что-то первое сентября уже прошло, а тишина раздела осталась не тронута Предлагаю задачку - есть дерево в форме списка - первый элемент значение узла, остальные - лес У нас же динамика. Типа такого
Задача - красиво визуализировать его на экране - в текстовом или в графическом виде, горизонтально или вертикально и т.п. - как фантазия подскажет Я взял простую классику:
(a b (c d e) f (g h (i j (k (l)) m n o)))
(defn show-tree (t)
(defn foldl-last (f g a l)
(defn go (a l) (cond (null? l) a
(null? (cdr l)) (g (car l) a)
(go (f (car l) a) (cdr l)) ))
(go a l))
(defn go (t v)
(defn f (c d)
lambda (x a) ++ a \n v "|" \n v c "- " (go x (++ v d " ")))
(cond (list? t)
(++ "<" (car t) ">"
(foldl-last (f "+" "|") (f "`" " ") "" (cdr t)))
t))
(go t ""))
=> OK
def t '(a b (c d e) f (g h (i j (k (l)) m n o)))
=> OK
t
=> (a b (c d e) f (g h (i j (k (l)) m n o)))
++ \n (show-tree t)
=>
<a>
|
+- b
|
+- <c>
| |
| +- d
| |
| `- e
|
+- f
|
`- <g>
|
+- h
|
`- <i>
|
+- j
|
+- <k>
| |
| `- <l>
|
+- m
|
+- n
|
`- oРешение задачи: «Красиво вывести дерево»
textual
Листинг программы
(defun dwtree (tree w x y &optional (lv 0)) (cond ((null tree) y) ((atom (car tree)) (let ((xn (+ x 20)) (yn (+ y 15))) (grwLine w x y x yn _BLACK) (grwLine w x yn xn yn _BLACK) (grwPrint w xn (+ y 7) (output (car tree)) _RED) (dwtree (cdr tree) w x yn lv))) (t (let ((xn (+ x 30 (* lv 5))) (yn (+ y 15))) (grwLine w x y x yn _BLACK) (grwLine w x yn xn yn _BLACK) (grwPrint w xn (- yn 7) "<*>" _BLACK) (let* ((new-v (dwtree (car tree) w xn yn (+ lv 1))) (yy (if (null (cdr tree)) new-v (+ 15 new-v)))) (when (cdr tree) (grwLine w x y x yy _BLACK)) (dwtree (cdr tree) w x yy lv) yy)))))