diff options
Diffstat (limited to 'racket/aoc2022/day-04/day-04.ipynb')
-rw-r--r-- | racket/aoc2022/day-04/day-04.ipynb | 148 |
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 +} |