I'm trying to remove the last occurrence of a value from a list, and my program is failing during the recursive call with nested lists.
I have a function that counts the number of occurrences of the symbol:
(define (countOccurrences lst elem count)
(cond
[(empty? lst) count]
[(list? (car lst)) (countOccurrences (cdr lst) elem
(countOccurrences (car lst) elem count))]
[(equal? (car lst) elem) (countOccurrences (cdr lst) elem (add1 count))]
[else (countOccurrences (cdr lst) elem count)]))
And the main body is here:
(define (lastLess lst elem)
(let ((count (countOccurrences lst elem 0)))
(if (< 0 count)
(lastLessHelper lst elem count)
lst)))
Helper function:
(define (lastLessHelper lst elem count)
(cond
[(empty? lst) empty]
[(eq? count 0) (cdr lst)]
[(eq? (car lst) elem) (set! count (sub1 count))
(cond
[(eq? count 0) (cdr lst)]
[else (cons (car lst)
(lastLessHelper (cdr lst) elem count))])]
[(list? (car lst)) (cons (lastLessHelper (car lst) elem count)
(lastLessHelper (cdr lst) elem count))]
[else (cons (car lst) (lastLessHelper (cdr lst) elem count))]))
The problem is this line:
[(list? (car lst)) (cons (lastLessHelper (car lst) elem count) (lastLessHelper (cdr lst) elem count))]
I decrement the 'count' variable whenever the (car lst) is equal to elem, and during the first recursive call (lastLessHelper (car lst) elem count) it decrements correctly, but when that call returns and it recurses on the cdr lst: (lastLessHelper (cdr lst) elem count))] the value of 'count' returns to its original value.
It works for a normal list input, such as (lastLess '(1 2 3 2 4 5) '2)) I correctly get (1 2 3 4 5), but when using nested lists as input, such as (lastLess '(1 (2 3) 4 2 5) '2) it returns (1 (2 3) 4 2 5).
How to keep the value of 'count' during the recursive calls? I should note, there is probably easier ways to do this, but this is a homework exercise and we are forbidden to use the 'reverse' call.
EDIT: Sylwester's comment helped me understand. My problem wasn't counting the occurrences of an item, the problem was to remove the last occurrence of an item. My thought was to first count the occurrences of that item, then traverse the list and decrement that count until it was 0, then I would know to remove that item, and then just cons the rest of the list.