Skip to content

Instantly share code, notes, and snippets.

@sbenhaim
Created December 20, 2015 04:01
Show Gist options
  • Save sbenhaim/a3ab19fb9d8883bdeff1 to your computer and use it in GitHub Desktop.
Save sbenhaim/a3ab19fb9d8883bdeff1 to your computer and use it in GitHub Desktop.
(ns advent.a15
(:require
[clojure.string :as str]
[clojure.core.logic :as l :refer [run run* fresh]]
[clojure.core.logic.fd :as fd]))
(def text "Sugar: capacity 3, durability 0, flavor 0, texture -3, calories 2
Sprinkles: capacity -3, durability 3, flavOr 0, texture 0, calories 9
Candy: capacity -1, durability 0, flavor 4, texture 0, calories 1
Chocolate: capacity 0, durability 0, flavor -2, texture 2, calories 8")
(def test "Butterscotch: capacity -1, durability -2, flavor 6, texture 3, calories 8
Cinnamon: capacity 2, durability 3, flavor -2, texture -1, calories 3")
(defn parse-int [i]
(Integer/parseInt i))
(defn parse [l]
(let [ns (re-seq #"-?\d+" l)]
(map parse-int ns)))
(defn rules [text]
(map parse (str/split-lines text)))
(defn transpose [vss]
(for [i (range (count (first vss)))]
(for [vs vss]
(nth vs i))))
(defn attrs [mults rules]
(for [cat (transpose rules)]
(map #(* %1 %2) mults cat)))
(defn score [mults rules]
(let [attrs (attrs mults rules)
vals (map (partial reduce +) attrs)]
(if (some neg? vals) 0
(reduce * vals))))
(defn mults [n [w x y z]]
(run* [q]
(fresh [a b c d]
(fd/in a b c d (fd/interval 0 n))
(fd/eq (= (+ a b c d) n)
(= (+ (* a w) (* b x) (* c y) (* d z)) 500))
(l/== q [a b c d]))))
(let [rules (rules text)
vals (map butlast rules)
cals (map last rules)
mults (mults 100 cals)
scores (for [m mults] (score m vals))]
(apply max scores))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment