How would I do the following in sicp/scheme/dr. racket?
(define (even? n) (= (% n 2) 0))
Currently it seems like that's not a primitive symbol: %: unbound identifier in: %.
This may be the stupidest way in the world to do it, but without a % or bitwise-&1 I am doing (without logs or anything else):
(define (even? n)
(if (< (abs n) 2)
(= n 0)
(even? (- n 2))))
mod is modulo in scheme:
(define (even? n)
(= (modulo n 2) 0))
I think it's a good practice to get comfortable writing your own procedures when it feels like they are "missing". You could implement your own mod as -
(define (mod a b)
(if (< a b)
a
(mod (- a b) b)))
(mod 0 3) ; 0
(mod 1 3) ; 1
(mod 2 3) ; 2
(mod 3 3) ; 0
(mod 4 3) ; 1
(mod 5 3) ; 2
(mod 6 3) ; 0
(mod 7 3) ; 1
(mod 8 3) ; 2
But maybe we make it more robust by supporting negative numbers and preventing caller from divi
(define (mod a b)
(if (= b 0)
(error 'mod "division by zero")
(rem (+ b (rem a b)) b)))
(define (rem a b)
(cond ((= b 0)
(error 'rem "division by zero"))
((< b 0)
(rem a (neg b)))
((< a 0)
(neg (rem (neg a) b)))
((< a b)
a)
(else
(rem (- a b) b))))
Related
(define (pow b n)
"YOUR-DOC-HERE"
(cond ((= n 0) 1)
((even? n) (pow (pow b (/ n 2)) 2))
((odd? n) (* b (pow (pow b (/ (- n 1) 2)) 2)))))
(define (pow b n)
"YOUR-DOC-HERE"
(cond ((= n 0) 1)
((even? n) (* (pow b (/ n 2)) (pow b (/ n 2))))
((odd? n) (* b (pow b (/ (- n 1) 2)) (pow b (/ (- n 1) 2))))))
Here are two versions of my code for a power function with logarithmic efficiency. However, the first function would have a maximum recursion depth exceeded error and the second, though works, doesn't seem to function at a required efficiency. I am new to Scheme and I wonder what's wrong with these implementations?
Your 1st version uses itself to square every value, which creates an infinite loop in the even? clause.
Your 2nd version calls pow twice in each clause which reverses any gain from the logarithmic algorithm.
Your can fix it using let like this:
(define (pow b n)
"Recursive power in logarithmic depth."
(let ((square (lambda (x) (* x x))))
(cond ((= n 0) 1)
((even? n) (square (pow b (/ n 2))))
((odd? n) (* b (square (pow b (/ (- n 1) 2))))))))
or like this:
(define (pow b n)
"Recursive power in logarithmic depth."
(cond ((= n 0) 1)
((even? n)
(let ((x (pow b (/ n 2))))
(* x x)))
((odd? n)
(let ((x (square (pow b (/ (- n 1) 2)))))
(* b x x)))))
I am trying to write a hyperoperation program in MIT/GNU-Scheme however am having some trouble, I have written individual ones up to n=5 working but would like to make one that functions does them all. I will include some of my failed attempts below.
(define hyp (lambda (n x y)
(hypiter n x x y)))
(define hypiter (lambda (lev an cou lim)
(if (= lev 1) an
(hypiter lev (hyp (- lev 1) an cou) cou lim))))
(define hyper (lambda (n x y)
(hyper n x x y)))
(define hyperiter (lambda (lev an cou lim)
(if (= lev 1) (+ an cou)
(hyper (- lev 1) an cou))))
(define h (lambda (n a b)
(cond
((= n 1) (+ a b))
((= b 1) (- n 1))
(else (h (- n 1) (h (- n 1) a a) (- b 1)))))))
(define hyperoperation (lambda (n a b)
(cond
((= n 0) (+ 1 b))
((and (= n 1) (= b 0)) a)
((and (= n 2) (= b 0)) 0)
((and (>= n 3) (= b 0)) 1)
(else (hyperoperation (- b 1) a (hyperoperation n a (- b 1)))))))
According to the definition in wikipedia, there is an error in the last line of your last definition. It should be:
(else (hyperoperation (- n 1) a (hyperoperation n a (- b 1))))))
instead of:
(else (hyperoperation (- b 1) a (hyperoperation n a (- b 1)))))))
So a possible correct recursive definition could be:
(define (hyperoperation n a b)
(cond ((= n 0) (+ b 1))
((= b 0) (cond ((= n 1) a)
((= n 2) 0)
(else 1)))
(else (hyperoperation (- n 1) a (hyperoperation n a (- b 1))))))
I'm trying to create a list like (3 3 3 2 2 1).
my code:
(define Func
(lambda (n F)
(define L
(lambda (n)
(if (< n 0)
(list)
(cons n (L (- n 1))) )))
(L n) ))
what I need to add to get it?
thank you
I would break it down into three functions.
(define (repeat e n) (if (= n 0) '() (cons e (repeat e (- n 1)))))
(define (count-down n) (if (= n 0) '() (cons n (count-down (- n 1)))))
(define (f n) (apply append (map (lambda (n) (repeat n n)) (count-down n))))
(f 3); => '(3 3 3 2 2 1)
Flattening this out into a single function would require something like this:
(define (g a b)
(if (= a 0) '()
(if (= b 0)
(g (- a 1) (- a 1))
(cons a (g a (- b 1))))))
(define (f n) (g n n))
(f 3) ;=> '(3 3 3 2 2 1)
Here is a tail recursive version. It does the iterations in reverse!
(define (numbers from to)
(define step (if (< from to) -1 1))
(define final (+ from step))
(let loop ((to to) (down to) (acc '()))
(cond ((= final to) acc)
((zero? down)
(let ((n (+ to step)))
(loop n n acc)))
(else
(loop to (- down 1) (cons to acc))))))
(numbers 3 1)
; ==> (3 3 3 2 2 1)
To make this work in standard Scheme you might need to change the define to let* as it's sure step is not available at the time final gets evaluated.
I would use a simple recursive procedure with build-list
(define (main n)
(if (= n 0)
empty
(append (build-list n (const n)) (main (sub1 n)))))
(main 3) ;; '(3 3 3 2 2 1)
(main 6) ;; '(6 6 6 6 6 6 5 5 5 5 5 4 4 4 4 3 3 3 2 2 1)
And here's a tail-recursive version
(define (main n)
(let loop ((m n) (k identity))
(if (= m 0)
(k empty)
(loop (sub1 m) (λ (xs) (k (append (build-list m (const m)) xs)))))))
(main 3) ;; '(3 3 3 2 2 1)
(main 6) ;; '(6 6 6 6 6 6 5 5 5 5 5 4 4 4 4 3 3 3 2 2 1)
(define (range n m)
(if (< n m)
(let up ((n n)) ; `n` shadowed in body of named let `up`
(if (= n m) (list n)
(cons n (up (+ n 1))) ))
(let down ((n n))
(if (= n m) (list n)
(cons n (down (- n 1))) ))))
(define (replicate n x)
(let rep ((m n)) ; Named let eliminating wrapper recursion
(if (= m 0) '() ; `replicate` partial function defined for
(cons x ; zero-inclusive natural numbers
(rep (- m 1)) ))))
(define (concat lst)
(if (null? lst) '()
(append (car lst)
(concat (cdr lst)) )))
(display
(concat ; `(3 3 3 2 2 1)`
(map (lambda (x) (replicate x x)) ; `((3 3 3) (2 2) (1))`
(range 3 1) ))) ; `(3 2 1)`
Alternative to concat:
(define (flatten lst)
(if (null? lst) '()
(let ((x (car lst))) ; Memoization of `(car lst)`
(if (list? x)
(append x (flatten (cdr lst)))
(cons x (flatten (cdr lst))) ))))
(display
(flatten '(1 2 (3 (4 5) 6) ((7)) 8)) ) ; `(1 2 3 (4 5) 6 (7) 8)`
I've written the code for multiplicative inverse of modulo m. It works for most of the initial cases but not for some. The code is below:
(define (inverse x m)
(let loop ((x (modulo x m)) (a 1))
(cond ((zero? x) #f) ((= x 1) a)
(else (let ((q (- (quotient m x))))
(loop (+ m (* q x)) (modulo (* q a) m)))))))
For example it gives correct values for (inverse 5 11) -> 9 (inverse 9 11) -> 5 (inverse 7 11 ) - > 8 (inverse 8 12) -> #f but when i give (inverse 5 12) it produces #f while it should have been 5. Can you see where the bug is?
Thanks for any help.
The algorithm you quoted is Algorithm 9.4.4 from the book Prime Numbers by Richard Crandall and Carl Pomerance. In the text of the book they state that the algorithm works for both prime and composite moduli, but in the errata to their book they correctly state that the algorithm works always for prime moduli and mostly, but not always, for composite moduli. Hence the failure that you found.
Like you, I used Algorithm 9.4.4 and was mystified at some of my results until I discovered the problem.
Here's the modular inverse function that I use now, which works with both prime and composite moduli, as long as its two arguments are coprime to one another. It is essentially the extended Euclidean algorithm that #OscarLopez uses, but with some redundant calculations stripped out. If you like, you can change the function to return #f instead of throwing an error.
(define (inverse x m)
(let loop ((x x) (b m) (a 0) (u 1))
(if (zero? x)
(if (= b 1) (modulo a m)
(error 'inverse "must be coprime"))
(let* ((q (quotient b x)))
(loop (modulo b x) x u (- a (* u q)))))))
Does it have to be precisely that algorithm? if not, try this one, taken from wikibooks:
(define (egcd a b)
(if (zero? a)
(values b 0 1)
(let-values (((g y x) (egcd (modulo b a) a)))
(values g (- x (* (quotient b a) y)) y))))
(define (modinv a m)
(let-values (((g x y) (egcd a m)))
(if (not (= g 1))
#f
(modulo x m))))
It works as expected:
(modinv 5 11) ; 9
(modinv 9 11) ; 5
(modinv 7 11) ; 8
(modinv 8 12) ; #f
(modinv 5 12) ; 5
I think this is the Haskell code on that page translated directly into Scheme:
(define (inverse p q)
(cond ((= p 0) #f)
((= p 1) 1)
(else
(let ((recurse (inverse (mod q p) p)))
(and recurse
(let ((n (- p recurse)))
(div (+ (* n q) 1) p)))))))
It looks like you're trying to convert it from recursive to tail-recursive, which is why things don't match up so well.
These two functions below can help you as well.
Theory
Here’s how we find the multiplicative inverse d. We want e*d = 1(mod n), which means that ed + nk = 1 for some integer k. So we’ll write a procedure that solves the general equation ax + by = 1, where a and b are given, x and y are variables, and all of these values are integers. We’ll use this procedure to solve ed + nk = 1 for d and k. Then we can throw away k and simply return d.
>
(define (ax+by=1 a b)
(if (= b 0)
(cons 1 0)
(let* ((q (quotient a b))
(r (remainder a b))
(e (ax+by=1 b r))
(s (car e))
(t (cdr e)))
(cons t (- s (* q t))))))
This function is a general solution to an equation in form of ax+by=1 where a and b is given.The inverse-mod function simply uses this solution and returns the inverse.
(define inverse-mod (lambda (a m)
(if (not (= 1 (gcd a m)))
(display "**Error** No inverse exists.")
(if (> 0(car (ax+by=1 a m)))
(+ (car (ax+by=1 a m)) m)
(car (ax+by=1 a m))))))
Some test cases are :
(inverse-mod 5 11) ; -> 9 5*9 = 45 = 1 (mod 11)
(inverse-mod 9 11) ; -> 5
(inverse-mod 7 11) ; -> 8 7*8 = 56 = 1 (mod 11)
(inverse-mod 5 12) ; -> 5 5*5 = 25 = 1 (mod 12)
(inverse-mod 8 12) ; -> error no inverse exists
I am new to Scheme. I have tried and implemented probabilistic variant of Rabin-Miller algorithm using PLT Scheme. I know it is probabilistic and all, but I am getting the wrong results most of the time. I have implemented the same thing using C, and it worked well (never failed a try). I get the expected output while debugging, but when I run, it almost always returns with an incorrect result. I used the algorithm from Wikipedia.
(define expmod( lambda(b e m)
;(define result 1)
(define r 1)
(let loop()
(if (bitwise-and e 1)
(set! r (remainder (* r b) m)))
(set! e (arithmetic-shift e -1))
(set! b (remainder (* b b) m))
(if (> e 0)
(loop)))r))
(define rab_mil( lambda(n k)
(call/cc (lambda(breakout)
(define s 0)
(define d 0)
(define a 0)
(define n1 (- n 1))
(define x 0)
(let loop((count 0))
(if (=(remainder n1 2) 0)
(begin
(set! count (+ count 1))
(set! s count)
(set! n1 (/ n1 2))
(loop count))
(set! d n1)))
(let loop((count k))
(set! a (random (- n 3)))
(set! a (+ a 2))
(set! x (expmod a d n))
(set! count (- count 1))
(if (or (= x 1) (= x (- n 1)))
(begin
(if (> count 0)(loop count))))
(let innerloop((r 0))
(set! r (+ r 1))
(if (< r (- s 1)) (innerloop r))
(set! x (expmod x 2 n))
(if (= x 1)
(begin
(breakout #f)))
(if (= x (- n 1))
(if (> count 0)(loop count)))
)
(if (= x (- s 1))
(breakout #f))(if (> count 0) (loop count)))#t))))
Also, Am I programming the right way in Scheme? (I am not sure about the breaking out of loop part where I use call/cc. I found it on some site and been using it ever since.)
Thanks in advance.
in general you are programming in a too "imperative" fashion; a more elegant expmod would be
(define (expmod b e m)
(define (emod b e)
(case ((= e 1) (remainder b m))
((= (remainder e 2) 1)
(remainder (* b (emod b (- e 1))) m)
(else (emod (remainder (* b b) m) (/ e 2)))))))
(emod b e))
which avoids the use of set! and just implements recursively the rules
b^1 == b (mod m)
b^k == b b^(k-1) (mod m) [k odd]
b^(2k) == (b^2)^k (mod m)
Similarly the rab_mil thing is programmed in a very non-scheme fashion. Here's an alternative implementation. Note that there is no 'breaking' of the loops and no call/cc; instead the breaking out is implemented as a tail-recursive call which really corresponds to 'goto' in Scheme:
(define (rab_mil n k)
;; calculate the number 2 appears as factor of 'n'
(define (twos-powers n)
(if (= (remainder n 2) 0)
(+ 1 (twos-powers (/ n 2)))
0))
;; factor n to 2^s * d where d is odd:
(let* ((s (twos-powers n 0))
(d (/ n (expt 2 s))))
;; outer loop
(define (loop k)
(define (next) (loop (- k 1)))
(if (= k 0) 'probably-prime
(let* ((a (+ 2 (random (- n 2))))
(x (expmod a d n)))
(if (or (= x 1) (= x (- n 1)))
(next)
(inner x next))))))
;; inner loop
(define (inner x next)
(define (i r x)
(if (= r s) (next)
(let ((x (expmod x 2 n)))
(case ((= x 1) 'composite)
((= x (- n 1)) (next))
(else (i (+ 1 r) x))))
(i 1 x))
;; run the algorithm
(loop k)))