diff options
Diffstat (limited to 'users/tazjin/aoc2023')
-rw-r--r-- | users/tazjin/aoc2023/day1.el | 52 | ||||
-rw-r--r-- | users/tazjin/aoc2023/day2.el | 64 | ||||
-rw-r--r-- | users/tazjin/aoc2023/day3.el | 110 |
3 files changed, 226 insertions, 0 deletions
diff --git a/users/tazjin/aoc2023/day1.el b/users/tazjin/aoc2023/day1.el new file mode 100644 index 0000000000..b1a7faff02 --- /dev/null +++ b/users/tazjin/aoc2023/day1.el @@ -0,0 +1,52 @@ +(require 's) +(require 'f) + +;; task 1 + +(defun digit-p (c) + (and (> c ?0) + (<= c ?9))) + +(defun aocd1-sum-values (lines) + (-sum + (-map (lambda (line) + (let ((digits (-filter #'digit-p (string-to-list line)))) + (string-to-number (string (-first-item digits) (-last-item digits))))) + lines))) + +(let ((lines (s-lines (s-trim (f-read "~/Downloads/input.txt"))))) + (aocd1-sum-values lines)) + +;; task 2 + +(defun replace-written-numbers (input) + (with-temp-buffer + (insert input) + (let ((start 1)) + (while (< start (point-max)) + (format-replace-strings + '(("oneight" . "18") + ("twone" . "21") + ("threeight" . "38") + ("fiveight" . "58") + ("sevenine" . "79") + ("eightwo" . "82") + ("eighthree" . "83") + ("nineight" . "98")) + nil start (min (+ 10 start) (point-max))) + (format-replace-strings + '(("one" . "1") + ("two" . "2") + ("three" . "3") + ("four" . "4") + ("five" . "5") + ("six" . "6") + ("seven" . "7") + ("eight" . "8") + ("nine" . "9")) + nil start (min (+ 5 start) (point-max))) + (setq start (1+ start)))) + (buffer-string))) + +(let ((lines (s-lines (s-trim (f-read "~/Downloads/input.txt"))))) + (aocd1-sum-values (-map #'replace-written-numbers lines))) diff --git a/users/tazjin/aoc2023/day2.el b/users/tazjin/aoc2023/day2.el new file mode 100644 index 0000000000..9374d7862c --- /dev/null +++ b/users/tazjin/aoc2023/day2.el @@ -0,0 +1,64 @@ +(require 'dash) +(require 's) +(require 'f) + +(defvar aoc23-day2-example + + "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green +Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue +Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red +Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red +Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green") + +;; part 1 + +(cl-defstruct aoc23d2-set red green blue) + +(defun aoc23d2-parse-set (input) + (let ((set (make-aoc23d2-set :red 0 :green 0 :blue 0)) + (colours (-map #'s-trim (s-split "," input)))) + (cl-loop for colour in colours + do (pcase (s-split " " colour t) + (`(,num "red") (setf (aoc23d2-set-red set) (string-to-number num))) + (`(,num "green") (setf (aoc23d2-set-green set) (string-to-number num))) + (`(,num "blue") (setf (aoc23d2-set-blue set) (string-to-number num))))) + set)) + +(cl-defstruct aoc23d2-game id sets) + +(defun aoc23d2-parse-game (input) + (pcase-let* ((`(,id-str ,sets-str) (s-split-up-to ":" input 1 t)) + (game-id (string-to-number (s-chop-left (length "Game ") id-str))) + (sets (-map #'aoc23d2-parse-set (s-split ";" sets-str t)))) + (make-aoc23d2-game :id game-id :sets sets))) + +(defun aoc23d2-game-possible-p (game r g b) + (cl-every (lambda (set) + (and (<= (aoc23d2-set-red set) r) + (<= (aoc23d2-set-green set) g) + (<= (aoc23d2-set-blue set) b))) + (aoc23d2-game-sets game))) + +(let ((input (f-read "~/Downloads/input.txt"))) + (-sum + (-map #'aoc23d2-game-id + (-filter (lambda (g) (aoc23d2-game-possible-p g 12 13 14)) + (-map #'aoc23d2-parse-game (s-lines (s-trim input))))))) + +;; part 2 + +(defun aoc23d2-game-min-cubes-power (game) + (let ((r 0) + (g 0) + (b 0)) + (-each (aoc23d2-game-sets game) + (lambda (set) + (setq r (max r (aoc23d2-set-red set))) + (setq g (max g (aoc23d2-set-green set))) + (setq b (max b (aoc23d2-set-blue set))))) + (* (max 1 r) (max 1 g) (max 1 b)))) + +(let ((input (f-read "~/Downloads/input.txt"))) + (-sum + (-map #'aoc23d2-game-min-cubes-power + (-map #'aoc23d2-parse-game (s-lines (s-trim input)))))) diff --git a/users/tazjin/aoc2023/day3.el b/users/tazjin/aoc2023/day3.el new file mode 100644 index 0000000000..dd39c1b836 --- /dev/null +++ b/users/tazjin/aoc2023/day3.el @@ -0,0 +1,110 @@ +(defun aoc23d3-symbol-p (c) + (not (or (= c ? ) + (and (>= c ?0) + (<= c ?9))))) + +(defun rectangle-for-bounds (bounds) + (let* ((start (save-excursion + (goto-char (car bounds)) + (let ((col (current-column))) + (forward-line -1) + (move-to-column (max 0 (1- col)))) + (point))) + (end (save-excursion + (goto-char (cdr bounds)) + (let ((col (current-column))) + (forward-line 1) + (move-to-column (1+ col))) + (point)))) + (list start end))) + +(defun get-machine-part () + (interactive) + (when-let* ((num-raw (number-at-point)) + (num (abs num-raw)) + ;; handles negative number edge case (bounds contain the `-') + (bounds-raw (bounds-of-thing-at-point 'number)) + (bounds (if (< num-raw 0) + (cons (1- (car bounds-raw)) (cdr bounds-raw)) + bounds-raw)) + (rectangle (rectangle-for-bounds bounds)) + (neighbours (apply #'concat + (apply #'extract-rectangle rectangle)))) + (if (-any #'aoc23d3-symbol-p (string-to-list neighbours)) + (cons num rectangle) + (cons nil rectangle)))) + + +(defun find-machine-parts (input) + (with-temp-buffer + (insert input) + (goto-char (point-min)) + (save-excursion + (replace-string "." " ")) + + (cl-loop while (forward-word) + for result = (get-machine-part) + when (car result) collect (car result)))) + + +;; debugging + +(defvar aoc23d3-example "467..114.. +...*...... +..35..633. +......#... +617*...... +.....+.58. +..592..... +......755. +...$.*.... +.664.598..") + +(defvar aoc23d3-example2 "12.......*.. ++.........34 +.......-12.. +..78........ +..*....60... +78.......... +.......23... +....90*12... +............ +2.2......12. +.*.........* +1.1.......56") + +(defvar aoc23d3-example3 "243. +..*. +....") + +(defun aoc23d3-debug (p) + "Interactive debugger for the solution, can be bound to a key in +an input buffer. Dots should already have been replaced with +spaces." + (interactive "P") + (unless p + (goto-char aoc23d3-last)) + (rectangle-mark-mode 1) + (forward-word) + (setq aoc23d3-last (point)) + (pcase (get-machine-part) + (`(nil ,b ,e) (progn (set-mark b) + (goto-char e) + (set-face-attribute 'region nil :background "#FAA0A0"))) + (`(,num ,b ,e) (progn (set-mark b) + (goto-char e) + (set-face-attribute 'region nil :background "#d1ffbd"))) + (other (deactivate-mark)))) + +(cl-assert (= 4361 (-sum (find-machine-parts aoc23d3-example))) nil + "example from website is working") + +(cl-assert (= 413 (-sum (find-machine-parts aoc23d3-example2))) nil + "example from subreddit is working") + +(cl-assert (= 243 (-sum (find-machine-parts aoc23d3-example3))) nil + "example from telegram is working") + +;; day 1 (incomplete) + +(-sum (find-machine-parts (s-trim (f-read "~/Downloads/input.txt")))) |