-
Notifications
You must be signed in to change notification settings - Fork 0
/
1.lisp
63 lines (55 loc) · 1.97 KB
/
1.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
;;; Google Code Jam 2020, Round 1C, Problem 1: Overexcited Fan
;;
(defun solve (&optional (in *standard-input*))
(dotimes (caseno (the (integer 0 1000) (read in)))
(format t "Case #~D: " (+ caseno 1))
(solve-case in)))
(defun dir-xy-offset (c)
(ecase c
((#\N) (values 0 1))
((#\S) (values 0 -1))
((#\W) (values -1 0))
((#\E) (values 1 0))
((#\*) (values 0 0)))) ;Stay where we are
(defun dir-x-offset (c)
(multiple-value-bind (x y) (dir-xy-offset c) (declare (ignore y)) x))
(defun dir-y-offset (c)
(multiple-value-bind (x y) (dir-xy-offset c) (declare (ignore x)) y))
(defun solve-case (in)
(format t "~A~%"
(solve-case-1
(read in)
(read in)
(map 'list #'identity (read-line in))
0
nil)))
(defvar *debug* nil)
(defun warnd (format &rest args)
(when *debug* (apply #'warn format args)))
(defun solve-case-1 (x y seq steps best-so-far)
(cond ((= x y 0)
(warnd "BRANCH CLOSED-IN")
(if best-so-far (min best-so-far steps) steps))
((and best-so-far (> steps best-so-far)) ;We can't get any better
(warnd "BRANCH BEST")
best-so-far)
((<= (+ (abs x) (abs y)) steps) ;We can get there in time
(warnd "BRANCH CLOSE-ENOUGH")
(let ((new-solution steps))
(let ((new-best (if best-so-far (min best-so-far new-solution) new-solution)))
(if (endp seq)
new-best
(multiple-value-bind (dx dy)
(dir-xy-offset (first seq))
(solve-case-1 (+ x dx) (+ y dy) (rest seq) (1+ steps) new-best))))))
((endp seq)
(warnd "BRANCH FINISHED-SEQ")
(or best-so-far 'IMPOSSIBLE))
(t
(warnd "BRANCH ELSE")
(multiple-value-bind (dx dy)
(dir-xy-offset (first seq))
(solve-case-1 (+ x dx) (+ y dy) (rest seq) (1+ steps) best-so-far)))
))
;(trace solve-case-1)
(solve)