Capping values in a map while keeping one fixed I'm working with some Clojurescript code that reacts to user input over three sliders. These sliders get stored in a map, and I need to make sure that the sum of all is &lt;= a max value. Every time a value from the map is modified I have the guarantee that it will be in the [0, max] range, and I must reduce if necessary the others so that the total sum is still &lt;= max.

I implemented it, but as I don't have a lot of experience with Clojure and Clojurescript I'm sure it can be improved. I would like to listen to any comment about making it shorter, more concise, more idiomatic, easier to read, etc. Thanks!

PS: I know that the names of the functions don't make much sense, I'm still in mid development and changing things all the time. alloc stands for allocation.

(def MaxAlloc 100)

(defn verify-alloc
  [alloc fixed-id]
  (let [total (reduce + 0 (vals alloc))]
    (if (&lt;= total MaxAlloc)
      alloc
      (let [others (dissoc alloc fixed-id)]
        (assoc
          (de-alloc (dissoc alloc fixed-id) (- total MaxAlloc))
          fixed-id (get alloc fixed-id)) ) ) ) )


verify-alloc checks if there is an excess, and if so removes the fixed element from the map and calls de-alloc to remove the excess.

(defn de-alloc
  [alloc excess]
  (let [pair (first alloc)
        k (first pair)
        v (second pair)]
    (if (&gt; v excess)
      (assoc alloc k (- v excess))
      (assoc (de-alloc (dissoc alloc k) (- excess v)) k 0) ) ) )


de-alloc works by removing as much excess as it can from the first value in the map, and if there is still some excess value, calls itself recursively removing the 'zeroed' element from the map.

And it would be used like this:

(verify-alloc {:a 0 :b 30 :c 40} :c)
{:a 0, :b 30, :c 40}

(verify-alloc {:a 10 :b 40 :c 70} :a)
{:a 10, :b 20, :c 70}

(verify-alloc {:a 90 :b 40 :c 70} :b)
{:b 40, :a 0, :c 60}


I would also like to change the algorithm so that instead of completely decreasing elements one after the other, it would distribute this decrease in equal parts among the remaining elements. But I could not find my way around it. Ideas?
Your verify-alloc function is badly named: it doesn't verify, it normalises. 

A normalisation function that preserves the proportions of the other values and limits the sum to MaxAlloc is 

(defn normalise [m k]
  (let [remains (dissoc m k)
        allowance (- MaxAlloc (m k))
        weight (-&gt;&gt; remains
                    vals
                    (apply +))
        factor (/ allowance weight)]
    (if (&lt;= weight allowance)
      m
      (merge m (zipmap (keys remains) (map #(* factor %) (vals remains)))))))


This is written to be concise, not to be fast. 

If there'd nothing to be done, everything is hunky-dory:

(normalise {:a 0 :b 30 :c 40} :c)
;{:a 0, :b 30, :c 40}


But if the values need scaling, we can run into problems with arithmetic: 

(normalise {:a 90 :b 40 :c 70} :b)
;{:a 135/4, :b 40, :c 105/4}


If you want these as integers, you may have to forego some precision. How you do this is up to you.