diff --git a/1/main.scm b/1/main.scm new file mode 100644 index 0000000..22d81c6 --- /dev/null +++ b/1/main.scm @@ -0,0 +1,60 @@ +(import (scheme base) + (scheme file) + (scheme process-context) + (scheme write)) + +(include "../common.scm") + +(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 print (map part1 (command-line-arguments))) +(for-each print (map part2 (command-line-arguments))) +