diff options
author | lamp | 2023-12-04 01:28:22 +0000 |
---|---|---|
committer | lamp | 2023-12-04 01:28:22 +0000 |
commit | 8714ae3ac6eb5c77fdf5103685a926e3b482612b (patch) | |
tree | 4cdc2ddfb220f1b2ef4e7c4938ea4eda7aafd37b /3.scm | |
parent | 78232b574dc4eba001d536a865c115582c4e2325 (diff) |
add day 3 solutions
Diffstat (limited to '3.scm')
-rwxr-xr-x | 3.scm | 61 |
1 files changed, 61 insertions, 0 deletions
@@ -0,0 +1,61 @@ +#!/usr/bin/env -S guile -s +!# +(use-modules (ice-9 regex) + (ice-9 textual-ports) + (srfi srfi-1)) + +(define line-length 140) ;; nasty :( + +(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 (candidates-for-line line) + (letrec ((loop (lambda (l ls) + (if (not l) ls + (loop (string-match "[0-9]+" line (match:end l)) (cons l ls)))))) + (loop (string-match "[0-9]+" line) '()))) + +(define (find-candidates lines) + (let ((i -1)) + (concatenate (map-in-order (lambda (line) (let ((cands (candidates-for-line line))) + (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 (saturating-add lhs rhs max) + (let ((res (+ lhs rhs))) + (if (> res max) max res))) + +(define (saturating-sub lhs rhs min) + (let ((res (- lhs rhs))) + (if (< res min) min res))) + +(define (contains-part-symbol? str) + (string-match "[^0-9|\\.]" str)) + +(define (part-number? candidate lines) + (let ((above (substring (list-ref lines (saturating-sub (car candidate) 1 0)) + (saturating-sub (cadr candidate) 1 0) + (saturating-add (+ (cadr candidate) (caddr candidate)) 1 line-length))) + (below (substring (list-ref lines (saturating-add (car candidate) 1 (- (length lines) 1))) + (saturating-sub (cadr candidate) 1 0) + (saturating-add (+ (cadr candidate) (caddr candidate)) 1 line-length))) + (left (substring (list-ref lines (car candidate)) + (saturating-sub (cadr candidate) 1 0) + (cadr candidate))) + (right (substring (list-ref lines (car candidate)) + (+ (cadr candidate) (caddr candidate)) + (saturating-add (+ (cadr candidate) (caddr candidate)) 1 line-length)))) + (or (contains-part-symbol? above) + (contains-part-symbol? below) + (contains-part-symbol? left) + (contains-part-symbol? right)))) + +(let* ((port (open-input-file "3.txt")) + (lines (read-lines port))) + (close-port port) + (display (fold + 0 (map cadddr (filter (lambda (cand) (part-number? cand lines)) (find-candidates lines)))))) |