Advertisement
Guest User

Untitled

a guest
Jan 3rd, 2019
211
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 3.75 KB | None | 0 0
  1. (defvar *required-tools-by-area-type '((0 climbing-gear torch)
  2.                                        (1 climbing-gear NIL)
  3.                                        (2 torch NIL)))
  4.  
  5. (defun cave-change-area (curr next target depth)
  6.   (let* ((ctools (third curr))
  7.          (ctime (fourth curr))
  8.          (nx (first next))
  9.          (ny (second next))
  10.          (carea-type (area-type (first curr) (second curr) target depth))
  11.          (narea-type (area-type nx ny target depth)))
  12.     (if (equal carea-type narea-type)
  13.       (list (list nx ny ctools (+ ctime 1)))
  14.       (loop :for ntools in (rest (assoc narea-type *required-tools-by-area-type))
  15.             :collecting (list
  16.                           nx
  17.                           ny
  18.                           ntools
  19.                           (+ ctime (if (equal ntools ctools) 1 8)))))))
  20.  
  21. (defun cave-neighbors (curr target depth)
  22.   (let* ((x (first curr))
  23.          (y (second curr))
  24.          neighbors)
  25.     (if (> y 0)
  26.       (push (list x (- y 1)) neighbors))
  27.     (push (list (+ x 1) y) neighbors)
  28.     (push (list x (+ y 1)) neighbors)
  29.     (if (> x 0)
  30.       (push (list (- x 1) y) neighbors) neighbors)
  31.     (reduce
  32.       #'append
  33.       (mapcar
  34.         #'(lambda (n)
  35.             (cave-change-area curr n target depth))
  36.         neighbors))))
  37.  
  38. (defun cave-backtrack (curr come-from)
  39.   (let ((key (format NIL "~d,~d,~a" (first curr) (second curr) (fourth curr))))
  40.     (cond ((not (gethash key come-from)) (list curr))
  41.           (T (cons curr (cave-backtrack (gethash key come-from) come-from))))))
  42.  
  43. (defun solve-day22-2 (depth target)
  44.   (setf *geologic-index-cache* (make-hash-table :test 'equal))
  45.   (let ((frontier (list '(0 0 0 torch 0 NIL))) ; priority x y tools time
  46.         (cost-so-far (make-hash-table :test 'equal))
  47.         (come-from (make-hash-table :test 'equal))
  48.         best-at-target)
  49.     (setf (gethash "0,0,TORCH" cost-so-far) 0)
  50.     (loop :while frontier
  51.           ; :do (format t "~A~%" (rest (first frontier)))
  52.           :do (let* ((curr (rest (pop frontier)))
  53.                      (at-target(and (equal (first curr) (first target))
  54.                                     (equal (second curr) (second target)))))
  55.                 (if at-target
  56.                   (let ((actual-time (+ (fourth curr)
  57.                                         (if (equal (third curr) 'torch) 0 7))))
  58.                     ; (progn (format t "~A~%" (reverse (cave-backtrack curr come-from))) (break))
  59.                     (if best-at-target
  60.                       (return (min best-at-target actual-time))
  61.                       (setf best-at-target actual-time)))
  62.                   (loop :for next :in (cave-neighbors curr target depth)
  63.                         :do (let ((key (format NIL "~d,~d,~a" (first next) (second next) (third next))))
  64.                               (when (or (null (gethash key cost-so-far))
  65.                                         (< (fourth next)
  66.                                            (gethash key cost-so-far)))
  67.                                 (let* ((priority (+ (fourth next)
  68.                                                     (manhattan-distance-seq next target)))
  69.                                        (item (cons priority next)))
  70.                                   (setf (gethash key cost-so-far) (fourth next)
  71.                                         (gethash key come-from) curr
  72.                                         frontier (cons item frontier)
  73.                                         frontier (sort frontier #'< :key #'first)))))))))))
  74.  
  75. (defun day22-2 ()
  76.   (let* ((in (open "./day22.input"))
  77.          (lst (read-by-line in))
  78.          (result (solve-day22-2 (parse-cave-depth (first lst))
  79.                                 (parse-cave-target (second lst)))))
  80.     (close in)
  81.     result))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement