How to not recurse twice in LISP - lisp

I'm trying to write a program that returns the Pell numbers sequence based on a given number.
For example (pellNumb 6) should return a list (0 1 2 5 12 29 70)
This is my code so far.
I am able of calculating the numbers, but I am not able of skipping the double recursion.
(defun base (n)
(if (= n 0)
0
(if (= n 1)
1)))
(defun pellNumb (n)
(if (or (= n 0) (= n 1))
(base n)
(let ((x (pellNumb (- n 2))))
(setq y (+ (* 2 (pellNumb (- n 1))) x))
(print y))))
The output for (pellNumb 4) is 2 2 5 12, and this is because i'm recursing to (pellNumb 2) twice.
Is there a way to skip that, and store these values in a list ?
Thanks!

Get the nth number
Yes, there is a way - use multiple values:
(defun pell-numbers (n)
"Return the n-th Pell number, n-1 number is returned as the 2nd value.
See https://oeis.org/A000129, https://en.wikipedia.org/wiki/Pell_number"
(check-type n (integer 0))
(cond ((= n 0) (values 0 0))
((= n 1) (values 1 0))
(t (multiple-value-bind (prev prev-1) (pell-numbers (1- n))
(values (+ (* 2 prev) prev-1)
prev)))))
(pell-numbers 10)
==> 2378 ; 985
This is a standard trick for recursive sequences which depend on several previous values, such as the Fibonacci.
Performance
Note that your double recursion means that (pell-numbers n) has exponential(!) performance (computation requires O(2^n) time), while my single recursion is linear (i.e., O(n)).
Moreover, Fibonacci numbers have a convenient property which allows a logarithmic recursive implementation, i.e., taking O(log(n)) time.
Get all the numbers up to n in a list
If you need all numbers up to the nth, you need a simple loop:
(defun pell-numbers-loop (n)
(loop repeat n
for cur = 1 then (+ (* 2 cur) prev)
and prev = 0 then cur
collect cur))
(pell-numbers-loop 10)
==> (1 2 5 12 29 70 169 408 985 2378)
If you insist on recursion:
(defun pell-numbers-recursive (n)
(labels ((pnr (n)
(cond ((= n 0) (list 0))
((= n 1) (list 1 0))
(t (let ((prev (pnr (1- n))))
(cons (+ (* 2 (first prev)) (second prev))
prev))))))
(nreverse (pnr n))))
(pell-numbers-recursive 10)
==> (0 1 2 5 12 29 70 169 408 985 2378)
Note that the recursion is non-tail, so the loop version is probably more efficient.
One can, of course, produce a tail recursive version:
(defun pell-numbers-tail (n)
(labels ((pnt (i prev)
(if (= i 0)
prev ; done
(pnt (1- i)
(cond ((null prev) (list 0)) ; n=0
((null (cdr prev)) (cons 1 prev)) ; n=1
(t
(cons (+ (* 2 (or (first prev) 1))
(or (second prev) 0))
prev)))))))
(nreverse (pnt (1+ n) ()))))
(pell-numbers-tail 10)
==> (0 1 2 5 12 29 70 169 408 985 2378)

Related

Make a program that determines the average of its digits from a number

I must make a program that averages the digits of a number, but it is impossible for me, especially the module of a division (remainder).
What I can do?
(define (digitos number)
(cond
[(and (>= number 1) (< number 11)) 1]
[else (+ 1 (digitos (/ number 10)))]))
(define (modulo_ n m)
(cond
[(real? n) (- n (* (floor (/ n m)) m))]
[else (remainder n m)]))
(define (sumatoria number)
(cond
[(equal? number 0) 0]
[else (+ (modulo_ number 10) (sumatoria (/ number 10)))]))
(define (promedio number)
(/ (sumatoria number) (digitos number)))
;(promedio 40) ;3
update:
your question is repeated
How to count number of digits?
Count digits in list Racket
Return the sum of odd digits of a number
Convert number to list of digits
; only consider nature number 0,1,2,3,...
; if you want input Decimal use number->string
(define (cut-right-digit n)
(/ (- n (remainder n 10)) 10))
(define (sum-each-digit n result)
(cond
[(<= 0 n 9)
(+ result n)]
[else
(sum-each-digit (cut-right-digit n) (+ result (remainder n 10)))]))
(define (digits n result)
(cond
[(<= 0 n 9)
result]
[else
(digits (cut-right-digit n) (+ 1 result))]))
(define (avg-digits n)
(/ (sum-each-digit n 0) (digits n 1)))
;;; TEST
(avg-digits 0) ; 0
(avg-digits 1) ; 1
(avg-digits 11111) ; 1
(avg-digits 10203040506789) ; (/ 55 14)
(avg-digits 101001) ; 1/2

