CanadianBeaver
CanadianBeaver

Reputation: 81

How do I determine if a list in Racket is in ascending order, descending order, or neither

I need to create a function that identifies if a list in in increasing or decreasing order. If the list is in increasing order then the function will output "ascending", if the list is in decreasing order then the function will output "descending", if the list is neither increasing or decreasing the list outputs "mixed".

Here is my code so far and obviously it doesn't work. I'm still new to doing recursion in Racket so I'm pretty sure this is not how you properly do recursion. I've seen solutions to determine if the list is in ascending order but those don't help because here I have to examine 3 different cases here as well including the base case.

(define (order? L)
  (cond
    [(empty? L) '()]
    [(> (first L) (first (rest L)))
     (order? (rest L)) "descending"]
    [(< (first L) (first (rest L)))
    (order? (rest L)) "ascending"]
    [else ("mixed")]))

This is 3 examples that show the 3 different cases.

(check-expect (order? (list 2 4 6 8)) "ascending")
(check-expect (order? (list 2 8 4 1 9 10 2)) "mixed")
(check-expect (order? (list 9 8 7 6 3 2)) "descending")

Upvotes: 0

Views: 315

Answers (1)

&#211;scar L&#243;pez
&#211;scar L&#243;pez

Reputation: 236114

Actually, for this problem you don't need to use recursion. The <= and >= operators are all you need (< and > are not enough, they'll fail if there are repeated elements):

(define (order? lst)
  (cond ((apply >= lst)  "ascending")
        ((apply <= lst) "descending")
        (else                "mixed")))

The above works because <= and >= accept multiple parameters, and to test if a list is in ascending order we just have to see if this is true:

(<= 2 4 6 8)
=> #t

And similarly for the descending case. We use apply to pass a list as argument to an operator that supports a variable number of arguments. It works as expected:

(order? (list 2 4 6 8))
=> "ascending"
(order? (list 2 8 4 1 9 10 2))
=> "mixed"
(order? (list 9 8 7 6 3 2))
=> "descending"

To solve the problem using recursion you'd basically have to apply <= or >= on each element and the next one, stopping if you find a false condition.

You should write two helper procedures, one for testing if the list is ascendent, the other for testing if it's descendent.

The main conceptual problem of your attempted solution is that you're not stopping in the right moment, and the base case is wrong - it should return true on each of your two helpers.

Upvotes: 1

Related Questions