function for finding if x is a multiple of y - clojure

Look at the function below. I want to pass a vector of factors and test if any of the elements in the vector is a factor of x. How do I do that?
(defn multiple?
"Takes a seq of factors, and returns true if x is multiple of any factor."
([x & factors] (for [e m] ))
([x factor] (= 0 (rem x factor))))

You could try using some and map:
(defn multiple? [x & factors]
(some zero? (map #(rem x %) factors)))
Also some returns nil if all tests fail, if you need it to actually return false, you could put a true? in there:
(defn multiple? [x & factors]
(true? (some zero? (map #(rem x %) factors))))
Note that some short-circuits and map is lazy, so multiple? stops as soon as a match is found. e.g. the following code tests against the sequence 1,2,3,4,....
=> (apply multiple? 10 (map inc (range)))
true
Obviously this computation can only terminate if multiple? doesn't test against every number in the sequence.

You can solve it only using some.
=> (defn multiple? [x factors]
(some #(zero? (rem x %)) factors))
#'user/multiple?
=> (= true (multiple? 10 [3 4]))
false
=> (= true (multiple? 10 [3 4 5 6]))
true
some will stop at the first factor.

Try this, using explicit tail recursion:
(defn multiple? [x factors]
"if any of the elements in the vector is a factor of x"
(loop [factors factors]
(cond (empty? factors) false
(zero? (rem x (first factors))) true
:else (recur (rest factors)))))
The advantages of the above solution include: it will stop as soon as it finds if any of the elements in the vector is a factor of x, without iterating over the whole vector; it's efficient and runs in constant space thanks to the use of tail recursion; and it returns directly a boolean result, no need to consider the case of returning nil. Use it like this:
(multiple? 10 [3 4])
=> false
(multiple? 10 [3 4 5 6])
=> true
If you want to obviate the need to explicitly pass a vector (for calling the procedure like this: (multiple? 10 3 4 5 6))) then simply add a & to the parameter list, just like it was in the question.

A more Clojurian way is to write a more general-purpose function: instead of answering true/false question it would return all factors of x. And because sequences are lazy it is almost as efficient if you want to find out if it's empty or not.
(defn factors [x & fs]
(for [f fs :when (zero? (rem x f))] f))
(factors 5 2 3 4)
=> ()
(factors 6 2 3 4)
=> (2 3)
then you can answer your original question by simply using empty?:
(empty? (factors 5 2 3 4))
=> true
(empty? (factors 6 2 3 4))
=> false

Related

How to make reduce more readable in Clojure?

A reduce call has its f argument first. Visually speaking, this is often the biggest part of the form.
e.g.
(reduce
(fn [[longest current] x]
(let [tail (last current)
next-seq (if (or (not tail) (> x tail))
(conj current x)
[x])
new-longest (if (> (count next-seq) (count longest))
next-seq
longest)]
[new-longest next-seq]))
[[][]]
col))
The problem is, the val argument (in this case [[][]]) and col argument come afterward, below, and it's a long way for your eyes to travel to match those with the parameters of f.
It would look more readable to me if it were in this order instead:
(reduceb val col
(fn [x y]
...))
Should I implement this macro, or am I approaching this entirely wrong in the first place?
You certainly shouldn't write that macro, since it is easily written as a function instead. I'm not super keen on writing it as a function, either, though; if you really want to pair the reduce with its last two args, you could write:
(-> (fn [x y]
...)
(reduce init coll))
Personally when I need a large function like this, I find that a comma actually serves as a good visual anchor, and makes it easier to tell that two forms are on that last line:
(reduce (fn [x y]
...)
init, coll)
Better still is usually to not write such a large reduce in the first place. Here you're combining at least two steps into one rather large and difficult step, by trying to find all at once the longest decreasing subsequence. Instead, try splitting the collection up into decreasing subsequences, and then take the largest one.
(defn decreasing-subsequences [xs]
(lazy-seq
(cond (empty? xs) []
(not (next xs)) (list xs)
:else (let [[x & [y :as more]] xs
remainder (decreasing-subsequences more)]
(if (> y x)
(cons [x] remainder)
(cons (cons x (first remainder)) (rest remainder)))))))
Then you can replace your reduce with:
(apply max-key count (decreasing-subsequences xs))
Now, the lazy function is not particularly shorter than your reduce, but it is doing one single thing, which means it can be understood more easily; also, it has a name (giving you a hint as to what it's supposed to do), and it can be reused in contexts where you're looking for some other property based on decreasing subsequences, not just the longest. You can even reuse it more often than that, if you replace the > in (> y x) with a function parameter, allowing you to split up into subsequences based on any predicate. Plus, as mentioned it is lazy, so you can use it in situations where a reduce of any sort would be impossible.
Speaking of ease of understanding, as you can see I misunderstood what your function is supposed to do when reading it. I'll leave as an exercise for you the task of converting this to strictly-increasing subsequences, where it looked to me like you were computing decreasing subsequences.
You don't have to use reduce or recursion to get the descending (or ascending) sequences. Here we are returning all the descending sequences in order from longest to shortest:
(def in [3 2 1 0 -1 2 7 6 7 6 5 4 3 2])
(defn descending-sequences [xs]
(->> xs
(partition 2 1)
(map (juxt (fn [[x y]] (> x y)) identity))
(partition-by first)
(filter ffirst)
(map #(let [xs' (mapcat second %)]
(take-nth 2 (cons (first xs') xs'))))
(sort-by (comp - count))))
(descending-sequences in)
;;=> ((7 6 5 4 3 2) (3 2 1 0 -1) (7 6))
(partition 2 1) gives every possible comparison and partition-by allows you to mark out the runs of continuous decreases. At this point you can already see the answer and the rest of the code is removing the baggage that is no longer needed.
If you want the ascending sequences instead then you only need to change the < to a >:
;;=> ((-1 2 7) (6 7))
If, as in the question, you only want the longest sequence then put a first as the last function call in the thread last macro. Alternatively replace the sort-by with:
(apply max-key count)
For maximum readability you can name the operations:
(defn greatest-continuous [op xs]
(let [op-pair? (fn [[x y]] (op x y))
take-every-second #(take-nth 2 (cons (first %) %))
make-canonical #(take-every-second (apply concat %))]
(->> xs
(partition 2 1)
(partition-by op-pair?)
(filter (comp op-pair? first))
(map make-canonical)
(apply max-key count))))
I feel your pain...they can be hard to read.
I see 2 possible improvements. The simplest is to write a wrapper similar to the Plumatic Plumbing defnk style:
(fnk-reduce { :fn (fn [state val] ... <new state value>)
:init []
:coll some-collection } )
so the function call has a single map arg, where each of the 3 pieces is labelled & can come in any order in the map literal.
Another possibility is to just extract the reducing fn and give it a name. This can be either internal or external to the code expression containing the reduce:
(let [glommer (fn [state value] (into state value)) ]
(reduce glommer #{} some-coll))
or possibly
(defn glommer [state value] (into state value))
(reduce glommer #{} some-coll))
As always, anything that increases clarity is preferred. If you haven't noticed already, I'm a big fan of Martin Fowler's idea of Introduce Explaining Variable refactoring. :)
I will apologize in advance for posting a longer solution to something where you wanted more brevity/clarity.
We are in the new age of clojure transducers and it appears a bit that your solution was passing the "longest" and "current" forward for record-keeping. Rather than passing that state forward, a stateful transducer would do the trick.
(def longest-decreasing
(fn [rf]
(let [longest (volatile! [])
current (volatile! [])
tail (volatile! nil)]
(fn
([] (rf))
([result] (transduce identity rf result))
([result x] (do (if (or (nil? #tail) (< x #tail))
(if (> (count (vswap! current conj (vreset! tail x)))
(count #longest))
(vreset! longest #current))
(vreset! current [(vreset! tail x)]))
#longest)))))))
Before you dismiss this approach, realize that it just gives you the right answer and you can do some different things with it:
(def coll [2 1 10 9 8 40])
(transduce longest-decreasing conj coll) ;; => [10 9 8]
(transduce longest-decreasing + coll) ;; => 27
(reductions (longest-decreasing conj) [] coll) ;; => ([] [2] [2 1] [2 1] [2 1] [10 9 8] [10 9 8])
Again, I know that this may appear longer but the potential to compose this with other transducers might be worth the effort (not sure if my airity 1 breaks that??)
I believe that iterate can be a more readable substitute for reduce. For example here is the iteratee function that iterate will use to solve this problem:
(defn step-state-hof [op]
(fn [{:keys [unprocessed current answer]}]
(let [[x y & more] unprocessed]
(let [next-current (if (op x y)
(conj current y)
[y])
next-answer (if (> (count next-current) (count answer))
next-current
answer)]
{:unprocessed (cons y more)
:current next-current
:answer next-answer}))))
current is built up until it becomes longer than answer, in which case a new answer is created. Whenever the condition op is not satisfied we start again building up a new current.
iterate itself returns an infinite sequence, so needs to be stopped when the iteratee has been called the right number of times:
(def in [3 2 1 0 -1 2 7 6 7 6 5 4 3 2])
(->> (iterate (step-state-hof >) {:unprocessed (rest in)
:current (vec (take 1 in))})
(drop (- (count in) 2))
first
:answer)
;;=> [7 6 5 4 3 2]
Often you would use a drop-while or take-while to short circuit just when the answer has been obtained. We could so that here however there is no short circuiting required as we know in advance that the inner function of step-state-hof needs to be called (- (count in) 1) times. That is one less than the count because it is processing two elements at a time. Note that first is forcing the final call.
I wanted this order for the form:
reduce
val, col
f
I was able to figure out that this technically satisfies my requirements:
> (apply reduce
(->>
[0 [1 2 3 4]]
(cons
(fn [acc x]
(+ acc x)))))
10
But it's not the easiest thing to read.
This looks much simpler:
> (defn reduce< [val col f]
(reduce f val col))
nil
> (reduce< 0 [1 2 3 4]
(fn [acc x]
(+ acc x)))
10
(< is shorthand for "parameters are rotated left"). Using reduce<, I can see what's being passed to f by the time my eyes get to the f argument, so I can just focus on reading the f implementation (which may get pretty long). Additionally, if f does get long, I no longer have to visually check the indentation of the val and col arguments to determine that they belong to the reduce symbol way farther up. I personally think this is more readable than binding f to a symbol before calling reduce, especially since fn can still accept a name for clarity.
This is a general solution, but the other answers here provide many good alternative ways to solve the specific problem I gave as an example.

repeatedly apply a function until test no longer yields true

I wrote this code to nest a function n times and am trying to extend the code to handle a test. Once the test returns nil the loop is stopped. The output be a vector containing elements that tested true. Is it simplest to add a while loop in this case? Here is a sample of what I've written:
(defn nester [a inter f]
(loop [level inter expr a]
(if (= level 0) expr
(if (> level 0) (recur (dec level) (f expr))))))
An example input would be an integer 2, and I want to nest the inc function until the output is great than 6. The output should be [2 3 4 5 6 7].
(defn nester [a inter f test-fn]
(loop [level inter
expr a]
(if (or (zero? level)
(nil? (test-fn expr)))
expr
(recur (dec level)
(f expr)))))
If you also accept false (additionally to nil) from your test-fn, you could compose this more lazily:
(defn nester [a inter f test-fn]
(->> (iterate f a)
(take (inc inter))
(drop-while test-fn)
first))
EDIT: The above was answered to your initial question. Now that you have specified completely changed the meaning of your question:
If you want to generate a vector of all iterations of a function f over a value n with a predicate p:
(defn nester [f n p]
(->> (iterate f n)
(take-while p)
vec))
(nester inc 2 (partial > 8)) ;; predicate "until the output is greater than six"
;; translated to "as long as 8 is greater than
;; the output"
=> [2 3 4 5 6 7]
To "nest" or iterate a function over a value, Clojure has the iterate function. For example, (iterate inc 2) can be thought of as an infinite lazy list [2, (inc 2), (inc (inc 2)), (inc (inc (inc 2))) ...] (I use the [] brackets not to denote a "list"--in fact, they represent a "vector" in Clojure terms--but to avoid confusion with () which can denote a data list or an s-expression that is supposed to be a function call--iterate does not return a vector). Of course, you probably don't want an infinite list, which is where the lazy part comes in. A lazy list will only give you what you ask it for. So if you ask for the first ten elements, that's what you get:
user> (take 10 (iterate inc 2))
> (2 3 4 5 6 7 8 9 10 11)
Of course, you could try to ask for the whole list, but be prepared to either restart your REPL, or dispatch in a separate thread, because this call will never end:
user> (iterate inc 2)
> (2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
=== Shutting down REPL ===
=== Starting new REPL at C:\Users\Omnomnomri\Clojure\user ===
Clojure 1.5.0
user>
Here, I'm using clooj, and this is what it looks like when I restart my REPL. Anyways, that's all just a tangent. The point is that iterate answers the core of your question. The other part, stopping upon some test condition, involves take-while. As you might imagine, take-while is a lot like take, only instead of stopping after some number of elements, it stops upon some test condition (or in Clojure parlance, a predicate):
user> (take-while #(< % 10) (iterate inc 2))
> (2 3 4 5 6 7 8 9)
Note that take-while is exclusive with its predicate test, so that here once the value fails the test (of being less than 10), it excludes that value, and only includes the previous values in the return result. At this point, solving your example is pretty straightfoward:
user> (take-while #(< % 7) (iterate inc 2))
> (2 3 4 5 6)
And if you need it to be a vector, wrap the whole thing in a call to vec:
user> (vec (take-while #(< % 7) (iterate inc 2)))
> [2 3 4 5 6]

Given a partially ordered set, remove all smaller items

I'm struggling to find a beautiful, idiomatic way to write a function
(defn remove-smaller
[coll partial-order-fn]
___
)
where partial-order-fn takes two arguments and return -1 0 or 1 is they are comparable (resp. smaller, equal, bigger) or nil otherwise.
The result of remove-smaller should be coll, with all items that are smaller than any other item in coll are removed.
Example: If we defined a partial order such as numbers are compared normally, letters too, but a letter and a number are not comparable:
1 < 2 a < t 2 ? a
Then we would have:
(remove-smaller [1 9 a f 3 4 z])
==> [9 z]
(defn partial-compare [x y]
(when (= (type x) (type y))
(compare x y)))
(defn remove-smaller [coll partial-order-fn]
(filter
(fn [x] (every? #(let [p (partial-order-fn x %)]
(or (nil? p) (>= p 0)))
coll))
coll))
(defn -main []
(remove-smaller [1 9 \a \f 3 4 \z] partial-compare))
This outputs (9 \z), which is correct unless you want the return value to be of the same type as coll.
In practice I might just use tom's answer, since no algorithm can guarantee better than O(n^2) worst-case performance and it's easy to read. But if performance matters, choosing an algorithm that is always n^2 isn't good if you can avoid it; the below solution avoids re-iterating over any items which are known not to be maxes, and therefore can be as good as O(n) if the set turns out to actually be totally ordered. (of course, this relies on transitivity of the ordering relation, but since you call this a partial order that's implied)
(defn remove-smaller [cmp coll]
(reduce (fn [maxes x]
(let [[acc keep-x]
,,(reduce (fn [[acc keep-x] [max diff]]
(cond (neg? diff) [(conj acc max) false]
(pos? diff) [acc keep-x]
:else [(conj acc max) keep-x]))
[[] true], (map #(list % (or (cmp x %) 0))
maxes))]
(if keep-x
(conj acc x)
acc)))
(), coll))
(def data [1 9 \a \f 3 4 \z])
(defn my-fn [x y]
(when (= (type x) (type y))
(compare x y)))
(defn remove-smaller [coll partial-order-fn]
(mapv #(->> % (sort partial-order-fn) last) (vals (group-by type data))))
(remove-smaller data my-fn)
;=> [9 \z]
Potentially the order of the remaining items might differ to the input collection, but there is no order between the equality 'partitions'

clojure for sequence comprehnsion adding two elements at a time

The comprehension:
(for [i (range 5])] i)
... yields: (0 1 2 3 4)
Is there an idiomatic way to get (0 0 1 1 2 4 3 9 4 16) (i.e. the numbers and their squares) using mostly the for comprehension?
The only way I've found so far is doing a:
(apply concat (for [i (range 5)] (list i (* i i))))
Actually, using only for is pretty simple if you consider applying each function (identity and square) for each value.
(for [i (range 5), ; for every value
f [identity #(* % %)]] ; for every function
(f i)) ; apply the function to the value
; => (0 0 1 1 2 4 3 9 4 16)
Since for loops x times, it will return a collection of x values. Multiple nested loops (unless limited by while or when) will give x * y * z * ... results. That is why external concatenation will always be necessary.
A similar correlation between input and output exists with map. However, if multiple collections are given in map, the number of values in the returned collection is the size of the smallest collection parameter.
=> (map (juxt identity #(* % %)) (range 5))
([0 0] [1 1] [2 4] [3 9] [4 16])
Concatenating the results of map is so common mapcat was created. Because of that, one might argue mapcat is a more idiomatic way over for loops.
=> (mapcat (juxt identity #(* % %)) (range 5))
(0 0 1 1 2 4 3 9 4 16)
Although this is just shorthand for apply concat (map, and a forcat function or macro could be created just as easily.
However, if an accumulation over a collection is needed, reduce is usually considered the most idiomatic.
=> (reduce (fn [acc i] (conj acc i (* i i))) [] (range 5))
[0 0 1 1 2 4 3 9 4 16]
Both the for and map options would mean traversing a collection twice, once for the range, and once for concatenating the resulting collection. The reduce option only traverses the range.
Care to share why "using mostly the for comprehension" is a requirement ?
I think you are doing it right.
A slightly compressed way maybe achieved using flatten
(flatten (for [i (range 5)] [ i (* i i) ] ))
But I would get rid of the for comprehension and just use interleave
(let [x (range 5)
y (map #(* % %) x)]
(interleave x y))
Disclaimer: I am just an amateur clojurist ;)

Building a lazy, impure id generator

I'd like to know how to create an infinite, impure sequence of unique values in Clojure.
(def generator ...) ; def, not defn
(take 4 generator) ; => (1 2 3 4)
(take 4 generator) ; => (5 6 7 8). note the generator's impurity.
I think that such a design could be more convenient than e.g. wrapping a single integer value into a reference type and increment it from its consumers, as:
The proposed approach reduces the implementation details to a single point of change: the generator. Otherwise all the consumers would have to care about both the reference type (atom), and the concrete function that provides the next value (inc)
Sequences can take advantage many clojure.core functions. 'Manually' building a list of ids out of an atom would be a bit bulky: (take 4 (repeatedly #(swap! _ inc)))
I couldn't come up with a working implementation. Is it possible at all?
You can wrap a lazy sequence around an impure class (like a java.util.concurrent.atomic.AtomicLong) to create an id sequence:
(def id-counter (java.util.concurrent.atomic.AtomicLong.))
(defn id-gen []
(cons
(.getAndIncrement id-counter)
(lazy-seq
(id-gen))))
This works, but only if you don't save the head of the sequence. If you create a var that captures the head:
(def id-seq (id-gen))
Then call it repeatedly, it will return ids from the beginning of the sequence, because you've held onto the head of the sequence:
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
(take 3 id-seq)
;; => (0 1 2)
If you re-create the sequence though, you'll get fresh values because of the impurity:
(take 3 (id-gen))
;; (3 4 5)
(take 3 (id-gen))
;; (6 7 8)
(take 3 (id-gen))
;; (9 10 11)
I only recommend doing the following for educational purposes (not production code), but you can create your own instance of ISeq which implements the impurity more directly:
(def custom-seq
(reify clojure.lang.ISeq
(first [this] (.getAndIncrement id-counter))
(next [this] (.getAndIncrement id-counter))
(cons [this thing]
(cons thing this))
(more [this] (cons
(.getAndIncrement id-counter)
this))
(count [this] (throw (RuntimeException. "count: not supported")))
(empty [this] (throw (RuntimeException. "empty: not supported")))
(equiv [this obj] (throw (RuntimeException. "equiv: not supported")))
(seq [this] this)))
(take 3 custom-seq)
;; (12 13 14)
(take 3 custom-seq)
;; (15 16 17)
I had a fun time discovering something during answering your question. The first thing that occured to me was that perhaps, for whatever ultimate goal you need these IDs for, the gensym function might be helpful.
Then, I thought "well hey, that seems to increment some impure counter to generate new IDs" and "well hey, what's in the source code for that?" Which led me to this:
(. clojure.lang.RT (nextID))
Which seems to do what you need. Cool! If you want to use it the way you suggest, then I would probably make it a function:
(defn generate-id []
(. clojure.lang.RT (nextID)))
Then you can do:
user> (repeatedly 5 generate-id)
=> (372 373 374 375 376)
I haven't yet tested whether this will produce always unique values "globally"--I'm not sure about terminology, but I'm talking about when you might be using this generate-id function from within different threads, but want to still be sure that it's producing unique values.
this is another solution, maybe:
user=> (defn positive-numbers
([] (positive-numbers 1))
([n] (cons n (lazy-seq (positive-numbers (inc n))))))
#'user/positive-numbers
user=> (take 4 (positive-numbers))
(1 2 3 4)
user=> (take 4 (positive-numbers 5))
(5 6 7 8)
A way that would be more idiomatic, thread-safe, and invites no weirdness over head references would be to use a closure over one of clojures built in mutable references. Here is a quick sample I worked up since I was having the same issue. It simply closes over a ref.
(def id-generator (let [counter (ref 0)]
(fn [] (dosync (let [cur-val #counter]
(do (alter counter + 1)
cur-val))))))
Every time you call (id-generator) you will get the next number in the sequence.
Here's another quick way:
user> (defn make-generator [& [ii init]]
(let [a (atom (or ii 0 ))
f #(swap! a inc)]
#(repeatedly f)))
#'user/make-generator
user> (def g (make-generator))
#'user/g
user> (take 3 (g))
(1 2 3)
user> (take 3 (g))
(4 5 6)
user> (take 3 (g))
(7 8 9)
This is hack but it works and it is extremely simple
; there be dragons !
(defn id-gen [n] (repeatedly n (fn [] (hash #()))))
(id-gen 3) ; (2133991908 877609209 1060288067 442239263 274390974)
Basically clojure creates an 'anonymous' function but since clojure itselfs needs a name for that, it uses uniques impure ids to avoid collitions. If you hash a unique name then you should get a unique number.
Hope it helps
Creating identifiers from an arbitrary collection of seed identifiers:
(defonce ^:private counter (volatile! 0))
(defn- next-int []
(vswap! counter inc))
(defn- char-range
[a b]
(mapv char
(range (int a) (int b))))
(defn- unique-id-gen
"Generates a sequence of unique identifiers seeded with ids sequence"
[ids]
;; Laziness ftw:
(apply concat
(iterate (fn [xs]
(for [x xs
y ids]
(str x y)))
(map str ids))))
(def inf-ids-seq (unique-id-gen (concat (char-range \a \z)
(char-range \A \Z)
(char-range \0 \9)
[\_ \-])))
(defn- new-class
"Returns an unused new classname"
[]
(nth inf-ids-seq (next-int)))
(repeatedly 10 new-class)
Demonstration:
(take 16 (unique-id-gen [\a 8 \c]))
;; => ("a" "8" "c" "aa" "a8" "ac" "8a" "88" "8c" "ca" "c8" "cc" "aaa" "aa8" "aac" "a8a")