# uncoupling lists

Write a function that accepts a list and returns a copy of the list with couples (successive pairs of equal elements) removed.

``` \$ cat dc.rkt
#lang racket

(define (decouple l)

; Return a copy of the given list with all adjacent pairs of equal elements
; removed.

; This code is ridiculous.  The problem has an elegant one-pass solution.

(define (dc done pending decoupled reversals)

(if (null? pending)

(if decoupled
(dc '() done #f (+ reversals 1))
(if (odd? reversals) (reverse done) done))

(let ((e (car pending))
(next-pending (cdr pending)))

(cond

((null? next-pending)
(let ((done (cons e done)))
(if decoupled
(dc '() done #f (+ reversals 1))
(if (odd? reversals) (reverse done) done))))

((eq? e (car next-pending))
(dc done (cdr next-pending) #t reversals))

(#t
(dc (cons e done) next-pending decoupled reversals))))))

(dc '() l #f 1))

(require rackunit)

(check-equal? (decouple '(red blue green green blue red yellow)) '(yellow))
(check-equal? (decouple '(red red red)) '(red))
(check-equal? (decouple '(red red)) '())
(check-equal? (decouple '(red)) '(red))
(check-equal? (decouple '(red red blue blue)) '())
(check-equal? (decouple '(red red blue green green)) '(blue))

(check-equal? (decouple '()) '())
(check-equal? (decouple '(1)) '(1))
(check-equal? (decouple '(1 1)) '())
(check-equal? (decouple '(1 1 1)) '(1))
(check-equal? (decouple '(1 1 1 1)) '())
(check-equal? (decouple '(1 2 2 1)) '())
(check-equal? (decouple '(a 1 1 b)) '(a b))
(check-equal? (decouple '(a b 1 1 b c)) '(a c))
(check-equal? (decouple '(a 1 1 1 b 1 1 b 1 c)) '(a c))

\$ racket dc.rkt

\$
```