I'm new to racket and trying to give a function an integer and it should return it's Fibonacci value (iteratively). I don't know what I'm getting wrong with the do and if I incorporate an if statement to catch when the number = 1 everything breaks
(define (fib-iterat n)
(do ((i 1 (+ i 1))
(nextTerm 0 (+ value0 value1))
(value0 0 (+ value1 0))
(value1 1 (+ nextTerm 0)))
((> i n) nextTerm))
)
I get:
1 = 1
2 = 1
6 = 3
9 = 7
12 = 16
;;; correct
(define (fib n)
(do ((i 0 (+ i 1))
(n1 1 (+ n0 n1))
(n0 0 n1))
((= i n) n0)))
;;; still correct
(define (fib n)
(do ((i 0 (+ i 1))
(n0 0 n1)
(n1 1 (+ n0 n1)))
((= i n) n0)))
;;; wrong
(define (fib-iterat n)
(do ((i 0 (+ i 1))
(value1 1 nextTerm)
(value0 0 value1)
(nextTerm 1 (+ value0 value1))) ; first bracket close
((= i n) (list value0 value1 nextTerm)))) ; second bracket
I never read any "do loop" code (but it should be easy to understand). You can think like this way. We separate old state and new state. In first bracket variable calculus only use old state values. So in do loop first bracket order in many case should be irrelevant. We refresh variable value but new values will be use in next loop or second bracket.
try (fib-iterat 2),
we call old state (o1,o2,o3),
i=0≠n,
old state:none,
new state:(value0,value1,nextTerm)=(0,1,1),
i=i+1
i=1≠n,
old state:(0,1,1),
new state:(o2,o3,o2+o3)=(1,1,1),
i=i+1
i=2=n,
old state:(1,1,1),
new state:(o2,o3,o2+o3)=(1,1,2)
we want (1,2,2) so it wrong.
I think the most important thing is don't think it a set! binding. It's more like this.
(define (f n)
(do ([i 0 (+ i 1)]
[n1 1 (+ n1 n3)]
[n2 1 (+ n1 n2)]
[n3 1 (+ n2 n3)])
((= i n) (list n1 n2 n3))))
(define (my-do-loop n)
(local ((define (λ0 i n1 n2 n3) (+ i 1))
(define (λ1 i n1 n2 n3) (+ n1 n3))
(define (λ2 i n1 n2 n3) (+ n1 n2))
(define (λ3 i n1 n2 n3) (+ n2 n3))
(define (aux i n1 n2 n3)
(if (= i n)
(list n1 n2 n3)
(aux (λ0 i n1 n2 n3)
(λ1 i n1 n2 n3)
(λ2 i n1 n2 n3)
(λ3 i n1 n2 n3)))))
(aux 0 1 1 1)))
So it makes us easy understanding why we only use old value and binding order is not important because we don't do any value binding.
Related
I code a function to roll dnd's dice :
(define (rnd [n 0] [d 0] [li '()] [count 0])
(cond [(= n 0) '()]
[(= count n) (values li (foldl + 0 li))]
[(< count n) (rnd n d (cons (random 1 (+ d 1)) li) (+ count 1))]))
But I always feel this code was ugly.
Have idea to improve this?
Here is a simplified version:
(define (rnd [n 0] [d 1] [li '()])
(if (<= n 0)
(values li (foldl + 0 li))
(rnd (- n 1) d (cons (random 1 (+ d 1)) li))))
Note that the default value of d is 1 instead of zero, otherwise the function does not work with just one argument.
I already tried this problem multiple times but can't seen to get it right. I want to write an iterative procedure decompose-as-sum-of-squares which inputs a positive integer n and outputs the first integer p such that p^2 + q^2 = n, where q^2 = (n - p^2), and neither p nor n - p^2 is 1. If such p does not exist, the function should return n.
A sample output is (dss 65)returns 4.
This is my code so far.
(define (dss n)
(define (sum-of-squares n)
(if (zero? n) 0
(cons (expt n 2)
(sum-of-squares (- n 1)))))
(sum-of-squares 1))
The output I get is
(dss 65) ; (1 . 0)
Which is clearly wrong. Please help!
Lists have nothing to do with this problem, the solution follows from the definition: you have to test all p values starting from 2 and see if we can find an integer q greater than 1 that satisfies the formula p^2 + q^2 = n. Something like this:
(define (dss n)
(define (sum-of-squares p)
(cond ((>= p n) n)
((let ((q (sqrt (- n (sqr p)))))
(and (integer? q) (not (= q 1))))
p)
(else (sum-of-squares (add1 p)))))
(sum-of-squares 2))
(dss 65)
=> 4
This is Trying code
(defun f (a n)
(if (zerop n)
1
(* a (f a (- n 1)))))
(f 3) should return 27, (f 4) should return 256
I tried using two variables, but it be against the rules.
Is it possible to use only one variable using recursive?
Thanks for any ideas
I don't know CL, but I do know Clojure and other languages that use recursion.
In cases where a recursive function has 1 parameter acting as an accumulator, but is only set on the first call, the typical way around this is to wrap f in another function. There are 2 (basically the same) ways of doing this:
(defun g (a n)
(if (zerop n)
1
(* a (g a (- n 1)))))
(defun f (n)
; I'm assuming you want the initial value of "a" to be 1
(g 1 n))
Or, more succinctly:
(defun f (n)
(let (g (fn (n)
(if (zerop n)
1
(* a (g a (- n 1))))))))
; Instead of f being recursive, f calls g, which is recursive
(g 1 n))
Excuse any syntax errors.
Using an additional variable to count down would be the sane choice, but you don't need to change the contract of just one numeric argument input just for this. You can make a helper to do that:
(defun exptnn (n)
"Get the (expt n n)"
(check-type n integer)
(labels ((helper (acc count)
(if (zerop count)
acc
(helper (* acc n) (1- count)))))
(if (< n 0)
(/ 1 (helper 1 (- n)))
(helper 1 n))))
Now to solve with without any helpers just with one argument is possible since there is a solution doing that already, but I must say that is like programming in Brainf*ck without the joy!
CL-USER 15 > (defun f (n)
(labels ((g (m)
(if (zerop m)
1
(* n (g (1- m))))))
(g n)))
F
CL-USER 16 > (f 0)
1
CL-USER 17 > (f 1)
1
CL-USER 18 > (f 2)
4
CL-USER 19 > (f 3)
27
CL-USER 20 > (f 4)
256
CL-USER 21 > (loop for i below 10 collect (f i))
(1 1 4 27 256 3125 46656 823543 16777216 387420489)
This is a solution where no functions with more than one parameter are used (except for =, +, *, logand, ash; note also that logand and ash always take a constant as second parameter so they can be implemented as unary functions too).
The idea is to "hide" the two parameters needed for the obvious recursive approach in a single integer using odd/even bits.
(defun pair (n)
(if (= n 0)
0
(+ (* 3 (logand n 1))
(ash (pair (ash n -1)) 2))))
(defun pair-first (p)
(if (= p 0)
0
(+ (logand p 1)
(ash (pair-first (ash p -2)) 1))))
(defun pair-second (p)
(pair-first (ash p -1)))
(defun subsec (p)
(if (= 2 (logand p 2))
(- p 2)
(+ (logand p 1) 2 (ash (subsec (ash p -2)) 2))))
(defun pairpow (p)
(if (= (pair-second p) 1)
(pair-first p)
(* (pair-first p)
(pairpow (subsec p)))))
(defun f (n)
(pairpow (pair n)))
No reasonable real use, of course; but a funny exercise indeed.
Yes, this is possible:
(defun f (n)
(cond
((numberp n)
(f (cons n n)))
((zerop (car n))
1)
(t
(* (cdr n)
(f (cons (1- (car n))
(cdr n)))))))
The trick is that you can store any data structure (including a pair of numbers) in a single variable.
Alternatively, you can use helpers from the standard library:
(defun f (n)
(apply #'*
(loop repeat n collect n)))
But that doesn't use recursion. Or simply:
(defun f (n)
(expt n n))
For class, I have to write a function that takes positive integer n and returns the sum of n’s odd digits in scheme. So far, I have my base case such that if n equals 0 then 0. But I am not sure on how to continue.
(define sumOddDigits
(lambda (n)
(if (= n 0)
0
Test cases:
(sumOddDigits 0) → 0
(sumOddDigits 4) → 0
(sumOddDigits 3) → 3
(sumOddDigits 1984) → 10
You could do it efficiently using one functional loop:
(define (sumOddDigits n)
(let loop ([n n])
(cond [(zero? n) 0]
[else
(let-values ([(q r) (quotient/remainder n 10)])
(+ (if (odd? r) r 0)
(loop q)))])))
One can get list of digits using following function which uses 'named let':
(define (getDigits n)
(let loop ((ol '()) ; start with an empty outlist
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
Then one can apply a filter using odd? function to get all odd elements of list- and then apply 'apply' function with '+' to add all those elements:
(apply + (filter
(lambda(x)
(odd? x))
digitList))
Together following can be the full function:
(define (addOddDigits N)
(define (getDigits n)
(let loop ((ol '())
(n n))
(let-values (((q r) (quotient/remainder n 10)))
(if (= q 0) (cons r ol)
(loop (cons r ol) q)))))
(define digitList (getDigits N))
(println digitList)
(apply + (filter
(lambda(x)
(odd? x))
digitList)))
Testing:
(addOddDigits 156)
Output:
'(1 5 6)
6
Your basecase is if n < 10. Because you are then on the last digit.
You then need to check if it's odd, and if so return it. Else, return the addition qualifier(0).
If n > 10, you remainder off the first digit, then test it for odd.
If odd, then add it to a recursive call, sending in the quotient of 10(shaves off the digit you just added).
Else, you recursively call add-odds with the quotient of 10, without adding the current digit.
Here it is in a recursive form(Scheme LOVES recursion) :
(define add-odds
(lambda (n)
(if(< n 10)
(if(= (remainder n 2) 1)
n
0)
(if(= (remainder (remainder n 10) 2) 1)
(+ (remainder n 10) (add-odds (quotient n 10)))
(add-odds(quotient n 10))))))
First get a (reversed) list of digits with simple recursive implementation:
(define (list-digits n)
(if (zero? n) '()
(let-values ([(q r) (quotient/remainder n 10)])
(cons r (list-digits q)))))
then filter the odd ones and sum them:
(define (sum-of-odd-digits n)
(apply + (filter odd? (list-digits n))))
Note: (list-digits 0) returns '() but it is ok for later usage.
More accurate list-digits iterative implementation (produce list of digits in right order):
(define (list-digits n)
(define (iter n acc)
(if (zero? n) acc
(let-values ([(q r) (quotient/remainder n 10)])
(iter q (cons r acc)))))
(iter n '()))
I am trying to write a code in LISP to multiply two 64-bit numbers.
Using SBCL on ubuntu platform to compile program.
My algorithm is as follows.
1) Convert first number into 64-bit binary representation.
2) Perform binary addition of first number with itself second number of times.
I wrote following function to convert decimal number into binary (takes decimal number & empty list as parameter)
(defun bin (N B)
(cond
((= N 0) B)
((evenp N)(bin (round (/ N 2)) (cons 0 B)))
((oddp N) (bin (floor (/ N 2)) (cons 1 B)))
))
Following function to to perform binary addition.( takes nos of bits, initial carry, first binary no, second binary no, empty list)
(defun addbin (n carry L1 L2 L3)
(cond
((< n 0) (cons carry L3))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 0) (= carry 0)) (addbin (- n 1) 0 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 0) (= carry 1)) (addbin (- n 1) 0 L1 L2 (cons 1 L3)))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 1) (= carry 0)) (addbin (- n 1) 0 L1 L2 (cons 1 L3)))
((and (= (lastE L1 n) 0) (= (lastE L2 n) 1) (= carry 1)) (addbin (- n 1) 1 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 0) (= carry 0)) (addbin (- n 1) 0 L1 L2 (cons 1 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 0) (= carry 1)) (addbin (- n 1) 1 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 1) (= carry 0)) (addbin (- n 1) 1 L1 L2 (cons 0 L3)))
((and (= (lastE L1 n) 1) (= (lastE L2 n) 1) (= carry 1)) (addbin (- n 1) 1 L1 L2 (cons 1 L3)))
))
supplementary function to return nth bit in binary number is (takes list & n)
(defun lastE (L n)
(cond
((= n 0) (first L))
(t (lastE (rest L) (- n 1)))
))
and multiplication function as
(defun bin_mult(nA A B)
(cond
((= B 1) A)
(t (bin_mult (addbin (- (length A) 1) 0 A nA ()) A (- B 1)))
))
and I am executing following piece of code to perform multiplication
(print "Enter two numbers to be multiplied")
(finish-output nil)
(defvar num1)
(defvar num2)
(defvar a)
(setq num1 (read))
(setq num2 (read))
(setq a (bin num1 ()))
(defvar cnt)
(setq cnt (integer-length num1))
(print cnt)
(dotimes (i (- 63 cnt))
(push 0 a)
)
(print "First number in binary format is" )
(print a)
(print "Multiplication two numbers with concurrency is")
(print (bin_mult a a num2))
I am getting following output (for 10*4)
(1 0 1 0)
I tried tracing the execution of bin_mult function on command prompt.
I am getting following output for (trace bin_mult x x 4) where x is (1 0 1 0)
(bin_mult x x 4)
0: (BIN_MULT (1 0 1 0) (1 0 1 0) 4)
1: (BIN_MULT (1 0 1 0 0) (1 0 1 0) 3)
2: (BIN_MULT (1 0 1 0 0) (1 0 1 0) 2)
3: (BIN_MULT (1 0 1 0 0) (1 0 1 0) 1)
3: BIN_MULT returned (1 0 1 0)
2: BIN_MULT returned (1 0 1 0)
1: BIN_MULT returned (1 0 1 0)
0: BIN_MULT returned (1 0 1 0)
(1 0 1 0)
Somehow intermediate results are not getting added.
Kindly help in resolving bug in this piece of code..
Thank you..
I'm not sure what you are trying to do, but you can just do the multiplication and simulate overflow later.
(defun multiply-overflow (bits &rest xs)
(let ((result (reduce #'* xs :initial-value 1)))
(multiple-value-bind (_ remainder) (floor result (1- (ash 1 bits)))
remainder)))
(multiply-overflow 64 1000000000000 1000000000000)
; ==> 2003764205206950850