Advertisement
Guest User

Untitled

a guest
Jul 7th, 2015
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.98 KB | None | 0 0
  1. ;;
  2. ;; 111004 Railroads
  3. ;;
  4.  
  5. (defun partition-with (pred l)
  6. (loop
  7. with head = nil
  8. for r on l
  9. if (funcall pred (first r))
  10. return (list (reverse head) r)
  11. else do (push (first r) head)
  12. finally return (list (reverse head) nil)))
  13.  
  14. (defun dijkstra (g &optional v-start)
  15. (let* ((max-v (length edges))
  16. (in-tree (make-bool-vector max-v nil))
  17. (parents (make-vector max-v nil))
  18. (distances (make-vector max-v most-positive-fixnum)))
  19. (aset distances (or v-start 0) 0)
  20. (loop
  21. with v = 0
  22. while (not (aref in-tree v))
  23. do (aset in-tree v t)
  24. do (dolist (e (elt g v))
  25. (when (> (elt distances (car e)) (+ (elt distances v) (cdr e)))
  26. (aset distances (car e) (+ (elt distances v) (cdr e)))
  27. (aset parents (car e) v)))
  28. do (loop
  29. with d = most-positive-fixnum
  30. for i from 0 to (1- max-v)
  31. do (when (and
  32. (not (elt in-tree i))
  33. (> d (elt distances i)))
  34. (setq d (elt distances i))
  35. (setq v i))))
  36. (list distances parents)))
  37.  
  38. (defun solve (names start goal lines)
  39. (let* ((max-v (apply '+ (mapcar 'length lines)))
  40. (labels nil)
  41. (edges (make-vector max-v nil))
  42. (timetables (make-vector max-v nil)))
  43. (cl-labels (
  44. (add-vertex (val)
  45. (let ((v (length labels)))
  46. (setq labels (nconc labels (list val)))
  47. v))
  48. (add-edge (v1 v2 w)
  49. (push (cons v2 w) (elt edges v1)))
  50. (add-to-timetable (v)
  51. (let ((v-label (elt labels v)))
  52. (aset timetables (car v-label)
  53. (let ((earlier-later (partition-with (lambda (time-vertex)
  54. (> (car time-vertex) (cdr v-label)))
  55. (aref timetables (car v-label)))))
  56. (nconc (first earlier-later) (list (cons (cdr (elt labels v)) v)) (second earlier-later)))))
  57. v)
  58. (get-station-stop-create (s)
  59. (destructuring-bind (n h m) s
  60. (let ((i (position n names :test 'equal))
  61. (time (+ m (* 60 h))))
  62. (or
  63. (cdr (assoc time (aref timetables i)))
  64. (add-to-timetable (add-vertex (cons i time))))))))
  65. (get-station-stop-create start)
  66. (dolist (path (mapcar (lambda (l)
  67. (mapcar (lambda (x) (get-station-stop-create x)) l))
  68. lines))
  69. (loop
  70. for p on path
  71. until (null (second p))
  72. do (add-edge
  73. (first p)
  74. (second p)
  75. (- (cdr (elt labels (second p))) (cdr (elt labels (first p)))))))
  76. (loop
  77. for city across timetables
  78. do (loop
  79. for time-vertex on city
  80. until (null (second time-vertex))
  81. do (add-edge
  82. (cdr (first time-vertex))
  83. (cdr (second time-vertex))
  84. (- (car (second time-vertex)) (car (first time-vertex))))))
  85. (destructuring-bind (distances parents) (dijkstra edges 0)
  86. (loop
  87. with earliest-arrival = nil
  88. with time = most-positive-fixnum
  89. for v from 0 to (1- max-v)
  90. for city-time in labels
  91. for d across distances
  92. if (and
  93. (not (null d))
  94. (= (position goal names :test 'equal) (car city-time))
  95. (< d time))
  96. do
  97. (setq time d)
  98. (setq earliest-arrival v)
  99. finally return (when earliest-arrival
  100. (let ((departure (elt labels (loop
  101. with v = earliest-arrival
  102. until (= 0 (elt parents v))
  103. finally return v
  104. do (setq v (elt parents v))))))
  105. (list
  106. (elt names (car departure))
  107. (/ (cdr departure) 60)
  108. (mod (cdr departure) 60)))))))))
  109.  
  110. (should (equal (solve
  111. '("Hamburg" "Frankfurt" "Darmstadt")
  112. '("Hamburg" 8 0)
  113. "Frankfurt"
  114. '(
  115. (("Hamburg" 8 0))
  116. (("Hamburg" 9 49)
  117. ("Frankfurt" 10 6))
  118. (("Hamburg" 13 25)
  119. ("Darmstadt" 15 50))
  120. (("Frankfurt" 12 5)
  121. ("Darmstadt" 14 11))))
  122. '("Hamburg" 9 49)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement