Day 04: Use a single fold for both parts.

This commit is contained in:
Jonathan Chan 2021-12-05 10:04:08 -08:00
parent 8d88893d2a
commit cb4d7a3028
2 changed files with 17 additions and 14 deletions

11
lib.rkt
View File

@ -191,14 +191,21 @@
(cons (f v (first lst)) lst))
(list init) lst)))
;; list-ref* : (listof a) -> number -> a -> a
;; list-ref* : (listof a) -> number -> a -> (or a #f)
;; Same as list-ref, except a default value is provided
;; if the index is beyond the length of the list.
(define (list-ref* lst pos failure-result)
(define (list-ref* lst pos [failure-result #f])
(if (>= pos (length lst))
failure-result
(list-ref lst pos)))
;; first* : (listof a) -> (or a #f)
;; Get first of list or default if empty
(define (first* lst [failure-result #f])
(match lst
['() failure-result]
[`(,hd ,@_) hd]))
;; repeat : number -> (listof any) -> (listof any)
(define (repeat m lst)
(if (zero? m) '()

View File

@ -28,26 +28,22 @@
(define (score board)
(sum (filter number? (apply append board))))
(define part1
(define-values (part1 part2)
(for/fold ([boards boards]
[winner #f]
[winning #f]
#:result (* (score winner) winning))
([n order]
#:break winner)
(define boards*
(map #{blot % n} boards))
(values boards* (findf winner? boards*) n)))
(define part2
(for/fold ([boards boards]
[loser #f]
[losing #f]
#:result (* (score loser) losing))
#:result (values (* (score winner) winning)
(* (score loser) losing)))
([m order]
#:break (empty? boards))
(define boards*
(map #{blot % m} boards))
(values (filter ( not winner?) boards*) (first boards*) m)))
(define-values (winners losers)
(partition winner? boards*))
(values losers
(or winner (first* winners)) (if winner winning m)
(first* winners) m)))
(show-solution part1 part2)