047dfea432f2

Add day 6
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sun, 06 Dec 2015 16:44:34 +0000
parents 9117efa6cbbd
children 9c8c02923c69
branches/tags (none)
files advent.lisp

Changes

--- a/advent.lisp	Sat Dec 05 16:38:12 2015 +0000
+++ b/advent.lisp	Sun Dec 06 16:44:34 2015 +0000
@@ -98,6 +98,7 @@
       (houses (ppcre:regex-replace-all "(.)." data "\\1"))
       (houses (ppcre:regex-replace-all ".(.)" data "\\1")))))
 
+
 ;;;; Day 4
 (defun advent-4-data ()
   "ckczppom")
@@ -125,7 +126,7 @@
   (mine data 6))
 
 
-;;;; Day 4
+;;;; Day 5
 (defun advent-5-data ()
   (-> "data/5"
       beef:slurp
@@ -173,5 +174,71 @@
 (defun advent-5-2 (data)
   (count-if #'is-nice-2 data))
 
-#+comment (advent-4-1 "abcdef")
-#+comment (advent-5-2 (advent-5-data))
+
+;;;; Day 6
+(defun advent-6-data ()
+  (beef:slurp-lines "data/6" :ignore-trailing-newline t))
+
+(defmacro loop-array (arr name &rest body)
+  (let ((i (gensym "index")))
+    `(loop :for ,i :below (array-total-size ,arr)
+           :for ,name = (row-major-aref ,arr ,i)
+           ,@body)))
+
+(defun parse-indexes (s)
+  (->> s
+       (split-sequence #\,)
+       (mapcar #'parse-integer)))
+
+(defun flip (b)
+  (if (zerop b) 1 0))
+
+(defun parse-line (line)
+  (let ((parts (split-sequence #\space line)))
+    (list (parse-indexes (beef:index parts -3))
+          (parse-indexes (beef:index parts -1))
+          (cond
+            ((equal (car parts) "toggle") :toggle)
+            ((equal (cadr parts) "on") :on)
+            ((equal (cadr parts) "off") :off)
+            (t (error "Unknown operation!"))))))
+
+(defmacro loop-square (r c from-row from-col to-row to-col &rest body)
+  `(loop :for ,r :from ,from-row :to ,to-row
+         :do (loop :for ,c :from ,from-col :to ,to-col
+                   ,@body)))
+
+(defun advent-6-1 (data)
+  (let ((lights (make-array '(1000 1000) :element-type 'bit)))
+    (loop
+      :for line :in data
+      :for ((from-row from-col) (to-row to-col) operation) = (parse-line line)
+      :do (loop-square
+            r c from-row from-col to-row to-col
+            :do (setf (bit lights r c)
+                      (case operation
+                        (:toggle (flip (bit lights r c)))
+                        (:on 1)
+                        (:off 0)
+                        (t 0)))))
+    (loop-array lights b
+                :sum b)))
+
+(defun advent-6-2 (data)
+  (let ((lights (make-array '(1000 1000) :element-type 'integer)))
+    (loop
+      :for line :in data
+      :for ((from-row from-col) (to-row to-col) operation) = (parse-line line)
+      :do (loop-square
+            r c from-row from-col to-row to-col
+            :do (case operation
+                  (:toggle (incf (aref lights r c) 2))
+                  (:on (incf (aref lights r c)))
+                  (:off (when (not (zerop (aref lights r c)))
+                          (decf (aref lights r c)))))))
+    (loop-array lights b
+                :sum b)))
+
+;;;; Scratch
+#+comment (advent-6-1 '("turn on 0,0 through 2,2"))
+#+comment (advent-6-2 (advent-6-data))