; making a palindrome

(define (palin str)
  (define (string-reverse str) (list->string (reverse (string->list str))))
  (let ((freqs (make-vector 256 0)))
    (define (s t i d)
      (string-append t
        (make-string (/ (vector-ref freqs i) d) (integer->char i))))
    (do ((cs (string->list str) (cdr cs))) ((null? cs))
      (let ((i (char->integer (car cs))))
        (vector-set! freqs i (+ (vector-ref freqs i) 1))))
    (let loop ((i 0) (left "") (center ""))
      (cond ((= 256 i) (string-append left center (string-reverse left)))
            ((even? (vector-ref freqs i)) (loop (+ i 1) (s left i 2) center))
            ((string=? center "") (loop (+ i 1) left (s center i 1)))
            (else #f)))))

(display (palin "pprrrraaxxxiiiiiissss")) (newline)

(define (palin str)
  (let ((freqs (make-vector 256 0)) (len (string-length str)))
    (do ((cs (string->list str) (cdr cs))) ((null? cs))
      (let ((i (char->integer (car cs))))
        (vector-set! freqs i (+ (vector-ref freqs i) 1))))
    (let loop ((i 0) (p 0) (center-char #f) (center-count 0))
      (cond ((= 256 i)
              (when center-char
                (do ((j 0 (+ j 1))) ((= j center-count))
                  (string-set! str (+ p j) center-char)))
              str)
            ((even? (vector-ref freqs i))
              (do ((j 0 (+ j 1)))
                  ((= j (/ (vector-ref freqs i) 2)))
                (string-set! str (+ p j) (integer->char i))
                (string-set! str (- len p j 1) (integer->char i)))
              (loop (+ i 1) (+ p (/ (vector-ref freqs i) 2))
                    center-char center-count))
            ((not center-char)
              (loop (+ i 1) p (integer->char i) (vector-ref freqs i)))
            (else #f)))))

(display (palin "pprrrraaxxxiiiiiissss")) (newline)