-
Notifications
You must be signed in to change notification settings - Fork 0
/
03.el
71 lines (52 loc) · 1.79 KB
/
03.el
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
64
65
66
67
68
69
70
71
;;; Advent of Code 2020
;;; 03 December
;;;
;;; Assumes input data has been loaded into a buffer called 03.input.
;;; This buffer can be read-only.
(defvar +data-buffer+ "03.input"
"Name of buffer containing input data")
(defvar +width+ nil
"Width of line for input data")
(defvar +length+ nil
"Length (number of lines in buffer)")
(defun set-buffer-width-length nil
(save-current-buffer
(set-buffer +data-buffer+)
(goto-char 0)
(when (re-search-forward "^[\\.#]+$")
(let ((m (match-data)))
(setq +width+ (- (second m) (first m)))))
(goto-char 0)
(setq +length+ (1- (how-many "^.*$"))))
(cons +length+ +width+))
(defun thing-at (x y)
"Return the character at line x column y (0 indexed); pretends that columns repeat ad inf by replicating the column"
;; goto-line is absolute and sets point at beginning of line
(goto-line (1+ x))
(forward-char (mod y +width+))
(char-after (point)))
(defmacro incf (var &optional delta)
`(setq ,var (+ ,var (or ,delta 1))))
(defun solve1 (step-x step-y)
(save-current-buffer
(set-buffer +data-buffer+)
(set-buffer-width-length)
(goto-char 0) ; probably not needed
;; c counts the number of occurrences of ?\#
;; y and x are the column and line number, respectively.
;; The first point is not counted (and it is a ?\. anyway)
(let ((c 0) (y step-y) (x step-x))
(while (< x +length+)
(when (eql ?# (thing-at x y))
(incf c))
(incf x step-x)
(incf y step-y)
)
c)))
(defun solve2 ()
"Solve for more slopes, returning the product of the number of trees (#s) encountered"
(let* ((slopes '((1 . 1) (1 . 3) (1 . 5) (1 . 7) (2 . 1)))
(trees (mapcar (lambda (xy) (solve1 (car xy) (cdr xy))) slopes)))
;; reduce is in 'cl
(apply #'* trees)))