Compare commits

...

2 commits

Author SHA1 Message Date
5926b5cd3f clean up day 19 2024-12-19 14:26:56 +01:00
57f4a063d6 solved day19 2024-12-19 14:20:50 +01:00
2 changed files with 25 additions and 90 deletions

View file

@ -1,4 +1,3 @@
(defpackage :aoc/2024/19
(:use :cl :aoc :alexandria :trivia :lla)
(:export
@ -44,72 +43,13 @@ bbrgwb"))
(defparameter sample-data
(parse-input sample-text))
(defstruct node
name
terminates
next)
(defun towel-tree (towels word)
(let ((towel-tree (make-hash-table))
(terminates nil))
(loop
for towel in towels
if (emptyp towel
do (setf terminates t)
else
do (setf (gethash (char towel 0) towel-tree)
(sort
(let ((r (subseq towel 1)))
(cons r (gethash (char towel 0) towel-tree)))
#'(lambda (a b)
(cond
((< (length a) (length b)) t)
((> (length a) (length b)) nil)
(t (string-lessp a b)))
))))
(loop
for k being the hash-keys in towel-tree
for v being the hash-values in towel-tree
do (setf (gethash k towel-tree) (towel-tree v (concatenate 'string word (list k))))
)
(make-node
:name word
:terminates terminates
:next towel-tree)))
(defun show-tree (tree &optional (depth 0))
(loop
for k being the hash-keys in (node-next tree)
for v being the hash-values in (node-next tree)
do (format t "~v@{~A~:*~}" depth " ")
(format t "~A(~A)~%" k (if (node-terminates v) " OK" ""))
(show-tree v (1+ depth))))
(defun valid-pattern-p-old (og-tree pattern)
(defun check (tree pattern word words)
(let ((terminate (node-terminates tree)))
(if (emptyp pattern)
terminate
(let* ((c (char pattern 0))
(np (subseq pattern 1))
(nw (concatenate 'string word (list c))))
(or
(if-let ((nt (gethash c (node-next tree))))
(check nt np nw words))
(and terminate
(if-let ((nt (gethash c (node-next og-tree))))
(check nt np "" (cons word words))
))
)))))
(check og-tree pattern "" '()))
(defvar *patterns* (make-hash-table :test #'equal))
(defvar *valid-patterns* (make-hash-table :test #'equal))
(defvar *possible-patterns* (make-hash-table :test #'equal))
(defvar *pattern-cache* (make-hash-table :test #'equal))
(defvar *valid-cache* (make-hash-table :test #'equal))
(defvar *possible-cache* (make-hash-table :test #'equal))
(defun reset-patterns ()
(setf *patterns* (make-hash-table :test #'equal))
(setf *valid-patterns* (make-hash-table :test #'equal))
(setf *possible-patterns* (make-hash-table :test #'equal))
(setf *pattern-cache* (make-hash-table :test #'equal))
(setf *valid-cache* (make-hash-table :test #'equal))
(setf *possible-cache* (make-hash-table :test #'equal))
)
(defun string-prefix-p (prefix string)
@ -119,20 +59,20 @@ bbrgwb"))
(defun remaining-patterns (towels pattern)
(or
(gethash pattern *patterns*)
(gethash pattern *pattern-cache*)
(let ((remaining (loop
for towel in towels
if (string-prefix-p towel pattern)
collect (subseq pattern (length towel))
)))
(setf (gethash pattern *patterns*) remaining))))
(setf (gethash pattern *pattern-cache*) remaining))))
(defun valid-pattern-p (towels pattern)
(multiple-value-bind (is-valid found)
(gethash pattern *valid-patterns*)
(gethash pattern *valid-cache*)
(if found
is-valid
(setf (gethash pattern *valid-patterns*)
(setf (gethash pattern *valid-cache*)
(if (emptyp pattern)
t
(if-let (ps (remaining-patterns towels pattern))
@ -146,7 +86,7 @@ bbrgwb"))
(defun towels-to-regex (onsen)
(format nil "^(~{~A~^|~})*$" (onsen-towels onsen)))
(defun valid-patterns (onsen)
(defun valid-cache (onsen)
(reset-patterns)
(loop
for pattern in (onsen-patterns onsen)
@ -154,12 +94,11 @@ bbrgwb"))
collect pattern))
(defun possible-patterns (towels pattern)
(multiple-value-bind (is-valid found)
(gethash pattern *possible-patterns*)
(format t "~A ~A ~A~%" pattern is-valid found)
(multiple-value-bind (n found)
(gethash pattern *possible-cache*)
(if found
(if is-valid 1 0)
(setf (gethash pattern *possible-patterns*)
n
(setf (gethash pattern *possible-cache*)
(if (emptyp pattern)
1
(if-let (ps (remaining-patterns towels pattern))
@ -172,10 +111,14 @@ bbrgwb"))
))
(defun part1 (onsen)
(format nil "~A" (length (valid-patterns onsen))))
(format nil "~A" (length (valid-cache onsen))))
(defun part2 (data)
(length data))
(reset-patterns)
(format nil "~A"
(loop for p in (onsen-patterns data)
for n = (possible-patterns (onsen-towels data) p)
sum n)))
(defun solve-day ()
(format t "part1: ~A~%" (part1 input-data))

View file

@ -64,21 +64,13 @@
)
(define-test test-bar
:parent suite-2024-19
)
(define-test+run test-part1
:parent suite-2024-19
(is equal "6" (part1 sample-data)))
(define-test+run test-part2
:parent suite-2024-19
(is equal nil (part2 sample-data)))
(is equal "16" (part2 sample-data)))
(defun run-tests ()
(test 'suite-2024-19))