[p9] Study and various failed attempts

master
Jacopo De Simoi 3 months ago
parent f225c51d96
commit e67c57ef4d
  1. 234
      p9/p9.org

@ -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 |

Loading…
Cancel
Save