Given these definitions:
(define s 8)
(define p (/ s 2))
(define (f s p)
(cond [(or (> s 0) p) 'yes] [(< s 0) 'no]))
I want to evaluate this expression:
(f 0 (and (< s p) (> s 2)))
So far I have:
⇒ (f 0 (and (< 8 p) (> s 2)))
⇒ (f 0 (and (< 8 4) (> s 2)))
⇒ (f 0 (and false (> s 2)))
⇒ (f 0 false)
How do I finish this?
You need to replace this with the body of f (the cond expression) with the parameters replaced by their matching arguments.
Racket sees that f is a procedure and evaluates it's arguments:
(f 0 (and (< s p) (> s 2))) ; ==>
(f 0 (and (< 8 4) (> 8 2))) ; ==>
(f 0 (and #f #t)) ; ==>
(f 0 #f) ; s=0, p=#f
Then the arguments is substituted for the variables in the body of f:
; ==>
(cond [(or (> 0 0) #f) 'yes]
[(< 0 0) 'no])
since both (or (> 0 0) #f) and (< 0 0) are #f the result is the undefined value chosen by the implementation. In racket it's #<void>
; ==>
#<void>
This could have been avoided by always have a else term:
(define (f s p)
(cond [(or (> s 0) p) 'yes]
[(< s 0) 'no]
[else 'banana]))
(f 0 (and (< s p) (> s 2))) ; ==> banana
Related
I am trying to write a racket program that computes the sum of the first n terms in a fibonacci sequence without using recursion, and only using abstract list functions (so map, builld-list, foldr, foldl). I can use helper functions.
I'm stuck on how to make a list of the fibonacci numbers without using recursion. I thought I could use a lambda function:
(lambda (lst) (+ (list-ref lst (- (length lst) 1)) (list-ref lst (- (length lst 2)))))
But I am not sure how to generate the input list/how to add this to a function.
Once I have a fibonacci sequence I know I can just use (foldl + (car lst) (cdr lst)) to find the sum.
Could anyone explain to me how to make the fibonacci sequence/give me a hint?
; This is how I figure out
#|
(1 2 3 4 (0 1))
-> (1 2 3 (1 1))
-> (1 2 (1 2))
-> (1 (2 3))
-> (3 5)
|#
(define (fib n)
(cond
[(= n 0) 0]
[(= n 1) 1]
[(> n 1)
(second
(foldr (λ (no-use ls) (list (second ls) (+ (first ls) (second ls))))
'(0 1)
(build-list (- n 1) (λ (x) x))))]))
(fib 10)
(build-list 10 fib)
Upgrade version 2
(define (fib-v2 n)
(first
(foldr (λ (no-use ls) (list (second ls) (+ (first ls) (second ls))))
'(0 1)
(build-list n (λ (x) x)))))
(build-list 10 fib-v2)
fib-seq produces a list of first n fibonacci numbers and fib-sum produces the sum of first n fibonacci numbers.
; Number -> [List-of Number]
(define (fib-seq n)
(cond [(= n 0) '()]
[(= n 1) '(0)]
[else (reverse
(for/fold ([lon '(1 0)]) ([_ (in-range (- n 2))])
(cons (apply + (take lon 2)) lon)))]))
; Number -> Number
(define (fib-sum n)
(if (= n 0) 0 (add1 (apply + (take (fib-seq n) (sub1 n))))))
Note: fib-sum is equivalent to the following recursive versions:
(define (fib0 n)
(if (< n 2) n (+ (fib0 (- n 1)) (fib0 (- n 2)))))
(define (fib1 n)
(let loop ((cnt 0) (a 0) (b 1))
(if (= n cnt) a (loop (+ cnt 1) b (+ a b)))))
(define (fib2 n (a 0) (b 1))
(if (= n 0) 0 (if (< n 2) 1 (+ a (fib2 (- n 1) b (+ a b))))))
Once I have a fibonacci sequence I know I can just use (foldl + (car lst) (cdr lst)) to find the sum.
Note that you don't have to generate an intermediate sequence to find the sum. Consider the (fast) matrix exponentiation solution:
(require math/matrix)
(define (fib3 n)
(matrix-ref (matrix-expt (matrix ([1 1] [1 0])) n) 1 0))
Testing:
(require rackunit)
(check-true
(let* ([l (build-list 20 identity)]
[fl (list fib0 fib1 fib2 fib3 fib-sum)]
[ll (make-list (length fl) l)])
(andmap (λ (x) (equal? (map fib0 l) x))
(map (λ (x y) (map x y)) fl ll))))
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))
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
I have a non-linear list. I need to find out the number of sub-lists at any level in the initial list, for which the sum of the numerical atoms at the odd levels, is an even number. The superficial level is counted as 1. I wrote something like:
(defun numbering (l level)
;counts the levels that verify the initial conditions
(cond
((null l) l)
((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l))))
(T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))
)
)
(defun verify (n)
;returns true if the parameter "n" is even, or NIL, otherwise
(cond
((numberp n)(= (mod n 2) 0))
(T f)
)
)
(defun sumlist (l)
;returns the sum of the numerical atoms from a list, at its superficial level
(cond
((null l) 0)
((numberp (car l)) (+ (car l) (sumlist(cdr l))))
(T (sumlist(cdr l)))
)
)
(defun mainNumbering (l)
; main function, for initializing the level with 1
(numbering l 1)
)
If I run "(mainnum '(1 2 (a b 4) 8 (6 g)))" I get the error: " Undefined function MAPCAR# called with arguments ((LAMBDA (A) (NUMEROTARE A #)) (1 2 (A B 4) 8 (6 G)))."
Does anyone know, what am I missing? Thanks in advance!
Well, that's true, there is no such function as mapcar#, it's just a typo, you missing space in this line:
(T (apply '+ (mapcar#' (lambda (a) (numbering a (+ 1 level))) l )))
It should be:
(T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))
Here is a possible solution, if I have interpreted correctly your specification:
(defun sum(l)
(loop for x in l when (numberp x) sum x))
(defun test(l &optional (level 1))
(+ (if (and (oddp level) (evenp (sum l))) 1 0)
(loop for x in l when (listp x) sum (test x (1+ level)))))
(test '(1 2 (a b 4) 7 (6 2 g) (7 1 (2 (3) (4 4) 2) 1 a))) ; => 2
The function sum applied to a list returns the sum of all its numbers (without entering in its sublists).
The function test, for a list with an odd level, sum its numbers, and, if the result is even, add 1 to the sum of the results of the function applied to the sublists of l, 0 otherwise.
in numbering you should add the case when l is a number,so
(defun numbering (l level)
;counts the levels that verify the initial conditions
(cond
((null l) l)
((atom l)0)
((and (verify (sumlist l)) (not (verify level))) (+ 1 (apply '+ (mapcar #' (lambda (a) (numbering a (+ 1 level))) l))))
(T (apply '+ (mapcar #'(lambda (a) (numbering a (+ 1 level))) l )))
)
)
will resolve the problem
Given a list, how would I select a new list, containing a slice of the original list (Given offset and number of elements) ?
EDIT:
Good suggestions so far. Isn't there something specified in one of the SRFI's? This appears to be a very fundamental thing, so I'm surprised that I need to implement it in user-land.
Strangely, slice is not provided with SRFI-1 but you can make it shorter by using SRFI-1's take and drop:
(define (slice l offset n)
(take (drop l offset) n))
I thought that one of the extensions I've used with Scheme, like the PLT Scheme library or Swindle, would have this built-in, but it doesn't seem to be the case. It's not even defined in the new R6RS libraries.
The following code will do what you want:
(define get-n-items
(lambda (lst num)
(if (> num 0)
(cons (car lst) (get-n-items (cdr lst) (- num 1)))
'()))) ;'
(define slice
(lambda (lst start count)
(if (> start 1)
(slice (cdr lst) (- start 1) count)
(get-n-items lst count))))
Example:
> (define l '(2 3 4 5 6 7 8 9)) ;'
()
> l
(2 3 4 5 6 7 8 9)
> (slice l 2 4)
(3 4 5 6)
>
You can try this function:
subseq sequence start &optional end
The start parameter is your offset. The end parameter can be easily turned into the number of elements to grab by simply adding start + number-of-elements.
A small bonus is that subseq works on all sequences, this includes not only lists but also string and vectors.
Edit: It seems that not all lisp implementations have subseq, though it will do the job just fine if you have it.
(define (sublist list start number)
(cond ((> start 0) (sublist (cdr list) (- start 1) number))
((> number 0) (cons (car list)
(sublist (cdr list) 0 (- number 1))))
(else '())))
Try something like this:
(define (slice l offset length)
(if (null? l)
l
(if (> offset 0)
(slice (cdr l) (- offset 1) length)
(if (> length 0)
(cons (car l) (slice (cdr l) 0 (- length 1)))
'()))))
Here's my implementation of slice that uses a proper tail call
(define (slice a b xs (ys null))
(cond ((> a 0) (slice (- a 1) b (cdr xs) ys))
((> b 0) (slice a (- b 1) (cdr xs) (cons (car xs) ys)))
(else (reverse ys))))
(slice 0 3 '(A B C D E F G)) ;=> '(A B C)
(slice 2 4 '(A B C D E F G)) ;=> '(C D E F)