#+title: Solution to p8 #+begin_src emacs-lisp :results none (with-temp-buffer (insert-file-contents "input") (advent/replace-multiple-regex-buffer '(("," . " ") ("^" . "(") ("$" . ")"))) (goto-char (point-min)) (insert "(setq data '(") (goto-char (point-max)) (insert "))") (eval-buffer)) #+end_src First of all, sort the pair of boxes by means of their distance. #+begin_src emacs-lisp :results none (defun square (x) (* x x)) (defun distance-squared (el) (let ((a (car el)) (b (cdr el))) (+ (square (- (car a) (car b))) (square (- (cadr a) (cadr b))) (square (- (caddr a) (caddr b)))))) (defun symmetric-pairs (list) (apply #'append (--map-indexed (-map (lambda (other) (cons it other)) (-drop (1+ it-index) list)) list))) (setq sorted-pairs (--sort (< (distance-squared it) (distance-squared other)) (symmetric-pairs data))) #+end_src This is for part 1 #+begin_src emacs-lisp (defun insert-pair (circuits el) (let* ((list (list (car el) (cdr el))) (ind-a (--find-index (-contains-p it (car el)) circuits)) (ind-b (--find-index (-contains-p it (cdr el)) circuits))) (cond ((not (or ind-a ind-b)) (cons list circuits)) ((and ind-a ind-b (not (eq ind-a ind-b))) (-remove-at ind-b (-replace-at ind-a (-union (nth ind-a circuits) (nth ind-b circuits)) circuits))) (t (-replace-at (or ind-a ind-b) (-union list (nth (or ind-a ind-b) circuits)) circuits))))) (setq circuits (-reduce-from #'insert-pair nil (-take 1000 sorted-pairs))) (-product (-take 3 (-sort '> (-map #'length circuits)))) #+end_src #+RESULTS: : 81536 This is for part 2. Will it explode? #+begin_src emacs-lisp (let ((sorted-pairs sorted-pairs) (circuits nil) (last-junction nil)) (while (or (> 1 (length circuits)) (> (length data) (length (apply 'append circuits)))) (setq last-junction (pop sorted-pairs) circuits (insert-pair circuits last-junction))) last-junction ;(* (caar last-junction) (cadr last-junction)) ) #+end_src #+RESULTS: | (84981 85692 23226) | 91121 | 84159 | 34357 |