2014年2月25日

codejamの過去問でcommon lispの練習2

問題は2013のqualification round B

結果用の高さ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)))))
       )
    )
     )
  )