-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcompress.lisp
36 lines (30 loc) · 982 Bytes
/
compress.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
34
35
36
(defun compress (lst)
(make-compressed-list '() (first lst) 1 (rest lst)))
(defun decompress (lst)
(make-decompressed-list '() (first lst) (rest lst)))
(defun make-compressed-list (out elm n in)
(if (null elm)
out
(let ((next (first in))
(rest-in (rest in)))
(if (or (null next) (not (= elm next)))
(make-compressed-list (cons (encode-element elm n) out) next 1 rest-in)
(make-compressed-list out elm (+ n 1) rest-in)))))
(defun make-decompressed-list (out elm tail)
(if (null elm)
out
(let ((new-out
(if (consp elm)
(unroll-pair out elm)
(cons elm out))))
(make-decompressed-list new-out (first tail) (rest tail)))))
(defun encode-element (elm n)
(if (= n 1)
elm
(cons elm n)))
(defun unroll-pair (out pair)
(let ((elm (first pair))
(n (rest pair)))
(if (= n 1)
(cons elm out)
(unroll-pair (cons elm out) (cons elm (- n 1))))))