summaryrefslogtreecommitdiff
path: root/5-2.scm
blob: 0664348779853ace5fd2238ef03ef99d63c6bf4f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/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 (split-up nums)
  (map string->number (filter (lambda (x) (not (string-null? x))) (string-split nums char-set:whitespace))))

(define (perform-mapping val map)
  (let* ((mapping (filter (lambda (x) (and (>= val (cadr x))
                                           (< val (+ (cadr x) (caddr x))))) map)))
    (if (null? mapping) val
        (+ val (- (caar mapping) (cadar mapping))))))

(define (perform-all-mappings val maps)
  (do ((i 0 (1+ i))) ((= i (length maps)))
    (set! val (perform-mapping val (list-ref maps i))))
  val)

(define (parse-next-map lines)
  (let ((map-started #f)
        (map-parsed #f)
        (current-map '()))
    (while (not map-parsed)
      (if (and (not map-started)
               (string-match "map" (car lines)))
          (set! map-started #t)
          (when map-started
            (if (string-match "[0-9]" (car lines))
                (set! current-map (append current-map `(,(split-up (car lines)))))
                (set! map-parsed #t))))
      (set! lines (cdr lines)))
    `(,current-map ,lines)))

(define (in-ranges ranges val)
  (let ((found #f))
  (while (and (not (null? ranges)) (not found))
    (if (and (>= val (car ranges))
             (< val (+ (car ranges) (cadr ranges))))
        (set! found #t)
        (set! ranges (cddr ranges))))
  found))

(let* ((port (open-input-file "5.txt"))
       (lines (read-lines port))
       (seeds (split-up (match:substring (string-match ": ([0-9| ]+)" (car lines)) 1)))
       (lines (cdr lines))
       (maps '())
       (index 0))
  (close-port port)
  (do ((i 0 (1+ i))) ((= i 7))
    (let ((res (parse-next-map lines)))
      (set! maps (append maps `(,(car res))))
      (set! lines (cadr res))))
  (set! maps (reverse (map (lambda (x) (map (lambda (y) `(,(cadr y) ,(car y) ,(caddr y))) x)) maps)))
  (while (not (in-ranges seeds (perform-all-mappings index maps))) (set! index (1+ index)))
  (display index))