day 2 of #adventofcode in #guile #scheme
(define (convert-line line)
(define (hand-str hand)
(match (string-split (string-trim hand) #\space)
[(cube-number cube-color) (cons (string->number cube-number) (string->symbol cube-color))]))
(let* [(game/games (string-split line #:))
(game-id (string->number
(second (string-split (car game/games) #\space))))
(games-raw (map (lambda (set) (string-split set #\,)) (string-split (second game/games) #\;)))
(games (map (lambda (game) (map hand-str game)) games-raw))]
(cons game-id games)))
(define (game-value game)
(define max-cubes-ht
(alist->hash-table '((red . 12) (green . 13) (blue . 14))))
(define (valid-set set)
(fold (lambda (hand prev) (and prev (<= (car hand) (hash-ref max-cubes-ht (cdr hand)))))
#t set))
(if (fold (lambda (a b) (and a b)) #t (map valid-set (cdr game)))
(car game)
0))
;; (game-id ((num . color) …) …)
(define (game-value-2 game)
(define ht (make-hash-table))
(for-each
(lambda (set)
(for-each
(lambda (hand)
(cond
[(hash-ref ht (cdr hand)) => (lambda (number) (when (< number (car hand)) (hash-set! ht (cdr hand) (car hand))))]
[else (hash-set! ht (cdr hand) (car hand))]))
set))
(cdr game))
(fold * 1 (hash-map->list (lambda (key value) value) ht)))
;; part 1
(fold + 0 (call-with-input-file “input” (lambda (port) (map game-value (get-lines port convert-line)))))
;; part 2
(fold + 0 (call-with-input-file “input” (lambda (port) (map game-value-2 (get-lines port convert-line)))))