- AtCoder ABC452のA・B問題をCommon Lispで解いた記録です。
- A問題では五節句の日付を配列に持たせ、月をインデックスとして対応する日と比較することで判定しています。
- B問題では各マスの座標が端(x=0、x=W-1、y=0、y=H-1)に該当するかをcondで分岐し、
#か.を出力しています。 - どちらも条件を整理してシンプルな関数に落とし込める問題でした。
1. ABC452A – Gothec
以下の 5 つの日を五節句と呼びます。
- 1 月 7 日
- 3 月 3 日
- 5 月 5 日
- 7 月 7 日
- 9 月 9 日
月 日が五節句に含まれるならば
Yesを、含まれないならばNoを出力してください。入力
M D月 日が五節句に含まれるならば
Yesを、含まれないならばNoを出力せよ。
1.1. 配列で判定した
各月の節句にあたる日付を配列で持って、判定することにしました。
(defun sekku-p (m d)
(let ((five-sekku #(0 7 0 3 0 5 0 7 0 9 0 0 0)))
(= d (aref five-sekku m))))
(defun solve ()
(let* ((m (read))
(d (read)))
(princ (if (sekku-p m d) "Yes" "No"))))
#-swank
(solve)Code language: Lisp (lisp)
節句の数が少なく、各月に最大でも1日しかない、という条件を利用しています。

2. B – Draw Frame
縦 行、横 列のマス目があります。
高橋くんは、このマス目のそれぞれのマスを白か黒で塗ろうとしています。高橋くんは、マス目に含まれるマスのうち端にあるマスをすべて黒く塗り、それ以外のマスを白く塗ります。
高橋くんが色を塗ったあとのマス目を出力してください。より厳密には、マス が端にあるとは、マス と辺で隣接しているマスの個数が 4 個未満であることをいいます。
- 入力はすべて整数
入力は以下の形式で標準入力から与えられる。
H W行にわたって、長さ の文字列を出力せよ。
行目 の 文字目 には、マス が黒く塗られているなら#、白く塗られているなら.を出力せよ。
入力例
4 5
#####
#...#
#...#
#####Code language: PHP (php)
2.1. タイルの条件で出力する
(defun solve ()
(let* ((h (read))
(w (read)))
(draw-tiles h w)))
(defun draw-tiles (h w)
(loop for y from 0 below h do
(loop for x from 0 below w do
(princ (tile x y w h)))
(princ #\newline)))
(defun tile (x y w h)
(cond ((= x 0) "#")
((= x (1- w)) "#")
((= y 0) "#")
((= y (1- h)) "#")
(t ".")))
#-swank
(solve)Code language: Lisp (lisp)


この条件だと、端にあるかだけで判定できますね。
縦横の順番だけは要注意です。