about summary refs log tree commit diff
path: root/day18.clj
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2020-12-20 14:10:36 +0100
committerLeah Neukirchen <leah@vuxu.org>2020-12-20 14:10:36 +0100
commit7d40e89b5f28a859cd082a8d6af1ab46b02bd610 (patch)
tree9977fd55a23906ade709e673cbb12171bc247473 /day18.clj
parente40c307a686af0476d2dd8ceca29117bf5181b5c (diff)
downloadadventofcode2020-7d40e89b5f28a859cd082a8d6af1ab46b02bd610.tar.gz
adventofcode2020-7d40e89b5f28a859cd082a8d6af1ab46b02bd610.tar.xz
adventofcode2020-7d40e89b5f28a859cd082a8d6af1ab46b02bd610.zip
day18
Diffstat (limited to 'day18.clj')
-rw-r--r--day18.clj57
1 files changed, 57 insertions, 0 deletions
diff --git a/day18.clj b/day18.clj
new file mode 100644
index 0000000..450969a
--- /dev/null
+++ b/day18.clj
@@ -0,0 +1,57 @@
+(ns day18
+  (:require [instaparse.core :as insta])
+  (:require [clojure.core.match :refer [match]]))
+
+(def WS
+  (insta/parser "WS = #'\\s+'"))
+
+(def transform-options
+  {:IntLiteral read-string})
+
+(def parser1
+  (insta/parser
+    "AddExpr = AddExpr '+' Paren | AddExpr '*' Paren | Paren
+     Paren = '(' AddExpr ')' | IntLiteral
+     IntLiteral = #'[0-9]+'"
+    :auto-whitespace WS))
+
+(def parser2
+  (insta/parser
+    "MultExpr = MultExpr '*' AddExpr | AddExpr
+     AddExpr = AddExpr '+' Paren | Paren
+     Paren = '(' MultExpr ')' | IntLiteral
+     IntLiteral = #'[0-9]+'"
+    :auto-whitespace WS))
+
+(defn eval-expr [expr]
+  (match expr
+         [:MultExpr e1 "*" e2] (* (eval-expr e1) (eval-expr e2))
+         [:AddExpr e1 "+" e2] (+ (eval-expr e1) (eval-expr e2))
+         [:AddExpr e1 "*" e2] (* (eval-expr e1) (eval-expr e2))
+         [:MultExpr e1] (eval-expr e1)
+         [:AddExpr e1] (eval-expr e1)
+         [:Paren e1] (eval-expr e1)
+         [:Paren "(" e1 ")"] (eval-expr e1)
+         :else expr))
+
+(defn eval1 [input]
+  (->> (parser1 input)
+       (insta/transform transform-options)
+       eval-expr))
+
+(->> (slurp "day18")
+     clojure.string/split-lines
+     (map eval1)
+     (apply +))
+;; => 3159145843816
+
+(defn eval2 [input]
+  (->> (parser2 input)
+       (insta/transform transform-options)
+       eval-expr))
+
+(->> (slurp "day18")
+     clojure.string/split-lines
+     (map eval2)
+     (apply +))
+;; => 55699621957369