58 lines
1.9 KiB
Scheme
58 lines
1.9 KiB
Scheme
(import (scheme base)
|
|
(scheme file)
|
|
(scheme process-context)
|
|
(scheme write))
|
|
|
|
(define (direction->arithmetic direction)
|
|
(cond
|
|
((char=? direction #\L) -)
|
|
((char=? direction #\R) +)))
|
|
|
|
(define (part1 file)
|
|
(with-input-from-file file
|
|
(lambda ()
|
|
(let loop ((dial 50)
|
|
(line (read-line))
|
|
(zeros 0))
|
|
(if (eof-object? line)
|
|
(number->string zeros)
|
|
(let* ((direction (string-ref line 0))
|
|
(distance (string->number (substring line 1 (string-length line))))
|
|
(new-dial (modulo ((direction->arithmetic direction) dial distance) 100)))
|
|
(loop new-dial (read-line) (if (zero? new-dial) (+ 1 zeros) zeros))))))))
|
|
|
|
(define (pseudo-modulo/count-wraps a b)
|
|
(let loop ((n a)
|
|
(wraps 0))
|
|
(cond
|
|
((zero? n)
|
|
(values n (+ 1 wraps)))
|
|
((negative? n)
|
|
(loop (+ n b) (+ 1 wraps)))
|
|
((= n b)
|
|
(values 0 (+ 1 wraps)))
|
|
((> n b)
|
|
(loop (- n b) (+ 1 wraps)))
|
|
(else
|
|
(values n wraps)))))
|
|
|
|
;; Could be improved...
|
|
(define (part2 file)
|
|
(with-input-from-file file
|
|
(lambda ()
|
|
(let loop ((dial 50)
|
|
(zeros 0)
|
|
(line (read-line)))
|
|
(if (eof-object? line)
|
|
(number->string zeros)
|
|
(let* ((direction (string-ref line 0))
|
|
(distance (string->number (substring line 1 (string-length line))))
|
|
(dial+-distance ((direction->arithmetic direction) dial distance)))
|
|
(let-values (((new-dial add-zeros) (pseudo-modulo/count-wraps dial+-distance 100)))
|
|
(loop new-dial
|
|
(+ zeros add-zeros (if (and (zero? dial) (negative? dial+-distance)) -1 0))
|
|
(read-line)))))))))
|
|
|
|
(for-each (lambda (s) (display s) (newline)) (map part1 (cdr (command-line))))
|
|
(for-each (lambda (s) (display s) (newline)) (map part2 (cdr (command-line))))
|
|
|