2012年3月22日

Google Code Jam練習問題

Google Code Jam 2012のエントリー受付中なので早速登録しました
Lisper目指してますので回答はCommon Lispで挑戦していきます
事前準備と言うことで練習問題に挑戦しました

2011の予選問題に挑戦

Problem A.
は問題のまま素直にプログラム組むとターンで繰り返すようになりますが、そうすると遅そうなので距離をまとめて引き算して次のスイッチの距離までを一気に計算するようにしました
BなのかOなのかの判断がイマイチ野暮ったい回りくどい記述になっているなと思います
この辺りをなんとかするともう少しスッキリしたものになるんじゃないかなと

(defun operate (input)
  (labels ((getrobot (lst) (car (car lst)))
    (getdistance (lst) (cdr (car lst)))
    (getnextpos (robot lst) (if (assoc robot lst) (cdr (assoc robot lst)) 0))
    (getdiff (pos lst) (abs (- pos (getdistance lst))))
    (getpos (pos target dist)
     (cond ((< pos target) (if (< (+ pos dist) target) (+ pos dist) target))
    (t (if (< (- pos dist) target) target (- pos dist)))))
    (rec (lst bpos opos turn)
  (cond ((null (cdr lst))
         (if (eq 'b (getrobot lst))
    (+ turn (getdiff bpos lst))
    (+ turn (getdiff opos lst))
    ))
        ((eq 'b (getrobot lst))
         (let ((diff (getdiff bpos lst)))
    (rec (cdr lst) (getdistance lst) (getpos opos (getnextpos 'o lst) (1+ diff)) (1+ (+ turn diff)))))
        (t
   (let ((diff (getdiff opos lst)))
     (rec (cdr lst) (getpos bpos (getnextpos 'b lst) (1+ diff)) (getdistance lst) (1+ (+ turn diff)))))
        )
  )
    )
    (rec input 1 1 1)
    )
  )

(dotimes (i (read) i)
  (let ((r nil))
    (dotimes (j (read) j)
      (setf r (cons (cons (read) (read)) r)))
    (format t "Case #~A: ~A~%" (1+ i) (operate (nreverse r)))))


Problem B.
は問題の意味が分からない
英語が辛いです