Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (ns testhere.core
- (:use [clojure.core.match :only [match]]))
- (defn div [a b]
- (if (>= (* a b) 0)
- (/ a b)
- (+ (/ a b) 1)))
- (defn gcd [a b]
- (loop [a a, b b, x 0, y 1, lx 1, ly 0]
- (if (zero? b)
- [a lx ly]
- (let [q (div a b)]
- (recur b (rem a b)
- (- lx (* q x))
- (- ly (* q y))
- x y)))))
- (defn diof-solve [a b c]
- (letfn [(divs-by-a? [x] (zero? (rem x a)))
- (divs-by-b? [x] (zero? (rem x b)))]
- (match [a b c ]
- [0 0 0 ] [true 0 0 0]
- [0 0 _ ] [false 0 0 0]
- [0 _ (c :when divs-by-b?)] [true 0 (/ c b) 0]
- [0 _ _ ] [false 0 0 0]
- [_ 0 (c :when divs-by-a?)] [true (/ c a) 0 0]
- [_ 0 _ ] [false 0 0 0]
- [_ _ _ ] (let [[divisor x y] (gcd a b)]
- (if (zero? (rem c divisor))
- [true
- (/ (* x c) divisor)
- (/ (* y c) divisor)
- divisor]
- [false 0 0 0])))))
- (defn solve-task [rx ry a b]
- (let [[solvable da db dc] (diof-solve a b (- ry rx))
- solve (fn []
- (let [min-infinity Integer/MIN_VALUE
- infinity Integer/MAX_VALUE
- same-sign? (fn [x y] (> (* x y) 0))
- diff-sign? (complement same-sign?)
- kl (if (not (zero? (rem (* da dc) b)))
- (inc (/ (* (- da) dc)
- b))
- (/ (* (- da) dc)
- b))
- kh (if (not (zero? (rem (* db dc) a)))
- (inc (/ (* db dc)
- a))
- (/ (* db dc)
- a))
- kkl (max (if (same-sign? b dc) kl min-infinity)
- (if (same-sign? a dc) kh min-infinity))
- kkh (min (if (diff-sign? b dc) kl infinity)
- (if (diff-sign? a dc) kh infinity))]
- (cond
- (= kkl min-infinity) (+ da (/ (* kkh b) dc)
- (- db) (/ (* kkh a) dc))
- (= kkh infinity) (+ da (/ (* kkl b) dc)
- (- db) (/ (* kkl a) dc))
- :else (min
- (+ da (/ (* kkh b) dc)
- (- db) (/ (* kkh a) dc))
- (+ da (/ (* kkl b) dc)
- (- db) (/ (* kkl a) dc))))))]
- (max -1 (cond (not solvable) -1
- (= a 0) (- db)
- (= b 0) da
- :else (solve)))))
Advertisement
Add Comment
Please, Sign In to add comment