Racket, split a list in two different size lists. And randomly

I would like to code a program that given a list and a percentage, splits the list in two different size lists. It should have random pick of the elements, that way the created lists are always different.
These code is able to do that:
(define (clamp x a b)
(max (min x b) a))
(define (split pct xs)
(define pos (exact-round (* (clamp pct 0.0 1.0) (length xs))))
(split-at (shuffle xs) pos))
Here is an example:
(split 0.25 '(1 2 3 4 5 6 7 8 9))
'(6 2)
'(3 7 1 4 5 8 9)
But, instead of "shuffle" I would like to use this function to achieve the same:
(define (get-randomly-no-pair list)
(list-ref list (random (length list))))
so, get-randomly-no-pair takes one element randomly from the initial list. And all the elements are used to create both lists.
(define (shuffle-list lst)
(define indexes (shuffle (range (length lst))))
(lambda ()
(begin0
(list-ref lst (car indexes))
(set! indexes (cdr indexes)))))
(define gen (shuffle-list (list 10 12 14 16 18 20))
(gen) ; ==> 14 (e.g.)
Now I see you assume you need to pass the list then I would rather make a mapper:
(define (shuffle-accessor len)
(define indexes (list->vector (shuffle (range len))))
(lambda (lst index)
(list-ref lst (vector-ref indexes index))))
(define lst3-ref (shuffle-accessor 3))
(lst3-ref '(1 2 3) 0) ; ==> 3 (e.g.)
(lst3-ref '(6 7 8) 0) ; ==> 8

Lisp recursive square use one variables

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))

calculate sum of multiples of 3 & 5 below 1000

I have written the following program to calculate the sum of all multiples of 3 & 5 below 1000 in scheme. However, it gives me an incorrect output.
Any help would be much appreciated.
(define (multiples)
(define (calc a sum ctr cir)
(cond (> a 1000) (sum)
(= ctr 7) (calc (+ a (list-ref cir 0)) (+ sum a) 0 (list 3 2 1 3 1 2 3))
(else (calc (+ a (list-ref cir ctr)) (+ sum a) (+ 1 ctr) (list 3 2 1 3 1 2 3)))))
(calc 0 0 0 (list 3 2 1 3 1 2 3)))
You can simply port imperative style solution to functional Scheme by using an accumulator(sum parameter) and a target parameter to test when to stop summing:
(define (multiples)
(define (multiples-iter num sum target)
(if (> num target)
sum
(multiples-iter (+ 1 num)
(if (or (zero? (mod num 3)) (zero? (mod num 5)))
(+ sum num)
sum)
target)))
(multiples-iter 0 0 1000))
Here's my (Racket-specific) solution, which doesn't involve lots of (or, for that matter, any) modulo calls, and is completely general (so that you don't need to construct the (3 2 1 3 1 2 3) list that the OP has):
(define (sum-of-multiples a b limit)
(define (sum-of-multiple x)
(for/fold ((sum 0))
((i (in-range 0 limit x)))
(+ sum i)))
(- (+ (sum-of-multiple a) (sum-of-multiple b))
(sum-of-multiple (lcm a b))))
Test run:
> (sum-of-multiples 3 5 1000)
233168
If you're using Racket, there's a very compact way to do what you ask, using looping constructs:
(for/fold ([sum 0])
([i (in-range 1 1000)]
#:when (or (zero? (modulo i 3)) (zero? (modulo i 5))))
(+ sum i))
=> 233168
One problem is that your code is missing a pair of parentheses around the cond clauses.
In the line (cond (> a 1000) (sum) the condition is just> while a and 1000 are interpreted as forms to be evaluated if > is true (which it is), and thus 1000 will be returned as the result.
Two other problem (masked by the first one) is that you are initializing ctr to 0 when it reaches 7, while it should be set to the next value, i.e. 1, and that you are including 1000 in the result.
The corrected version of your function is
(define (multiples)
(define (calc a sum ctr cir)
(cond ((>= a 1000) sum)
((= ctr 7) (calc (+ a (list-ref cir 0)) (+ sum a) 1 (list 3 2 1 3 1 2 3)))
(else (calc (+ a (list-ref cir ctr)) (+ sum a) (+ 1 ctr) (list 3 2 1 3 1 2 3)))))
(calc 0 0 0 (list 3 2 1 3 1 2 3)))
The same algorithm can also be defined as a non-recursive function like this:
(define (multiples)
(do ((cir (list 3 2 1 3 1 2 3))
(ctr 0 (+ ctr 1))
(a 0 (+ a (list-ref cir (modulo ctr 7))))
(sum 0 (+ sum a)))
((>= a 1000) sum)))
(require-extension (srfi 1))
(define (sum-mod-3-5 upto)
(define (%sum-mod-3-5 so-far generator-position steps)
(let ((next (car generator-position)))
(if (> (+ steps next) upto)
so-far
(%sum-mod-3-5 (+ so-far steps)
(cdr generator-position)
(+ steps next)))))
(%sum-mod-3-5 0 (circular-list 3 2 1 3 1 2 3) 0)) ; 233168
For this particular task, it will do on average half the operations then you would do if incrementing the counter by one, also, one less if condition to check.
Also, modulo (as being division in disguise, probably) is more expensive then summation.
EDIT: I'm not a pro on modular system in different dialects of Scheme. The SRFI-1 extension here is only required to make it easier to create a circular list. I couldn't find an analogue to Common Lisp (#0=(3 2 1 3 1 2 3) . #0#), but perhaps, someone more knowledgeable will correct this.
If you absolutely want to use the "repeating pattern" method, you could go about it something like this.
This uses recursion on the list of intervals rather than relying on list-ref and explicit indexing.
(define (mults limit)
(define steps '(3 2 1 3 1 2 3))
(define (mults-help a sum ls)
(cond ((>= a limit) sum)
((null? ls) (mults-help a sum steps))
(else (mults-help (+ a (car ls))
(+ a sum)
(cdr ls)))))
(mults-help 0 0 steps))

Creating a list of Fibonacci numbers in Scheme?

I've made a basic program that output Fibonacci sequence for whatever length "n".
Here's the code I have:
(define (fibh n)
(if (< n 2)
n
(+ (fibh (- n 1)) (fibh (- n 2)))))
(define (fib n)
(do ((i 1 (+ i 1)))
((> i n))
(display (fibh i))))
It will output, for example, 112358.
What I want is a list such as (1 1 2 3 5 8).
Any explanation how to do this would be greatly appreciated.
(map fibh '(1 2 3 4 5 6))
would do the trick. If you don't want to enumerate the integers by hand, then implement a simple recursive function that will do that for you, like:
(define (count i n)
(if (= i n)
'()
(cons i (count (+ i 1) n))))
(Note: this is not tail-recursive, but with that algorithm to compute the Fibonacci numbers, that's not your prime concern.)
Petite Chez Scheme Version 8.3
Copyright (c) 1985-2011 Cadence Research Systems
> (define (fib n)
(let loop ((n n) (f2 1) (f1 1) (fs (list)))
(if (zero? n) (reverse fs)
(loop (- n 1) f1 (+ f2 f1) (cons f2 fs)))))
> (fib 50)
(1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584
4181 6765 10946 17711 28657 46368 75025 121393 196418 317811
514229 832040 1346269 2178309 3524578 5702887 9227465
14930352 24157817 39088169 63245986 102334155 165580141
267914296 433494437 701408733 1134903170 1836311903
2971215073 4807526976 7778742049 12586269025)