-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday07.rkt
62 lines (55 loc) · 2.2 KB
/
day07.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
#lang racket
(require "aoc.rkt"
threading)
(define (create-requirements data)
(define requirements (make-hash))
(for ([line (in-list data)])
(match-define (list a b) line)
(hash-update! requirements b (λ (v) (cons a v)) '()))
requirements)
(define (solve part)
(define remaining-letters
(list->mutable-set (map string (string->list upper-alphabet))))
(define end-times (make-hash)) ; for/hash would create an immutable hash-set
(for ([l remaining-letters]) (hash-set! end-times l +inf.0))
(define (processing-time s)
(define (ord s)
(char->integer (string-ref s 0)))
(match part
[1 1]
[_ (- (ord s) 4)]))
(define ((is-available? time) letter)
(for/and ([l (in-list (hash-ref requirements letter '()))])
(<= (hash-ref end-times l) time)))
(define workers (if (= part 1) 1 5))
(for/fold ([t 0]
[w workers]
[letters '()]
#:result (if (= part 1)
letters
(apply max (hash-values end-times))))
([t (in-naturals)]
#:break (set-empty? remaining-letters))
(let*
([available-letters (~>> remaining-letters
(set->list)
(filter (is-available? t))
(sort _ string<?))]
[available-workers (min workers
(+ w (count (λ (et) (= t (hash-ref end-times et t)))
(hash->list end-times))))]
[processed-letters (for/list ([l (in-list available-letters)]
[w (in-range available-workers)])
(set-remove! remaining-letters l)
(hash-set! end-times l (+ t (processing-time l)))
l)]
[employed-workers (length processed-letters)])
(values t
(- available-workers employed-workers)
(append letters processed-letters)))))
(define data
(map (curry regexp-match* #px" ([A-Z]) " #:match-select cadr)
(read-input 7)))
(define requirements (create-requirements data))
(string-join (solve 1) "")
(solve 2)