Created
December 18, 2017 19:29
-
-
Save pavloo/24effddfdd561150a169d6793509cb5a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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