Skip to content

Commit

Permalink
Restructured
Browse files Browse the repository at this point in the history
Broke up the big code file s.t. each day has its own file.
  • Loading branch information
abraemer committed Dec 4, 2018
1 parent 54f4852 commit 8cb0826
Show file tree
Hide file tree
Showing 6 changed files with 224 additions and 219 deletions.
219 changes: 0 additions & 219 deletions advent-of-code-2018.lisp

This file was deleted.

19 changes: 19 additions & 0 deletions day1.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
;;;; day1.lisp

(in-package #:advent-of-code-2018)


(defun day1 ()
(let* ((changes (mapcar #'parse-integer (read-puzzlefile "input1.txt")))
(total (reduce #'+ changes))
(seen (make-hash-table :size 1024)) ;use hashtable as a set
(first-repetition
(loop
;loop continuously over the changes
:for change :in (setf (cdr (last changes)) changes)
:sum change :into freq
:until (gethash freq seen) ;check the set
:do (setf (gethash freq seen) t)
:finally (return freq))))
(format t "The resulting frequency is ~a.~%The first frequency reached twice is ~a.~%"
total first-repetition)))
42 changes: 42 additions & 0 deletions day2.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
;;;; day2.lisp

(in-package #:advent-of-code-2018)


(defun count-chars (string)
(loop
:with counts := nil
:for char :across string
:for count = (assoc char counts)
:if count :do
(incf (cdr count))
:else :do
(push (cons char 1) counts)
:finally (return counts)))

(defun differences (s1 s2)
(count nil (map 'list #'equal s1 s2)))

(defun common-parts (s1 s2)
(coerce
(remove nil (map 'list (lambda (char1 char2)
(when (equal char1 char2)
char1))
s1 s2))
'string))

(defun day2 ()
(loop-line-by-line (puzzlepath "input2.txt")
:for counts := (count-chars line)
:counting (rassoc 2 counts) :into doubles
:counting (rassoc 3 counts) :into triples
:finally (format t "There are ~a phrases with double character and ~a phrases with triple characters.~%Solution: ~a~%" doubles triples (* doubles triples))))

(defun day2-extra ()
(loop :for lines := (read-puzzlefile "input2.txt") :then (rest lines)
:while lines
:for orig := (first lines)
:until (loop :for other :in (rest lines)
:when (= 1 (differences orig other))
:do (format t "They solution is ~s.~%" (common-parts orig other))
:and :return t)))
37 changes: 37 additions & 0 deletions day3.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
;;;; day3.lisp

(in-package #:advent-of-code-2018)


(defun day3-parse-line (line)
;; example "#1 @ 896,863: 29x19"
(ppcre:register-groups-bind ((#'parse-integer id xpos ypos width height))
("#(\\d+) @ (\\d+),(\\d+): (\\d+)x(\\d+)" line)
(mapcan #'list '(:id :xpos :ypos :width :height) (list id xpos ypos width height))))

(defun make-claim (claim board)
(loop
:for x :from (getf claim :xpos) :below (+ (getf claim :xpos)
(getf claim :width))
:do (loop
:for y :from (getf claim :ypos) :below (+ (getf claim :ypos)
(getf claim :height))
:do (push (getf claim :id) (aref board x y)))))

(defun day3 ()
(let ((board (make-array '(1000 1000) :initial-element nil))
(ids (make-hash-table :test 'equal)))
(loop-line-by-line (puzzlepath "input3.txt")
:for claim := (day3-parse-line line)
:do (make-claim claim board)
:do (setf (gethash (getf claim :id) ids) t))
(loop
:with overlaps := 0
:for index :below (reduce #'* (array-dimensions board))
:for entries := (row-major-aref board index)
:when (>= (length entries) 2)
:do (incf overlaps) :and
:do (dolist (id entries) (remhash id ids))
:finally
(format t "There are ~a square inches of fabric within two or more claims.~%Id ~a has no overlaps at all." overlaps (first (hash-keys ids))))))

70 changes: 70 additions & 0 deletions day4.lisp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
;;;; day4.lisp

(in-package #:advent-of-code-2018)

(defun day4-parse-time (time)
;; ex. "[1518-05-25 00:11] some more text here"
;;ignore the year
(ppcre:register-groups-bind ((#'parse-integer nil month day hour min))
("\\[(\\d+)-(\\d+)-(\\d+) (\\d+):(\\d+)\\]" time)
(mapcan #'list '(:month :day :hour :min) (list month day hour min))))

(defun day4-time< (log1 log2)
(loop :for entry :in '(:month :day :hour :min)
:when (< (getf log1 entry 0)
(getf log2 entry 0))
:return t
:when (> (getf log1 entry 0)
(getf log2 entry 0))
:return nil))

(defun day4-parse-event (event)
(case (read-from-string event)
(guard (list :event 'guard :id (read-from-string (subseq event 7))))
(falls (list :event 'sleep))
(wakes (list :event 'wake-up))))

(defun day4-parse-line (line)
(let ((index (position #\] line)))
(append (day4-parse-time line)
(day4-parse-event (subseq line (+ 2 index))))))

(defun day4-organise-log (raw-data)
(labels ((rec (data shift start log)
(if (null data)
(nreverse (cons (nreverse shift) log))
(let ((event (getf (first data) :event))
(minute (getf (first data) :min)))
(case event
(guard (rec (rest data) (list (getf (first data) :id)) nil (cons (nreverse shift) log)))
(wake-up (rec (rest data) (cons (cons start minute) shift) nil log))
(sleep (rec (rest data) shift minute log)))))))
(rec (rest raw-data) (list (getf (first raw-data) :id)) nil nil)))

(defun day4-asleep-counters (log)
(let ((counters (make-hash-table)))
(loop :for entry :in log
:for counter := (gethash (first entry) counters (make-array 60 :initial-element 0))
:do (loop :for (start . end) :in (rest entry)
:do (loop :for index :from start :below end
:do (incf (aref counter index))))
:do (setf (gethash (first entry) counters) counter)
:finally (return counters))))

(defun day4-prep-logdata ()
(day4-organise-log
(loop-line-by-line (puzzlepath "input4.txt")
:collect (day4-parse-line line) into log
:finally (return (sort log #'day4-time<)))))

(defun day4 ()
(let* ((asleep-counters (day4-asleep-counters (day4-prep-logdata)))
(most-asleep-id (max-key asleep-counters :accessor (lambda (c) (reduce #'+ c))))
(most-asleep-minute (max-index (gethash most-asleep-id asleep-counters)))
(most-freq-asleep-id (max-key asleep-counters :accessor (lambda (c) (reduce #'max c))))
(most-freq-asleep-minute (max-index (gethash most-freq-asleep-id asleep-counters))))
(format t "The most asleep guard is #~a and it's most asleep during minute ~a -> Answer: ~a~%"
most-asleep-id most-asleep-minute (* most-asleep-id most-asleep-minute))
(format t "The most frequently asleep guard is #~a and it's most asleep during minute ~a -> Answer: ~a~%"
most-freq-asleep-id most-freq-asleep-minute (* most-freq-asleep-id most-freq-asleep-minute))))

Loading

0 comments on commit 8cb0826

Please sign in to comment.