fork(1) download
  1.  
  2. (define scan-left
  3. (lambda (fn initial elements)
  4. (if (null? elements)
  5. initial
  6. (scan-left fn (fn initial elements) (cdr elements)))))
  7.  
  8. ;;(scan-left (lambda (state current) (display current) (newline)) '() '(A B C))
  9.  
  10. (define delete-last-occurrence
  11. (lambda (elements token)
  12. ;; We're going to scan through the list, keeping a state consisting of
  13. ;; - the cons cell *BEFORE* the (currently) last occurrence
  14. ;; - the previous cons cell
  15. (define make-state
  16. (lambda (cell-b prev-cell)
  17. (cons cell-b prev-cell)))
  18. (define cell-before
  19. (lambda (state)
  20. (car state)))
  21. (define previous-cell
  22. (lambda (state)
  23. (cdr state)))
  24. ;; If the head of the current (sub)list is equal to the token,
  25. ;; then remember the previous cons cell as the cell before the
  26. ;; (currently) last occurrence.
  27. ;; Else just update the previous cell.
  28. (define consume-element
  29. (lambda (state current)
  30. (if (eqv? (car current) token)
  31. (make-state (previous-cell state) current)
  32. (make-state (cell-before state) current))))
  33. ;; Handle the easy cases separately.
  34. (cond ((null? elements) '())
  35. ((null? (cdr elements))
  36. (if (eqv? (car elements) token) '() elements))
  37. (else
  38. (let ((state
  39. (scan-left consume-element
  40. (make-state '() elements)
  41. (cdr elements))))
  42. (if (pair? (cell-before state))
  43. ;; We found an occurrence, and the cell-before is the ... well
  44. ;; cell before that last occurrence. Hence we modify it such that
  45. ;; its cdr no longer "points" to the cell whose car is the last
  46. ;; occurrence but instead "skips" that element.
  47. (let ((cell-to-modify (cell-before state)))
  48. (set-cdr! cell-to-modify
  49. (cdr (cdr (cell-before state))))
  50. elements)
  51. ;; No occurrence found. Either there is none, or only the first
  52. ;; element is equal to the token.
  53. (if (eqv? (car elements) token)
  54. (cdr elements)
  55. elements)))))))
  56.  
  57.  
  58. (display (delete-last-occurrence '() 'A))(newline)
  59. (display (delete-last-occurrence '(A) 'A))(newline)
  60. (display (delete-last-occurrence '(A B) 'A))(newline)
  61. (display (delete-last-occurrence '(A B A) 'A))(newline)
  62. (display (delete-last-occurrence '(A B A B) 'A))(newline)
  63.  
  64.  
  65.  
Success #stdin #stdout 0.01s 8672KB
stdin
Standard input is empty
stdout
()
()
(B)
(A B)
(A B B)