Skip to content

Instantly share code, notes, and snippets.

@jngbng
Last active September 25, 2021 15: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 jngbng/ef338e03fdc68d6e9bbfce969f0393c2 to your computer and use it in GitHub Desktop.
Save jngbng/ef338e03fdc68d6e9bbfce969f0393c2 to your computer and use it in GitHub Desktop.
logic programming 1 (feat. 문제적 남자)
(ns core-logic.core
(:require [clojure.core.logic :as logic]
[clojure.core.logic.fd :as fd]))
;;; 현명한 딸 셋을 두 상인이 사과 90개를 가져와
;;; 첫째에게 50개, 둘째에게 30개, 셋째에게 10개를 주며
;;; 그것을 팔아오되 첫째가 만약 10개를 1원에 팔면
;;; 둘째, 셋째도 똑같이 10개를 1원에 팔아야 한다는 조건을 걸었다.
;;; 하지만 팔아서 번 돈은 셋이 모두 같아야 한다.
;;; 어떻게 해야 조건대로 팔 수 있을까?
;;; 11개당 1원이라는 조건은 막내가 팔 수 없으므로 허용되지 않는다.
;;; 공짜는 안된다.
;;; 내부 거래는 안된다.
(defn solution-2 []
;; 모든 결과를 찾는다.
(logic/run* [q]
;; 방정식에 등장하는 변수들을 선언한다.
(logic/fresh [a Pa ; a개당 Pa원
b Pb ; b개당 Pb원
c1a c1b ; 첫째는 a세트를 c1a개, b세트를 c1b개 판매
c2a c2b
c3a c3b]
;; 0 < b < a < 10
(fd/in a b (fd/interval 1 9))
(fd/< b a)
;; 가격 범위는 적당히 설정
(fd/in Pa Pb (fd/interval 1 20))
;; 가격은 서로 다르다. 문제 조건에는 없지만 추가해봄.
(fd/distinct [Pa Pb])
;; 수식을 고려하여 가능한 범위 설정
(fd/in c1a c1b (fd/interval 1 50))
(fd/in c2a c2b (fd/interval 1 30))
(fd/in c3a c3b (fd/interval 1 10))
(fd/eq
;; 수량 조건
(= 50 (+ (* c1a a) (* c1b b)))
(= 30 (+ (* c2a a) (* c2b b)))
(= 10 (+ (* c3a a) (* c3b b)))
;; 가격 조건
(= (+ (* c1a Pa) (* c1b Pb))
(+ (* c2a Pa) (* c2b Pb)))
(= (+ (* c2a Pa) (* c2b Pb))
(+ (* c3a Pa) (* c3b Pb))))
(logic/== q {:price [{:qty a :price Pa}
{:qty b :price Pb}]
:sales [{:a c1a :b c1b}
{:a c2a :b c2b}
{:a c3a :b c3b}]}))))
;;;
;;; Result
;;;
({:price [{:qty 3, :price 1} {:qty 1, :price 7}],
:sales [{:a 15, :b 5} {:a 8, :b 6} {:a 1, :b 7}]}
{:price [{:qty 3, :price 1} {:qty 1, :price 7}],
:sales [{:a 16, :b 2} {:a 9, :b 3} {:a 2, :b 4}]}
{:price [{:qty 2, :price 2} {:qty 1, :price 11}],
:sales [{:a 23, :b 4} {:a 12, :b 6} {:a 1, :b 8}]}
{:price [{:qty 2, :price 2} {:qty 1, :price 11}],
:sales [{:a 24, :b 2} {:a 13, :b 4} {:a 2, :b 6}]}
{:price [{:qty 3, :price 2} {:qty 1, :price 14}],
:sales [{:a 15, :b 5} {:a 8, :b 6} {:a 1, :b 7}]}
{:price [{:qty 3, :price 2} {:qty 1, :price 14}],
:sales [{:a 16, :b 2} {:a 9, :b 3} {:a 2, :b 4}]}
{:price [{:qty 7, :price 1} {:qty 1, :price 3}],
:sales [{:a 7, :b 1} {:a 4, :b 2} {:a 1, :b 3}]}
{:price [{:qty 7, :price 2} {:qty 1, :price 6}],
:sales [{:a 7, :b 1} {:a 4, :b 2} {:a 1, :b 3}]}
{:price [{:qty 7, :price 3} {:qty 1, :price 9}],
:sales [{:a 7, :b 1} {:a 4, :b 2} {:a 1, :b 3}]}
{:price [{:qty 7, :price 4} {:qty 1, :price 12}],
:sales [{:a 7, :b 1} {:a 4, :b 2} {:a 1, :b 3}]}
{:price [{:qty 7, :price 5} {:qty 1, :price 15}],
:sales [{:a 7, :b 1} {:a 4, :b 2} {:a 1, :b 3}]}
{:price [{:qty 7, :price 6} {:qty 1, :price 18}],
:sales [{:a 7, :b 1} {:a 4, :b 2} {:a 1, :b 3}]})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment