(defstruct city name lat lon exits) (defun read-city (f) (let ((v (read f nil 'end))) (if (eq v 'end) nil (make-city :name v :lat (read f) :lon (read f))))) (defun read-city-list (f) (let ((c nil)) (loop do (setq c (read-city f)) (when (null c) (return 'ok)) (set (city-name c) c)))) (defun read-cities (fn) (let ((f (open fn))) (prog1 (read-city-list f) (close f)))) (defstruct road name length end1 end2) (defun read-road (f) (let ((v (read f nil 'end))) (if (eq v 'end) nil (make-road :name v :length (read f) :end1 (read f) :end2 (read f))))) (defun read-road-list (f) (let ((r nil) (city1 nil) (city2 nil) (exits nil)) (loop do (setq r (read-road f)) (when (null r) (return 'ok)) (setq city1 (symbol-value (road-end1 r))) (setq city2 (symbol-value (road-end2 r))) (setf (road-end1 r) city1) (setf (road-end2 r) city2) (setq exits (city-exits city1)) (setf (city-exits city1) (cons r exits)) (setq exits (city-exits city2)) (setq r (make-road :name (road-name r) :length (road-length r) :end1 (road-end2 r) :end2 (road-end1 r))) (setf (city-exits city2) (cons r exits))))) (defun read-roads (fn) (let ((f (open fn))) (prog1 (read-road-list f) (close f)))) (defun print-city (c) (list (city-name c) (city-lat c) (city-lon c) (print-roads (city-exits c)))) (defun print-roads (rr) (if (null rr) nil (cons (print-road (car rr)) (print-roads (cdr rr))))) (defun print-road (r) (list (road-name r) (road-length r) (city-name (road-end1 r)) (city-name (road-end2 r)))) (defun readem () (read-cities "cities.txt") (read-roads "roads.txt")) (defvar where-am-i nil) (defvar exits nil) (defun explore-from (c) (let ((i 1)) (setq where-am-i c) (princ "At: ") (princ (city-name c)) (princ " Latitude ") (princ (city-lat c)) (princ ", Longitude ") (princ (city-lon c)) (princ " ") (setq exits (city-exits c)) (princ (length exits)) (princ " exits:") (terpri) (dolist (e exits) (princ " ") (princ i) (princ ": ") (princ (road-name e)) (princ ", ") (princ (road-length e)) (princ " miles to ") (princ (city-name (road-end2 e))) (terpri) (setq i (+ i 1))) 'ok)) (defun explore-exit (n) (let ((x (nth (- n 1) exits))) (if (null x) 'no-such-exit (explore-from (road-end2 x)))))