CSE 240: Scheme Mastery


Q1: sumEven - The Recursive Challenge

1.1: Named Procedure

A standard recursive function. The base case checks for an empty list, and the recursive step branches based on whether the current element is even.

(define (sumEven lst)
  ; Base Case: If the list is empty, the sum is 0.
  (if (null? lst)
      0
      ; Recursive Step:
      (if (even? (car lst))
          ; If head is even, add it to the sum of the rest.
          (+ (car lst) (sumEven (cdr lst)))
          ; If head is odd, skip it and sum the rest.
          (sumEven (cdr lst)))))

1.2: Unnamed Procedure (IILE)

Key Concept: Recursion Without a Name

The prompt asks for an unnamed lambda that calls itself. How? The solution is to use letrec to create a locally-scoped, recursive helper function. This keeps the main lambda anonymous while still allowing recursion.

; Immediately invoke an unnamed lambda that takes the list.
((lambda (lst)
   ; 'letrec' creates a local helper that can call itself.
   (letrec (
        (sum-even-helper
         (lambda (sub-list)
           (if (null? sub-list)
               0
               (if (even? (car sub-list))
                   (+ (car sub-list) (sum-even-helper (cdr sub-list)))
                   (sum-even-helper (cdr sub-list)))))))
     ; The body of the main lambda just starts the recursion.
     (sum-even-helper lst)))
 '(1 3 -4 5 6 -7))

Q2 & Q3: The `append` Power-Up

These are best solved using the built-in append procedure. It's the most direct and efficient tool for the job.

; Q2: Add to the back
(define (list-push-back lst new-list)
  (append lst new-list))

; Q3: Add to the front
(define (list-push-front lst new-list)
  (append new-list lst))

Q4 & Q5: Drawing from Lists

Q4: list-draw-front

A classic recursive pattern: build a new list by taking the `car` and `cons`-ing it onto the recursive result of the `cdr`.

(define (list-draw-front n lst)
  ; Base Case: Stop if n is 0 or the list is empty.
  (if (or (= n 0) (null? lst))
      '()
      ; Recursive Step: Take the first element and recurse.
      (cons (car lst) (list-draw-front (- n 1) (cdr lst)))))

Q5: list-draw-back (The clever way)

A great example of functional composition. Instead of writing complex recursion, reuse existing functions. To get the last N items, just reverse the list, take the *first* N items, and reverse the result back!

(define (list-draw-back n lst)
  (reverse (list-draw-front n (reverse lst))))

Q6: Perfect Shuffle

This recursion masterfully weaves two lists together. It takes one element from each list and prepends them to the result of shuffling the rest of the lists.

; The list-shuffle procedure works by recursively building the shuffled list.
; If the first list is empty, both lists are empty, so we return an empty
; list to end the recursion. The algorithm takes the first element from lst1
; and the first element from lst2, prepends them to the result of shuffling
; the rest of the lists, and builds the final list in an alternating order.
(define (list-shuffle lst1 lst2)
  ; Base Case: If one list is empty, we're done.
  (if (null? lst1)
      '()
      ; Recursive Step: Prepend head of lst1, then head of lst2...
      (cons (car lst1)
            ; ...to the result of shuffling the rest of the lists.
            (cons (car lst2)
                  (list-shuffle (cdr lst1) (cdr lst2))))))