diff options
author | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-12-03 16:40:08 +0000 |
---|---|---|
committer | Aryadev Chavali <aryadev@aryadevchavali.com> | 2024-12-03 16:40:08 +0000 |
commit | e253bc500686b7d9adec1686d20c75714cf2ddf0 (patch) | |
tree | 5bfc137901f2c86e582ad2bc05882e6fba0c0ad6 | |
parent | 88351633d250638b02ad499123ec44bb39edf3ef (diff) | |
download | advent-of-code-e253bc500686b7d9adec1686d20c75714cf2ddf0.tar.gz advent-of-code-e253bc500686b7d9adec1686d20c75714cf2ddf0.tar.bz2 advent-of-code-e253bc500686b7d9adec1686d20c75714cf2ddf0.zip |
Solve round 2 and 3 for 2024
-rw-r--r-- | 2024/puzzle-2.py | 43 | ||||
-rw-r--r-- | 2024/puzzle-3.lisp | 58 |
2 files changed, 101 insertions, 0 deletions
diff --git a/2024/puzzle-2.py b/2024/puzzle-2.py new file mode 100644 index 0000000..98f2efd --- /dev/null +++ b/2024/puzzle-2.py @@ -0,0 +1,43 @@ +lines = [] +with open("2-input", "r") as fp: + lines = fp.readlines() + +levels = [list(map(int, line.strip().split(" "))) for line in lines] + +def is_good_level_1(level): + # 1) Is decreasing + # 2) Sliding window of two cells (x, y) => 1 <= |x-y| <= 3 + # figure out if decreasing from first two + decreasing = level[0] > level[1] + for i in range(len(level) - 1): + x = level[i] + y = level[i + 1] + diff = abs(x - y) + if (decreasing and x < y) or (not decreasing and x > y) or not (diff <= 3 and diff >= 1): + return False + return True + +good_levels = [level for level in levels if is_good_level_1(level)] +print(f"Round 1: {len(good_levels)}") + +def check_two_levels(x, y, decreasing): + diff = abs(x - y) + 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): + # 1) Is decreasing + # 2) Sliding window of two cells (x, y) => 1 <= |x-y| <= 3 + # 3) Can remove any one item to make it safe + ret = is_good_level_1(level) + if not ret: + # Consider slices of the level and check if they're good + slices = [level[:i] + level[i + 1:] for i in range(len(level))] + for s in slices: + if is_good_level_1(s): + return True + else: + return True + return False + +good_levels = [level for level in levels if is_good_level_2(level)] +print(f"Round 2: {len(good_levels)}") diff --git a/2024/puzzle-3.lisp b/2024/puzzle-3.lisp new file mode 100644 index 0000000..cca2f43 --- /dev/null +++ b/2024/puzzle-3.lisp @@ -0,0 +1,58 @@ +(load "util.lisp") + +(defparameter input (uiop:read-file-string "3-input")) + +(defun is-good-mul (str) + (let* ((delimiter (search "," str)) + (end (search ")" str))) + (if (or (null delimiter) (null end) + (> delimiter end) + (not (eq #\( (char str 3)))) + nil + (let* ((first-arg (subseq str 4 delimiter)) + (second-arg (subseq str (1+ delimiter) end))) + (and (every #'digit-char-p first-arg) + (every #'digit-char-p second-arg)))))) + +(defun trim-mul (str) + (subseq str 0 (1+ (search ")" str)))) + +(defun parse-mul (str) + (let ((start (search "(" str)) + (middle (search "," str)) + (end (search ")" str))) + (list (parse-integer (subseq str (1+ start) middle)) + (parse-integer (subseq str (1+ middle) end))))) + +(defun parse-input-muls (line) + (let ((possible (search-all "mul" line))) + (--> (cdr possible) + (append _ (list (length line))) + (mapcar (lambda (z1 z2) (cons z1 (subseq line z1 z2))) possible _) + (remove-if-not (lambda (x) (is-good-mul (cdr x))) _) + (mapcar (lambda (x) (cons (car x) (trim-mul (cdr x)))) _) + (mapcar (lambda (x) (cons (car x) (parse-mul (cdr x)))) _)))) + +(format t "Round 1: ~a~%" + (loop for (pos x y) in (parse-input-muls input) + sum (* x y))) + +(defun parse-input-conds (input) + (let ((dos (search-all "do()" input)) + (donts (search-all "don't()" input))) + (cons + '(do . 0) + (sort (append (mapcar (lambda (x) (cons 'do x)) dos) + (mapcar (lambda (x) (cons 'dont x)) donts)) + (lambda (x y) (< (cdr x) (cdr y))))))) + +(defun current-cond (pos conds) + (caar (last (remove-if (lambda (x) (> (cdr x) pos)) conds)))) + +(format t "Round 2: ~a~%" + (let ((conds (parse-input-conds input)) + (muls (parse-input-muls input))) + (loop for (pos x y) in muls + for current = (current-cond pos conds) + if (eq current 'do) + sum (* x y)))) |