🎄⌨️ Advent of Code 2018

Check-in [80485b]
Overview
Comment:Add Day 14 solutions
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 80485bbfcef6fedc6c3ed47ee7879d4e225759f5d79bc111b0bfec2a1eb33467
User & Date: joel on 2018-12-24 13:29:30
Other Links: manifest | tags
Context
2019-11-25
13:27
Day 15 first steps check-in: 440bf0 user: joel tags: day15
2018-12-24
13:29
Add Day 14 solutions Leaf check-in: 80485b user: joel tags: trunk
2018-12-22
19:04
Add Day 13 solutions check-in: 381699 user: joel tags: trunk
Changes

Added day14.rkt version [b43645].









































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
#lang racket

(require rackunit)

(define input 640441)

;; To try to get this code to finish running before Christmas,
;; going to try starting out with a mega-ass vector and keep
;; track of the index of the last value in a struct
(define recipes (make-vector 30000000))

(define (append-recipes! r-count val)
  (cond [(> val 9)
         (vector-set! recipes r-count 1)
         (vector-set! recipes (add1 r-count) (- val 10))
         (+ r-count 2)]
        [else
         (vector-set! recipes r-count val)
         (add1 r-count)]))

(append-recipes! 0 3)
(append-recipes! 1 7)

(struct state (rcount elf1 elf2) #:transparent)

; To start: there are 2 recipes with elves at positions 1 and 0
(define start (state 2 1 0))

(define (score current-state)
  (match-define (state recipe-count e1 e2) current-state)
  (+ (vector-ref recipes e1)
     (vector-ref recipes e2)))

(define (move-elf pos r-count)
  (modulo (+ pos (add1 (vector-ref recipes pos))) r-count))

;; For debugging
(define (list-recipes start end)
  (for/list ([i (in-range start end)])
            (vector-ref recipes i)))

;; Get the ten recipes after the given recipe
(define (get-10-after starting-state n)
  (let loop ([current-state starting-state])
    (match-define (state recipe-count e1 e2) current-state)
    (cond [(>= (- recipe-count 11) n)
           (list-recipes n (+ n 10))]
          [else
           (define new-count (append-recipes! recipe-count (score current-state)))
           (loop (state new-count (move-elf e1 new-count) (move-elf e2 new-count)))])))

(define (day14-part1 n)
  (apply string-append (map number->string (get-10-after start n))))

(module+ test
  (check-equal? (time (day14-part1 9)) "5158916779")
  (check-equal? (time (day14-part1 5)) "0124515891")
  (check-equal? (time (day14-part1 18)) "9251071085")
  (check-equal? (time (day14-part1 2018)) "5941429882")
  (check-equal? (time (day14-part1 input)) "1041411104")) ; Correct answer for part 1

(define input-part2 #(6 4 0 4 4 1))

(define (found-yet? start)
  (cond [(< start 0) #f]
        [else (for/and ([i (in-range start (+ start 6))])
                       (equal? (vector-ref input-part2 (- i start)) (vector-ref recipes i)))]))

;; How many recipes to the left of the input sequence?
(define (day14-part2)
  (let loop ([current-state start])
    (match-define (state recipe-count e1 e2) current-state)
    (define new-count (append-recipes! recipe-count (score current-state)))
    (define found?
      (cond [(equal? 2 (- new-count recipe-count))
             (or (found-yet? (- new-count 7)) (found-yet? (- new-count 6)))]
            [else (found-yet? (- new-count 6))]))
    (cond [(and found? (found-yet? (- new-count 7))) (- new-count 7)]
          [found? (- new-count 6)]
          [else
           (loop (state new-count (move-elf e1 new-count) (move-elf e2 new-count)))])))

(module+ test
  (check-equal? (time (day14-part2)) 20174745)) ; Correct answer for part 2