【AtCoder ADT】
loop・floor・文字列走査(AtCoder Da
ily Training EASY 2026/04/22 18:0
0start)
(Common Lisp)

関連記事

1. A – Range Swap

リストを配列にしてから、loopでifで場合分けして集めていくことで、入れ替えたリストをつくることにしました。

(defun range-swap (P Q R S An)
  (let* ((vec (make-array (length An)
			  :element-type 'fixnum
			  :initial-contents An)))
    (loop for n from 1 to (length An)
	  if (<= P n Q)
	    collect (aref vec (1- (+ n (- R P))))
	  else if (<= R n S)
	    collect (aref vec (1- (+ n (- P R))))
	  else
	    collect (aref vec (1- n)))))

(defun main ()
  (let* ((N (read))
	  (P (read))
	  (Q (read))
	  (R (read))
	  (S (read))
	  (An (loop repeat N collect (read))))
     (loop for x in (range-swap P Q R S An)
	   do (progn (princ x)
		     (princ #\space)) )))

#-swank
(main)
Code language: Lisp (lisp)
1. A – Range Swap

2. B – Full Moon

まずは、繰り上げの割り算の関数 div-round-up を作ってから、計算しました。
floorは、多値を返すので余りは無視するようにしました。

(defun div-round-up (n m)
  (multiple-value-bind (ans rem) (floor (+ n (1- m)) m)
    (declare (ignore rem))
    ans))


(defun times-full-moon (N M P)
  (div-round-up (1+ (- N M)) P))

(defun main ()
  (let* ((N (read))
	 (M (read))
	 (P (read)))
    (princ (times-full-moon N M P))))

#-swank
(main)
Code language: Lisp (lisp)
2. B – Full Moon

3. C – Ticket Gate Log

前の文字と同じ文字だと +1 していって、あとは 最初と最後の文字を確認します。
1文字は o なら +1、最終文字が i なら+1、します。

(defun restore-io (str)
  (let* ((lst (loop for ch across str
		    collect ch)))
    (loop for (a b) on lst
	  for i from 0
	  with result = 0
	  when (and (= i 0) (eql a #\o))
	    do (incf result)
	  when (eql a b)
	    do (incf result)
	  when (and (null b) (eql a #\i))
	    do (incf result)
	  finally (return result))))

(defun main ()
  (princ (restore-io (read-line))))

#-swank
(main)
Code language: Lisp (lisp)
3. C – Ticket Gate Log