【AtCoder ADT】
文字処理・偶数フィルタ・部分列判定
(easy_20260430_1)

関連記事

1. A – 22222

文字 ‘2’ 以外を消すので、char-not-equal で判定しました。
ほかにも、’2′ の数を数えて、その文字数で出力するのでも解けそうです。

(defun main ()
  (princ (remove-if #'(lambda (ch)
			(char-not-equal ch #\2)) (read-line))))
#-swank(main)
Code language: Lisp (lisp)
1. A – 22222

2. B – Filter

ループ内で 偶数(even)か判定して、それだけを出力しました。

(defun main ()
  (let* ((N (read))
	 (An (loop repeat N collect (read))))
    (loop for A in An
	  when (evenp A)
	    do (princ A)
	       (princ #\space))))
#-swank(main)Code language: Lisp (lisp)
2. B – Filter

3. C – Trifecta

記録を小さい順に並べて、0起算で3つ記録リストでの位置を求めて、1起算に変換しました。
こういう0起算と1起算の変換タイミングは、どこにするか頭を整理した方がよいと思いました。

(defun top3 (records)
  (let* ((sorted (sort (copy-seq records) #'<)))
    (loop for n from 0 to 2
	  collect (1+ (position (nth n sorted) records)))))

(defun main ()
  (let* ((N (read))
	 (Tn (loop repeat N collect (read))))
    (loop for n in (top3 Tn)
	  do (princ n)
	     (princ #\space))))
#-swank(main)Code language: Lisp (lisp)
3. C – Trifecta

4. D – A^A

ぴったりじゃないと答えとして出力しないので、オーバーしたか判定する必要があります。
そこで、終端時に nn が x より大きくないか判定しています。

(defun solve (x)
  (loop for n from 1
	for nn = (expt n n)
	while (< nn x)
	finally (return (if (= nn x) n -1 ))))

(defun main ()
  (princ (solve (read))))
#-swank(main)Code language: Lisp (lisp)
4. D – A^A

5. E – Airport Code(2)

コードの最後尾が X の場合をどう処理するか考えました。
今回は、最後の X は抜き出して、 2文字のコードとして取り扱うことにしました。
コードの判定は、1文字ずつ見つかるまでループを回して、最後まで進んでいるかで判定しています。

(defun last-char (str)
  (char str (1- (length str))))

;; (code-root "NXX") ;=> NX
(defun code-root (tt)
  (subseq tt 0
	  (if (char= (last-char tt) #\X) 2 3)))

;; (airport-code-p "narita" "NRX") ;=> T
(defun airport-code-p (ss tt)
  (let ((root (string-downcase (code-root tt))))
    (loop for ch across ss
	  with pos = 0
	  when (>= pos (length root))
	    do (return t)
	  when (char= ch (char root pos))
	    do (incf pos)
	  finally (return nil))))

;; (yesno t) ;=> "Yes"
(defun yesno (c)
  (declare (type boolean))
  (if c "Yes" "No"))

(defun main ()
  (let* ((ss (read-line))
	 (tt (read-line)))
    (princ (yesno (airport-code-p ss tt)))))

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

ところが、誤答 2。

5. E – Airport Code(2)

5.1. コード

(>= pos (length root)) の判定タイミングをposを増やしたあとにしました。
なぜかというと、ssの最後の文字がコードの最後の文字のとき(”nar” “NRX”)に、判定されないまま nil を返してしまっていたからです。

;; (airport-code-p "narita" "NRX") ;=> T
;; (airport-code-p "nar" "NRX")    ;=> T
(defun airport-code-p (ss tt)
  (let ((root (string-downcase (code-root tt))))
    (loop for ch across ss
	  with pos = 0
	  when (char= ch (char root pos))
	    do (incf pos)
	  when (>= pos (length root))
	    do (return t)
	  finally (return nil))))Code language: JavaScript (javascript)

問題ではrootのサイズが 2〜3 が保証されるので正解なのですが、見返してみたら、 rootのサイズが 0 だと (char root 0)でエラーのアクセスになるのがちょっと良くないかも、と思いました。
posの終端判定はwhileにして、finallyで改めて(= pos length root)か判定してもよいかも。

5.1. コード

時間内に全部クリアできました。

5.1. コード