【AtCoder】
AtCoder Daily Training EASY 2026
/04/23 18:00start【Common Lisp】

関連記事

1. A – AtCoder Language

単語リストが少なかったのでcondで場合分けして実装しました。

(defun str->atcoder (str)
  (cond ((string= str "red") "SSS")
	((string= str "blue") "FFF")
	((string= str "green") "MMM")
	(t "Unknown")))

(defun main ()
  (princ (str->atcoder (read-line))))

#-swank
(main)Code language: PHP (php)

後から、連想リスト(alist)のような形でデータとして持った方がスマートかも、と思いました。

1. A – AtCoder Language

2. B – Four Points

3つ組から「小数派」を取る関数 the-one を作ると、素直に解けました。

(defun the-one (a b c)
  (cond ((= a b) c)
	((= a c) b)
	((= b c) a)
	(t nil)))

(defun main ()
  (let* ((x1 (read))
	 (y1 (read))
	 (x2 (read))
	 (y2 (read))
	 (x3 (read))
	 (y3 (read)))
    (princ (the-one x1 x2 x3))
    (princ #\space)
    (princ (the-one y1 y2 y3))))

#-swank(main)Code language: Lisp (lisp)

3つの点の読み取り方は、もう少しループやリストで簡潔に書けそう。

2. B – Four Points

3. C – Traveling Takahashi Problem

点(x, y)を表すデータ構造をリスト ‘(x y) にします。
移動コストは、差の2乗の和の平方根です。

;; p, q are points (x y) (x y)
(defun move-cost (p q)
  (declare (type list p q))
  (sqrt (+ (square (- (car p) (car q)))
	   (square (- (cadr p) (cadr q)))
	   0.0l0)))

(defun square (x)
  (* x x))Code language: Lisp (lisp)

リストから分配束縛で順に2つの点を取って、計算していきます。
最初と最後には、(0, 0)の点を追加しておきます。

(defun total-move-cost (lst)
  (loop for (p q) on lst
	until (null q)
	sum (move-cost p q)))

(defun main ()
  (let* ((n (read))
	 (lst (loop for i from 0 to (1+ n)
		    if (or (= i 0) (= i (1+ n)))
		      collect (list 0 0)
		    else
		      collect (list (read) (read)))))
    (format t "~f" (total-move-cost lst))))

#-swank(main)Code language: Lisp (lisp)

全体は、

3. C – Traveling Takahashi Problem

4. D – Hands on Ring (Eash)

D – Hands on Ring (Easy)
D – Hands on Ring (Easy)

手が右回り・左回りのどちらを通るのかで、移動距離が変わります。
なので、まずは逆手が目的地までの間にあるかを調べ、あれば 0-N をまたぐルートになります。


;; ? x in [a, b] (not always a < b)
(defun in-range (x a b)
  (or (<= a x b) (<= b x a)))

;; hand is symbol 'R or 'L read by (read)
(defun move-time-from-to (N left right hand to)
  (let* ((from (if (eq hand 'R) right left))
	 (other (if (eq hand 'R) left right)))
    (if (in-range other from to)
	(- N (abs (- from to)))
	(abs (- from to)))))Code language: Lisp (lisp)

動かす手がどちらかは、’R, ‘L のシンボルでそのまま比較しています。

4. D – Hands on Ring (Eash)
(defun in-range (x a b)
  (or (<= a x b) (<= b x a)))

(defun move-time-from-to (N left right hand to)
  (let* ((from (if (eq hand 'R) right left))
	 (other (if (eq hand 'R) left right)))
    (if (in-range other from to)
	(- N (abs (- from to)))
	(abs (- from to)))))

;; (solve 6 '((R 4) (L 5) (R 6))) ;=> 8 
(defun solve(N queries)
  (loop for query in queries
	with left = 1
	with right = 2
	with result = 0
	do (let* ((hand (car query))
		  (to (cadr query)))
	     (incf result (move-time-from-to
			   N left right hand to))
	     (if (eq hand 'R)
		 (setf right to)
		 (setf left to)))
	finally (return result)))

(defun main ()
  (let* ((N (read))
	 (Q (read))
	 (queries (loop repeat Q
			collect (list (read) (read)))))
    (princ (solve N queries))))

#-swank(main)Code language: Lisp (lisp)