-
Notifications
You must be signed in to change notification settings - Fork 0
/
day-04-1.rkt
72 lines (60 loc) · 2.44 KB
/
day-04-1.rkt
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
#lang racket
(require gregor
gregor/period
gregor/time)
(struct log (timestamp message)
#:transparent)
(define LOG-REGEXP #px"\\[(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2})\\] (.+)")
(define (string->log s)
(match-define (list _ year month day hour minute message) (regexp-match LOG-REGEXP s))
(log (datetime (string->number year)
(string->number month)
(string->number day)
(string->number hour)
(string->number minute))
message))
(define GUARD-ID-REGEXP #px"Guard #(\\d+) begins shift")
(define (string->guard-id s)
(match-define (list _ id) (regexp-match GUARD-ID-REGEXP s))
id)
(define logs (map string->log (sort (file->lines "day-04-1.txt") string<=?)))
(define frequencies
(for/fold ([frequencies (hash)]
[guard-id #f]
[sleep-timestamp #f]
#:result frequencies)
([l logs])
(define message (log-message l))
(cond
[(string-prefix? message "Guard #")
(values frequencies (string->guard-id message) #f)]
[(string=? message "falls asleep")
(values frequencies guard-id (log-timestamp l))]
[(string=? message "wakes up")
(match-define (period [minutes mdelta]) (period-between sleep-timestamp (log-timestamp l)))
(define frequencies*
(for/fold ([frequencies frequencies])
([i (in-range mdelta)])
(define k (->time (+period sleep-timestamp (period [minutes i]))))
(hash-update frequencies k (curry cons guard-id) (list))))
(values frequencies* guard-id #f)])))
(define appearances-by-id
(for*/fold ([appearances (hash)])
([(minute ids) (in-hash frequencies)]
[id ids])
(hash-update appearances id (curry cons minute) null)))
(define most-sleepy-id
(car
(first (sort (hash->list appearances-by-id) (lambda (a b)
(> (length (cdr a))
(length (cdr b))))))))
(define appearances-by-minute
(for*/fold ([appearances (hash)])
([minute (hash-ref appearances-by-id most-sleepy-id)])
(hash-update appearances minute add1 0)))
(define most-sleepy-minute
(first (sort (hash->list appearances-by-minute) (lambda (a b)
(> (cdr a) (cdr b))))))
(*
(string->number most-sleepy-id)
(->minutes (car most-sleepy-minute)))