; two homework problems

(define (read-line . port)
  (define (eat p c)
    (if (and (not (eof-object? (peek-char p)))
             (char=? (peek-char p) c))
        (read-char p)))
  (let ((p (if (null? port) (current-input-port) (car port))))
    (let loop ((c (read-char p)) (line '()))
      (cond ((eof-object? c) (if (null? line) c (list->string (reverse line))))
            ((char=? #\newline c) (eat p #\return) (list->string (reverse line)))
            ((char=? #\return c) (eat p #\newline) (list->string (reverse line)))
            (else (loop (read-char p) (cons c line)))))))

(define (inflect xs)
  (define (x i) (vector-ref xs i))
  (let loop ((lo 0) (left-sum 0)
             (hi (- (vector-length xs) 1))
             (right-sum 0))
    (cond ((< hi lo)
            (values lo left-sum right-sum
              (abs (- left-sum right-sum))))
          ((< left-sum right-sum)
            (loop (+ lo 1) (+ left-sum (x lo))
                  hi right-sum))
          (else (loop lo left-sum (- hi 1)
                      (+ right-sum (x hi)))))))

(call-with-values
  (lambda () (inflect '#(3 7 9 8 2 5 6)))
  (lambda (point left-sum right-sum diff)
    (display point) (newline)
    (display left-sum) (newline)
    (display right-sum) (newline)
    (display diff) (newline)))

(define (tail n file-name)
  (with-input-from-file file-name
    (lambda ()
      (let ((buffer (make-vector n "")))
        (let loop ((i 0) (line (read-line)))
          (cond ((eof-object? line)
                  (do ((j 0 (+ j 1))) ((= j n))
                    (display (vector-ref buffer (modulo (+ i j) n)))
                    (newline)))
          (else (vector-set! buffer i line)
                (loop (modulo (+ i 1) n)
                      (read-line)))))))))

; (tail 5 "bible.txt")