b50f1ec26d64

Day 4 and 5
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Tue, 05 Dec 2017 18:16:40 -0500
parents 11607ca439c4
children 902b736dfedb
branches/tags (none)
files src/main.lisp vendor/make-quickutils.lisp vendor/quickutils.lisp

Changes

--- a/src/main.lisp	Sun Dec 03 18:39:45 2017 -0500
+++ b/src/main.lisp	Tue Dec 05 18:16:40 2017 -0500
@@ -12,18 +12,35 @@
     (map 'list #'digit-char-p <>)
     (remove nil <>)))
 
+(defun read-file-of-numbers (path)
+  (iterate (for line :in-file path :using #'read-line)
+           (appending (mapcar #'parse-integer (str:words line)))))
+
 (defun read-file-of-lines-of-numbers (path)
   (iterate (for line :in-file path :using #'read-line)
            (collect (mapcar #'parse-integer (str:words line)))))
 
+(defun read-file-of-lines-of-words (path)
+  (iterate (for line :in-file path :using #'read-line)
+           (collect (str:words line))))
+
+
+(defun contains-duplicates-p (list &key (test #'eql))
+  (iterate (for (head . tail) :on list)
+           (thereis (member head tail :test test))))
+
+(defun anagramp (string1 string2)
+  (string= (sort (copy-seq string1) #'char<)
+           (sort (copy-seq string2) #'char<)))
+
 
 ;;;; Problems -----------------------------------------------------------------
-(defun day-1-part-1 ()
+(defun day-1/1 ()
   (iterate (for (x . y) :pairs-of-list (read-file-of-digits "data/2017/01"))
            (when (= x y)
              (sum x))))
 
-(defun day-1-part-2 ()
+(defun day-1/2 ()
   (iterate
     (with data = (coerce (read-file-of-digits "data/2017/01") 'vector))
     (with length = (length data))
@@ -34,14 +51,14 @@
       (sum x))))
 
 
-(defun day-2-part-1 ()
+(defun day-2/1 ()
   (flet ((checksum (line)
            (- (apply #'max line)
               (apply #'min line))))
     (summation (remove nil (read-file-of-lines-of-numbers "data/2017/02"))
                :key #'checksum)))
 
-(defun day-2-part-2 ()
+(defun day-2/2 ()
   (labels ((validp (a b)
              (dividesp (max a b) (min a b)))
            (head-valid-p (list)
@@ -53,7 +70,7 @@
                :key #'checksum)))
 
 
-(defun day-3-part-1 ()
+(defun day-3/1 ()
   (labels ((manhattan-distance (a b)
              (+ (abs (- (realpart a)
                         (realpart b)))
@@ -63,7 +80,7 @@
              (manhattan-distance #c(0 0) p)))
     (distance-to-origin (advent.spiral:number-coordinates 325489))))
 
-(defun day-3-part-2 ()
+(defun day-3/2 ()
   (flet ((neighbors (coord)
            (iterate (for-nested ((dx :from -1 :to 1)
                                  (dy :from -1 :to 1)))
@@ -78,3 +95,44 @@
       (finding value :such-that (> value 325489))
       (setf (gethash coord memory) value))))
 
+
+(defun d4-valid-passphrase-p (phrase)
+  (not (contains-duplicates-p phrase :test #'string=)))
+
+(defun day-4/1 ()
+  (count-if #'d4-valid-passphrase-p
+            (read-file-of-lines-of-words "data/2017/04")))
+
+(defun day-4/2 ()
+  (flet ((contains-anagram-p (phrase)
+           (iterate (for (word . tail) :on phrase)
+                    (thereis (find-if (curry #'anagramp word) tail)))))
+    (-<> (read-file-of-lines-of-words "data/2017/04")
+      (remove-if-not #'d4-valid-passphrase-p <>)
+      (count-if-not #'contains-anagram-p <>))))
+
+
+(defun day-5/1 ()
+  (iterate
+    (with maze = (coerce (read-file-of-numbers "data/2017/05") 'vector))
+    (with bound = (1- (length maze)))
+    (with address = 0)
+    (for steps :from 0)
+    (finding steps :such-that (not (<= 0 address bound)))
+    (for offset = (aref maze address))
+    (incf (aref maze address))
+    (incf address offset)))
+
+(defun day-5/2 ()
+  (iterate
+    (declare (optimize speed)
+             (type fixnum bound address steps offset))
+    (with maze = (coerce (read-file-of-numbers "data/2017/05") 'simple-vector))
+    (with bound = (1- (length maze)))
+    (with address = 0)
+    (for steps :from 0)
+    (finding steps :such-that (not (<= 0 address bound)))
+    (for offset = (aref maze address))
+    (incf (aref maze address)
+          (if (>= offset 3) -1 1))
+    (incf address offset)))
--- a/vendor/make-quickutils.lisp	Sun Dec 03 18:39:45 2017 -0500
+++ b/vendor/make-quickutils.lisp	Tue Dec 05 18:16:40 2017 -0500
@@ -8,6 +8,7 @@
                :rcurry
                :range
                :compose
+               :ensure-keyword
                :read-file-into-string
 
                )
--- a/vendor/quickutils.lisp	Sun Dec 03 18:39:45 2017 -0500
+++ b/vendor/quickutils.lisp	Tue Dec 05 18:16:40 2017 -0500
@@ -2,7 +2,7 @@
 ;;;; See http://quickutil.org for details.
 
 ;;;; To regenerate:
-;;;; (qtlc:save-utils-as "quickutils.lisp" :utilities '(:CURRY :RCURRY :RANGE :COMPOSE :READ-FILE-INTO-STRING) :ensure-package T :package "ADVENT.QUICKUTILS")
+;;;; (qtlc:save-utils-as "quickutils.lisp" :utilities '(:CURRY :RCURRY :RANGE :COMPOSE :ENSURE-KEYWORD :READ-FILE-INTO-STRING) :ensure-package T :package "ADVENT.QUICKUTILS")
 
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (unless (find-package "ADVENT.QUICKUTILS")
@@ -15,8 +15,8 @@
 (when (boundp '*utilities*)
   (setf *utilities* (union *utilities* '(:MAKE-GENSYM-LIST :ENSURE-FUNCTION
                                          :CURRY :RCURRY :RANGE :COMPOSE
-                                         :ONCE-ONLY :WITH-OPEN-FILE*
-                                         :WITH-INPUT-FROM-FILE
+                                         :ENSURE-KEYWORD :ONCE-ONLY
+                                         :WITH-OPEN-FILE* :WITH-INPUT-FROM-FILE
                                          :READ-FILE-INTO-STRING))))
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (defun make-gensym-list (length &optional (x "G"))
@@ -109,6 +109,11 @@
              ,(compose-1 funs))))))
   
 
+  (defun ensure-keyword (x)
+    "Ensure that a keyword is returned for the string designator `x`."
+    (values (intern (string x) :keyword)))
+  
+
   (defmacro once-only (specs &body forms)
     "Evaluates `forms` with symbols specified in `specs` rebound to temporary
 variables, ensuring that each initform is evaluated only once.
@@ -200,6 +205,6 @@
               :while (= bytes-read buffer-size)))))))
   
 (eval-when (:compile-toplevel :load-toplevel :execute)
-  (export '(curry rcurry range compose read-file-into-string)))
+  (export '(curry rcurry range compose ensure-keyword read-file-into-string)))
 
 ;;;; END OF quickutils.lisp ;;;;