Overview
Comment: | Day 4 solutions |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
6a713844133d51c8700a5a1756e8930e |
User & Date: | joel on 2018-12-05 04:25:41 |
Other Links: | manifest | tags |
Context
2018-12-05
| ||
19:21 | Add Day 5 input check-in: c5988d user: joel tags: trunk | |
04:25 | Day 4 solutions check-in: 6a7138 user: joel tags: trunk | |
2018-12-04
| ||
12:30 | Add Day 4 input check-in: dd720a user: joel tags: trunk | |
Changes
Added day04.rkt version [f05619].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | #lang racket (require sugar rackunit) (define input (sort (file->lines "day04-input.txt") string<?)) ;; Pull apart the strings (define (parse-line line) (define pattern #px"\\[\\d{4}-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2})\\] (?:Guard #|falls |)(\\d+|asleep|wakes)") (define parsed (regexp-match pattern line)) (append (map string->number (sublist parsed 1 5)) (list (last parsed)))) ;; Local Convenience (define (hash-with-key h key) (hash-set h key (or (hash-ref h key #f) '()))) (define (add-to-end lst v) (reverse (cons v (reverse lst)))) ;; Returns a hash table of guards => list of wake/sleep logs in chrono order (define (lines->guards/hash loglines) (for/fold ([guards (hash)] [current-guard ""] #:result guards) ([l (in-list (map parse-line loglines))]) (cond [(member (last l) '("asleep" "wakes")) (values (hash-set guards current-guard (add-to-end (hash-ref guards current-guard) l)) current-guard)] [else (values (hash-with-key guards (last l)) (last l))]))) ;; Consolidate a list whose entries are alternating sleep/wake times into a ;; list of sleep/wake minute pairs (define (sleeptimes->pairs sleeptimes) (for/list ([twolines (in-list (slice-at sleeptimes 2))]) (match twolines [(list (list _ _ _ sleepmin _) (list _ _ _ wakemin _)) (list sleepmin wakemin)]))) ;; NOW: Use all the above to build a hash table where key:value is guard:list of all minute-pairs (define guard-sleeptime-pairs (let ([guardlog (lines->guards/hash input)]) (for/hash ([(guard lines) (in-hash guardlog)]) (values guard (sleeptimes->pairs lines))))) ;; Converts '(a b) into a 60-position vector where values at indexes a through (b-1) are 1 ;; (each position a minute of the hour; the 1s indicate minutes where the guard was asleep) (define (pair->minutemap p) (vector-append (make-vector (first p)) (make-vector (- (second p) (first p)) 1) (make-vector (- 60 (second p))))) ;; Use vector addition to sum up all the sleep-minute-maps for each guard, ;; showing when and how often they were asleep during their shifts (define guard-sleepmaps (for/list ([guard (in-hash-keys guard-sleeptime-pairs)]) (cons guard (for/fold ([smap (make-vector 60)]) ([minutemap (in-list (hash-ref guard-sleeptime-pairs guard))]) (vector-map + (pair->minutemap minutemap) smap))))) ;; For each guard: '(guard-ID [asleep min count] [max sleeps during any minute] [minute with max sleeps]) (define analysis (for/list ([g (in-list guard-sleepmaps)]) (let* ([minutes (vector->list (cdr g))] [max-sleeps (apply max minutes)]) (list (car g) (vector-count positive? (cdr g)) max-sleeps (index-of minutes max-sleeps))))) ;; Comparison function for sorting analysis (define (guard-slept-more-mins? a b) (or (> (second a) (second b)) ; was asleep more minutes out of the hour (and (= (second a) (second b)) ; OR was asleep the same number of minutes… (> (third a) (third b))))) ; …but had more sleeps in a given minute ;; Computers answers of the form given in the puzzle: ;; "What is the ID of the guard you chose multiplied by the minute you chose?" (define (compute-using lst) (let* ([winner-stats (first lst)] [guard-id (string->number (first winner-stats))] [minute (last winner-stats)]) (* guard-id minute))) ;; Strategy 1: Find the guard with the most minutes asleep and the minute ;; that guard spends asleep the most. (define (day04-part1) (compute-using (sort analysis guard-slept-more-mins?))) (module+ test (check-equal? (day04-part1) 99759)) ; Correct answer for part 1 ;; Strategy 2: Find the guard that is most frequently asleep on the same minute. (define (day04-part2) (compute-using (sort analysis > #:key third))) (module+ test (check-equal? (day04-part2) 97884)) |