Skip to content

Instantly share code, notes, and snippets.

@Alwinfy
Last active December 3, 2024 06:53
Show Gist options
  • Save Alwinfy/26266703c1018921ea30e009965134ea to your computer and use it in GitHub Desktop.
Save Alwinfy/26266703c1018921ea30e009965134ea to your computer and use it in GitHub Desktop.
yet another parser problem
(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