To show how to check primality with the Lucas sequence, let’s look at
an example. Consider the first few numbers in the Lucas sequence:
1,3,4,7,11,18,29,47,76,123,...
If we are interested to see if a particular number, say 7, is prime,
we take the 7th number in the Lucas sequence and subtract 1. The 7th
Lucas number is 29. Subtract 1 and we have 28. Now, if this result is
evenly divisible by 7, 7 is probably prime. In our example, 28 is
divisible by 7, so it is probably prime. We call these numbers Lucas
pseudoprimes.
If we were interested in another number, say 8, we would take the 8th
Lucas number and subtract 1. In this case, we get 46, which is not
evenly divisible by 8. So, 8 is definitely not prime. This method is
useful for filtering out composite numbers.
So, the general procedure to determine if an integer p could possibly
be prime is as follows:
Find the pth Lucas number
Subtract 1
Check to see if p divides the result evenly
Define a SCHEME function, named (lucas-pseudoprime p) which uses
this approach to determine if an integer p is a Lucas pseudoprime.
I have this so far:
(define (lucas-pseudoprime p)
(define (helper-lucas goal current next)
(if (= goal current)
(head next)
(helper-lucas goal (+ current 1) next))
(let ((solution (- p 1))
(if (= (module solution p) 0) #t
#f)))))
Not sure what's going wrong with this.
I have a simple lisp program here that computes an approximation of the average length between two points chosen uniformly at random on the unit interval. If I run the program, I get a rational number 16666671666667/50000000000000, but when I (naively) try to format the rational number to 20 places, some of the precision is thrown away 0.33333343000000000000. I think that, under the hood, SBCL is casting the rational to a floating point number before formatting it, but I'm not really sure how to tell. I'm just using the expression (format t "~20$~%" (scale-all-line-contributions 10000000 1). Is there a way to convert a rational number to decimal notation keeping as much precision as possible? I understand the format system is powerful and expansive, but I'm having trouble finding documentation about it specifically related to rational numbers.
Here's the code below for completeness' sake, since it isn't very long.
(defun number-of-pairs (n i)
"get the number of pairs with distance x
for non-zero distances we have to consider two cases"
(cond
((= i 0) n)
((> i 0) (* 2 (- n i)))
((> i n) 0)))
(defun line-contribution (n i power)
"get the number of segments of length i in a line of n segments and their weight combined"
(let
((number-of-pairs (number-of-pairs n i))
(weight-of-pair (expt i power)))
(* number-of-pairs weight-of-pair)))
(defun all-line-contributions (n power)
"get the line contributions for reach [0 .. n]"
(loop for i from 1 upto (- n 1) summing (line-contribution n i power)))
(defun normalized-all-line-contributions (n power)
"normalize line contributions by number of pairs"
(let ((pair-count (expt n 2)))
(/ (all-line-contributions n power) pair-count)))
(defun scale-all-line-contributions (n power)
"scale the line contributions by the distance n
this will guarantee convergence"
(/ (normalized-all-line-contributions n power) (expt n power)))
(print (scale-all-line-contributions 10000000 1))
(format t "~20$~%" (scale-all-line-contributions 10000000 1))
edit: fixed logic error in code. new rational number, float pair is 33333333333333/100000000000000 0.33333334000000000000
You can use either coerce or float. For instance:
(format t "~20$" (coerce 16666671666667/50000000000000 'long-float))
; prints 0.33333343333334000000
(format t "~a" (float 16666671666667/50000000000000 1.0l0))
; prints 0.33333343333334d0
Note that a coercion to long-float can produce different results in different implementations of Common Lisp (in particular in CLISP).
The second parameter to float is a prototype: you should provide any float literal and the first parameter will be converted to the same kind of float.
(define (fib n)
(fib-iter 1 0 n))
(define (fib-iter a b count)
(if (= count 0)
b
(fib-iter (+ a b) a (- count 1))))
Just having some fun with SICP.
I completely understand the idea of Fibonacci algorithm but this code made me stuck up.
What exactly the last line does in compare to imperative style thing(is this just a basic recursion or)?
The procedure is implementing the Fibonacci series as an iterative process. In this case, fib is the main procedure that calls fib-iter, which does the actual work by means of an iteration. Notice that count is used to control the number of iterations we want, whereas a and b are used to store the results of the Fibonacci series for n-1 and n-2 respectively. The line (fib-iter (+ a b) a (- count 1)) is advancing the iteration to the next values.
Please take the time to read about iterative vs. recursive processes in the book, also read about tail recursion - these are the concepts you need to grasp for really understanding what's happening in the example.
For comparison, let's see how the same procedures would look using a more conventional syntax (Python's):
def fib(n):
return fib_iter(1, 0, n)
def fib_iter(a, b, count):
while count != 0: # same as asking `(if (= count 0) ...)`
a, b = a + b, a # same as passing `(+ a b) a` to recursive call
count -= 1 # same as `(- count 1)`
return b # same as returning `b` at end of recursion
As you see, the fib_iter procedure is simply iterating over a range of values controlled by the count variable, assigning a and b to the next values in the series, up until a number of iterations is completed; at this point the result is in b and is returned.
An iterative version of odd? for non-negative integer arguments can be written using and, or, and not. To do so, you have to take advantage of the fact that and and or are special forms that evaluate their arguments in order from left to right, exiting as soon as the value is determined. Write (boolean-odd? x) without using if or cond, but using and, or, not (boolean) instead. You may use + and -, but do not use quotient, remainder, /, etc.
A number is even if two divides it evenly, and odd if there if there is a remainder of one. In general, when you divide a number k by a number n, the remainder is one element of the set {0,1,…n-1}. You can generalize your question by asking whether, when k is divided by n, the remainder is in some privileged set of remainder values. Since this is almost certainly homework, I do not want to provide a direct answer to your question, but I'll answer this more general version, without sticking to the constraints of using only and and or.
(define (special-remainder? k n special-remainders)
(if (< k n)
(member k special-remainders)
(special-remainder? (- k n) special-remainders)))
This special-remainder? recursively divides k by n until a remainder less than n is found. Then n is tested for its specialness. In the case that you're considering, you'll be able to eliminate special-remainders, because you don't need (member k special-remainders). Since you only have one special remainder, you can just check whether k is that special remainder.
A positive odd number can be defined as 1 + 2n. Thus an odd number is:
If x is 1
If x is greater than 1 and x-2 is odd.
Thus one* solution that is tail recursive/iterative looks like this:
(define (odd? x)
(or (= ...) ; #t if 1
(and ... ; #f if less than 1
(odd? ...))); recurse with 2 less
*having played around with it it's many ways to do do this and still have it iterative and without if/cond.
The question i'm trying to answer:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
Where am I going wrong? my prime? test seems to be the issue, but it works fine on relatively small numbers. However the prime? test gives a wrong answer with larger numbers. Is there an easier way to go about this?
(define b 3)
(define z 0)
(define divides?
(lambda (a b)
(= (remainder a b) 0)))
(define (prime? n)
(cond
((or (= n 1) (= n 0)) false)
((even? n) false)
((= n 2) true)
((= n b) true)
((divides? n b) false)
(else (and (set! b (+ b 1)) (prime? n)))))
;Largest Prime Factor Test
(define (LPF x)
(cond
((divides? 600851475143 x)
(cond
((prime? x)
(cond
((> x z) (set! z x)))))))
(if (< x 775146) (LPF (+ x 1)) (display z)))
Writing in a certain pseudocode, your intent seems to be
pe3 = last [x | x <- [2 .. 775146], isPrime x, rem 600851475143 x == 0]
read it: for x drawn from range 2 to 775146, if isPrime x holds, if 600851475143 % x is 0, collect such x; return the largest. We also write the application (g x) without the parentheses here, as just g x.
Calculating a remainder is cheaper than testing for primality, so we'll swap the two operations:
pe3 n = last [x | x <- [2 .. isqrt n], rem n x == 0, isPrime x]
This algorithm might work for the specific numbers involved, but unfortunately it is incorrect in general - say for 9000009, whose integer square root is 3000, it will return 101. But 9901 is the right answer (i.e. 9901 is the biggest prime divisor of 9000009, not 101).
Let's first focus on finding the smallest prime factor, instead:
pe3a n = head ([x | x <- [2 .. isqrt n], rem n x == 0, isPrime x] ++ [n])
Why the ( ... ++ [n]) (++ meaning the concatenation of lists)?? Because if n itself is prime, no divisor will be found at all, and the first list will come back empty, []. In which case the answer must be n itself. But if not, then the answer is the first (i.e. head) of the divisors list. Of course when we find it, we don't need to continue searching for more. Just one is enough, if the smallest is all we need.
OK, so trying it (at an imaginary lazy pseudocode interpreter), we get 3 as its first factor:
> pe3a 9000009
3
Now we can divide that 3 out of our number:
> div 9000009 3
3000003
and continue with 3000003, instead of 9000009. That means we can stop at its square root, 1732, instead of at 3000 - a sizable gain in efficiency! Also, we don't need to start over from 2 - it was tested already - we can start from the last found factor:
pe3b (start, n) = (d, div n d)
where
d = head ([x | x <- [start .. isqrt n], rem n x == 0, isPrime x] ++ [n])
> pe3b (3, 3000003)
(3,1000001)
so we get a second 3 back, and the number is divided by the found divisor once again.
> pe3b (3, 1000001)
(101,9901)
the next prime divisor found is 101, and the number to factorize now is 1000001 / 101 = 9901. Again we start from the last found divisor, 101, because all the smaller ones were already tried:
> pe3b (101, 9901)
(9901,1)
Interesting. isqrt(9901) == 99, the list [101 .. 99] is empty, and so the result was immediately produced. 9901 is the first factor of itself above 100, and in fact above 1, because all the previous numbers were already tried, in succession, and divided out of it. That means 9901 is a prime, no need to test it for primality.
In fact, all factors found by this algorithm are guaranteed to be prime by construction by the same reasoning, and all the calls to isPrime were superfluous.
Do also take note that the biggest number for which the division (the remainder operation) was performed here, was 101 - not 3000. Not only our new algorithm is correct, it is also much more efficient!
Now you can code in Scheme this algorithm of repeated pe3b application and dividing by the last found factor. Stop when 1 is reached.
So, in the same pseudocode,
divStep (start, n) = (d, div n d)
where d = head ([x | x <- [start .. isqrt n], rem n x == 0] ++ [n])
pe3 n = fst . until ((== 1) . snd) divStep $ (2,n) -- (1st,2nd) in a tuple
factorizing n = takeWhile ((> 1) . fst) . drop 1 . iterate divStep $ (2,n)
factors n = map fst . factorizing $ n
isPrime n = factors n == [n]
Read . and $ as "of". until pred step start is a higher-order pattern of repeated applications of a function, until a predicate is fulfilled ( ((== 1) . snd) means that the second component of a result equals 1). It is usually coded in Scheme with named let.
To see the whole history of computation, iterate step start is another pattern which collects all the interim results (and the starting value, which we don't need, so we drop it). To see just the factors themselves, we take the first components of each result with map fst. A number is prime if it's the only divisor, greater than 1, of itself. Testing:
> pe3 9000009
9901
> factorizing 9000009
[(3,3000003),(3,1000001),(101,9901),(9901,1)]
> factors 9000009
[3,3,101,9901]
> pe3 600851475143
6857
> factorizing 600851475143
[(71,8462696833),(839,10086647),(1471,6857),(6857,1)] -- 1471 is the largest
> factors 600851475143 -- factor tried,
[71,839,1471,6857] -- *not* 775146 !!
> factors 600851475143999917 -- isqrt 600851475143999917 == 775146099
[41,37309,392798360393] -- isqrt 392798360393 == 626736
Easy answer:
$ factor 600851475143
600851475143: 71 839 1471 6857
More serious answer: Your prime? function is indeed broken; I'm not even certain what it's trying to do. (Also, your (= n 2) test is too late to be useful: the (even? n) test has trumped it.)
My suggestion: Implement the Sieve of Eratosthenes. Here's my implementation.