From d722fa8f8ed4d63975618d98e65e65ac5059d2c7 Mon Sep 17 00:00:00 2001 From: swatts Date: Mon, 4 Dec 2023 17:41:14 +0100 Subject: [PATCH] forgot to add freeze --- _freeze/aoc/aoc/execute-results/html.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/_freeze/aoc/aoc/execute-results/html.json b/_freeze/aoc/aoc/execute-results/html.json index 6ad7981..381ca1f 100644 --- a/_freeze/aoc/aoc/execute-results/html.json +++ b/_freeze/aoc/aoc/execute-results/html.json @@ -1,9 +1,9 @@ { - "hash": "f2153629741ffdb224d17506ac1334cc", + "hash": "09a49daa543b453fd6fb6a5841ae9a21", "result": { - "markdown": "---\ntoc: true\ndescription: Advent of Code 2023 Solutions in Python\ncategories:\n - python\ntitle: \"\\U0001F384\"\ndate: '2023-12-01'\ncode-line-numbers: true\nhighlight-style: github\n---\n\n## 1\nQuite challenging for a day 1! Learned some new regex for part 2 which was fun - positive lookahead `?=...` essentially means you can extract overlapping matches\n\n::: {.column-page}\n\n::: {.cell execution_count=1}\n``` {.python .cell-code}\nwith open(\"aoc/1/input.txt\", \"r\") as f:\n inp = f.readlines()\n\nONE_TO_NINE = list(map(str, list(range(1, 10))))\n\n\ndef extract_first_num(a):\n for char in a:\n if char in ONE_TO_NINE:\n return char\n\n\ntotal = 0\nfor row in inp:\n total += int(extract_first_num(row) + extract_first_num(row[::-1]))\n\nprint(\"Part 1 answer:\")\nprint(total)\n\nimport re\n\n\ndef convert_num(x):\n num_map = dict(\n zip(\n [\"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\"],\n ONE_TO_NINE,\n )\n )\n\n if x.isnumeric():\n return x\n else:\n return num_map[x]\n\n\ntotal = 0\nfor row in inp:\n cap = re.findall(r\"(?=(\\d|one|two|three|four|five|six|seven|eight|nine))\", row)\n total += int(convert_num(cap[0]) + convert_num(cap[-1]))\n\n\nprint(\"Part 2 answer:\")\nprint(total)\n```\n\n::: {.cell-output .cell-output-stdout}\n```\nPart 1 answer:\n54951\nPart 2 answer:\n55218\n```\n:::\n:::\n\n\n:::\n## 2\n\n\n::: {.column-page}\n\n:::\n\n", + "markdown": "---\ntoc: true\ndescription: Advent of Code 2023 Solutions in Python\ncategories:\n - python\ntitle: \"\\U0001F384\"\ndate: '2023-12-01'\ncode-line-numbers: true\nhighlight-style: github\n---\n\n## 1\nQuite challenging for a day 1! Learned some new regex for part 2 which was fun - positive lookahead `?=...` essentially means you can extract overlapping matches\n\n::: {.column-page}\n\n::: {.cell execution_count=1}\n``` {.python .cell-code}\nwith open(\"aoc/1/input.txt\", \"r\") as f:\n inp = f.readlines()\n\nONE_TO_NINE = list(map(str, list(range(1, 10))))\n\n\ndef extract_first_num(a):\n for char in a:\n if char in ONE_TO_NINE:\n return char\n\n\ntotal = 0\nfor row in inp:\n total += int(extract_first_num(row) + extract_first_num(row[::-1]))\n\nprint(\"Part 1 answer:\")\nprint(total)\n\nimport re\n\n\ndef convert_num(x):\n num_map = dict(\n zip(\n [\"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\"],\n ONE_TO_NINE,\n )\n )\n\n if x.isnumeric():\n return x\n else:\n return num_map[x]\n\n\ntotal = 0\nfor row in inp:\n cap = re.findall(r\"(?=(\\d|one|two|three|four|five|six|seven|eight|nine))\", row)\n total += int(convert_num(cap[0]) + convert_num(cap[-1]))\n\n\nprint(\"Part 2 answer:\")\nprint(total)\n```\n\n::: {.cell-output .cell-output-stdout}\n```\nPart 1 answer:\n54951\nPart 2 answer:\n55218\n```\n:::\n:::\n\n\n:::\n## 2\nFeel like this should have been day one 😄\n\n::: {.column-page}\n\n::: {.cell execution_count=2}\n``` {.python .cell-code}\nwith open(\"aoc/2/input.txt\", \"r\") as f:\n inp = f.readlines()\n \ntotal = 0\n \nfor row in inp:\n index, game = row.split(\":\")\n index = int(index.replace(\"Game \", \"\"))\n possible = True\n \n for game in game.split(\";\"):\n bag_one = dict(\n red=12,\n green=13,\n blue=14,\n )\n \n for colours in game.split(\",\"):\n num, color = colours.strip().split(\" \")\n if int(num) > bag_one[color]:\n possible = False\n \n if possible:\n total += index\n \nprint(\"Part 1 answer:\")\nprint(total)\n\nimport math\n\ntotal = 0\n\nfor row in inp:\n index, game = row.split(\":\")\n index = int(index.replace(\"Game \", \"\"))\n bag_max = dict(\n red=0,\n green=0,\n blue=0,\n )\n for game in game.split(\";\"): \n for colours in game.split(\",\"):\n num, color = colours.strip().split(\" \")\n if int(num) > bag_max[color]:\n bag_max[color] = int(num)\n \n total += math.prod(bag_max.values())\n \nprint(\"Part 2 answer:\")\nprint(total)\n```\n\n::: {.cell-output .cell-output-stdout}\n```\nPart 1 answer:\n2563\nPart 2 answer:\n70768\n```\n:::\n:::\n\n\n:::\n## 3\nI don't like grids 🫠 I probably made this harder than it needed to be. If I were to do this again I probably would have just used euclidian distance comparisons\n\n::: {.column-page}\n\n::: {.cell execution_count=3}\n``` {.python .cell-code}\nimport re\nfrom collections import defaultdict\nfrom itertools import product\n\nwith open(\"aoc/3/input.txt\", \"r\") as f:\n inp = f.readlines()\n \n# examine all unique chars to populate regex pattern and SYMBOLS set\n# print(set(y for x in inp for y in x))\n \ntotal = 0\nSYMBOLS = {\"*\", \"#\", \"$\", \"+\", \"-\", \"%\", \"=\", \"/\", \"&\", \"@\"}\np = re.compile(\"\\d+|\\*|#|\\$|\\+|-|%|=|\\/|&|@\")\n\ngrid = []\nsyms = []\n\ndef poss_neighbours(i: int, j: tuple):\n i_s = list(filter(lambda x: x >= 0, [i, i-1, i+1]))\n j_s = list(filter(lambda x: x >=0 and x < len(inp[0]), [*j, j[0]-1, j[-1]+1]))\n \n for out_i in i_s:\n for out_j in j_s:\n if out_i == i and out_j in j:\n continue\n \n yield out_i, out_j\n\nassert set(poss_neighbours(0, (0,))) == {(1,0), (1,1), (0,1)}\n \n# construct the data structures for iterating over numbers and symbols\nfor i, row in enumerate(inp):\n for m in p.finditer(row):\n group = m.group()\n js = tuple(range(*m.span()))\n out = (group, i, js)\n \n if m.group() in SYMBOLS:\n syms.append(\n (group, i, js[0])\n )\n else:\n grid.append(\n (int(group), i, js)\n ) \n \n# part 1 logic\nfor num, i, js in grid:\n poss = list(poss_neighbours(i, js))\n \n for _, sym_i, sym_j in syms:\n if (sym_i, sym_j) in poss:\n total += num\n\nprint(\"Part 1 answer:\")\nprint(total)\n\nimport math\ntotal = 0\n\n# part 2 logic\nfor sym, i, j in syms:\n if sym == \"*\":\n poss = list(poss_neighbours(i, (j, )))\n \n adj = set()\n for num, num_i, num_js in grid:\n for num_j in num_js:\n if (num_i, num_j) in poss:\n adj.add(num)\n \n if len(adj) == 2:\n total += math.prod(adj)\n\nprint(\"Part 2 answer:\")\nprint(total)\n```\n\n::: {.cell-output .cell-output-stdout}\n```\nPart 1 answer:\n551094\nPart 2 answer:\n80179647\n```\n:::\n:::\n\n\n:::\n## 4\nEnjoyed the logic for the second part with the copies. I'm sure there was potential to go on a wild goose chase with recursion here, so I'm happy to have avoided the temptation 🤣\n\n::: {.column-page}\n\n::: {.cell execution_count=4}\n``` {.python .cell-code}\nwith open(\"aoc/4/input.txt\", \"r\") as f:\n inp = f.readlines()\n \ntotal = 0\n\n# part 1 logic\nfor row in inp:\n index, rest = row.split(\":\")\n \n win, play = rest.split(\"|\")\n win = list(filter(lambda x: x.isnumeric(), win.strip().split(\" \")))\n play = list(filter(lambda x: x.isnumeric(), play.strip().split(\" \")))\n score = 0\n \n \n for num in win:\n if num in play:\n score += 1\n \n if score > 0:\n total += 2 ** (score - 1)\n \n\nprint(\"Part 1 answer:\")\nprint(total)\n\ntotal = 0\ncopies = {}\n\n# part 2 logic\nfor row in inp:\n index, rest = row.split(\":\")\n index = int(index.split(\"d\")[1].strip())\n \n win, play = rest.split(\"|\")\n win = list(filter(lambda x: x.isnumeric(), win.strip().split(\" \")))\n play = list(filter(lambda x: x.isnumeric(), play.strip().split(\" \")))\n score = 0\n \n for num in win:\n if num in play:\n score += 1\n \n for x in range(index+1, index+score+1):\n copies[x] = copies.get(x, 0) + copies.get(index, 0) + 1\n \n total += copies.get(index, 0) + 1\n \n\nprint(\"Part 2 answer:\")\nprint(total)\n```\n\n::: {.cell-output .cell-output-stdout}\n```\nPart 1 answer:\n23678\nPart 2 answer:\n15455663\n```\n:::\n:::\n\n\n:::\n\n", "supporting": [ - "aoc_files/figure-html" + "aoc_files" ], "filters": [], "includes": {}