aboutsummaryrefslogtreecommitdiff
path: root/racket/aoc2022/day-04/day-04.ipynb
diff options
context:
space:
mode:
Diffstat (limited to 'racket/aoc2022/day-04/day-04.ipynb')
-rw-r--r--racket/aoc2022/day-04/day-04.ipynb148
1 files changed, 148 insertions, 0 deletions
diff --git a/racket/aoc2022/day-04/day-04.ipynb b/racket/aoc2022/day-04/day-04.ipynb
new file mode 100644
index 0000000..44c8980
--- /dev/null
+++ b/racket/aoc2022/day-04/day-04.ipynb
@@ -0,0 +1,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
+}