Last active
December 3, 2024 06:53
-
-
Save Alwinfy/26266703c1018921ea30e009965134ea to your computer and use it in GitHub Desktop.
yet another parser problem
This file contains hidden or 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
(set! *warn-on-reflection* true) | |
(defn chp [okay?] | |
(fn [munch] | |
(when-let [[h & more] munch] | |
(and (okay? h) [h more])))) | |
(defn seqp [& parsers] | |
(fn [munch] | |
(loop [parsers parsers munch munch acc []] | |
(if-let [[parser & parsers] parsers] | |
(when-let [[body more] (parser munch)] | |
(recur parsers more (conj acc body))) | |
[acc munch])))) | |
(defn literalp [content] | |
(apply seqp (map (comp chp set list) content))) | |
(defn fmap [f parser] | |
(fn [munch] | |
(if-let [[val more] (parser munch)] | |
[(f val) more]))) | |
(defn par [& parsers] | |
(fn [munch] | |
(loop [parsers parsers] | |
(when-let [[h & more] parsers] | |
(or (h munch) (recur more)))))) | |
(defn manyp [parser] | |
(fn [munch] | |
(loop [acc [] munch munch] | |
(if-let [[body more] (parser munch)] | |
(recur (conj acc body) more) | |
[acc munch])))) | |
(defn inching [parser munch] | |
(loop [munch munch acc []] | |
(if-let [[body more] (parser munch)] | |
(recur more (conj acc body)) | |
(if-let [[_ & t] munch] | |
(recur t acc) | |
acc)))) | |
(def intp | |
(fmap (comp parse-long (partial apply str)) | |
(manyp (chp #(<= (int \0) (int %) (int \9)))))) | |
(def mul | |
(fmap | |
(fn [[_ a _ b _]] [:mul a b]) | |
(seqp | |
(literalp "mul(") | |
intp | |
(literalp ",") | |
intp | |
(literalp ")")))) | |
(def scavenge | |
(par | |
mul | |
(fmap (constantly [:do]) (literalp "do()")) | |
(fmap (constantly [:dont]) (literalp "don't()")))) | |
(def target | |
(with-open [fh (java.io.FileReader. "day3.in")] | |
(slurp fh))) | |
(def insns (inching scavenge target)) | |
(def interp1 (fn [acc [act & args]] | |
(if (= :mul act) | |
(+ acc (apply * args)) | |
acc))) | |
(def interp2 (fn [[acc active] [act & args]] | |
(case act | |
:mul [(+ acc (apply * active args)) active] | |
:do [acc 1] | |
:dont [acc 0]))) | |
(println (reduce interp1 0 insns)) | |
(println (first (reduce interp2 [0 1] insns))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment