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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Advent of Code 2022\n",
"#### Day 5: Supply Stacks\n",
"\n",
"You're operating a crane, following a set of instructions telling you how many boxes to move from one stack to another. After you follow the instructions, the top boxes in the stacks spell out a message.\n",
"\n",
"**Part 1.** What's the message if the crane moves one box at a time?\n",
"\n",
"**Part 2.** What's the message if the crane moves all of the boxes at once?\n",
"\n",
"I'm bringing in my usual utility functions."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"(require racket\n",
" advent-of-code\n",
" threading\n",
" (only-in relation ->string ->list ->number)\n",
" (only-in algorithms chunks-of))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The data file in this one is unusual: the first 10 lines are a pictorial representation of the stacks of boxes, and the remaining lines are instructions in the form `move X from Y to Z`.\n",
"\n",
"Tackling the boxes first, I can get the contents of each stack if I treat the picture as an array and transpose it, drop the first row that contains only brackets, then only take rows 1, 5, 9..., which are the rows with letters in them and trim the leading spaces from each row. I then use this list to create a hashtable."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"(define assignments (~> (fetch-aoc-input (find-session) 2022 5) (string-split \"\\n\")))\n",
"\n",
"(define crates-list\n",
" (~>> assignments\n",
" (take _ 8)\n",
" (map ->list)\n",
" (apply map list _)\n",
" rest\n",
" (chunks-of _ 4)\n",
" (map (λ~> first ->string string-trim ->list) _)))\n",
"\n",
"(define crates\n",
" (for/hash ([c (in-list crates-list)] [i (in-naturals 1)])\n",
" (values i c)))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The instructions are a little easier; this is just a regex and destructuring like in Day 4."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"(struct instruction (n from to))\n",
"\n",
"(define (parse-instruction str)\n",
" (match str\n",
" [(regexp #px\"move (\\\\d+) from (\\\\d) to (\\\\d)\" (list _ n from to))\n",
" (instruction (->number n) (->number from) (->number to))]))\n",
"\n",
"(define instructions (~>> assignments (drop _ 10) (map parse-instruction)))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Part 1\n",
"\n",
"The main function to iterate over the list of instructions is the same for both parts, except for whether the boxes taken off of the origin stack are reversed or not when they end up on the destination stack. They end up reversed if they're taken off one at a time, and don't reverse if the whole stack is picked up at once.\n",
"\n",
"Once I've iterated through all the instructions, the `#:result` clause parses the final crate state."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<code>\"WHTLRMZRC\"</code>"
],
"text/plain": [
"\"WHTLRMZRC\""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(define (find-crate-message cs [reverse? #true])\n",
" (define direction (if reverse? reverse identity))\n",
" (for/fold ([current-crates cs]\n",
" #:result (~>> (hash-values current-crates) (map first) (apply string)))\n",
" ([i (in-list instructions)])\n",
" (match-define (instruction n from to) i)\n",
" (define taken (~> (hash-ref current-crates from) (take _ n) direction))\n",
" (~> current-crates\n",
" (hash-update _ from (λ (v) (drop v n)))\n",
" (hash-update _ to (λ (v) (append taken v))))))\n",
"\n",
"(find-crate-message crates)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"##### Part 2\n",
"\n",
"The result, if the moved boxes don't get flipped:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<code>\"GMPMLWNMG\"</code>"
],
"text/plain": [
"\"GMPMLWNMG\""
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"(find-crate-message crates #false)"
]
}
],
"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
}
|