-
Notifications
You must be signed in to change notification settings - Fork 21
/
Copy pathadjacent-duplicates.lisp
33 lines (32 loc) · 1.09 KB
/
adjacent-duplicates.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
(defpackage :cp/adjacent-duplicates
(:use :cl)
(:export #:delete-adjacent-duplicates))
(in-package :cp/adjacent-duplicates)
(declaim (inline delete-adjacent-duplicates))
(defun delete-adjacent-duplicates (seq &key (test #'eql))
"Destructively deletes adjacent duplicates of SEQ: e.g. #(1 1 1 2 2 1 3) ->
#(1 2 1 3)"
(declare (sequence seq))
(etypecase seq
(vector
(if (zerop (length seq))
seq
(let ((prev (aref seq 0))
(end 1))
(loop for pos from 1 below (length seq)
unless (funcall test prev (aref seq pos))
do (setf prev (aref seq pos)
(aref seq end) (aref seq pos)
end (+ 1 end)))
(if (array-has-fill-pointer-p seq)
(progn
(setf (fill-pointer seq) end)
seq)
(adjust-array seq end)))))
(list
(let ((tmp seq))
(loop while (cdr tmp)
when (funcall test (first tmp) (second tmp))
do (pop (cdr tmp))
else do (pop tmp))
seq))))