Skip to content

Commit

Permalink
Starting d5
Browse files Browse the repository at this point in the history
  • Loading branch information
derailed-dash committed Dec 5, 2024
1 parent 43251a5 commit c020a7a
Show file tree
Hide file tree
Showing 2 changed files with 293 additions and 2 deletions.
295 changes: 293 additions & 2 deletions src/AoC_2024/Dazbo's_Advent_of_Code_2024.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1502,6 +1502,297 @@
"logger.info(f\"Part 2 soln={soln}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"---\n",
"## Day 5: Print Queue"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"DAY = \"5\" # replace with actual number (without leading digit)\n",
"day_link = f\"#### See [Day {DAY}](https://adventofcode.com/{YEAR}/day/{DAY}).\"\n",
"display(Markdown(day_link))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"d_name = \"d\" + str(DAY).zfill(2) # e.g. d01\n",
"script_name = \"aoc\" + str(YEAR) + d_name # e.g. aoc2024d01\n",
"locations = dc.get_locations(d_name)\n",
"logger.setLevel(logging.DEBUG)\n",
"# td.setup_file_logging(logger, locations.output_dir)\n",
"\n",
"# Retrieve input and store in local file\n",
"try:\n",
" write_puzzle_input_file(YEAR, DAY, locations)\n",
" with open(locations.input_file, mode=\"rt\") as f:\n",
" input_data = f.read().splitlines()\n",
"\n",
" logger.info(\"Input data:\\n%s\", dc.top_and_tail(input_data))\n",
"except ValueError as e:\n",
" logger.error(e)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Day 5 Part 1\n",
"\n",
"Out input is in two blocks:\n",
"\n",
"1. The page order rules - one rule per line. These are pairs of rules, e.g. `47|53`. This means that `if` an update contains *both* of these page numbers, then page `47` must be printed at some point *before* `53`.\n",
"1. The specified page numbers required in a particular update - one update set per line.\n",
"\n",
"The sample input:\n",
"\n",
"```text\n",
"47|53\n",
"97|13\n",
"97|61\n",
"97|47\n",
"75|29\n",
"61|13\n",
"75|53\n",
"29|13\n",
"97|29\n",
"53|29\n",
"61|53\n",
"97|53\n",
"61|29\n",
"47|13\n",
"75|47\n",
"97|75\n",
"47|61\n",
"75|61\n",
"47|29\n",
"75|13\n",
"53|13\n",
"\n",
"75,47,61,53,29\n",
"97,61,53,29,13\n",
"75,29,13\n",
"75,97,47,61,53\n",
"61,13,29\n",
"97,13,75,29,47\n",
"```\n",
"\n",
"**What is the sum of middle page numbers from only the updates are correctly ordered?**\n",
"\n",
"#### Solution Approach\n",
"\n",
"Rules for a given update:\n",
"\n",
"- For any page number N, there should be a rule `B|N` for every `B` that comes BEFORE it.\n",
"- For any page number N, there must NOT be a rule `B|N` for any `B` that comes AFTER it.\n",
"- For any page number N, there should be a rule `N|A` for every `A` that comes AFTER it.\n",
"- For any page number N, there must NOT be a rule `N|A` for any `A` that comes BEFORE it.\n",
"\n",
"- The rules appear to be a complete set, meaning that there wil be a rule for _every_ possible pair of pages. (?)\n",
"- A given update does necessarily include every page and therefore does not need to include every rule.\n",
"\n",
"Let's:\n",
"\n",
"- Build a dictionary mapping "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"class PageOrdering():\n",
" \n",
" def __init__(self, data: str) -> None:\n",
" \n",
" comes_after, comes_before, updates = self._process_data(data)\n",
" self._comes_after = comes_after\n",
" self._comes_before = comes_before\n",
" self._updates = updates\n",
" \n",
" @property\n",
" def updates(self):\n",
" return self._updates\n",
" \n",
" def _test_comes_before(self, update: list[int]):\n",
" \"\"\"\n",
" - For any page number N, there should be a rule `B|N` for every `B` that comes BEFORE it.\n",
" - For any page number N, there must NOT be a rule `B|N` for any `B` that comes AFTER it.\n",
" - For any page number N, there should be a rule `N|A` for every `A` that comes AFTER it.\n",
" - For any page number N, there must NOT be a rule `N|A` for any `A` that comes BEFORE it.\n",
" \"\"\"\n",
" for page in enumerate(update):\n",
" if \n",
" \n",
" \n",
" def _process_data(self, data: str):\n",
" comes_after = {}\n",
" comes_before = {}\n",
" updates = [] \n",
" \n",
" # split into blocks.\n",
" rules_block, updates_block = data.split(\"\\n\\n\") \n",
" \n",
" # build two-way adjacency dictionary\n",
" for rule in rules_block.splitlines():\n",
" x, y = list(map(int, rule.split(\"|\")))\n",
" comes_after[x] = y\n",
" comes_before[y] = x\n",
" \n",
" # Turn updates block into list of lists\n",
" updates = [[int(x) for x in update_line.split(\",\")] for update_line in updates_block.splitlines()]\n",
" \n",
" return comes_after, comes_before, updates\n",
" \n",
" def __repr__(self) -> str:\n",
" return f\"PageOrdering(rules_len={len(self._comes_before)},updates_len={len(self._updates)})\"\n",
"\n",
" def __str__(self) -> str:\n",
" return \"\\n\".join(\",\".join(map(str, update_row)) for update_row in self._updates) \n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def solve_part1(data):\n",
" page_ordering = PageOrdering(data)\n",
" logger.debug(page_ordering)\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"sample_inputs = []\n",
"sample_inputs.append(\"\"\"\\\n",
"47|53\n",
"97|13\n",
"97|61\n",
"97|47\n",
"75|29\n",
"61|13\n",
"75|53\n",
"29|13\n",
"97|29\n",
"53|29\n",
"61|53\n",
"97|53\n",
"61|29\n",
"47|13\n",
"75|47\n",
"97|75\n",
"47|61\n",
"75|61\n",
"47|29\n",
"75|13\n",
"53|13\n",
"\n",
"75,47,61,53,29\n",
"97,61,53,29,13\n",
"75,29,13\n",
"75,97,47,61,53\n",
"61,13,29\n",
"97,13,75,29,47\"\"\")\n",
"sample_answers = [143]\n",
"\n",
"for curr_input, curr_ans in zip(sample_inputs, sample_answers):\n",
" validate(solve_part1(curr_input), curr_ans) # test with sample data\n",
" logger.info(\"Test passed\")\n",
"\n",
"logger.info(\"All tests passed!\")\n",
"\n",
"soln = solve_part1(input_data)\n",
"logger.info(f\"Part 1 soln={soln}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Day 5 Part 2\n",
"\n",
"Overview..."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def solve_part2(data):\n",
" pass"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"%%time\n",
"sample_inputs = []\n",
"sample_inputs.append(\"\"\"\\\n",
"47|53\n",
"97|13\n",
"97|61\n",
"97|47\n",
"75|29\n",
"61|13\n",
"75|53\n",
"29|13\n",
"97|29\n",
"53|29\n",
"61|53\n",
"97|53\n",
"61|29\n",
"47|13\n",
"75|47\n",
"97|75\n",
"47|61\n",
"75|61\n",
"47|29\n",
"75|13\n",
"53|13\n",
"\n",
"75,47,61,53,29\n",
"97,61,53,29,13\n",
"75,29,13\n",
"75,97,47,61,53\n",
"61,13,29\n",
"97,13,75,29,47\"\"\")\n",
"sample_answers = [143]\n",
"\n",
"for curr_input, curr_ans in zip(sample_inputs, sample_answers):\n",
" validate(solve_part2(curr_input), curr_ans) # test with sample data\n",
" logger.info(\"Test passed\") \n",
"\n",
"logger.info(\"Tests passed!\")\n",
"\n",
"soln = solve_part2(input_data)\n",
"logger.info(f\"Part 2 soln={soln}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down Expand Up @@ -1633,7 +1924,7 @@
"toc_visible": true
},
"kernelspec": {
"display_name": ".aoc-env",
"display_name": ".AoC-env",
"language": "python",
"name": "python3"
},
Expand All @@ -1647,7 +1938,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.6"
"version": "3.11.9"
},
"toc-autonumbering": false,
"toc-showcode": false,
Expand Down
Binary file added src/AoC_2024/d05/input/input.txt
Binary file not shown.

0 comments on commit c020a7a

Please sign in to comment.