Fork me on GitHub
#core-logic
<
2019-12-25
>
erwinrooijakkers00:12:45

I am trying to solve Advent of Code day 14 using core.logic

erwinrooijakkers00:12:26

Day 14 is about “Stoichemetry” and minimizing reactants. It has constraints like this:

``````10 ORE => 10 A
1 ORE => 1 B
7 A, 1 B => 1 C
7 A, 1 C => 1 D
7 A, 1 D => 1 E
7 A, 1 E => 1 FUEL``````

erwinrooijakkers00:12:44

This means 1 FUEL can be made of 7A and 1E

erwinrooijakkers00:12:57

The goal is to find how much ORE is needed for 1 FUEL

erwinrooijakkers00:12:07

Any pointers on how to do this?

erwinrooijakkers00:12:52

What type of features can I use?

erwinrooijakkers00:12:17

Any examples that solve a similar problem?

erwinrooijakkers00:12:21

I have the input now as a hash map from output to inputs:

``````{[1 "D"] ([7 "A"] [1 "C"]),
[1 "FUEL"] ([7 "A"] [1 "E"]),
[10 "A"] ([10 "ORE"]),
[1 "C"] ([7 "A"] [1 "B"]),
[1 "B"] ([1 "ORE"]),
[1 "E"] ([7 "A"] [1 "D"])}``````

erwinrooijakkers00:12:01

Hope someone can give me some pointers! Merry Christmas

hiredman02:12:59

I think key is representation, you'll want to use a map of thing to count of thing instead of those pairs of thing and count

hiredman02:12:18

And write a relation, call it reduco that takes an input map and an output map, and it has a bunch of conde clauses that do things like constrain the fuel count of output to be one less them the input, and the count of a to be 7 more, and the count of e to be 1 one, using the fd namespace

hiredman02:12:34

so something like

``````(require '[clojure.core.logic :as l]
'[clojure.core.logic.fd :as fd])

(defn reduco [input output]
(l/conde
[(fd/> (get input "FUEL") 0)
(fd/- (get input "FUEL") 1 (get output "FUEL"))
(fd/+ (get input "A") 7 (get output "A"))
(fd/+ (get input "E") 1 (get output "E"))
;;
(l/== (get input "ORE") (get output "ORE"))
(l/== (get input "B") (get output "B"))
(l/== (get input "C") (get output "C"))
(l/== (get input "D") (get output "D"))
]))

(l/run 1 [output]
(l/fresh [ore a b c d e fuel]
(l/== output {"FUEL" fuel
"ORE" ore
"A" a
"B" b
"C" c
"D" d
"E" e})
(reduco {"FUEL" 1
"ORE" 0
"A" 0
"B" 0
"C" 0
"D" 0
"E" 0}
{"FUEL" fuel
"ORE" ore
"A" a
"B" b
"C" c
"D" d
"E" e})))``````
but with reduco fleshed out with the rest of the reduction rules and then with some driving goal that recursively calls reduco until you get back a map with nothing but ore in it

hiredman02:12:08

the tricky thing with mixing maps and core.logic is map stuff will be non-relational, so just watch out for it

erwinrooijakkers12:12:13

Why doesn’t this find negative values?

``````(defn sqrts [n]
(l/run 2 [x]
(fd/in x (fd/interval (- n) n))
(fd/* x x n)))

(sqrts 4)
;; => (2)

(sqrts 25)
;; => (5)``````