#+title: solution to p17 Load program #+begin_src emacs-lisp :results none (require 'dash) (defun replace-regexp-from-top (a b) (goto-char (point-min)) (replace-regexp a b)) (with-temp-buffer (insert-file-contents "input") (replace-regexp-from-top "Register \\(.\\): \\(.*\\)$" "(setq \\1 \\2)") (replace-regexp-from-top "\\(.\\),\\(.\\)" "(\\1 \\2)") (replace-regexp-from-top "," " ") (replace-regexp-from-top "Program: \\(.*\\)$" "(setq program '(\\1))") (eval-buffer)) #+end_src Convert the opcodes into instructions #+begin_src emacs-lisp (let ((opcode-alist '( (0 . adv) (1 . bxl) (2 . bst) (3 . jnz) (4 . bxc) (5 . out) (6 . bdv) (7 . cdv)))) (setq proggo (--map (cons (cdr (assoc (car it) opcode-alist)) (cdr it)) program))) #+end_src #+RESULTS: | bst | 4 | | bxl | 5 | | cdv | 5 | | bxl | 6 | | adv | 3 | | bxc | 1 | | out | 5 | | jnz | 0 | Now define the instructions and run, for part 1 #+begin_src emacs-lisp (defun combo (c) (let ((combo-alist `( (4 . ,A) (5 . ,B) (6 . ,C)))) (if (< c 4) c (cdr (assoc c combo-alist))))) (defun aux-adv (c) (ash A (* -1 (combo c)))) (defun adv (c) (setq A (aux-adv c))) (defun bdv (c) (setq B (aux-adv c))) (defun cdv (c) (setq C (aux-adv c))) (defun bxl (l) (setq B (logxor l B))) (defun bst (c) (setq B (mod (combo c) 8))) (defun out (c) (push (mod (combo c) 8) so)) (defun bxc (l) (setq B (logxor B C)) ) (defun jnz (l) (unless (eq A 0) (setq ip (- (/ l 2) 1)))) (defun exec (pr) (setq so nil ip 0 stack-trace nil) (while (nth ip pr) (push (list A B C ip (nth ip pr)) stack-trace) (eval (nth ip pr)) (setq ip (1+ ip))) (substring (apply #'concat (-map (-partial #'format "%d,") (reverse so))) 0 -1)) (exec proggo) #+end_src #+RESULTS: : 3 now for part 2 we create the initial value 3 bits at a time #+begin_src emacs-lisp (defun prep-reg (data) (apply #'+ (--map-indexed (ash it (* 3 it-index)) data)) ) (defun setup-registers (data) (setq A (prep-reg data) B 0 C 0)) (defun exec (pr data) (let ((so nil) (ip 0) (stack-trace nil)) (setup-registers data) (while (nth ip pr) (eval (nth ip pr)) (setq ip (1+ ip))) (reverse so))) (defun grow-data (data) (--mapcat (-map (lambda (i) (append it (list i))) (-iota 8)) data)) (setq data (-last-item (-iterate #'grow-data '(nil) 4)) target (-flatten program)) (defun good-data (data) (let ((n (- (length (car data)) 2))) (--filter (equal (-take n (exec proggo it)) (-take n target)) (grow-data data)))) (setq aaaa (-last-item (-iterate #'good-data data 15))) (-min (-map 'prep-reg (--filter (equal (exec proggo it) target) aaaa))) #+end_src #+RESULTS: : 105981155568026