summaryrefslogtreecommitdiff
path: root/3-2.scm
diff options
context:
space:
mode:
Diffstat (limited to '3-2.scm')
-rwxr-xr-x3-2.scm45
1 files changed, 45 insertions, 0 deletions
diff --git a/3-2.scm b/3-2.scm
new file mode 100755
index 0000000..d20f63c
--- /dev/null
+++ b/3-2.scm
@@ -0,0 +1,45 @@
+#!/usr/bin/env -S guile -s
+!#
+(use-modules (ice-9 regex)
+ (ice-9 textual-ports)
+ (srfi srfi-1))
+
+(define (read-lines port)
+ (letrec ((loop (lambda (l ls)
+ (if (eof-object? l)
+ ls
+ (loop (get-line port) (cons l ls))))))
+ (reverse (loop (get-line port) '()))))
+
+(define (matches-for-line line regex)
+ (letrec ((loop (lambda (l ls)
+ (if (not l) ls
+ (loop (string-match regex line (match:end l)) (cons l ls))))))
+ (loop (string-match regex line) '())))
+
+(define (find-candidates lines)
+ (let ((i -1))
+ (concatenate (map-in-order (lambda (line) (let ((cands (matches-for-line line "[0-9]+")))
+ (set! i (+ i 1))
+ (map (lambda (cand)
+ `(,i ,(match:start cand) ,(- (match:end cand) (match:start cand)) ,(string->number (match:substring cand)))) cands))) lines))))
+
+(define (find-gears lines)
+ (let ((i -1))
+ (concatenate (map-in-order (lambda (line) (let ((cands (matches-for-line line "\\*")))
+ (set! i (+ i 1))
+ (map (lambda (cand)
+ `(,i ,(match:start cand))) cands))) lines))))
+
+(define (parts-for-gear parts gear)
+ (filter (lambda (part)
+ (and (>= (car part) (- (car gear) 1))
+ (<= (car part) (+ (car gear) 1))
+ (<= (- (cadr gear) (cadr part)) (caddr part))
+ (>= (- (cadr gear) (cadr part)) -1))) parts))
+
+(let* ((port (open-input-file "3.txt"))
+ (lines (read-lines port))
+ (parts (find-candidates lines)))
+ (close-port port)
+ (display (fold + 0 (map (lambda (x) (* (car x) (cadr x))) (filter (lambda (x) (= (length x) 2)) (map (lambda (gear) (map cadddr (parts-for-gear parts gear))) (find-gears lines)))))))