(defun stepping-away (cc line column) (or (and (eq cc ?^) (= line 0)) (and (eq cc ?v) (= line (- map-height 1))) (and (eq cc ?<) (= column 0)) (and (eq cc ?>) (= column (- map-width 1))))) (defun move () (interactive) (insert "X") (delete-forward-char 1) (backward-char) (cond ((eq current-char ?^) ;going up (previous-logical-line) (when (eq (char-after) ?#) (setq current-char ?>) (next-logical-line))) ((eq current-char ?>) (forward-char) (when (eq (char-after) ?#) (setq current-char ?v) (backward-char))) ((eq current-char ?v) (next-logical-line) (when (eq (char-after) ?#) (setq current-char ?<) (previous-logical-line))) ((eq current-char ?<) (backward-char) (when (eq (char-after) ?#) (setq current-char ?^) (forward-char)))) (insert current-char) (delete-forward-char 1) (backward-char)) (defun walk-out-first-run () (interactive) (let* ((sl (split-string (buffer-substring-no-properties (point-min) (point-max)))) (map-height (length sl)) (map-width (length (car sl)))) (goto-char (point-min)) (search-forward-regexp "[\\\\^|>|<|v]") (backward-char) (setq current-char (char-after)) ;; now the point is initialized at the guard's position (setq guard-initial-position (point)) (while (not (stepping-away current-char (- (line-number-at-pos) 1) (current-column))) (move)) (insert "X") (delete-forward-char 1) (backward-char))) (defun walk-out-p () "This returns t if we get out of the map, nil if we are stuck in a loop" (interactive) (let* ((sl (split-string (buffer-substring-no-properties (point-min) (point-max)))) (map-height (length sl)) (map-width (length (car sl)))) (goto-char (point-min)) (search-forward-regexp "[\\\\^|>|<|v]") (backward-char) (setq current-char (char-after)) (setq current-list ()) ;; now the point is initialized at the guard's position (while (and (not (member (cons (point) current-char) current-list)) (not (stepping-away current-char (- (line-number-at-pos) 1) (current-column)))) (push (cons (point) current-char) current-list) (move)) (stepping-away current-char (- (line-number-at-pos) 1) (current-column)))) (setq point-list (with-temp-buffer (insert-file-contents "input") (walk-out-first-run) (goto-char (point-min)) (-unfold (lambda (x) (when (search-forward "X" nil t) (list (- (point) 1)))) nil))) ; the above is the list of points that I can try to modify; we need to now implement the looping condition ; now (length point-list) is the answer to the first part (length (-filter (lambda (x) (with-temp-buffer (insert-file-contents "input") (goto-char x) (insert "#") (delete-forward-char 1) (not (walk-out-p)))) (--remove (eq it guard-initial-position) point-list))) 1711