diff options
Diffstat (limited to '3-2.scm')
-rwxr-xr-x | 3-2.scm | 45 |
1 files changed, 45 insertions, 0 deletions
@@ -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))))))) |