(defn prime [x]
(if (#(<= % (Math/sqrt x)) (first (filter zero? (mod x (range 2 (inc x))))))
false
true))
Hi there! I want to check the given number is prime or not using clojure. Firstly, I want to filter all the divisors of x, then select the first number of these divisors. Finally, comparing to the square root of x, if the first divisor is smaller or equal to x, then the given number is not a prime. Otherwise, it is. However, when I run the code, I got such an error. How can I figure out the problem that convert a Lazyseq to a Number? I would appreciate if anyone can help me!
I think the problem is slightly different. We do not want to try values greater than the square root of the number we want to know is prime or not. Reason is explain in this SO. (Basically if x = a * b, then both a AND b cannot be greater than the square root)
So the sequence we are building, is up to the square root
(defn root-1 [x]
(inc (long (Math/sqrt x))))
(defn range-1 [x]
(range 2 (root-1 x)))
Finally, we are filtering on divisor:
(defn filter-1 [x]
(filter #(zero? (rem x %))
(range-1 x)))
And especially, we can stop at the first one, and filter being lazy, that comes up nicely with:
(defn is-prime [x]
(nil? (first (filter-1 x))))
Which we can try with:
(is-prime 10) ; false
(is-prime 11) ; true
Fast check that number is prime:
(ns example.core
(:gen-class)
(:require [clojure.core.reducers :as r]))
(defn prime-number?
[n]
(let [square-root (Math/sqrt n)
mod-zero? (fn [res new-val]
(if (zero? (mod n new-val))
(reduced false)
true))]
(r/reduce mod-zero? true (range 2 (inc square-root)))))
(prime-number? 2147483647)
;=> true
Two comments:
range returns a seq, which you are trying to apply (mod x ...) to. I think you are missing a map..
There is no real point in returning true and false from an if, if you think about it ;) (hint, try to see how the function not behaves)
You should make another attempt and update us on what you came up with!
Paraphrasing your recipe:
Filter all the divisors of x.
Select the first of these.
If it is smaller then or equal to the square root of x, then x
is not a prime.
The given code has the problems:
The surrounding if form is redundant.
The filter function is wrong. It ought to incorporate the zero? and
the mod x.
There is no need to construct and apply an anonymous function. Just
apply the test directly.
And, though the repaired algorithm would work, it is still clumsy.
The first divisor of a prime x is x itself. There is no need to
muck about with square roots.
The range ought to be from 2 to the square root of x. Then a nil
value for the first divisor indicates a prime.
Related
I am trying to write a clojure function for Fermat's little theorem.
I am breaking the problem down and trying to complete it step by step.
The first thing I want to write is the code to answer this part of my problem:
Given a number n, pick a random number a that is less than n. Compute the remainder of a^n modulo n.
Here is the code I have written so far:
(defn exp [a n]
(reduce * (repeat n a)))
(mod (exp 3 5) 5)
This seems to work correctly and can test for prime numbers. However I now want to put this inside a function and get a to be selected at random. Is there a simple way of getting random integers in clojure?
Any help much appreciated.
You probably want the rand-int function:
(defn rand-mod [n]
(mod (exp (rand-int n) n) n))
You can make a function that randomly select a number, compute the answer using your exp function, and return both values as a vector:
(defn rand-mod [n]
(let [a (rand-int n)]
[a (mod (exp a n) n)]))
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
Coming from imperative programming languages, I am trying to wrap my head around Clojure in hopes of using it for its multi-threading capability.
One of the problems from 4Clojure is to write a function that generates a list of Fibonacci numbers of length N, for N > 1. I wrote a function, but given my limited background, I would like some input on whether or not this is the best Clojure way of doing things. The code is as follows:
(fn fib [x] (cond
(= x 2) '(1 1)
:else (reverse (conj (reverse (fib (dec x))) (+ (last (fib (dec x))) (-> (fib (dec x)) reverse rest first))))
))
The most idiomatic "functional" way would probably be to create an infinite lazy sequence of fibonacci numbers and then extract the first n values, i.e.:
(take n some-infinite-fibonacci-sequence)
The following link has some very interesting ways of generating fibonnaci sequences along those lines:
http://en.wikibooks.org/wiki/Clojure_Programming/Examples/Lazy_Fibonacci
Finally here is another fun implementation to consider:
(defn fib [n]
(let [next-fib-pair (fn [[a b]] [b (+ a b)])
fib-pairs (iterate next-fib-pair [1 1])
all-fibs (map first fib-pairs)]
(take n all-fibs)))
(fib 6)
=> (1 1 2 3 5 8)
It's not as concise as it could be, but demonstrates quite nicely the use of Clojure's destructuring, lazy sequences and higher order functions to solve the problem.
Here is a version of Fibonacci that I like very much (I took the implementation from the clojure wikibook: http://en.wikibooks.org/wiki/Clojure_Programming)
(def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq)))
It works like this: Imagine you already have the infinite sequence of Fibonacci numbers. If you take the tail of the sequence and add it element-wise to the original sequence you get the (tail of the tail of the) Fibonacci sequence
0 1 1 2 3 5 8 ...
1 1 2 3 5 8 ...
-----------------
1 2 3 5 8 13 ...
thus you can use this to calculate the sequence. You need two initial elements [0 1] (or [1 1] depending on where you start the sequence) and then you just map over the two sequences adding the elements. Note that you need lazy sequences here.
I think this is the most elegant and (at least for me) mind stretching implementation.
Edit: The fib function is
(defn fib [n] (nth fib-seq n))
Here's one way of doing it that gives you a bit of exposure to lazy sequences, although it's certainly not really an optimal way of computing the Fibonacci sequence.
Given the definition of the Fibonacci sequence, we can see that it's built up by repeatedly applying the same rule to the base case of '(1 1). The Clojure function iterate sounds like it would be good for this:
user> (doc iterate)
-------------------------
clojure.core/iterate
([f x])
Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects
So for our function we'd want something that takes the values we've computed so far, sums the two most recent, and returns a list of the new value and all the old values.
(fn [[x y & _ :as all]] (cons (+ x y) all))
The argument list here just means that x and y will be bound to the first two values from the list passed as the function's argument, a list containing all arguments after the first two will be bound to _, and the original list passed as an argument to the function can be referred to via all.
Now, iterate will return an infinite sequence of intermediate values, so for our case we'll want to wrap it in something that'll just return the value we're interested in; lazy evaluation will stop the entire infinite sequence being evaluated.
(defn fib [n]
(nth (iterate (fn [[x y & _ :as all]] (cons (+ x y) all)) '(1 1)) (- n 2)))
Note also that this returns the result in the opposite order to your implementation; it's a simple matter to fix this with reverse of course.
Edit: or indeed, as amalloy says, by using vectors:
(defn fib [n]
(nth (iterate (fn [all]
(conj all (->> all (take-last 2) (apply +)))) [1 1])
(- n 2)))
See Christophe Grand's Fibonacci solution in Programming Clojure by Stu Halloway. It is the most elegant solution I have seen.
(defn fibo [] (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))
(take 10 (fibo))
Also see
How can I generate the Fibonacci sequence using Clojure?
How do I do mutually recursive definitions in Clojure?
Here is a code in Scala to find prime numbers which uses recursive definitions:
val odds: Stream[Int] = cons(3, odds map { _ + 2 })
val primes: Stream[Int] = cons(2, odds filter isPrime)
def primeDivisors(n: Int) =
primes takeWhile { _ <= Math.ceil(Math.sqrt(n))} filter { n % _ == 0 }
def isPrime(n: Int) = primeDivisors(n) isEmpty
primes take 10
I translated this to Clojure:
(def odds (iterate #(+ % 2) 3))
(def primes (cons 2 (filter is-prime odds)))
(defn prime-divisors [n]
(filter #(zero? (mod n %))
(take-while #(<= % (Math/ceil (Math/sqrt n)))
primes)))
(defn is-prime [n] (empty? (prime-divisors n)))
(take 10 primes)
But writing the definitions in the Clojure REPL one by one gives
java.lang.Exception: Unable to resolve symbol: is-prime in this context (NO_SOURCE_FILE:8)
after I write (def primes (cons 2 (filter is-prime odds))).
Is there a way to do mutually recursive definitions in Clojure?
You need to (declare is-prime) before the first time you reference it.
This is referred to as a "forward declaration".
Greg's answer is correct. However you have to rearrange your code: (def odds ...) (declare primes) (defn prime-divisors ...) (defn prime? ...) (def primes ...). This should do the trick.
The problem is, that the definition of primes is not a function. It is executed immediately and hence tries to dereference the prime? Var which is not bound, yet. Hence the exception. Re-arranging should take care of that.
(Disclaimer: I haven't checked that the code works with the re-arrangement.)
And I think prime? is broken. (prime? 2) should give false, no?
I'm doing Project Euler to learn Clojure.
The purpose of this function is to calculate the lcm of the set of integers from 1 to m.
(lcm 10) returns 2520
This is a rather brute-force way of doing this. In theory, we go through each number from m to infinity and return the first number for which all values 1 through m divide that number evenly.
If I understand what 'lazy' means correctly (and if I am truly being lazy here), then this should run in constant space. There's no need to hold more than the list of numbers from 1 to m and 1 value from the infinite set of numbers that we're looping through.
I am, however, getting a java.lang.OutOfMemoryError: Java heap space at m values greater than 17.
(defn lcm [m]
(let [xs (range 1 (+ m 1))]
(first (for [x (iterate inc m) :when
(empty?
(filter (fn [y] (not (factor-of? y x))) xs))] x))))
Thanks!
As far as I can tell, your code is in fact lazy (also in the sense that it's in no hurry to reach the answer... ;-) -- see below), however it generates piles upon piles upon piles of garbage. Just consider that (lvm 17) amounts to asking for over 1.2 million lazy filtering operations on (range 1 18). I can't reproduce your out-of-memory problem, but I'd tentatively conjecture it might be an issue with your memory & GC settings.
Now although I realise that your question is not actually about algorithms, note that the production of all that garbage, the carrying out of all those filtering operations etc. not only utterly destroy the space complexity of this, but the time complexity as well. Why not use an actual LCM algorithm? Like the one exploiting lcm(X) = gcd(X) / product(X) for X a set of natural numbers. The GCD can be calculated with Euclid's algorithm.
(defn gcd
([x y]
(cond (zero? x) y
(< y x) (recur y x)
:else (recur x (rem y x))))
([x y & zs]
(reduce gcd (gcd x y) zs)))
(defn lcm
([x y] (/ (* x y) (gcd x y)))
([x y & zs]
(reduce lcm (lcm x y) zs)))
With the above in place, (apply lcm (range 1 18)) will give you your answer in short order.
I'm getting the same OutOfMemoryError on Clojure 1.1, but not on 1.2.
I imagine it's a bug in 1.1 where for holds on to more garbage than necessary.
So I suppose the fix is to upgrade Clojure. Or to use Michal's algorithm for an answer in a fraction of the time.
While I accept that this is acknowledged to be brute force, I shiver at the idea. For the set of consecutive numbers that runs up to 50, the lcm is 3099044504245996706400. Do you really want a loop that tests every number up to that point to identify the lcm of the set?
Other schemes would seem far better. For example, factor each member of the sequence, then simply count the maximum number of occurrences of each prime factor. Or, build a simple prime sieve, that simultaneously factors the set of numbers, while allowing you to count factor multiplicities.
These schemes can be written to be highly efficient. Or you can use brute force. The latter seems silly here.
Michal is correct about the problem. A sieve will be a little bit faster, since no gcd calculations are needed:
EDIT: This code is actually horribly wrong. I've left it here to remind myself to check my work twice if I have such a hangover.
(ns euler (:use clojure.contrib.math))
(defn sieve
([m] (sieve m (vec (repeat (+ 1 m) true)) 2))
([m sieve-vector factor]
(if (< factor m)
(if (sieve-vector factor)
(recur m
(reduce #(assoc %1 %2 false)
sieve-vector
(range (* 2 factor) (+ 1 m) factor))
(inc factor))
(recur m sieve-vector (inc factor)))
sieve-vector)))
(defn primes [m] (map key (filter val (seq (zipmap (range 2 m) (subvec (sieve m) 2))))))
(defn prime-Powers-LCM [m] (zipmap (primes m) (map #(quot m %) (primes m))))
(defn LCM [m] (reduce #(* %1 (expt (key %2) (val %2))) 1 (seq (prime-Powers-LCM m))))