~zge/aoc20

aoc20/aoc20.cl -rw-r--r-- 2.6 KiB
81aeb91ePhilip K Simplify day 3 a month ago
                                                                                
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
(ql:quickload :cl-ppcre)

(defun read-as-list ()
  (do ((list nil (cons item list))
       (item nil (read *standard-input* nil :eof)))
      ((eq item :eof) (rest (nreverse list)))))

(defun read-file-as-list (file)
  (with-open-file (*standard-input* file)
    (read-as-list)))

(defun read-lines ()
  (do ((list nil (cons item list))
       (item nil (read-line *standard-input* nil :eof)))
      ((eq item :eof) (rest (nreverse list)))))

(defun read-file-lines (file)
  (with-open-file (*standard-input* file)
    (read-lines)))

(defun xor (x y)
  (or (and x (not y))
      (and y (not x))))


;;; Day 1: Report Repair

(defun find-sum (list sum n)
  (declare (optimize (speed 3) (space 3) (debug 0))
	   (type fixnum sum)
	   (type fixnum n))
  (cond ((null list) nil)
	((< sum 0) nil)
	((and (= n 1) (= (first list) sum))
	 (list (first list)))
	((let ((res (find-sum (cdr list) (- sum (first list)) (1- n))))
	   (if res (cons (first list) res)
	       (find-sum (cdr list) sum n))))))

(defun day-1.1 (list)
  (destructuring-bind (a b) (find-sum list 2020 2)
    (* a b)))

(defun day-1.2 (list)
  (destructuring-bind (a b c) (find-sum list 2020 3)
    (* a b c)))

;; (day-1.1 (read-file-as-list "input1.txt"))
;; (day-1.2 (read-file-as-list "input1.txt"))


;;; Day 2: Password Philosophy

(defun parse-entry (line)
  (multiple-value-bind (match data)
      (ppcre:scan-to-strings "^(\\d+)-(\\d+) (.): (.+)$" line)
    (when match
      (list (parse-integer (aref data 0))
	    (parse-integer (aref data 1))
	    (aref (aref data 2) 0)
	    (aref data 3)))))

(defun password-check-1 (min max letter password)
  (<= min (count letter password) max))

(defun password-check-2 (i1 i2 letter password)
  (xor (eq letter (aref password (1- i1)))
       (eq letter (aref password (1- i2)))))

(defun day-2.1 (lines)
  (loop for line in lines
	count (apply #'password-check-1 (parse-entry line))))

(defun day-2.2 (lines)
  (loop for line in lines
	count (apply #'password-check-2 (parse-entry line))))

;; (day-2.1 (read-file-lines "input2.txt"))
;; (day-2.2 (read-file-lines "input2.txt"))


;;; Day 3: Toboggan Trajectory

(defun day-3.1 (lines right down)
  (do ((lines lines (nthcdr down lines))
       (x 0 (mod (+ x right) (length (car lines))))
       (hits 0 (if (eq (aref (car lines) x) #\#)
		   (1+ hits) hits)))
      ((null lines) hits)))

(defun day-3.2 (lines &rest directions)
  (let (hits)
    (dolist (direction directions)
      (push (apply #'day-3.1 lines direction)
	    hits))
    (apply #'* hits)))

;; (day-3.1 (read-file-lines "input3.txt") 3 1)
;; (day-3.2 (read-file-lines "input3.txt") '(1 1) '(3 1) '(5 1) '(7 1) '(1 2))