5641b3a7009e

Day 11
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 12 Dec 2015 23:19:04 +0000
parents 162d5f701f64
children be03b663f936
branches/tags (none)
files advent.lisp

Changes

--- a/advent.lisp	Sat Dec 12 22:15:08 2015 +0000
+++ b/advent.lisp	Sat Dec 12 23:19:04 2015 +0000
@@ -531,9 +531,101 @@
   (length (iterate 50 #'look-and-say (las-to-list data))))
 
 
+;;;; Day 11
+(defun advent-11-data ()
+  "vzbxkghb")
+
+
+(defparameter base 26)
+(defparameter ascii-alpha-start (char-code #\a))
+(defun num-to-char (n)
+  (code-char (+ n ascii-alpha-start)))
+
+(defun char-to-num (ch)
+  (- (char-code ch) ascii-alpha-start))
+
+
+(defmacro loop-window (seq width binding-form &rest body)
+  (let ((i (gensym "IGNORE"))
+        (s (gensym "SEQ"))
+        (n (gensym "WIDTH"))
+        (tail (gensym "TAIL")))
+    `(let ((,s ,seq)
+           (,n ,width))
+       (loop :for ,i :upto (- (length ,s) ,n)
+             :for ,tail :on ,s
+             :for ,binding-form = (subseq ,tail 0 ,n)
+             ,@body))))
+
+
+(defun is-straight-3 (l)
+  (destructuring-bind (a b c) l
+    (and (= 1 (- b a))
+         (= 1 (- c b)))))
+
+(defun has-straight-3 (nums)
+  (loop-window nums 3 triplet
+               :thereis (is-straight-3 triplet)))
+
+
+(defparameter bad-chars
+  (mapcar #'char-to-num '(#\i #\l #\o)))
+
+(defun no-bad (nums)
+  (loop :for bad :in bad-chars
+        :never (find bad nums)))
+
+
+(defun two-pairs (nums)
+  (-> nums
+      (loop-window 2 (a b)
+                   :when (= a b)
+                   :collect a)
+      remove-duplicates
+      length
+      (>= 2)))
+
+
+(defun valid (nums)
+  (and (has-straight-3 nums)
+       (no-bad nums)
+       (two-pairs nums)
+       nums))
+
+
+(defun incr-nums (nums)
+  (labels ((inc-mod (x)
+             (mod (1+ x) base))
+           (inc (nums)
+             (if (not nums)
+               '(1)
+               (let ((head (inc-mod (car nums))))
+                 (if (zerop head)
+                   (cons head (inc (cdr nums)))
+                   (cons head (cdr nums)))))))
+    (reverse (inc (reverse nums)))))
+
+
+(defun advent-11-1 (data)
+  (flet ((chars-to-string (chs)
+           (apply #'concatenate 'string (mapcar #'string chs)))
+         (nums-to-chars (nums)
+           (mapcar #'num-to-char nums))
+         (string-to-nums (str)
+           (loop :for ch :across str
+                 :collect (char-to-num ch))))
+    (-> (loop :for pw = (incr-nums (string-to-nums data))
+              :then (incr-nums pw)
+              :thereis (valid pw))
+        nums-to-chars
+        chars-to-string)))
+
+
+
 
 
 ;;;; Scratch
 #+comment (advent-8-2 '("\"dogs\""))
-#+comment (advent-10-1 (advent-10-data))
+#+comment (advent-11-1 (advent-11-1 (advent-11-data)))
+#+comment (advent-11-1 "abcdefgh")
 #+comment (advent-10-2 (advent-10-data))