【AtCoder ABC376B】
Hands on Ring (Easy)
(Common Lisp)

関連記事

1. 問題

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

2. コード

手が右回り・左回りのどちらを通るのかで、移動距離が変わります。
なので、まずは逆手が目的地までの間にあるかを調べ、あれば 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 のシンボルでそのまま比較しています。

2. コード
(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)