fork download
  1. (defun lzw-compress (sequence elements)
  2. (let ((dictionary (make-hash-table :test #'equalp))
  3. (index -1)
  4. (seq nil))
  5. (map nil
  6. (lambda (e)
  7. (setf (gethash (list e) dictionary) (incf index)))
  8. elements)
  9. (nconc (loop
  10. for e across sequence
  11. do (setf seq (list* e seq))
  12. unless (gethash seq dictionary)
  13. collect (gethash (cdr seq) dictionary)
  14. and
  15. do (setf (gethash seq dictionary) (incf index)
  16. seq (list (car seq))))
  17. (list (gethash seq dictionary)))))
  18.  
  19. (defun lzw-decompress (list elements)
  20. (let ((dictionary (make-array (length elements)
  21. :adjustable t
  22. :fill-pointer t
  23. :initial-contents (map 'list #'list elements))))
  24. (loop
  25. for index in list
  26. for ee = e
  27. and e = (if (< index (length dictionary))
  28. (aref dictionary index)
  29. e)
  30. for s = (append (last e) ee)
  31. unless (find s dictionary :test #'equalp)
  32. do (vector-push-extend s dictionary)
  33. append (reverse (setf e (aref dictionary index))))))
  34.  
  35.  
  36. (defun test (data &optional elements)
  37. (let* ((data-elements (or elements (remove-duplicates data)))
  38. (compressed (lzw-compress data data-elements))
  39. (decompressed (lzw-decompress compressed data-elements)))
  40. (format t "~%characters: ~s~%uncompressed: ~a~%compressed: ~a~%decompressed: ~{~a~}~%"
  41. data-elements data compressed decompressed)
  42. nil))
  43.  
  44. (test "010101010" "0123")
  45. (test "01230123012" "0123")
  46. (test "00001110000" "0123")
  47. (test "akamakigami aomakigami kimakigami")
  48.  
Success #stdin #stdout 0.01s 10736KB
stdin
Standard input is empty
stdout
characters:   "0123"
uncompressed: 010101010
compressed:   (0 1 4 6 5)
decompressed: 010101010

characters:   "0123"
uncompressed: 01230123012
compressed:   (0 1 2 3 4 6 8)
decompressed: 01230123012

characters:   "0123"
uncompressed: 00001110000
compressed:   (0 4 0 1 7 5 0)
decompressed: 00001110000

characters:   "o kgami"
uncompressed: akamakigami aomakigami kimakigami
compressed:   (4 2 4 5 7 6 3 9 6 1 4 0 10 2 12 14 1 20 19 21 5 6)
decompressed: akamakigami aomakigami kimakigami