{ "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": [ "\"WHTLRMZRC\"" ], "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": [ "\"GMPMLWNMG\"" ], "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 }