(require '[clojure.string:as str]) 
(def the_base 16)


(def digits (rest (range the_base)))


(def primes [])


(for [n digits] (if (= 1 (count (filter (fn[m] (and (< m n) (= 0 (mod n m)))) digits)) ) (def primes (conj primes n))))


(defn duplicity [n p partial] (if (= 0 (mod n p)) (duplicity (/ n p) p (conj partial p)) partial))


(defn factorize [n] (let [a (flatten (for [p (filter #(< % n) primes)] 
  (remove #(= 1 %) (duplicity n p [1]))))] (if (= 0 (count a)) (lazy-seq [n]) a) ))


(defn multiplicity [s n] (count (filter #(= n %) s)))





(defn combine [x y] (concat x (flatten (for [w (dedupe y)] (repeat (- (multiplicity y w) (multiplicity x w)) w) ))))


(defn lcm [s] (reduce * (reduce combine (map factorize s))))


(defn exp [x n] (reduce * (repeat n x)))


(defn non_empty_subsets [s] (for [x (reverse (rest (range (exp 2 (count s)))))] 
  (remove nil? (for [i (range (count s))] (if (bit-test x i) (nth s i))))))





(defn power_up [s] (reduce + (loop [idx (- (count s) 1) s_next s] 
  (if (zero? idx) s_next (recur (dec idx) (map-indexed #(if (< %1 idx) (* %2 the_base) %2) s_next))))))










(defn max_for_digits [s] (power_up (sort #(> %1 %2) s)))


(defn min_for_digits [s] (power_up (sort #(< %1 %2) s)))


(defn log_base [x] (/ (Math/log x) (Math/log the_base)))


(defn remove_zeros [s] (remove #(= % 0) s))


(defn first_multiple_not_after [n ub] (loop [m ub] (if (= 0 (mod m n)) m (recur (dec m)))))


(defn representation [n] (let [full_power (int (log_base n))] 
  (loop [power full_power place (exp the_base full_power) rep [] rem n ] (if (= power -1) rep 
    (recur (dec power) (/ place the_base) (conj rep (int (/ rem place))) (- rem (* place (int (/ rem place)))))))))


(defn digit_qualifies [m s] (let [rep_m (representation m)] (= (sort s) (sort rep_m))))



(defn find_s_largest_lb [s] (let [lb (min_for_digits s)] (let [m (lcm s)] 
  (loop [v (first_multiple_not_after m (max_for_digits s))] (if (< v lb) [] 
    (if (digit_qualifies v s) (representation v) (recur (- v m)))))))) 



(defn find_largest_lb [] (let [subsets (non_empty_subsets (reverse digits))] 
  (loop [s_size (- the_base 1)] (let [hits (remove #(= (count %) 0) (map find_s_largest_lb (filter #(= (count %) s_size) subsets)))] 
    (if (pos? (count hits)) (first (sort #(first (remove_zeros (map - %2 %1))) hits)) (recur (dec s_size)))))))



(defn hex_digit [v] (case v 15 "F" 14 "E" 13 "D" 12 "C" 11 "B" 10 "A" (str v)))

(find_largest_lb)