Skip to content

Instantly share code, notes, and snippets.

@alexander-yakushev
Created December 12, 2023 19:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexander-yakushev/7f40fbafa4fa29b93706ca823be4250a to your computer and use it in GitHub Desktop.
Save alexander-yakushev/7f40fbafa4fa29b93706ca823be4250a to your computer and use it in GitHub Desktop.
Advent of Code 2023, day 12
(ns day12
(:require [clojure.string :as str]
[clojure.java.io :as io]))
(def lines (line-seq (io/reader "2023/day12.txt")))
(defn parse [task]
(for [line lines]
(let [[field hints] (str/split line #" ")]
(case task
1 [(str "." field ".") (map parse-long (str/split hints #","))]
2 [(str "." (str/join "?" (repeat 5 field)) ".")
(into [] cat (repeat 5 (map parse-long (str/split hints #","))))]))))
(defn variants [[^String field, hints]]
(let [cache (volatile! {})]
(letfn [(f [i j start c]
(let [key (+ (* 10000 i) j)]
(or (and (nil? c) (nil? start) (@cache key))
(let [c (or c (when (< i (.length field))
(.charAt field i)))]
(case c
nil (if (= j (count hints)) 1 0)
\. (if start
(let [len (- i start)]
(if (= len (nth hints j nil))
(recur (inc i) (inc j) nil nil)
0))
(recur (inc i) j nil nil))
\# (recur (inc i) j (or start i) nil)
\? (let [res (+ (f i j start \.)
(f i j start \#))]
(when (nil? start)
(vswap! cache assoc key res))
res))))))]
(f 0 0 nil nil))))
(defn solve [task]
(time (reduce + (map variants (parse task)))))
#_(solve 1)
#_(solve 2)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment