Home > other >  How to determine if a number is the largest element in a list - Using Racket
How to determine if a number is the largest element in a list - Using Racket

Time:10-18

I'm trying to write a function for peaks which consumes list to produce a sublist that consists of all the peaks of the original list. ex. (peaks (cons 1 (cons 6 (cons 4 (cons 5 empty))))) should produce (cons 6 (cons 5 empty))

MY answer seems right but I think I messed up somewhere because it's not the right answer. I did a helper function using recursion to determine the maximum number in the list and then subbed that into another recursion function to create a sublist consisting of maximum numbers.

Any advice on where I messed up? We just started learning recursions and this is the only question that tripping me up.

  (cond
    [(empty? (rest lon)) (first lon)]
    [else (max (first lon) (greatest (rest lon)))]))
 

(define (peaks lon)
  (cond 
    [(empty? (rest lon)) lon]
    [(equal? (first lon) (greatest lon)) (cons (first lon) (peaks (rest lon)))]
    [else (peaks (rest lon))]))```


  

CodePudding user response:

A possible solution is:

(define (peaks lst)
  (cond [(empty? lst) lst]
        [(empty? (rest lst)) lst]
        [(empty? (rest (rest lst))) (list (max (first lst) (second lst)))]
        [(<= (first lst) (second lst)) (peaks (rest lst))]
        [else (cons (first lst) (peaks (rest (rest lst))))]))

Examples:

> (peaks '(1 6 4 5))
'(6 5)

> (peaks '(9 1 2 6 7 3 4 5 0 8))
'(9 7 5 8)

> (peaks '())
'()

> (peaks '(7))
'(7)

> (peaks '(7 3))
'(7)

> (peaks '(3 4))
'(4)

> (peaks '(5 0 8))
'(5 8)

> (peaks '(6 7 3))
'(7)

CodePudding user response:

I might approach it like this. First I write a function is-peak which determines if three (3) adjacent elements contain a peak in the middle element -

(define (is-peak a b c)
  (and (< a b) (> b c)))

Then I write a peaks procedure using pattern match for lists containing elements 0, 1, 2, 3, or more elements -

(define (peaks ls)
  (match ls
    ;; 0, 1, or 2-element lists do not have peaks
    [(list) null]
    [(list a) null]
    [(list a b) null]

    ;; 3-element lists could have at most 1 peak
    [(list a b c)
     (if (is-peak a b c)
         (list b)
         null)]
    
    ;; 4 elements or more
    [(list a b c d ...)
     (if (is-peak a b c)
         (cons b (peaks (cddr ls)))
         (peaks (cdr ls)))]))
(peaks (list 1 2 1 3 4 5 4 2 1 5 6 7 4))
'(2 5 7)

We can visualize the linear process and track the values of a, b, c, d .... Notice how cddr allows us to fast-forward one element after a peak is found. This is because a peak can never be adjacent to another peak -

a b c d...
1 2 (peak) 1 3 4 5 4 2 1 5 6 7 4
1 3 4 5 4 2 1 5 6 7 4
3 4 5 4 2 1 5 6 7 4
4 5 (peak) 4 2 1 5 6 7 4
4 2 1 5 6 7 4
2 1 5 6 7 4
1 5 6 7 4
5 6 7 4
6 7 (peak) 4

Now we'll consider some other inputs for peaks -

(peaks (list 1 2 3 2 1))
(peaks (list 3 2 1 2 3))
(peaks null)
'(3)
'()
'()
  • Related