First of all, I'm new to Lisp (I currently use CLISP and SBCL). There probably are huge mistakes in this code so any guidelines are welcome :)
I'm very confused about how to do this. It's just about a habit and I don't want my actual help to implement an algorithm, as the one I came up with is not the best one.
Is it okay to use reduce twice in a row on the same list? (it is not exactly the same list as it has been reduced, but I hope you get my point)
Here the algorithm is pretty much the same as the run-length encoding the only differences I see are:
- when a letter occurs only once, it has no number indication
- the number of occurrences of a letters is put on the right instead of the left
For example:
input: aabcbaaabbbcc
output: a2bcba3b3c2
The steps I have chosen to do are these:
- Convert the string input to a char list
(\#a \#a \#b etc.)
- Use reduce to transform the char list to
((\#a \#a) (\#b) etc.)
- Transform the new list to a string using reduce again (this is where I'm wondering if the previous step should not be a reduce but a map)
I have implemented the 2 first steps of this algorithm here:
(defun compress-reduce (prev curr)
;prev is always a 2d list -> ex: ((a) (b))
;curr is always a char
(format t "prev: ~A | curr: ~A | " prev curr)
(let ((last-seq (nth 0 (last prev)))
(last-char (nth 0 (nth 0 (last prev)))))
(format t "last-seq: ~A | last-char: ~A~%" last-seq last-char)
(if
(= (char-int last-char) (char-int curr))
(and (push curr last-seq)
(setf (nth (- (length prev) 1) prev) last-seq) prev)
(append prev (list (list curr))))))
(defun compress ()
(let ((l (coerce "abcccbbabaaa" 'list) ))
; reduce
(format t "~A" (reduce #'compress-reduce l :initial-value (list (list (nth 0 l)))))))
(format t "~A" (compress))
This always outputs:
prev: ((a)) | curr: a | last-seq: (a) | last-char: a prev: ((a a)) | curr: b | last-seq: (a a) | last-char: a prev: ((a a) (b)) | curr: c | last-seq: (b) | last-char: b prev: ((a a) (b) (c)) | curr: c | last-seq: (c) | last-char: c prev: ((a a) (b) (c c)) | curr: c | last-seq: (c c) | last-char: c prev: ((a a) (b) (c c c)) | curr: b | last-seq: (c c c) | last-char: c prev: ((a a) (b) (c c c) (b)) | curr: b | last-seq: (b) | last-char: b prev: ((a a) (b) (c c c) (b b)) | curr: a | last-seq: (b b) | last-char: b prev: ((a a) (b) (c c c) (b b) (a)) | curr: b | last-seq: (a) | last-char: a prev: ((a a) (b) (c c c) (b b) (a) (b)) | curr: a | last-seq: (b) | last-char: b prev: ((a a) (b) (c c c) (b b) (a) (b) (a)) | curr: a | last-seq: (a) | last-char: a prev: ((a a) (b) (c c c) (b b) (a) (b) (a a)) | curr: a | last-seq: (a a) | last-char: a ((a a) (b) (c c c) (b b) (a) (b) (a a a))NIL