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.
140 lines
2.9 KiB
140 lines
2.9 KiB
#+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
|
|
|