Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

recursive function accepts list in scheme

Tags:

scheme

I'm new to Scheme and this is my very first Functional language. Implementing almost everything recursively seems to be awkward for me. Nevertheless, was able to implement functions of Factorial and Fibonacci problems having a single integer input.

However, what about when your function has an input of a list? Suppose this exercise:

FUNCTION: ret10 - extracts and returns as a list all the numbers greater than 10 that are found in a given list, guile> (ret10 ‘(x e (h n) 1 23 12 o)) OUTPUT: (23 12)

Should I have (define c(list)) as the argument of my function in this? or is there any other way?

Please help. Thanks!


Here's my derived solution based on sir Óscar López's answer below.. hope this helps others:

(define (ret10 lst)
    (cond
        ((null? lst) '())

        ((and (number? (car lst)) (> (car lst) 10))
            (cons (car lst)
            (ret10 (cdr lst))))

        (else (ret10 (cdr lst)))
    )
)
like image 547
Kevin Lloyd Bernal Avatar asked Apr 27 '26 14:04

Kevin Lloyd Bernal


1 Answers

This kind of problem where you receive a list as input and return another list as output has a well-known template for a solution. I'd start by recommending you take a look at The Little Schemer or How to Design Programs, either book will teach you the correct way to start thinking about the solution.

First, I'll show you how to solve a similar problem: copying a list, exactly as it comes. That'll demonstrate the general structure of the solution:

(define (copy lst)
  (cond ((null? lst)                ; if the input list is empty
         '())                       ; then return the empty list
        (else                       ; otherwise create a new list
         (cons (car lst)            ; `cons` the first element
               (copy (cdr lst)))))) ; and advance recursion over rest of list

Now let's see how the above relates to your problem. Clearly, the base case for the recursion will be the same. What's different is that we cons the first element with the rest of the list only if it's a number (hint: use the number? procedure) and it's greater than 10. If the condition doesn't hold, we just advance the recursion, without consing anything. Here's the general idea, fill-in the blanks:

(define (ret10 lst)
  (cond (<???> <???>)          ; base case: empty list
        (<???>                 ; if the condition holds
         (cons <???>           ; `cons` first element
               (ret10 <???>))) ; and advance recursion
        (else                  ; otherwise
         (ret10 <???>))))      ; simply advance recursion

Don't forget to test it:

(ret10 '(x e (h n) 1 23 12 o))
=> '(23 12)

As a final note: normally you'd solve this problem using the filter procedure - which takes as input a list and returns as output another list with only the elements that satisfy a given predicate. After you learn and understand how to write a solution "by hand", take a look at filter and write the solution using it, just to compare different approaches.

like image 140
Óscar López Avatar answered Apr 29 '26 05:04

Óscar López



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!