Clojure is-prime function? - clojure

I am doing is-prime? function that should return true if n is prime and false otherwise, it also should check to see if n is 1 or 2 and respond accordingly; if not, it should call no-divisors function. At the moment I get this output :
Can anyone see what's wrong, would be much appreciated
expected result is false,current false
expected result is true,current true
expected result is true,current false
expected result is false,current false
expected result is true,current false
no-divisors?
(->> (range 2 n)
(filter #(Divides % n))
empty? ))
(println (no-divisors? 4))
is-prime?
(defn is-prime? [n]
(and (< 1 n)
(not-any? (filter #(no-divisors? % n))
(range 2 n))))
(println "expected result is false,current"( is-prime? 1))
(println "expected result is true,current"( is-prime? 2))
(println "expected result is true,current" ( is-prime? 3))
(println "expected result is false,current"( is-prime? 4))
(println "expected result is true,current"( is-prime? 101))

If you format your code per Clojure conventions, it's pretty clear what the problem is:
(defn is-prime? [n]
(and (< 1 n)
(not-any? (filter #(no-divisors? % n))
(range 2 n))))
You're calling filter with a single argument which with return a transducer. Your call to not-any? then tries to treat that transducer as a predicate and since a transducer, given a single argument, returns a function -- and a function is "truthy" (not nil or false) then not-any? will return false per its definition.
The reason it returns true for 2 is that (range 2 2) is an empty sequence and not-any? returns true for an empty sequence without calling the predicate.

Some suggestions:
Several people have asked you for complete, well-formatted code. Provide
it. It will help you think clearly.
Use integer? and < to make sure you are testing a possible prime.
A prime is a number with no proper factors. Define it as such. You
are doing the work twice - Russian doll style.
It is easier to test your function on a range of possibles. I used (filter prime? (range -20 20)), yielding (2 3 5 7 11 13 17 19).
Name the function prime?. That's the Clojure convention. The initial is- is redundant. This may seem nit-picking, but simpler is clearer.
Best of luck!

Related

Beginner Clojurist Lazy Sequence error: Don't know how to create ISeq from: java.lang.Long

I am new to Clojure and Lisp, but love it so far. I am currently trying to understand lazy-seq's and Clojure's ability to define infinite sequences. I have the following code:
(defn geometric
([] geometric 1)
([n] (cons n (lazy-seq (geometric (* n 1/2))))))
If I run:
(geometric)
in my REPL, it returns 1, as expected. However, if I run,
(take 10 (geometric))
I get the following error:
IllegalArgumentException Don't know how to create ISeq from:
java.lang.Long clojure.lang.RT.seqFrom
What I expect to get is:
(1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 1/512)
Why am I getting this error? If I've understood correctly, one should be able to cons n to the lazy-sequence, and take should return the first ten values of the sequence, evaluated recursively.
One of my favorite functions: iterate takes a function f and a value x returning x, (f x), (f (f x), (f (f (f x))) etc.
Here is an elegant implementation with the same functionality:
(defn geometric []
(iterate #(/ % 2) 1))
Not a direct answer to your question but hopefully informative!
You have a small typo in your code:
(defn geometric
([] (geometric 1)) ;; notice the added parens around geometric 1
([n] (cons n (lazy-seq (geometric (* n 1/2))))))
Without this fix (geometric 1) was working because the implementation was to evaluate expression geometric (just a function value) which was discarded, then 1 expression was evaluated and returned as the function result (it was the last expression in this arity function body).
Now it works as expected:
(take 1 (geometric))
;; => (1)
(take 5 (geometric))
;; => (defn geometric
([] geometric 1)
([n] (cons n (lazy-seq (geometric (* n 1/2))))))
Notice that you cannot just call (geometric) safely in REPL as it will try to evaluate an infinite sequence.
Your problem is here:
([] geometric 1)
This expression means that, if geometric is called with no arguments, two things will happen:
The symbol geometric will be evaluated, which will result in the geometric function.
The number 1 will be returned.
What you probably meant was this:
([] (geometric 1))
This means that calling (geometric) is equivalent to calling (geometric 1). Your example will now work as expected:
(take 10 (geometric))
;=> (1 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256 1/512)
(geometric) evaluates to the number 1, not to a sequence. (take 10 1) gives the same error that you're seeing now.
You should try running (take 10 (geometric 1)), since (geometric 1) will produce a sequence which can be supplied to the second argument of take.

How to perform a map using reduce

Hello I have a simple function like this:
(def state
(memoize
(fn state [t]
(if (<= t 0)
0
1))))
on which I am trying to call (reduce state (range 10)) which the intent of calling the function state on the range 0 1 2 3 4 5 ..., and receiving back 0 1 1 1 1 1 1 1 1 1.
That is not happening, thus I am obviously misunderstanding something, since I am getting:
clojure.lang.ArityException: Wrong number of args (2) passed to: state
The syntax for reduce is (reduce f coll) and my understanding was that it is as simple as doing (reduce + [1 2 3 4 5]).
Obviously one can do this easily enough with map I was just under the impression that reduce would work as well. With map, (map (fn [x] (state x)) (range 10)).
PS. this is just a test case, I genuinely do need memoization for the real thing.
Thanks
Obviously one can do this easily enough with map I was just under the impression that reduce would work as well.
Yes. Any map can also be a reduce. (Except reduce is not lazy, while map is).
The result of a reduce function is going to be the result that is returned in the end after N iterations of your function over your reduction range.
Your function returns a 0 or a 1, therefore, your reduce will ultimately return either a 0 or 1.
If you want to return a list, then your reduction function needs to return a list. Or, use a function other than reduce, such as map.
Also -- all reduction functions take 2 arguments, not 1. So your state function is not a valid function to pass to reduce. Though, it is a valid function to pass to map.
Incidentally, you can do this with reduce, you don't need map -- in fact, many functions can be expressed as reduce, including map, filter and others. But, you'd need to alter your reduction function to make it compatible.
The comments and other answers suggest you must use map, but here is a reduce that will do it:
(def state
(memoize
(fn state [r t]
(if (<= t 0)
(conj r 0)
(conj r 1)))))
(reduce state [] (range 10))
;;-> [0 1 1 1 1 1 1 1 1 1]
This is a great idiom when you have logic for the value of a particular item that depends on knowing about the other items. You do not have such logic here, so map is a better choice. But conceptually you can express many things in functional programming in terms of a fold which is what reduce is.
Here is an alternate method, keeping the original state function from the question, and therefore its memoization intact:
(def state
(memoize
(fn state [t]
(if (<= t 0)
0
1))))
(defn r-fn [r t]
(conj r (state t)))
(reduce r-fn [] (range 10))
;;-> [0 1 1 1 1 1 1 1 1 1]
This is more succinctly written as:
(reduce #(conj %1 (state %2)) [] (range 10))
well, that's because the reduce function should take exactly 2 parameters: accumulator and item from the coll, bur in case the accumulator is not provided during reduce call, the first step of reduction is applied to first 2 values from coll:
(reduce + '(1 2 3 4)) is really (+ (+ (+ 1 2) 3) 4)
but that's not what you need in your case:
user> (map state (range 10))
(0 1 1 1 1 1 1 1 1 1)
as you don't want to reduce a coll to a single value, but rather map each value to another

creating a finite lazy sequence

I'm using the function iterate to create a lazy sequence. The sequence keeps producing new values on each item. At one point however the produced values "doesn't make sense" anymore, so they are useless. This should be the end of the lazy sequence. This is the intended behavior in a abstract form.
My approach was to let the sequence produce the values. And once detected that they are not useful anymore, the sequence would only emit nil values. Then, the sequence would be wrapped with a take-while, to make it finite.
simplified:
(take-while (comp not nil?)
(iterate #(let [v (myfunction1 %)]
(if (mypred? (myfunction2 v)) v nil)) start-value))
This works, but two questions arise here:
Is it generally a good idea to model a finite lazy sequence with a nil as a "stopper", or are there better ways?
The second question would be related to the way I implemented the mechanism above, especially inside the iterate.
The problem is: I need one function to get a value, then a predicate to test if it's valid, if yes: in needs to pass a second function, otherwise: return nil.
I'm looking for a less imperative way tho achieve this, more concretely omitting the let statement. Rather something like this:
(defn pass-if-true [pred v f]
(when (pred? v) (f v)))
#(pass-if-true mypred? (myfunction1 %) myfunction2)
For now, I'll go with this:
(comp #(when (mypred? %) (myfunction2 %)) myfunction1)
Is it generally a good idea to model a finite lazy sequence with a nil as a "stopper", or are there better ways?
nil is the idiomatic way to end a finite lazy sequence.
Regarding the second question, try writing it this way:
(def predicate (partial > 10))
(take-while predicate (iterate inc 0))
;; => (0 1 2 3 4 5 6 7 8 9)
Here inc takes the previous value and produces a next value, predicate tests whether or not a value is good. The first time predicate returns false, sequence is terminated.
Using a return value of nil can make a lazy sequence terminate.
For example, this code calculates the greatest common divisor of two integers:
(defn remainder-sequence [n d]
(let [[q r] ((juxt quot rem) n d)]
(if (= r 0) nil
(lazy-seq (cons r (remainder-sequence d r))))))
(defn gcd [n d]
(cond (< (Math/abs n) (Math/abs d)) (gcd d n)
(= 0 (rem n d)) d
:default (last (remainder-sequence n d))))
(gcd 100 32) ; returns 4

ArityException Wrong number of args (0) passed to: core/max

If I run this code, I will get an error "ArityException Wrong number of args (0) passed to: core/max"
(apply max (filter #(zero? (mod % 7)) (range 1 3)))
However, if I run this code
(apply max (filter #(zero? (mod % 7)) (range 1 10)))
then I get the result 7.
Is there anyone who can help me to figure out this problem?
(filter #(zero? (mod % 7)) (range 1 3))
this, produces an empty sequence.
However, max must be called with at least one argument. When you apply an empty sequence to it, it's called with zero arguments, and this produces the arity exception.
You could do something like this:
(defn my [a b]
(let [result (filter #(zero? (mod % 7)) (range a b))]
(if (zero? (count result))
nil ; or 0 or.. whatever
(apply max result))))
apply and reduce
Because the question came up, here's a short explanation of the difference between apply and reduce.
They are two totally different concepts, however, in the following case both do the same job when combined with max.
let xs be any collection of numbers.
(apply max xs) equals (reduce max xs)
apply
Usually functions are called with a number of arguments, so one can call max like so: (max 3), or (max 5 9), or (max 4 1 3) ... As noticed before: just (max) would be an arity exception.
Apply however, lets someone call a function passing the arguments in the form of a collection. So in correspondence to the last example, the following is possible: (apply max [3]), or (apply max [5 9]), or (apply max [4 1 3]) ... Just (apply max []) or even (apply max) would lead to the same arity exception as above. This is useful in many cases.
reduce
Reduce in contrast is a bit trickier. Along with map and filter it's absolutely essential for functional programming languages like Clojure.
The main idea of reduce is to walk through a collection, in each step desired information from the current item is processed and added to a memo or accumulator.
Say, one wants to find out the sum of all numbers in a collection.
Let xs be [3 4 5 23 9 4].
(reduce + xs) would do the job.
more explicitly one could write: (reduce (fn [memo value] (+ memo value)) xs)
The function which is passed as the first argument to reduce expects two parameters: The first one is the memo, the second one the value of the current item in the collection. The function is now called for each item in the collection. The return value of the function is saved as the memo.
Note: that the first value of the collection is used as an initial value of the memo, hence the iteration starts with the second value of the collection. Here's what it is doing:
(+ 3 4) ; memo is 7 now
(+ 7 5) ; memo is 12 now
(+ 12 23) ; memo is 35 now
(+ 35 9) ; memo is 44 now
(+ 44 4) ; memo is 48 now
(There's also a way to specify the start value of the memo, see clojuredocs.org for more details)
This works equally with max. In each iteration the value of the current item is compared with the memo. Each time the highest value is saved to the memo: Hence the memo in this case represents the "maximum value until now".
So (reduce max [4 1 3 5 2]) is calculated like this:
(max 4 1) ; memo is 4
(max 4 3) ; memo is 4
(max 4 5) ; memo is 5
(max 5 2) ; memo is 5
so?
Which one to use now? It showed that there's not really a notable difference in the time that (reduce max (range 100000000)) and (apply max (range 100000000)) take. Anyways, the apply solution looks easier to me, but that's just my opinion.
There are no numbers divisible by 7 between 1 and 3, the result of filter in your first example returns an empty sequence, which means that the first example if calling (apply max []) which is the same as calling (max). max requires at least one parameter, hence the ArityException.
A couple of options to fix it:
(last (filter #(zero? (mod % 7)) (range 1 3))
or
(if-let [by-7 (seq (filter #(zero? (mod % 7)) (range 1 3)))]
(apply max by-7)
nil ;; or whatever value in case the collection is empty
)
According to the error message, the number of arguments that are passed to max is 0, and that is wrong. I guess it makes sense because it's impossible to compute the maximum for an empty list.
The reason why max gets no arguments is that there are no numbers divisible by 7 between 1 and 3.

Clojure loop with cond

I am working on a Project Euler problem that involves factoring numbers and have written the following function to do that.
(defn get-factors [value]
(let [max-factor (->> (Math/sqrt value)
(Math/floor)
(Math/round))
ifactors #{}]
(loop [n 2 factors ifactors]
(do
(println (format ">> N: %d, Factors: %s" n factors))
(cond
(when (> n max-factor) ; exit of we have passed the max-factor
(do
(println (format "--Exiting(%d): %s" n factors))
factors)) ; return factors
(when (= 0 (mod value n)); have we found a factor?
(do
(println (format"--Factor(%d)" n))
(recur (inc n) (conj factors n (/ value n))))) ; recurse: add _n_ and reciprocal _n_ to list
:default (do ; otherwise
(println (format"--default(%d): %s" n (= 0 (mod value n))))
(recur (inc n) factors)) ; recurse: increment _n_, dont modify factors
)))))
However, the function is returning nil and my println statements are evaluated in a strange order. Here is the output from the REPL for (get-factors 12), which should return #{2,3,4,6}:
>> N: 2, Factors: #{}
--default(2): true
>> N: 3, Factors: #{}
--default(3): true
>> N: 4, Factors: #{}
--Exiting(4): #{}
--Factor(4)
>> N: 5, Factors: #{3 4}
--Exiting(5): #{3 4}
As you can see, the default state is being hit even though the (= 0 (mod value n)) of the previous case evaluates to true. Likewise, the exit condition is hit twice. The last case evaluated should be for n=3, but you can see output for up to n=5.
I'm obviously doing something fundamentally wrong but I am not seeing what. (Related, is there a better way to go about constructing a list?)
First, there is an implicit "when" (or "if") in the test part of any cond so you should not be using when yourself inside that test.
Second, you are using a single form, a when form, as the entire branch of the cond, therefore, the cond does not see the second form it expects when the test is true.
Check out this example of a proper cond:
http://clojuredocs.org/clojure_core/1.2.0/clojure.core/cond
If, as others have suggested, you strip out all the crud - the whens and dos and printlns - your program works!
A few suggestions:
Use quot instead of / to get an integer quotient.
You might as well start your threading macro thus: (->> value (Math/sqrt) ... ).
Use :else, not :default or anything else to introduce the catch-all clause in your cond.