advent-of-code

Perserverance, or the lack thereof

git clone git://git.shimmy1996.com/advent-of-code.git

day03.scm (4878B)

    1 (use-modules (ice-9 popen))
    2 (use-modules (ice-9 rdelim))
    3 (use-modules (ice-9 format))
    4 (use-modules (ice-9 hash-table))
    5 (use-modules (srfi srfi-1))
    6 
    7 (define (is-valid-loc schematic loc)
    8   (let ((x (car loc))
    9         (y (car (cdr loc)))
   10         (max-x (car (array-dimensions schematic)))
   11         (max-y (car (cdr (array-dimensions schematic)))))
   12     (and (and (>= x 0) (< x max-x))
   13          (and (>= y 0) (< y max-y)))))
   14 
   15 (define (is-adjacent-to-symbol schematic x y)
   16   (let ((found #f))
   17     (do ((dx -1 (1+ dx))) ((or (> dx 1) found))
   18       (do ((dy -1 (1+ dy))) ((or (> dy 1) found))
   19         (if (is-valid-loc schematic (list (+ x dx) (+ y dy)))
   20             (let ((cc (array-ref schematic (+ x dx) (+ y dy))))
   21               (if (not (or (eq? cc #\.) (char-numeric? cc)))
   22                   (set! found #t))))))
   23     found))
   24 
   25 (define (find-part-number schematic)
   26   (let ((part-numbers '())
   27         (curr-has-num #f)
   28         (curr-num 0)
   29         (curr-num-adjacent-to-symbol #f)
   30         (max-x (car (array-dimensions schematic)))
   31         (max-y (car (cdr (array-dimensions schematic)))))
   32     (do ((x 0 (1+ x))) ((>= x max-x))
   33       (do ((y 0 (1+ y))) ((>= y max-y))
   34         (let* ((c (array-ref schematic x y))
   35                (in-num (char-numeric? c)))
   36           (if in-num
   37               (let ((cc (- (char->integer c) (char->integer #\0))))
   38                 (if (not curr-has-num) (set! curr-has-num #t))
   39                 (set! curr-num (+ (* curr-num 10) cc))
   40                 (if (not curr-num-adjacent-to-symbol)
   41                     (set! curr-num-adjacent-to-symbol
   42                           (is-adjacent-to-symbol schematic x y)))))
   43           (if (or (not in-num) (= (1+ y) max-y))
   44               (if curr-has-num
   45                   (begin (if curr-num-adjacent-to-symbol
   46                              (set! part-numbers (cons curr-num part-numbers)))
   47                          (set! curr-has-num #f)
   48                          (set! curr-num 0)
   49                          (set! curr-num-adjacent-to-symbol #f)))))))
   50     (reverse part-numbers)))
   51 
   52 (let ((file (open-input-file "input.txt")) (schematic '()) (ans 0))
   53   (while #t
   54          (let ((line (car (%read-line file))))
   55            (if (eof-object? line)
   56                (break)
   57                (set! schematic (cons (string->list line) schematic)))))
   58   (set! schematic (list->array '(0 0) (reverse schematic)))
   59   (set! ans (fold + 0 (find-part-number schematic)))
   60   ;; 514969
   61   (format #t "Part 1: ~d" ans)
   62   (newline))
   63 
   64 (define (find-adjacent-protogear schematic x y)
   65   (let ((protogears '()))
   66     (do ((dx -1 (1+ dx))) ((> dx 1))
   67       (do ((dy -1 (1+ dy))) ((> dy 1))
   68         (if (is-valid-loc schematic (list (+ x dx) (+ y dy)))
   69             (let ((cc (array-ref schematic (+ x dx) (+ y dy))))
   70               (if (eq? cc #\*)
   71                   (set! protogears (cons (list (+ x dx) (+ y dy)) protogears)))))))
   72     protogears))
   73 
   74 (define (find-gear-ratio schematic)
   75   (let ((part-numbers '())
   76         (curr-has-num #f)
   77         (curr-num 0)
   78         (curr-protogear (make-hash-table))
   79         (protogear-specs (make-hash-table))
   80         (max-x (car (array-dimensions schematic)))
   81         (max-y (car (cdr (array-dimensions schematic)))))
   82     (do ((x 0 (1+ x))) ((>= x max-x))
   83       (do ((y 0 (1+ y))) ((>= y max-y))
   84         (let* ((c (array-ref schematic x y))
   85                (in-num (char-numeric? c)))
   86           (if in-num
   87               (let* ((cc (- (char->integer c) (char->integer #\0))))
   88                 (if (not curr-has-num) (set! curr-has-num #t))
   89                 (set! curr-num (+ (* curr-num 10) cc))
   90                 (fold (lambda (loc res) (hash-set! res loc #t))
   91                       curr-protogear
   92                       (find-adjacent-protogear schematic x y))))
   93           (if (or (not in-num) (= (1+ y) max-y))
   94               (if curr-has-num
   95                   (begin (hash-for-each
   96                           (lambda (k v)
   97                             (if (hash-ref protogear-specs k)
   98                                 (hash-set! protogear-specs k (cons curr-num (hash-ref protogear-specs k)))
   99                                 (hash-set! protogear-specs k (list curr-num))))
  100                           curr-protogear)
  101                          (hash-clear! curr-protogear)
  102                          (set! curr-has-num #f)
  103                          (set! curr-num 0)))))))
  104     (hash-map->list
  105      (lambda (k v)
  106        (if (= (length v) 2)
  107            (fold * 1 v)
  108            0))
  109      protogear-specs)))
  110 
  111 (let ((file (open-input-file "input.txt")) (schematic '()) (ans 0))
  112   (while #t
  113          (let ((line (car (%read-line file))))
  114            (if (eof-object? line)
  115                (break)
  116                (set! schematic (cons (string->list line) schematic)))))
  117   (set! schematic (list->array '(0 0) (reverse schematic)))
  118   (set! ans (fold + 0 (find-gear-ratio schematic)))
  119   ;; 78915902
  120   (format #t "Part 2: ~d" ans)
  121   (newline))