{
"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": [
"550
"
],
"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": [
"931
"
],
"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
}