結果用の高さ100の芝生を用意して、入力される刈り込みたい候補案を高さ100のものに適用する
適用は、入力縦横一行取り出して、その一行の一番高いものを結果用に当てはめる
当てはめる際に入力より高い場合は入力値に合わせる
すでに入力より低い場合はそのまま
縦横当てはめて結果用と入力が同じかどうか判定
(defmacro form1(x) `(format t "~A~%" ,x))
(defun repeat(x n)
(labels ((rec(i acc)
(if (= i n)
acc
(rec (1+ i) (cons x acc)))))
(rec 0 nil)))
(defun range(n)
(labels ((rec(i acc)
(if (= i n)
(reverse acc)
(rec (1+ i) (cons i acc)))))
(rec 0 nil)))
(defun readstream(callback)
(labels ((rec(n)
(let ((line (read-line *standard-input* nil)))
(when line
(funcall callback line n)
(rec (1+ n))))))
(rec 0)))
(defun parseNM(line)
(read-from-string (format nil "(~A)" line)))
(defun maxval(lst)
(reduce #'max (cdr lst) :initial-value (car lst)))
(defun toverticalvals(lst)
(mapcar (lambda(i)
(reduce (lambda(r x) (max r (nth i x))) (cdr lst) :initial-value (nth i (car lst))))
(range (length (car lst)))))
(defun applyverticalvals(lst vlst)
(mapcar (lambda(r) (mapcar #'min r vlst)) lst))
(defun compute(in)
(labels ((rec(in acc)
(if (null in)
(reverse acc)
(rec (cdr in) (cons (repeat (maxval (car in)) (length (car in))) acc)))))
(equal in (applyverticalvals (rec in nil) (toverticalvals in))))
)
(defun test()
;(form1 (toverticalvals '((2 1 2) (1 8 1) (2 1 3))))
;(form1 (range 10))
;(form1 (maxval '(8 7 6 5 4 3 2)))
)
(test)
(let ((in nil)
(no_of_problem 0)
(problemindex 0)
(size '(1 0))
(nextsizeindex 1)
(messagelut '((t . "YES") (nil . "NO"))))
(readstream (lambda(line n)
;(format t "~A ~A ~A~%" n nextsizeindex line)
(cond ((zerop n) (setf no_of_problem (read-from-string line)))
((= n nextsizeindex) (incf problemindex) (setf size (parseNM line)) (setf nextsizeindex (+ nextsizeindex (car size) 1)) (setf in nil))
(t (setf in (cons (parseNM line) in)) (when (= n (1- nextsizeindex))
(format t "Case #~A: ~A~%" problemindex (cdr (assoc (compute (reverse in)) messagelut)))))
)
)
)
)