Do people actually do the spoon thing? I always hit them on the edge of the counter.
wer2
I'm working on it. Just waiting till Christmas.
Marketplace on NPR. I like the more economic view of the news.
Here are some cool/memorable games:
- Brothers: A Tale of Two Sons
- Return of the Obra Dinn
- Braid
Also the director of "Canadian Bacon".
Didn't you hear? It's now a crime to have your kids walk by themselves. Just ask the bastions of freedom that are Georgia and Texas.
(That those events happened is obviously dumb.)
Lisp
Could probably just write points right to the results instead of to an intermediate list, but it runs instantly, so my motivation to do so was low.
Code
(defun p1-process-line (line)
(to-symbols line 'advt2024-d8))
(defun count-results (results)
(loop for i from 0 below (array-total-size results)
count (row-major-aref results i)))
(defun place-annode (pos results)
(let ((x (first pos)) (y (second pos)))
(when (in-map results x y)
(setf (aref results y x) t))))
(defun create-annodes-p1 (x1 y1 x2 y2)
(let ((delta-x (- x2 x1)) (delta-y (- y2 y1)))
(list (list (- x1 delta-x) (- y1 delta-y)) (list (+ x2 delta-x) (+ y2 delta-y)))))
(defun place-annodes (positions results create-annodes)
(when positions
(loop with a = (car positions)
with x1 = (first a)
with y1 = (second a)
for b in (cdr positions)
for ans = (funcall create-annodes x1 y1 (first b) (second b))
do (dolist (a ans) (place-annode a results)))
(place-annodes (cdr positions) results create-annodes)))
(defun place-all-annodes (xmits map &optional (create-annodes #'create-annodes-p1))
(let ((results (make-array (array-dimensions map) :element-type 'boolean :initial-element nil)))
(loop for k being the hash-key of xmits
do (place-annodes (gethash k xmits) results create-annodes))
results))
(defun find-transmitters (map)
"look throught the map and record where the transmitters are in a hash map"
(let ((h (make-hash-table)))
(destructuring-bind (rows cols) (array-dimensions map)
(loop for j from 0 below rows
do (loop for i from 0 below cols
for v = (aref map j i)
unless (eql v '|.|)
do (push (list i j) (gethash v h))
)))
h))
(defun run-p1 (file)
(let* ((map (list-to-2d-array (read-file file #'p1-process-line))))
(count-results (place-all-annodes (find-transmitters map) map))
))
(defun create-annodes-2 (x1 y1 x2 y2 map)
(destructuring-bind (rows cols) (array-dimensions map)
(let* ((m (/ (- y2 y1) (- x2 x1) ))
(b (- y2 (* m x2))))
(loop for x from 0 below cols
for y = (+ b (* x m))
for r = (nth-value 1 (floor y))
when (and (= r 0) (>= y 0) (< y rows))
collect (list x y)))))
(defun run-p2 (file)
(let* ((map (list-to-2d-array (read-file file #'p1-process-line))))
(count-results (place-all-annodes (find-transmitters map) map
(lambda (x1 y1 x2 y2)
(create-annodes-2 x1 y1 x2 y2 map))))))
Lisp
Could probably go much faster if I kept track of calculations to not repeat, but 4 seconds for part 2 on my old laptop is good enough for me. Also, not really a big change from part 1 to part 2.
Part 1 and 2
(defstruct calibration result inputs)
(defun p1-process-line (line)
(let ((parts (str:words line)))
(make-calibration :result (parse-integer (car parts) :junk-allowed t)
:inputs (mapcar #'parse-integer (cdr parts)))))
(defun apply-opperators (c opps)
(let ((accum (car (calibration-inputs c))))
(loop for o in opps
for v in (cdr (calibration-inputs c))
until (> accum (calibration-result c))
if (eql o 'ADD)
do (setf accum (+ accum v))
else if (eql o 'MUL)
do (setf accum (* accum v))
else
do (setf accum (+ v (* accum (expt 10 (1+ (floor (log v 10)))))))
finally (return accum)
)))
(defun generate-operators (item-count)
(labels ((g-rec (c results)
(if (< c 1)
results
(g-rec (1- c) (loop for r in results
collect (cons 'ADD r)
collect (cons 'MUL r))))))
(g-rec (1- item-count) '((ADD) (MUL)))))
(defun generate-ops-hash (c gen-ops)
(let ((h (make-hash-table)))
(dotimes (x c)
(setf (gethash (+ 2 x) h) (funcall gen-ops (+ 1 x))))
h))
(defun validate-calibration (c ops-h)
(let ((r (calibration-result c))
(ops (gethash (length (calibration-inputs c)) ops-h)))
(loop for o in ops
for v = (apply-opperators c o)
when (= v r)
return t)))
(defun run-p1 (file)
(let ((calibrations (read-file file #'p1-process-line))
(ops (generate-ops-hash 13 #'generate-operators)))
(loop for c in calibrations
when (validate-calibration c ops)
sum (calibration-result c))))
(defun generate-operators-p2 (item-count)
(labels ((g-rec (c results)
(if (< c 1)
results
(g-rec (1- c) (loop for r in results
collect (cons 'ADD r)
collect (cons 'MUL r)
collect (cons 'CAT r))))))
(g-rec (1- item-count) '((ADD) (MUL) (CAT)))))
(defun run-p2 (file)
(let ((calibrations (read-file file #'p1-process-line))
(ops (generate-ops-hash 13 #'generate-operators-p2)))
(loop for c in calibrations
when (validate-calibration c ops)
sum (calibration-result c))))
Lisp
Just did some basic regex stuff.
Part 1 and 2
(defun p1-mult (str)
"pulls out numbers and multiplies them, assumes already filtered by size"
(let ((vals (ppcre:all-matches-as-strings "\\d+" str)))
(apply #'* (or (mapcar #'parse-integer vals) '(0)))))
(defun p1-process-line (line)
"look for mul, do the mul, and sum"
(let ((ptrn "mul\\(\\d?\\d?\\d,\\d?\\d?\\d\\)"))
(apply #'+ (mapcar #'p1-mult (ppcre:all-matches-as-strings ptrn line)))))
(defun run-p1 (file)
(let ((data (read-file file #'p1-process-line)))
(apply #'+ data)))
(defun p2-process-line (line)
"looks for mul, do, and don't"
(let ((ptrn "(mul\\(\\d?\\d?\\d,\\d?\\d?\\d\\))|(do\\(\\))|(don't\\(\\))"))
(ppcre:all-matches-as-strings ptrn line)))
(defun p2-filter (data)
"expects list containing the string tokens (mul, do, don't) from the file"
(let ((process t))
(loop for x in data
when (string= "don't()" x)
do (setf process nil)
when (string= "do()" x)
do (setf process t)
when process
sum (p1-mult x))))
(defun run-p2 (file)
(let ((data (read-file file #'p2-process-line)))
;; treat the input as one line to make processing the do's and don't's easier
(p2-filter (flatten data))))
Lisp
Not super happy with the code, but it got the job done.
Part 1 and 2
(defun p1-process-line (line)
(to-symbols line))
(defun found-word-h (word data i j)
"checks for a word existing from the point horizontally to the right"
(loop for j2 from j
for w in word
when (not (eql w (aref data i j2)))
return nil
finally (return t)))
(defun found-word-v (word data i j)
"checks for a word existing from the point vertically down"
(loop for i2 from i
for w in word
when (not (eql w (aref data i2 j)))
return nil
finally (return t)))
(defun found-word-d-l (word data i j)
"checks for a word existsing from the point diagonally to the left and down"
(destructuring-bind (n m) (array-dimensions data)
(declare (ignorable n))
(and (>= (- i (length word)) -1)
(>= m (+ j (length word)))
(loop for i2 from i downto 0
for j2 from j
for w in word
when (not (eql w (aref data i2 j2)))
return nil
finally (return t)))))
(defun found-word-d-r (word data i j)
"checks for a word existing from the point diagonally to the right and down"
(destructuring-bind (n m) (array-dimensions data)
(and (>= n (+ i (length word)))
(>= m (+ j (length word)))
(loop for i2 from i
for j2 from j
for w in word
when (not (eql w (aref data i2 j2)))
return nil
finally (return t)))
))
(defun count-word-h (data word)
"Counts horizontal matches of the word"
(let ((word-r (reverse word))
(word-l (length word)))
(destructuring-bind (n m) (array-dimensions data)
(loop for i from 0 below n
sum (loop for j from 0 upto (- m word-l)
count (found-word-h word data i j)
count (found-word-h word-r data i j))))))
(defun count-word-v (data word)
"Counts vertical matches of the word"
(let ((word-r (reverse word))
(word-l (length word)))
(destructuring-bind (n m) (array-dimensions data)
(loop for j from 0 below m
sum (loop for i from 0 upto (- n word-l)
count (found-word-v word data i j)
count (found-word-v word-r data i j))))))
(defun count-word-d (data word)
"Counts diagonal matches of the word"
(let ((word-r (reverse word)))
(destructuring-bind (n m) (array-dimensions data)
(loop for i from 0 below n
sum (loop for j from 0 below m
count (found-word-d-l word data i j)
count (found-word-d-l word-r data i j)
count (found-word-d-r word data i j)
count (found-word-d-r word-r data i j)
)))))
(defun run-p1 (file)
"cares about the word xmas in any direction"
(let ((word '(X M A S))
(data (list-to-2d-array (read-file file #'p1-process-line))))
(+
(count-word-v data word)
(count-word-h data word)
(count-word-d data word))))
(defun run-p2 (file)
"cares about an x of mas crossed with mas"
(let ((word '(M A S))
(word-r '(S A M))
(data (list-to-2d-array (read-file file #'p1-process-line))))
(destructuring-bind (n m) (array-dimensions data)
(loop for i from 0 below (- n 2)
sum (loop for j from 0 below (- m 2)
count (and (found-word-d-r word data i j)
(found-word-d-l word data (+ i 2) j))
count (and (found-word-d-r word-r data i j)
(found-word-d-l word data (+ i 2) j))
count (and (found-word-d-r word data i j)
(found-word-d-l word-r data (+ i 2) j))
count (and (found-word-d-r word-r data i j)
(found-word-d-l word-r data (+ i 2) j))
)))))
Lisp
Part 1 and 2
(defun p1-process-rules (line)
(mapcar #'parse-integer (uiop:split-string line :separator "|")))
(defun p1-process-pages (line)
(mapcar #'parse-integer (uiop:split-string line :separator ",")))
(defun middle (pages)
(nth (floor (length pages) 2) pages))
(defun check-rule-p (rule pages)
(let ((p1 (position (car rule) pages))
(p2 (position (cadr rule) pages)))
(or (not p1) (not p2) (< p1 p2))))
(defun ordered-p (pages rules)
(loop for r in rules
unless (check-rule-p r pages)
return nil
finally
(return t)))
(defun run-p1 (rules-file pages-file)
(let ((rules (read-file rules-file #'p1-process-rules))
(pages (read-file pages-file #'p1-process-pages)))
(loop for p in pages
when (ordered-p p rules)
sum (middle p)
)))
(defun fix-pages (rules pages)
(sort pages (lambda (p1 p2) (ordered-p (list p1 p2) rules)) ))
(defun run-p2 (rules-file pages-file)
(let ((rules (read-file rules-file #'p1-process-rules))
(pages (read-file pages-file #'p1-process-pages)))
(loop for p in pages
unless (ordered-p p rules)
sum (middle (fix-pages rules p))
)))
The backend dev has seen into the depths of COBOL and JCL that keep the world from imploding.
And the code looked back.