recursive-graph-body-print 関数
¶graph-body-print
関数は、再帰的に記述することも可能です。再帰的な解法は2つの部分に分かれています。一つは、グラフの最大高さなど、一度だけ求めればよい複数の変数の値を
let
式を用いて決定する外側のラッパーであり、もう一つは、グラフを出力するために再帰的に呼び出される内側の関数です。
ラッパーはシンプルです:
(defun recursive-graph-body-print (numbers-list)
"Print a bar graph of the NUMBERS-LIST.
The numbers-list consists of the Y-axis values."
(let ((height (apply 'max numbers-list))
(symbol-width (length graph-blank))
from-position)
(recursive-graph-body-print-internal
numbers-list
height
symbol-width)))
再帰関数は少し複雑です。これは、再実行判定、出力コード、再帰呼び出し、そして次ステップ式の4つの部分で構成されています。再実行判定はwhen式で、numbers-listに残りの要素があるかどうかを判定します。要素がある場合、関数は出力コードを用いてグラフの1列を出力し、自身を再度呼び出します。関数は、次ステップ式によって生成された値に基づいて自身を再度呼び出し、これにより呼び出しはnumbers-listの短縮版に対して処理を行うことになります。
(defun recursive-graph-body-print-internal (numbers-list height symbol-width) "Print a bar graph. Used within recursive-graph-body-print function."
(when numbers-list
(setq from-position (point))
(insert-rectangle
(column-of-graph height (car numbers-list)))
(goto-char from-position)
(forward-char symbol-width)
(sit-for 0) ; Draw graph column by column.
(recursive-graph-body-print-internal
(cdr numbers-list) height symbol-width)))
インストール後、この式をテストできます。以下にサンプルを示します。
(recursive-graph-body-print '(3 2 5 6 7 5 3 4 6 4 3 2 1))
recursive-graph-body-print が生成する結果は以下の通りです。
*
** *
**** *
**** ***
* *********
************
*************
graph-body-print または recursive-graph-body-print のいずれかの関数が、グラフの本体を生成します。