fork download
  1. #lang racket
  2.  
  3. (require (only-in srfi/1 alist-cons alist-delete unfold zip))
  4.  
  5. (define (codeInfo n)
  6. (let ((lst (cons 0 (unfold (lambda (x)
  7. (= x n))
  8. (lambda (x)
  9. (apply + (map (lambda (y)
  10. (expt 2 y)) (range 1 (add1 x)))))
  11. add1
  12. 1))))
  13. `(,@lst ,(add1 (last lst)))))
  14.  
  15. ;; 各要素の発生回数を数える
  16. (define (countDatum data)
  17. (map (match-lambda
  18. ((cons n c) `(,c ,n)))
  19. (sort
  20. (foldl (lambda (elt lst)
  21. (cond ((assv elt lst)
  22. => (lambda (x)
  23. (alist-cons elt (add1 (cdr x))
  24. (alist-delete elt lst))))
  25. (else (alist-cons elt 1 lst))))
  26. ; 今度はデカイ値から降順に並べる
  27. '() (string->list data)) #:key cdr >)))
  28.  
  29. (define (compress data)
  30. (let* ((lst0 (string->list data))
  31. (lst1 (countDatum data))
  32. (lst2 (codeInfo (sub1 (length lst1))))
  33. (lst3 (zip (map cadr lst1) lst2)))
  34. (values (map (lambda (key)
  35. (cadr (assv key lst3))) lst0)
  36. (map (lambda (x)
  37. (match-let ((`(,a ,b) x))
  38. (cons b a))) lst3))))
  39.  
  40. #| 「二分木ヴァージョン」と、DとEにアテられる数値が違うが、そもそもDとEの出現率は同じだ。
  41. ソートによっては「安定ソート」な為、元の順番を保持しようとする。
  42. しかし、結果、こちらのエンコード/デコードでも「理論上は」問題がない。
  43. (compress "DAEBCBACBBBC") |#
Success #stdin #stdout 0.64s 95260KB
stdin
Standard input is empty
stdout
Standard output is empty