; triple or add five

(define (make-queue) (list (list)))

(define (enqueue q x) (cons (car q) (cons x (cdr q))))

(define (head q)
  (if (pair? (car q))
      (caar q)
      (if (pair? (cdr q))
          (car (reverse (cdr q)))
          (error 'head "empty"))))

(define (tail q)
  (if (pair? (car q))
      (cons (cdar q) (cdr q))
      (if (pair? (cdr q))
          (cons (cdr (reverse (cdr q))) (list))
          (error 'tail "empty"))))

(define (empty? q) (and (null? (car q)) (null? (cdr q))))

(define (triple-or-add-five n)
  (let loop ((queue (enqueue (make-queue) (list n))))
    (if (empty? queue) #f
      (let ((seq (head queue)) (queue (tail queue)))
        (if (= (car seq) 1) seq
          (if (< (car seq) 1) (loop queue)
            (let ((queue (enqueue queue (cons (- (car seq) 5) seq))))
              (if (zero? (modulo (car seq) 3))
                  (loop (enqueue queue (cons (/ (car seq) 3) seq)))
                  (loop queue)))))))))

(display (triple-or-add-five 24)) (newline)
(display (triple-or-add-five 99)) (newline)
(display (triple-or-add-five 15)) (newline)