Common Lisp備忘録

忘れた記憶を取り戻す

ABC 001b.lisp

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でそのまま割ればよかった。