(import (srfi :43)) ; vector extensions ; returns a list of numbers parsed from the first line of the file, ; separated by commas (define (read-comma-separated-numbers file) (let loop [(draws '()) (n 0)] (let [(c (get-char file))] (cond [(char=? c #\,) (loop (cons n draws) 0)] [(char-whitespace? c) (reverse (cons n draws))] [else (loop draws (+ (* n 10) (string->number (string c))))])))) ; returns numbers 0 to 9 from ascii character (define (char->number c) (- (char->integer c) 48)) ; 48 is ASCII's number zero (define-record-type matrix (fields width height data)) ; builds a matrix record from the given 2D vector ; vectors inside data vector are expected to all be the same length (define (matrix-from-data data) (make-matrix (vector-length (vector-ref data 0)) (vector-length data) data)) ; returns value at x,y coordinates in matrix ; if coordinate is out of bounds, returns default (define (matrix-get matrix x y default) (if (or (< x 0) (< y 0) (>= x (matrix-width matrix)) (>= y (matrix-height matrix))) default (vector-ref (vector-ref (matrix-data matrix) y) x))) ; set value at x,y in matrix with given one ; if coordinate is out of bounds, nothing happens (define (matrix-set! matrix x y value) (when (and (>= x 0) (>= y 0) (< x (matrix-width matrix)) (< y (matrix-height matrix))) (vector-set! (vector-ref (matrix-data matrix) y) x value))) (define (matrix-print matrix) (let y-loop [(y 0)] (printf "~a~%" (vector-ref (matrix-data matrix) y)) (when (< y (- (matrix-height matrix) 1)) (y-loop (+ y 1))))) ; parse 0-9 numerical data from file and return a matrix (define (load-matrix file) (let y-loop [(heightmap '())] (let x-loop [(line '())] (let [(c (get-char file))] (cond [(eof-object? c) (matrix-from-data (reverse-list->vector heightmap))] [(char-whitespace? c) (y-loop (cons (reverse-list->vector line) heightmap))] [(char-numeric? c) (x-loop (cons (char->number c) line))])))))