(define-module (aoc-utils) #:use-module (srfi srfi-1) #:use-module (srfi srfi-9) #:use-module (srfi srfi-9 gnu) #:use-module (ice-9 regex) #:use-module (ice-9 rdelim) #:export (file->list file->str file->matrix lines->number-list element-index matrix make-matrix matrix-inner matrix-width matrix-height matrix-ref matrix-valid-x? matrix-valid-y? matrix-valid-point? list-flatten)) (define (file->list filename) (let ((lines (string-split (call-with-input-file filename read-string) #\Newline))) ; Remove EOF token (take lines (1- (length lines))))) (define (file->str filename) (call-with-input-file filename read-string)) (define (file->matrix filename) (map string->list (file->list filename))) (define (lines->number-list lines) (map (lambda (line) (map string->number (string-split line #\Space))) lines)) (define (remove-nth l n) "Remove the `N' element from `L', returning a new list." (append (list-head l n) (list-tail l (1+ n)))) (define (indexes lst) "Get the indexes for `lst'." (let ((retval '())) (do ((i (1- (length lst)) (1- i))) ((< i 0)) (set! retval (cons i retval))) retval)) (define (element-index e lst) (cond [(eqv? e (car lst)) 0] [else (+ (element-index e (cdr lst)) 1)])) ;; Matrix utilities (define-record-type (matrix inner width height) matrix? (inner matrix-inner) (width matrix-width) (height matrix-height)) (define (make-matrix lst) (let ((height (length lst)) (width (length (car lst)))) (matrix (list-flatten lst) width height))) (define (list-flatten lst) (apply append lst)) (define (matrix-ref matrix x y) (if (matrix-valid-point? matrix x y) (list-ref (matrix-inner matrix) (+ x (* y (matrix-height matrix)))) #f)) (define (matrix-valid-x? matrix x) (and (>= x 0) (< x (matrix-width matrix)))) (define (matrix-valid-y? matrix y) (and (>= y 0) (< y (matrix-height matrix)))) (define (matrix-valid-point? matrix x y) (and (matrix-valid-x? matrix x) (matrix-valid-y? matrix y)))