You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
5.9 KiB

#+title: Solution to p9
#+begin_src emacs-lisp :results none
(with-temp-buffer
(insert-file-contents "input-test")
(advent/replace-multiple-regex-buffer
'(("," . " ")
("^" . "(")
("$" . ")")))
(goto-char (point-min))
(insert "(setq data '(")
(goto-char (point-max))
(insert "))")
(eval-buffer))
#+end_src
Find max area
#+begin_src emacs-lisp
(defun area (el)
(let ((a (car el))
(b (cdr el)))
(abs (* (- (car a) (car b) -1)
(- (cadr a) (cadr b) -1)))))
(defun symmetric-pairs (list)
(apply #'append (--map-indexed (-map (lambda (other) (cons it other))
(-drop (1+ it-index) list))
list)))
(-max (-map 'area (symmetric-pairs data)))
#+end_src
#+RESULTS:
: 50
For part 2, we begin by removing the vertices that are not corners.
(there may be some, or none, but I don't know for sure)
#+begin_src emacs-lisp :results none
(setq data-prev (-rotate 1 data)
data-next (-rotate -1 data)
data-pv (-zip-lists data data-prev data-next))
(defun normalize (x)
(if (= x 0) 0
(/ x (abs x))))
(defun cornerize (a b)
(list (normalize (- (car b) (car a)))
(normalize (- (cadr b) (cadr a)))))
(defun hor-or-ver (a b)
(if (= (car a) (car b)) 'vertical
'horizontal))
(setq data-corners
(--map (cons (car it)
(cons (cornerize (cadr it) (car it))
(cornerize (car it) (caddr it))))
data-pv))
(setq data-corners
(--remove (equal (cadr it) (cddr it)) data-corners))
#+end_src
OK, the datapoints are all corners. Now I know. Find which way is inside
#+begin_src emacs-lisp
;; find the leftmost and topmost coordinate
(setq leftmost (-min (-map #'car data))
topmost (-min (-map #'cadr data)))
;; find corners that lie on the leftmost coordinate; the domain must
;; be to their right it appears that there are only two such corners;
;; take the first one, and the outgoing direction; it is going down
;; and it must come from the right, so it should be (-1 0) . (0 -1)
(car (--filter (= (caar it) leftmost) data-corners))
;; We therefore know what corners are convex and what corners are concave
(setq quadrant-map
'( (((-1 0) . (0 -1)) . (4))
(((0 -1) . (1 0)) . (1))
(((1 0) . (0 1)) . (2))
(((0 1) . (-1 0)) . (3))
(((-1 0) . (0 1)) . (2 3 4))
(((0 1) . (1 0)) . (1 3 4))
(((1 0) . (0 -1)) . (4 1 2))
(((0 -1) . (-1 0)) . ( 1 2 3))))
(setq rects (symmetric-pairs data))
;; first filter away those that strictly contain a vertex
(defun strictly-contains-p (rect p)
(let ((minx (min (caar rect) (cadr rect)))
(maxx (max (caar rect) (cadr rect)))
(miny (min (cadar rect) (caddr rect)))
(maxy (max (cadar rect) (caddr rect)))
(px (car p))
(py (cadr p)))
(and (< minx px) (< px maxx)
(< miny py) (< py maxy))))
(setq rects-sifted (-remove (lambda (rect) (--any (strictly-contains-p rect it) data)) rects))
#+end_src
#+begin_src emacs-lisp
(defun incompatible-p (rect corner)
(let ((minx (min (caar rect) (cadr rect)))
(maxx (max (caar rect) (cadr rect)))
(miny (min (cadar rect) (caddr rect)))
(maxy (max (cadar rect) (caddr rect)))
(px (caar corner))
(py (cadar corner))
(quadrant-list (cdr (assoc (cdr corner) quadrant-map))))
(or (and (= px minx) (< miny py) (< py maxy) (< 2 (length (-intersection '(1 4) quadrant-list)))) ; on left edge
(and (= px maxx) (< miny py) (< py maxy) (< 2 (length (-intersection '(2 3) quadrant-list))))
(and (= py miny) (< minx px) (< px maxx) (< 2 (length (-intersection '(1 2) quadrant-list))))
(and (= py maxy) (< minx px) (< px maxx) (< 2 (length (-intersection '(3 4) quadrant-list)))))))
(setq final-rects (-remove (lambda (rect) (--any (incompatible-p rect it) data-corners)) rects-sifted))
(-max (-map #'area final-rects))
#+end_src
#+RESULTS:
: 40
#+begin_src emacs-lisp
(car rects)
(--filter (incompatible-p (cadr rects-sifted) it) data-corners)
(cadr rects-sifted)
#+end_src
#+RESULTS:
| (7 1) | 11 | 1 |
| (7 1) | 11 | 7 |
| (7 1) | 9 | 7 |
| (7 1) | 9 | 5 |
| (7 1) | 2 | 5 |
| (7 1) | 2 | 3 |
| (7 1) | 7 | 3 |
| (11 1) | 11 | 7 |
| (11 1) | 9 | 7 |
| (11 1) | 9 | 5 |
| (11 1) | 2 | 5 |
| (11 1) | 2 | 3 |
| (11 1) | 7 | 3 |
| (11 7) | 9 | 7 |
| (11 7) | 9 | 5 |
| (11 7) | 2 | 5 |
| (11 7) | 2 | 3 |
| (11 7) | 7 | 3 |
| (9 7) | 9 | 5 |
| (9 7) | 2 | 5 |
| (9 7) | 2 | 3 |
| (9 7) | 7 | 3 |
| (9 5) | 2 | 5 |
| (9 5) | 2 | 3 |
| (9 5) | 7 | 3 |
| (2 5) | 2 | 3 |
| (2 5) | 7 | 3 |
| (2 3) | 7 | 3 |
#+begin_src emacs-lisp
rects-sifted
#+end_src
#+RESULTS:
| (7 1) | 11 | 1 |
| (7 1) | 9 | 7 |
| (7 1) | 9 | 5 |
| (7 1) | 2 | 5 |
| (7 1) | 2 | 3 |
| (7 1) | 7 | 3 |
| (11 1) | 11 | 7 |
| (11 1) | 9 | 7 |
| (11 1) | 9 | 5 |
| (11 1) | 2 | 3 |
| (11 1) | 7 | 3 |
| (11 7) | 9 | 7 |
| (11 7) | 9 | 5 |
| (11 7) | 2 | 5 |
| (9 7) | 9 | 5 |
| (9 7) | 2 | 5 |
| (9 7) | 2 | 3 |
| (9 7) | 7 | 3 |
| (9 5) | 2 | 5 |
| (9 5) | 2 | 3 |
| (9 5) | 7 | 3 |
| (2 5) | 2 | 3 |
| (2 5) | 7 | 3 |
| (2 3) | 7 | 3 |
#+begin_src emacs-lisp
final-rects
#+end_src
#+RESULTS:
| (7 1) | 11 | 1 |
| (7 1) | 9 | 7 |
| (7 1) | 9 | 5 |
| (7 1) | 2 | 5 |
| (7 1) | 2 | 3 |
| (7 1) | 7 | 3 |
| (11 1) | 11 | 7 |
| (11 1) | 9 | 7 |
| (11 1) | 9 | 5 |
| (11 1) | 2 | 3 |
| (11 1) | 7 | 3 |
| (11 7) | 9 | 7 |
| (11 7) | 9 | 5 |
| (11 7) | 2 | 5 |
| (9 7) | 9 | 5 |
| (9 7) | 2 | 5 |
| (9 7) | 2 | 3 |
| (9 7) | 7 | 3 |
| (9 5) | 2 | 5 |
| (9 5) | 2 | 3 |
| (9 5) | 7 | 3 |
| (2 5) | 2 | 3 |
| (2 5) | 7 | 3 |
| (2 3) | 7 | 3 |