|
|
|
|
@ -2,7 +2,7 @@ |
|
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp :results none |
|
|
|
|
(with-temp-buffer |
|
|
|
|
(insert-file-contents "input-test") |
|
|
|
|
(insert-file-contents "input") |
|
|
|
|
(advent/replace-multiple-regex-buffer |
|
|
|
|
'(("," . " ") |
|
|
|
|
("^" . "(") |
|
|
|
|
@ -17,7 +17,7 @@ |
|
|
|
|
Find max area |
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
(defun area (el) |
|
|
|
|
(let ((a (car el)) |
|
|
|
|
(let ((a (car el)) |
|
|
|
|
(b (cdr el))) |
|
|
|
|
(abs (* (- (car a) (car b) -1) |
|
|
|
|
(- (cadr a) (cadr b) -1))))) |
|
|
|
|
@ -31,13 +31,14 @@ Find max area |
|
|
|
|
#+end_src |
|
|
|
|
|
|
|
|
|
#+RESULTS: |
|
|
|
|
: 50 |
|
|
|
|
: 4737096935 |
|
|
|
|
|
|
|
|
|
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) |
|
|
|
|
edges (-zip-lists data data-next) |
|
|
|
|
data-pv (-zip-lists data data-prev data-next)) |
|
|
|
|
|
|
|
|
|
(defun normalize (x) |
|
|
|
|
@ -57,160 +58,129 @@ For part 2, we begin by removing the vertices that are not corners. |
|
|
|
|
(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 :results none |
|
|
|
|
;; find the leftmost and topmost coordinate |
|
|
|
|
(setq leftmost (-min (-map #'car data)) |
|
|
|
|
topmost (-min (-map #'cadr data))) |
|
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
(defun incompatible-p (rect corner) |
|
|
|
|
;; 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) |
|
|
|
|
|
|
|
|
|
(setq orientation (-last-item (car (--filter (= (caar it) leftmost) data-corners)))) |
|
|
|
|
|
|
|
|
|
;; We therefore know what corners are convex and what corners are concave |
|
|
|
|
|
|
|
|
|
(defun corner-normal (corner) |
|
|
|
|
(let* ((cor (cdr corner)) |
|
|
|
|
(a (caar cor)) |
|
|
|
|
(d (caddr cor)) |
|
|
|
|
(b (cadar cor)) |
|
|
|
|
(c (cadr cor)) |
|
|
|
|
(det (* orientation (- (* b c) (* a d))))) |
|
|
|
|
(list det (- c a) (- d b)))) |
|
|
|
|
|
|
|
|
|
(setq data-normals (--map (cons (car it) (corner-normal it)) data-corners)) |
|
|
|
|
|
|
|
|
|
(setq rects (symmetric-pairs data)) |
|
|
|
|
|
|
|
|
|
;; first filter those rectangles that are defined by vertices that |
|
|
|
|
;; have the wrong orientation |
|
|
|
|
|
|
|
|
|
(defun compatible-or (u v) |
|
|
|
|
(if (or (= (car u) 0) (= (cadr u) 0)) t |
|
|
|
|
(if (> (car v) 0) (equal u (cdr v)) ;convex corner |
|
|
|
|
(not (equal u (cdr v))) ;concave corner |
|
|
|
|
))) |
|
|
|
|
|
|
|
|
|
(defun good-orientation-p (rect) |
|
|
|
|
(let ((a (assoc (car rect) data-normals)) |
|
|
|
|
(b (assoc (cdr rect) data-normals))) |
|
|
|
|
(and (compatible-or (cornerize (car b) (car a)) (cdr b)) |
|
|
|
|
(compatible-or (cornerize (car a) (car b)) (cdr a))))) |
|
|
|
|
|
|
|
|
|
(setq good-rects (-filter #'good-orientation-p rects)) |
|
|
|
|
|
|
|
|
|
;; then 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 (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 |
|
|
|
|
(px (car p)) |
|
|
|
|
(py (cadr p))) |
|
|
|
|
(and (< minx px) (< px maxx) |
|
|
|
|
(< miny py) (< py maxy)))) |
|
|
|
|
|
|
|
|
|
#+RESULTS: |
|
|
|
|
: 40 |
|
|
|
|
(setq rects-sifted (-remove (lambda (rect) (--any (strictly-contains-p rect it) data)) good-rects)) |
|
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
(car rects) |
|
|
|
|
(--filter (incompatible-p (cadr rects-sifted) it) data-corners) |
|
|
|
|
(length rects-sifted) |
|
|
|
|
#+end_src |
|
|
|
|
|
|
|
|
|
(cadr rects-sifted) |
|
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp :results none |
|
|
|
|
(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)) |
|
|
|
|
(convexity (cadr corner)) |
|
|
|
|
(normal (cddr corner))) |
|
|
|
|
|
|
|
|
|
(or (and (= px minx) (< miny py) (< py maxy) (< (advent/dot normal (list convexity 0)) 0)) ; on left edge |
|
|
|
|
(and (= px maxx) (< miny py) (< py maxy) (> (advent/dot normal (list convexity 0)) 0)) |
|
|
|
|
(and (= py miny) (< minx px) (< px maxx) (< (advent/dot normal (list 0 convexity)) 0)) |
|
|
|
|
(and (= py maxy) (< minx px) (< px maxx) (> (advent/dot normal (list 0 convexity)) 0))))) |
|
|
|
|
|
|
|
|
|
(setq rects-refined (-remove (lambda (rect) (--any (incompatible-p rect it) data-normals)) 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 | |
|
|
|
|
Now we should have eliminated all corner cases; we just need to remove |
|
|
|
|
those that are cut by an edge |
|
|
|
|
|
|
|
|
|
#+begin_src emacs-lisp |
|
|
|
|
rects-sifted |
|
|
|
|
#+end_src |
|
|
|
|
(length rects) |
|
|
|
|
(length good-rects) |
|
|
|
|
(length rects-sifted) |
|
|
|
|
(length rects-refined) |
|
|
|
|
|
|
|
|
|
#+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 | |
|
|
|
|
(defun cuts-p (rect edge) |
|
|
|
|
(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))) |
|
|
|
|
(eminx (min (caar edge) (caadr edge))) |
|
|
|
|
(emaxx (max (caar edge) (caadr edge))) |
|
|
|
|
(eminy (min (cadar edge) (cadadr edge))) |
|
|
|
|
(emaxy (max (cadar edge) (cadadr edge))) |
|
|
|
|
(ver (= eminx emaxx))) |
|
|
|
|
(if ver (and (< minx eminx) (< eminx maxx) (< eminy miny) (< maxy emaxy)) |
|
|
|
|
(and (< miny eminy) (< eminy maxy) (< eminx minx) (< maxx emaxx)))) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
(setq rects-uncut (-remove (lambda (rect) (--any (cuts-p rect it) edges)) rects-refined)) |
|
|
|
|
(length rects-uncut) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(-max (-map #'area rects-uncut)) |
|
|
|
|
|
|
|
|
|
#+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 | |
|
|
|
|
: 1644057540 |
|
|
|
|
|
|
|
|
|
| (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 | |
|
|
|
|
|