グラフを表示する関数で、横棒のグラフを描くバージョンを作りなさい。
解答を以下に載せていますが,行の途中にポイントがある場合は,グラフがきれいに表示されません。
原因は,横棒を表示してから,forward-line関数で次の行に移動するのですが,次の行の行頭に移動してしまうためです。from-positionの真下に移動する方法がまだ理解できていません。
それから,list2str関数を作ったのですが,これは,
(" " " " "*" "*" "*")
のようなリストを
" ***"
という文字列に変換するためのものです。emacs lispに同等の機能を持つ関数はあるのでしょうか?
(defvar graph-symbol "*" "String used as symbol in graph, usually an asterisk.") (defvar graph-blank " " "String used as blank in graph, usually a blank space. graph-blank must be the same number of columns wide as graph-symbol.") (defun column-of-graph (max-graph-height actual-height) (let ((insert-list nil) (number-of-top-blanks (- max-graph-height actual-height))) ;; graph-symbols を詰める (while (> actual-height 0) (setq insert-list (cons graph-symbol insert-list)) (setq actual-height (1- actual-height))) ;; graph-blanks を詰める (while (> number-of-top-blanks 0) (setq insert-list (cons graph-blank insert-list)) (setq number-of-top-blanks (1- number-of-top-blanks))) ;; リスト全体を返す insert-list)) (defun graph-body-print (numbers-list) (let ((height (apply 'max numbers-list)) (symbol-width (length graph-blank)) from-position) (while numbers-list (setq from-position (point)) (insert (list2str (nreverse (column-of-graph height (car numbers-list))))) (goto-char from-position) (forward-line) ;; 各桁ごとのグラフの描写 (sit-for 0) (setq numbers-list (cdr numbers-list))) (insert "\n") )) (defun list2str (lst) (let ((tmp nil)) (while lst (setq tmp (concat tmp (car lst))) (setq lst (cdr lst))) tmp)) ;(graph-body-print '(1 2 3 4 6 4 3 5 7 6 5 2 3))