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.

5.9 KiB

Solution to p9

  (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))

Find max area

  (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)))
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)

  (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))

OK, the datapoints are all corners. Now I know. Find which way is inside

      ;; 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))
  (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))
40
  (car rects)
  (--filter (incompatible-p (cadr rects-sifted) it) data-corners)

  (cadr rects-sifted)
(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
  rects-sifted
(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
  final-rects
(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