This repository was archived by the owner on Aug 14, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday09.rkt
More file actions
57 lines (51 loc) · 1.86 KB
/
day09.rkt
File metadata and controls
57 lines (51 loc) · 1.86 KB
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
#lang racket
;; Part 1
;;
;; We begin by storing all the input numbers in a vector.
;; Vectors are similar to lists, but they have constant-time
;; access.
(define input
(for/vector ((line (file->lines "inputs/day09.txt")))
(string->number line)))
;; We write a predicate that determines if a number is valid
;; based on its index in the vector.
(define (valid? index)
(define previous-25 (vector-copy input (- index 25) index))
(for*/or ((x previous-25)
(y previous-25)
#:unless (= x y))
(= (+ x y) (vector-ref input index))))
;; The answer to part 1 is the first number (starting at
;; index 25) that does NOT satisfy the validity predicate.
;; We store it in a variable because it's used in part 2.
(define first-invalid
(for/first ((i (in-naturals 25))
#:unless (valid? i))
(vector-ref input i)))
;; Display the answer to part 1.
first-invalid
;; Part 2
;;
;; In this part we need to calculate sums of various slices
;; of the original input vector. We first write a helper
;; function that determines whether there is a contiguous
;; set satisfying the conditions of part 2 that begins at
;; index `start`. If there is one, it returns the set as a
;; vector. If not, it returns #f: it can thus be used as a
;; predicate.
(define (contiguous-set start)
(define (loop acc end)
(cond
((acc . = . first-invalid) (vector-copy input start end))
((acc . > . first-invalid) #f)
(else (loop (+ acc (vector-ref input end))
(add1 end)))))
(loop 0 start))
;; We then iterate over the list and find the first index
;; that begins a contiguous set, and calculate the sum of
;; its minimum and maximum values, as per the puzzle
;; requirements.
(for/first ((i (in-naturals))
#:when (contiguous-set i))
(define lst (vector->list (contiguous-set i)))
(+ (apply min lst) (apply max lst)))