Optimise solutions a bit for 2024

This commit is contained in:
2024-12-04 02:43:12 +00:00
parent e253bc5006
commit 61aa2c1ded
3 changed files with 30 additions and 29 deletions

View File

@@ -22,21 +22,21 @@ print(f"Round 1: {len(good_levels)}")
def check_two_levels(x, y, decreasing): def check_two_levels(x, y, decreasing):
diff = abs(x - y) diff = abs(x - y)
return not ((decreasing and x < y) or (not decreasing and x > y) or not (diff <= 3 and diff >= 1)) return not ((decreasing and x < y)\
or (not decreasing and x > y) \
or not (diff <= 3 and diff >= 1))
def is_good_level_2(level): def is_good_level_2(level):
# 1) Is decreasing # 1) Is decreasing
# 2) Sliding window of two cells (x, y) => 1 <= |x-y| <= 3 # 2) Sliding window of two cells (x, y) => 1 <= |x-y| <= 3
# 3) Can remove any one item to make it safe # 3) Can remove any one item to make it safe
ret = is_good_level_1(level) if is_good_level_1(level):
if not ret: return True
# Consider slices of the level and check if they're good # Consider slices of the level and check if they're good
slices = [level[:i] + level[i + 1:] for i in range(len(level))] slices = [level[:i] + level[i + 1:] for i in range(len(level))]
for s in slices: for s in slices:
if is_good_level_1(s): if is_good_level_1(s):
return True return True
else:
return True
return False return False
good_levels = [level for level in levels if is_good_level_2(level)] good_levels = [level for level in levels if is_good_level_2(level)]

View File

@@ -3,19 +3,19 @@
(defparameter input (uiop:read-file-string "3-input")) (defparameter input (uiop:read-file-string "3-input"))
(defun is-good-mul (str) (defun is-good-mul (str)
(let* ((delimiter (search "," str)) (let ((start (search "(" str))
(middle (search "," str))
(end (search ")" str))) (end (search ")" str)))
(if (or (null delimiter) (null end) (and (not (null start)) (not (null middle)) (not (null end))
(> delimiter end) ;; mul( <- 3 character
(not (eq #\( (char str 3)))) (eq start 3)
nil ;; Simple to understand
(let* ((first-arg (subseq str 4 delimiter)) (< start end)
(second-arg (subseq str (1+ delimiter) end))) (< start middle)
(and (every #'digit-char-p first-arg) (< middle end)
(every #'digit-char-p second-arg)))))) ;; Make sure the arguments are purely numbers
(every #'digit-char-p (subseq str (1+ start) middle))
(defun trim-mul (str) (every #'digit-char-p (subseq str (1+ middle) end)))))
(subseq str 0 (1+ (search ")" str))))
(defun parse-mul (str) (defun parse-mul (str)
(let ((start (search "(" str)) (let ((start (search "(" str))
@@ -28,9 +28,11 @@
(let ((possible (search-all "mul" line))) (let ((possible (search-all "mul" line)))
(--> (cdr possible) (--> (cdr possible)
(append _ (list (length line))) (append _ (list (length line)))
;; index of mul -> (position substring)
(mapcar (lambda (z1 z2) (cons z1 (subseq line z1 z2))) possible _) (mapcar (lambda (z1 z2) (cons z1 (subseq line z1 z2))) possible _)
;; remove any bad muls
(remove-if-not (lambda (x) (is-good-mul (cdr x))) _) (remove-if-not (lambda (x) (is-good-mul (cdr x))) _)
(mapcar (lambda (x) (cons (car x) (trim-mul (cdr x)))) _) ;; parse muls
(mapcar (lambda (x) (cons (car x) (parse-mul (cdr x)))) _)))) (mapcar (lambda (x) (cons (car x) (parse-mul (cdr x)))) _))))
(format t "Round 1: ~a~%" (format t "Round 1: ~a~%"
@@ -40,11 +42,10 @@
(defun parse-input-conds (input) (defun parse-input-conds (input)
(let ((dos (search-all "do()" input)) (let ((dos (search-all "do()" input))
(donts (search-all "don't()" input))) (donts (search-all "don't()" input)))
(cons (--> (append (mapcar (lambda (x) (cons 'do x)) dos)
'(do . 0)
(sort (append (mapcar (lambda (x) (cons 'do x)) dos)
(mapcar (lambda (x) (cons 'dont x)) donts)) (mapcar (lambda (x) (cons 'dont x)) donts))
(lambda (x y) (< (cdr x) (cdr y))))))) (sort _ (lambda (x y) (< (cdr x) (cdr y))))
(cons '(do . 0) _))))
(defun current-cond (pos conds) (defun current-cond (pos conds)
(caar (last (remove-if (lambda (x) (> (cdr x) pos)) conds)))) (caar (last (remove-if (lambda (x) (> (cdr x) pos)) conds))))

View File

@@ -2,7 +2,7 @@
(if (null functions) (if (null functions)
first first
`(let* ,(loop :for f :in (cons first functions) `(let* ,(loop :for f :in (cons first functions)
appending `((_ ,f))) :appending `((_ ,f)))
_))) _)))
(defun search-all (substr str &optional acc len) (defun search-all (substr str &optional acc len)