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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Advent of Code 2022\n",
"#### Day 4: Camp Cleanup\n",
"\n",
"Each elf in a pair of elves is assigned a range of ID numbers.\n",
"\n",
"**Part 1.** How many pairs have one elf assigned to a range completely contained by the other's?\n",
"\n",
"**Part 2.** How many pairs have overlapping assignments?\n",
"\n",
"Since this problem heavily uses ranges, I'm using `rebellion/base/range` to do the heavy lifting."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"vscode": {
"languageId": "racket"
}
},
"outputs": [],
"source": [
"#lang iracket/lang #:require rackjure\n",
"(require advent-of-code\n",
" relation\n",
" rebellion/base/range)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Part 1\n",
"\n",
"All the assignments look like `\"11-22,33-44\"`, so we write a function to extract the numbers from the string with a regex, decompose the values with structural matching, and construct a pair of [`rebellion` ranges](https://docs.racket-lang.org/rebellion/Ranges.html).\n",
"\n",
"Once we have the two ranges, we can use a predicate that tests if one completely contains the other or vice versa to count the corresponding assignments."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"vscode": {
"languageId": "racket"
}
},
"outputs": [
{
"data": {
"text/html": [
"<code>550</code>"
],
"text/plain": [
"550"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(define assignments (~> (fetch-aoc-input (find-session) 2022 4) string-split))\n",
"\n",
"(define (parse-range str)\n",
" (match str\n",
" [(regexp #px\"(\\\\d+)-(\\\\d+),(\\\\d+)-(\\\\d+)\" (list _ a b c d))\n",
" (values (closed-range (->number a) (->number b)) (closed-range (->number c) (->number d)))]))\n",
"\n",
"(define (one-encloses-the-other? str)\n",
" (define-values (range1 range2) (parse-range str))\n",
" (or (range-encloses? range1 range2) (range-encloses? range2 range1)))\n",
"\n",
"(count one-encloses-the-other? assignments)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Part 2\n",
"\n",
"The procedure for part 2 is the same, just using the predicate for overlapping ranges instead."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"vscode": {
"languageId": "racket"
}
},
"outputs": [
{
"data": {
"text/html": [
"<code>931</code>"
],
"text/plain": [
"931"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(define (one-overlaps-the-other? str)\n",
" (define-values (range1 range2) (parse-range str))\n",
" (range-overlaps? range1 range2))\n",
"\n",
"(count one-overlaps-the-other? assignments)\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Racket (Trusted)",
"language": "racket",
"name": "racket-trusted"
},
"language_info": {
"codemirror_mode": "scheme",
"file_extension": ".rkt",
"mimetype": "text/x-racket",
"name": "Racket",
"pygments_lexer": "racket",
"version": "8.7"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "916dbcbb3f70747c44a77c7bcd40155683ae19c65e1c03b4aa3499c5328201f1"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
|