advent-of-code

Perserverance, or the lack thereof

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

day04.scm (2656B)

    1 (use-modules (ice-9 popen))
    2 (use-modules (ice-9 rdelim))
    3 (use-modules (ice-9 format))
    4 (use-modules (ice-9 regex))
    5 (use-modules (ice-9 hash-table))
    6 (use-modules (srfi srfi-1))
    7 
    8 (define (parse-numbers numbers)
    9   (filter (lambda (x) x) (map string->number (string-split numbers #\ ))))
   10 
   11 (define (parse-card line)
   12   (let* ((tmp (string-split line #\:))
   13          (card-id (string->number (regexp-substitute #f (string-match "Card +([0-9]+)" (car tmp)) 1)))
   14          (numbers (car (cdr tmp)))
   15          (tmp2 (string-split numbers #\|))
   16          (winning-numbers (parse-numbers (car tmp2)))
   17          (hand-numbers (parse-numbers (car (cdr tmp2)))))
   18     (list card-id winning-numbers hand-numbers)))
   19 
   20 (define (count-matches winning-numbers hand-numbers)
   21   (let* ((winning-numbers-set (alist->hash-table (map (lambda (x) (cons x #t)) winning-numbers)))
   22          (matched-count (fold + 0 (map (lambda (x) (if (hash-ref winning-numbers-set x) 1 0)) hand-numbers))))
   23     matched-count))
   24 
   25 (let ((file (open-input-file "input.txt")) (tot 0))
   26   (while #t
   27          (let ((line (car (%read-line file))))
   28            (if (eof-object? line)
   29                (break)
   30                (begin
   31                  (let* ((card (parse-card line))
   32                         (card-id (car card))
   33                         (winning-numbers (car (cdr card)))
   34                         (hand-numbers (car (cdr (cdr card))))
   35                         (matched-count (count-matches winning-numbers hand-numbers)))
   36                    (set! tot (+ tot (if (> matched-count 0) (expt 2 (- matched-count 1)) 0))))))))
   37   ;; 24175
   38   (format #t "Part 1: ~d" tot)
   39   (newline))
   40 
   41 (let ((file (open-input-file "input.txt")) (card-copies (make-hash-table)) (max-id 0))
   42   (while #t
   43          (let ((line (car (%read-line file))))
   44            (if (eof-object? line)
   45                (break)
   46                (begin
   47                  (let* ((card (parse-card line))
   48                         (card-id (car card))
   49                         (winning-numbers (car (cdr card)))
   50                         (hand-numbers (car (cdr (cdr card))))
   51                         (matched-count (count-matches winning-numbers hand-numbers)))
   52                    (set! max-id card-id)
   53                    (hash-set! card-copies card-id (+ 1 (hash-ref card-copies card-id 0)))
   54                    (do ((i 1 (1+ i)))
   55                        ((> i matched-count))
   56                      (hash-set! card-copies (+ card-id i)
   57                                 (+ (hash-ref card-copies card-id) (hash-ref card-copies (+ card-id i) 0)))))))))
   58   ;; 18846301
   59   (format #t "Part 2: ~d" (hash-fold (lambda (key value prior) (+ prior value)) 0 card-copies))
   60   (newline))