A day14.lisp => day14.lisp +84 -0
@@ 0,0 1,84 @@
+(defpackage #:advent2021.day14
+ (:use #:cl #:alexandria #:cl-ppcre #:advent2021.util)
+ (:export #:solve-part-1 #:solve-part-2))
+
+(in-package #:advent2021.day14)
+
+
+
+(with-puzzle-file (stream)
+ (defparameter +template+
+ (read-line stream))
+ (read-line stream)
+ (defparameter +rules+
+ (loop :with table := (make-hash-table :test 'equal)
+ :for line := (read-line stream nil)
+ :while line
+ :for (pair result) := (split " -> " line)
+ :for (a b) := (coerce pair 'list)
+ :do (setf (gethash (cons a b) table) (char result 0))
+ :finally (return table))))
+
+(defparameter +input+
+ (parse-lines #'identity))
+
+(defun insert-pairs (template)
+ (with-output-to-string (out)
+ (loop :for (a b) :on (coerce template 'list)
+ :while b
+ :do (write-char a out)
+ (write-char (gethash (cons a b) +rules+) out)
+ :finally (write-char a out))))
+
+(defun count-elements (template)
+ (loop :with dict := (make-hash-table)
+ :for elem :across template
+ :do (incf (gethash elem dict 0))
+ :finally (return dict)))
+
+(defun freq-difference (dict)
+ (loop :for elem :being :the :hash-keys :of dict
+ :using (hash-value count)
+ :maximize count :into highest
+ :minimize count :into lowest
+ :finally (return (- highest lowest))))
+
+(defun solve-part-1 ()
+ (loop :with template := +template+
+ :repeat 10
+ :do (setf template (insert-pairs template))
+ :finally (return (freq-difference (count-elements template)))))
+
+(defun template-table (template)
+ (loop :with table := (make-hash-table :test 'equal)
+ :for (a b) :on (coerce template 'list)
+ :while b
+ :do (incf (gethash (cons a b) table 0))
+ :finally (return table)))
+
+(defun insert-pairs* (template-table)
+ (loop :with next-generation := (make-hash-table :test 'equal)
+ :for (a . b) :being :the :hash-keys :of template-table
+ :using (hash-value count)
+ :for c := (gethash (cons a b) +rules+)
+ :do (incf (gethash (cons a c) next-generation 0) count)
+ (incf (gethash (cons c b) next-generation 0) count)
+ :finally (return next-generation)))
+
+(defun count-elements* (template-table)
+ (loop :with freq-dict := (make-hash-table)
+ :with template := (coerce +template+ 'list)
+ :for (a . b) :being :the :hash-keys :of template-table
+ :using (hash-value count)
+ :do (incf (gethash a freq-dict 0) (/ count 2))
+ (incf (gethash b freq-dict 0) (/ count 2))
+ :finally (progn
+ (incf (gethash (first template) freq-dict) 1/2)
+ (incf (gethash (car (last template)) freq-dict) 1/2)
+ (return freq-dict))))
+
+(defun solve-part-2 ()
+ (loop :with template := (template-table +template+)
+ :repeat 40
+ :do (setf template (insert-pairs* template))
+ :finally (return (freq-difference (count-elements* template)))))
A input/day14.txt => input/day14.txt +102 -0
@@ 0,0 1,102 @@
+VPPHOPVVSFSVFOCOSBKF
+
+CO -> B
+CV -> N
+HV -> H
+ON -> O
+FS -> F
+NS -> S
+VK -> C
+BV -> F
+SC -> N
+NV -> V
+NC -> F
+NH -> B
+BO -> K
+FC -> H
+NB -> H
+HO -> F
+SB -> N
+KP -> V
+OS -> C
+OB -> P
+SH -> N
+BC -> H
+CK -> H
+SO -> N
+SP -> P
+CF -> P
+KV -> F
+CS -> V
+FF -> P
+VS -> V
+CP -> S
+PH -> V
+OP -> K
+KH -> B
+FB -> S
+CN -> H
+KS -> P
+FN -> O
+PV -> O
+VC -> S
+HF -> N
+OC -> O
+PK -> V
+KC -> C
+HK -> C
+PO -> N
+OO -> S
+VH -> N
+CC -> K
+BP -> K
+HC -> K
+FV -> K
+KF -> V
+VF -> C
+HN -> S
+VP -> B
+HH -> O
+FO -> O
+PC -> N
+KK -> C
+PN -> P
+NN -> C
+FH -> N
+VV -> O
+OK -> V
+CB -> N
+SN -> H
+VO -> H
+BB -> C
+PB -> F
+NF -> P
+KO -> S
+PP -> K
+NO -> O
+SF -> N
+KN -> S
+PS -> O
+VN -> V
+SS -> N
+BF -> O
+HP -> H
+HS -> N
+BS -> S
+VB -> F
+PF -> K
+SV -> V
+BH -> P
+FP -> O
+CH -> P
+OH -> K
+OF -> F
+HB -> V
+FK -> V
+BN -> V
+SK -> F
+OV -> C
+NP -> S
+NK -> S
+BK -> C
+KB -> F