Skip to content

Instantly share code, notes, and snippets.

@pavloo
Created December 18, 2017 19:29
Show Gist options
  • Save pavloo/24effddfdd561150a169d6793509cb5a to your computer and use it in GitHub Desktop.
Save pavloo/24effddfdd561150a169d6793509cb5a to your computer and use it in GitHub Desktop.
(defstruct statement instruction condition)
(defstruct instruction reg value op)
(defstruct condition reg value con)
;; 1. Parse each line as Instruction
;; 2. Create Memory hash table with regs name - value (default of each reg is 0) +
;; 3. Execute each Instruction populating Memory +
;; 4. The largest reg value in Memory +
;; Part 2
;; 5. Add eval-after-statement hook for eval-statement
(require 'subr-x)
(defun find-max-reg-value (memory)
(let ((keys (hash-table-keys memory)) val (max (nth 0 (hash-table-values memory))))
(dolist (key keys)
(setq val (gethash key memory))
(when (> val max) (setq max val))
)
max
)
)
(defun parse-instruction (str)
(let (list op op-str)
(setq list (split-string str " " t))
(setq op-str (nth 1 list))
(setq op
(cond
((string= op-str "inc") '+)
((string= op-str "dec") '-)
)
)
(make-instruction
:reg (nth 0 list)
:value (string-to-number (nth 2 list))
:op op
)
)
)
(defun ne (a b)
(not (= a b))
)
(defun parse-condition (str)
(let (list con con-str)
(setq list (split-string str " " t))
(setq con-str (nth 1 list))
(setq con
(cond
((string= con-str ">") '>)
((string= con-str "<") '<)
((string= con-str ">=") '>=)
((string= con-str "<=") '<=)
((string= con-str "==") '=)
((string= con-str "!=") 'ne)
)
)
(make-condition
:reg (nth 0 list)
:value (string-to-number (nth 2 list))
:con con
)
)
)
(defun parse-statement (str)
(let (instr-list)
(setq instr-list (mapcar 'string-trim (split-string str "if" t)))
(make-statement
:instruction (parse-instruction (print (nth 0 instr-list)))
:condition (parse-condition (print (nth 1 instr-list)))
)
)
)
(defun parse-statements (file-path)
(with-temp-buffer
(insert-file-contents file-path)
(mapcar 'parse-statement (split-string (buffer-string) "\n" t))
)
)
(parse-statements "./default_input.txt")
;; example of pseudo-ast
(setq statements
(list
(make-statement
:instruction
(make-instruction :reg "a" :value 10 :op '+)
:condition
(make-condition :reg "a" :value 0 :con '=)
)
(make-statement
:instruction
(make-instruction :reg "b" :value 11 :op '+)
:condition
(make-condition :reg "a" :value 5 :con '>)
)
)
)
(defun eval-condition (condition memory)
(let ((reg-val (gethash (condition-reg condition) memory)))
(when (equal reg-val nil) (setq reg-val 0))
(apply (condition-con condition) (list reg-val (condition-value condition)))
)
)
(defun eval-instruction (instruction memory)
(let* ((reg (instruction-reg instruction)) (reg-val (gethash reg memory)) res)
(when (equal reg-val nil) (setq reg-val 0))
(setq res (apply (instruction-op instruction) (list reg-val (instruction-value instruction))))
(puthash reg res memory)
memory
)
)
(defun eval-statements (statements after-each-eval)
(let ((memory (make-hash-table :test 'equal)))
(dolist (stat statements)
(when (eval-condition (statement-condition stat) memory)
(eval-instruction (statement-instruction stat) memory)
)
(when after-each-eval (apply after-each-eval (list memory)))
)
memory
)
)
;; Part 1
(find-max-reg-value (eval-statements (parse-statements "./default_input.txt") nil)) ;; 1
(find-max-reg-value (eval-statements (parse-statements "./input.txt") nil))
(defun max-reg-value-ever ()
(let ((max-reg-val 0))
(find-max-reg-value
(eval-statements
(parse-statements "./input.txt")
(lambda (memory)
(let (val)
(setq val (find-max-reg-value memory))
(when (< max-reg-val val) (setq max-reg-val val))
)
)
)
)
max-reg-val
)
)
;; Part 2
(max-reg-value-ever)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment