練習(ヒストグラム)
2007/05/11
練習のため、また問題を取ってきた。
http://www.media.osaka-cu.ac.jp/~matsuura/2006-PP/index.html
課題4-2 (ヒストグラム)
学生の成績の分布をヒストグラムとして表示するプログラム Hist を作ってください.
0~100の整数をキーボードから繰り返し読み込み(-1が入力されたら終わり),
0点台(0~9点),10点台(10~19点),…,90点台,
100点の学生がそれぞれ何人いるかをヒストグラムで表示してください.
検討したこと
各点数台の人数データ格納領域を用意する
(setq hist-lst '(0 0 0 0 0 0 0 0 0 0))
アクセスしてみる
(nth 2 hist-lst)
更新は↓
(setf (nth 2 hist-lst) 3)
インクリメント更新は↓
(setf (nth 2 hist-lst) (1+ (nth 2 hist-lst)))
データ構造関係はこんな感じでいいのかな?
あと、そろそろ普通のループを覚えてみた。
回答
完成形
;プロンプト表示 入力値取得関数 (defun prompt-read (prompt) (format *query-io* "~a: " prompt) (force-output *query-io*) (read-from-string (read-line *query-io*))) ;各点数台の人数データ格納領域 (setq hist-lst '(0 0 0 0 0 0 0 0 0 0 0)) ;点数をhist-lstに格納する関数 (defun save-score (score) (labels ((x0 (s) (truncate s 10))) (setf (nth (x0 score) hist-lst) (1+ (nth (x0 score) hist-lst))))) ;****の表示 (defun print-line (n) (if (zerop n) nil (progn (format t "*") (print-line (1- n))))) ;結果表示関数 (defun print-hist (lst index) (if (null lst) nil (progn (format t "~3D0点台:" index) (print-line (car lst)) (format t "~%") (print-hist (cdr lst) (1+ index))))) ;=================================================== ;点数の入力 -1を入力すると終了 (let ((score 0)) (loop (if (= (setf score (prompt-read "点数")) -1) (return) (save-score score)))) ;結果表示 (format t "=============================~%") (print-hist hist-lst 0)
実行結果
$ clisp hist.cl 点数: 54 点数: 53 点数: 52 点数: 63 点数: 64 点数: 65 点数: 74 点数: 74 点数: 85 点数: 97 点数: 64 点数: 52 点数: 43 点数: -1 ============================= 00点台: 10点台: 20点台: 30点台: 40点台:* 50点台:**** 60点台:**** 70点台:** 80点台:* 90点台:* 100点台:
lispだと再帰ではない普通のループを書くときの方が、面倒な気がしてきました。
脳味噌の限界が近くなってきて、いろいろ妥協してしまった。
でも、lispでプログラムらしいもの書けたの始めてなので、嬉しい。