I am trying to use the ability to have multiple "then-expressions" for a conditional in cond but I've yet to be successful in that. The goal is to have a function take in a list and spit out the count.
(define (countInc aList)
(let ((count 0))
(lambda ()
(cond
[(= (length aList) 0) '()]
[(> (second aList) (first aList)) (set! count (+ count 1)) (countInc (rest aList))]
(else (countInc (rest aList)))))))
(check-expect (countInc '(1 2 3 4 5 6)) 5)
To explain, answer is 5 because 2 > 1, 3 > 2, 4 > 3, 5 > 4, and 6 > 5.
Notice that your base case is incorrect: you're returning an empty list, shouldn't we be returning the counter? By the way, your procedure is actually returning a lambda
with no arguments, that's not what you want to do.
Also: you should never use length
for determining if a list is empty, and in general you should avoid using set!
unless strictly necessary - Scheme favors a functional-programming style.
What you want to do can be written without mutating state variables, the trick is to keep track of the previous element while traversing the list - and beware of the many edge cases!
(define (countInc lst)
; edge cases
(if (or (empty? lst) (empty? (rest lst)))
0
; use a named let or a helper procedure
(let loop ((prev (first lst))
(lst (rest lst)))
(cond ((empty? (rest lst)) ; base case
(if (> (first lst) prev) 1 0))
((> (first lst) prev) ; found one, count it
(+ 1 (loop (first lst) (rest lst))))
(else ; skip this one
(loop (first lst) (rest lst)))))))
This works fine even for the edge cases, I've provided tests for them:
(countInc '())
=> 0
(countInc '(1))
=> 0
(countInc '(2 1))
=> 0
(countInc '(1 2))
=> 1
(countInc '(4 1 3 2 5 6))
=> 3
(countInc '(1 2 3 4 5 6))
=> 5
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.