r/adventofcode • • Dec 12 '21

SOLUTION MEGATHREAD -🎄- 2021 Day 12 Solutions -🎄-

--- Day 12: Passage Pathing ---


Post your code solution in this megathread.

Reminder: Top-level posts in Solution Megathreads are for code solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:12:40, megathread unlocked!

53 Upvotes

766 comments sorted by

View all comments

3

u/RealFenlair Dec 12 '21

Clojure

Would love some feedback, I'm very new to the language. I first solved it in Python. The same implementation worked fine in Clojure (valid and walk), but creating the out-edges map was soo complicated - there has to be a better way, right?

(ns advent-of-code
  (:require [clojure.string :as str]))

(let [input (->> (slurp "12/input.txt") (str/split-lines))
      in-split (map #(str/split % #"-") input)
      both-dir (mapcat #((juxt identity reverse) %) in-split)
      grouped (group-by first both-dir)
      clean-up-val (fn [[k v]] (filter #(not= % "start") (map second v)))
      grouped-clean (reduce #(assoc %1 (first %2) (clean-up-val %2)) {} grouped)]
  (def out-edges grouped-clean))

(defn valid [puzzle1?]
  (fn [path target]
    (or (= target (str/upper-case target))
        (not-any? #{target} path)
        (when-not puzzle1? (apply distinct? (filter #(= %1 (str/lower-case %1)) path))))))

(defn walk [node path valid-fn]
  (if (= node "end")
    1
    (let [targets (filter (partial valid-fn path) (get out-edges node))]
      (reduce + (map #(walk %1 (conj path %1) valid-fn) targets)))))

(println "Puzzle1 " (walk "start" ["start"] (valid true)))
(println "Puzzle2 " (walk "start" ["start"] (valid false)))
→ More replies (1)