ABC 001bでACしたソースコードが以下の通り。
(let* ((m (read)) (vv (cond ((< m 100) "00") ((<= m 5000) (format nil "~2,'0d" (* m (expt 10 -2)))) ((<= m 30000) (+ (* m (expt 10 -3)) 50)) ((<= m 70000) (+ (/ (- (/ m 1000) 30) 5) 80)) (t 89)))) (format t "~A~%" vv))
躓いたところ、忘れてたところを列挙する。Clispの出力結果をコピペしてるため、説明に不要な文字が含まれるが容赦されたし。
FORMAT
Break 5 [18]> (format nil "~2,'0d" 2) "02"
のように、FORMAT関数の中で制御文字列を
~2,'0d
とすると、フォーマット引数が1文字(ただしinteger)の場合に、頭に0を入れて文字列を生成する。
2が最低文字数、,'0でパディングする文字を指定し、~dで整数を10進法で出力する。(dはdecimalのd)
ちなみにFORMAT関数は
(format 出力先 制御文字列 フォーマット引数)
という並びになっており、制御文字列はリテラル文字列と指示子からなる。
~a ~d ~f
とかが指示子。
: @ 1 2 3
とかが前置パラメータ。
用語は、『実践Common Lisp』に準じた。
Power
Break 5 [18]> (expt 10 -2) 1/100
数字周りの型
(type-of (* 2000 (expt 10 -2))) (INTEGER 0 288230376151711743)
floatでもratio(分数)でもなく、integer
Break 5 [18]> (type-of 1/3) RATIO Break 5 [18]> (type-of 0.1) SINGLE-FLOAT
\の返り値がINTEGER
Break 5 [18]> (type-of (/ 2000 1000)) (INTEGER 0 288230376151711743) Break 5 [18]> (/ 2000 1000) 2
mをkmに直すのに、10**(-3)を掛けたりせずに、1000でそのまま割ればよかった。