From 87ab487d59fa85dbe2afa55cc841b02805ae42ca Mon Sep 17 00:00:00 2001 From: Louis Burda Date: Fri, 7 Apr 2023 17:18:18 -0400 Subject: Reorder days into src --- src/18/input | 50 +++++++++++++++ src/18/part1 | 175 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/18/part2 | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/18/solve.py | 81 +++++++++++++++++++++++++ src/18/test1 | 10 +++ 5 files changed, 500 insertions(+) create mode 100644 src/18/input create mode 100644 src/18/part1 create mode 100644 src/18/part2 create mode 100644 src/18/solve.py create mode 100644 src/18/test1 (limited to 'src/18') diff --git a/src/18/input b/src/18/input new file mode 100644 index 0000000..0f62ca5 --- /dev/null +++ b/src/18/input @@ -0,0 +1,50 @@ +|...||..|....|..#..|.|..#.|......#|.||.||.|..|.... +.#.....#....#|||#|#..||..|.#..|....#...||.#.#|.|.| +.|...|#..|||..|.#....#..|.|....|...||...#.#|...|#. +.........|.|.#||.##.#|.||.|#..||..||...##.##...... +..|.||.#.|.|.|....||#.....|.|.||##.#|##.|....|.#.. +#..#|#..|#...|...#...#....#|##......#..|||#..#.#.. +...#.#.#|...||...|.#...||#.....|##|||.....#.#.#.|. +.#..|.###|#.|.##......||..#...#.#..|#.|.##.#.#.|.. +..||.|.|.....###...#|...###..##|.#.#....#|..##.|.| +.##..#.|.#....##...||.|#..#.####..|#..##.|...#.... +..#...#|..|..|.|.#|#.|.|..|..||......#|.|...##..|. +..||...##|#.....#|..|..|.|.##.|.##.|#|.##|.||...#. +..|.||......#...#......|......|.##...|..|.|.#...#. +||#.#|...#.......#......|..|#.#.|.....#...#.|##..| +.....||.|..|##.#|..#..#|..#|.##....##|.##.||...### +#|..#..#....|...|.|....#.##...#..|.|..#........|#| +....#.|.....##.|..##.....##..#.....|#.|.#.|.#.###. +...###........|.....|..|#..#..|##..###.....#||..|| +#.#...#|..##...|..|||#.....|#|.......#..#.......#| +#.....||||.#..##.|..|#|.#..|.......|##.|#|#....#.| +#..##|...|....#.#.#.||.|..|.....#|...|....#|..##|# +#..|||#..#..|..#|....#.........#...#...#...|.|...# +.........|.|...#...|...#|##..#.....#.|.#..||.#...# +.|#...#|...#.###.|#.||.|..#..#.####..#..||.#.#|..| +.|#....||#|#|.|.|#....##..||.##|....#....#||...|.| +...|....|...|.||#...#...........#..#....##|.#....| +....#|#..#....|##...#..|#..#.|......|#........|#.. +.|..#...|..#.|.#....#....#.|...#..|........|..|... +...##|....||...##...|......|#..|..#..|.........##. +..##.|.#..........##.|....|##|.....|.#.#.|.....|.# +#|.|.......#|..#..#.#.|..|.|.#.||#.#...|.#..|..... +||.#............#...|...#..|#|..||##...#.|#|##|.#| +..|..||####.|....|##.#.|...|||#..|.|.|.........##. +...|....|..||.#..##||.|||#..|..#...#.##...||.|..|| +....|...|##...#|.|.|..#|..|#|..##.|....||..|.|.||. +#..#.......|.#..#..||...#|..#.....#|#..|..|...##.. +#...#..##..|.#...#.....|......###|..|...||.....|.. +#.|..#..|#..|#|..#..||#......|#.......|.#....###.. +#...#||...##|.#.#|####|...|......|.#.#..|#.##...|. +|.#..#....#..#.....|#..|#.|..##.#..|#|##........|| +#.........##..|....|#.........||..||##...||.|..|.| +.#....#.......#..|#.|...|....#.#.#........##.##.|. +.#.#..|.|#..|..#..###...|.#......|.|#.|.##..|.|##. +..||..|.##.##|...|....#||##....#..#.|#|.|#||#..|.. +.......#|#||.....|.||.|##..|.|....|....|.#...#..|. +#||##|.||..|##.|..|#.#.|.|....#|.#|.....|||..#.||. +.||#.|#...||#.#..#..|.|#.....#.#.|#.|...#..#...#.. +#........|..#...|#..###.|.#|...#..#...........#.|# +.|...#|....||.|...#.|..|.||##.|..#|.#|..|.#....#.. +||....###...#...|||.||..#.|.....||.#|..###..|....# diff --git a/src/18/part1 b/src/18/part1 new file mode 100644 index 0000000..02322ac --- /dev/null +++ b/src/18/part1 @@ -0,0 +1,175 @@ +--- Day 18: Settlers of The North Pole --- + +On the outskirts of the North Pole base construction project, many Elves are collecting lumber. + +The lumber collection area is 50 acres by 50 acres; each acre can be either open ground (.), +trees (|), or a lumberyard (#). You take a scan of the area (your puzzle input). + +Strange magic is at work here: each minute, the landscape looks entirely different. In exactly +one minute, an open acre can fill with trees, a wooded acre can be converted to a lumberyard, or a +lumberyard can be cleared to open ground (the lumber having been sent to other projects). + +The change to each acre is based entirely on the contents of that acre as well as the number of +open, wooded, or lumberyard acres adjacent to it at the start of each minute. Here, "adjacent" means +any of the eight acres surrounding that acre. (Acres on the edges of the lumber collection area +might have fewer than eight adjacent acres; the missing acres aren't counted.) + +In particular: + + + - An open acre will become filled with trees if three or more adjacent acres contained trees. +Otherwise, nothing happens. + + - An acre filled with trees will become a lumberyard if three or more adjacent acres were +lumberyards. Otherwise, nothing happens. + + - An acre containing a lumberyard will remain a lumberyard if it was adjacent to at least one other +lumberyard and at least one acre containing trees. Otherwise, it becomes open. + + +These changes happen across all acres simultaneously, each of them using the state of all acres at +the beginning of the minute and changing to their new form by the end of that same minute. Changes +that happen during the minute don't affect each other. + +For example, suppose the lumber collection area is instead only 10 by 10 acres with this initial +configuration: + +Initial state: +.#.#...|#. +.....#|##| +.|..|...#. +..|#.....# +#.#|||#|#| +...#.||... +.|....|... +||...#|.#| +|.||||..|. +...#.|..|. + +After 1 minute: +.......##. +......|### +.|..|...#. +..|#||...# +..##||.|#| +...#||||.. +||...|||.. +|||||.||.| +|||||||||| +....||..|. + +After 2 minutes: +.......#.. +......|#.. +.|.|||.... +..##|||..# +..###|||#| +...#|||||. +|||||||||. +|||||||||| +|||||||||| +.||||||||| + +After 3 minutes: +.......#.. +....|||#.. +.|.||||... +..###|||.# +...##|||#| +.||##||||| +|||||||||| +|||||||||| +|||||||||| +|||||||||| + +After 4 minutes: +.....|.#.. +...||||#.. +.|.#||||.. +..###||||# +...###||#| +|||##||||| +|||||||||| +|||||||||| +|||||||||| +|||||||||| + +After 5 minutes: +....|||#.. +...||||#.. +.|.##||||. +..####|||# +.|.###||#| +|||###|||| +|||||||||| +|||||||||| +|||||||||| +|||||||||| + +After 6 minutes: +...||||#.. +...||||#.. +.|.###|||. +..#.##|||# +|||#.##|#| +|||###|||| +||||#||||| +|||||||||| +|||||||||| +|||||||||| + +After 7 minutes: +...||||#.. +..||#|##.. +.|.####||. +||#..##||# +||##.##|#| +|||####||| +|||###|||| +|||||||||| +|||||||||| +|||||||||| + +After 8 minutes: +..||||##.. +..|#####.. +|||#####|. +||#...##|# +||##..###| +||##.###|| +|||####||| +||||#||||| +|||||||||| +|||||||||| + +After 9 minutes: +..||###... +.||#####.. +||##...##. +||#....### +|##....##| +||##..###| +||######|| +|||###|||| +|||||||||| +|||||||||| + +After 10 minutes: +.||##..... +||###..... +||##...... +|##.....## +|##.....## +|##....##| +||##.####| +||#####||| +||||#||||| +|||||||||| + +After 10 minutes, there are 37 wooded acres and 31 lumberyards. Multiplying the number of wooded +acres by the number of lumberyards gives the total resource value after ten minutes: 37 * 31 = +1147. + +What will the total resource value of the lumber collection area be after 10 minutes? + + diff --git a/src/18/part2 b/src/18/part2 new file mode 100644 index 0000000..c37ea49 --- /dev/null +++ b/src/18/part2 @@ -0,0 +1,184 @@ +--- Part Two --- + +You arrive at the vault only to discover that there is not one vault, but four - each with its own +entrance. + +On your map, find the area in the middle that looks like this: + +... +.@. +... + +Update your map to instead use the correct data: + +@#@ +### +@#@ + +This change will split your map into four separate sections, each with its own entrance: + +####### ####### +#a.#Cd# #a.#Cd# +##...## ##@#@## +##.@.## --> ####### +##...## ##@#@## +#cB#Ab# #cB#Ab# +####### ####### + +Because some of the keys are for doors in other vaults, it would take much too long to collect all +of the keys by yourself. Instead, you deploy four remote-controlled robots. Each starts at one of +the entrances (@). + +Your goal is still to collect all of the keys in the fewest steps, but now, each robot has its own +position and can move independently. You can only remotely control a single robot at a time. +Collecting a key instantly unlocks any corresponding doors, regardless of the vault in which the key +or door is found. + +For example, in the map above, the top-left robot first collects key a, unlocking door A in the +bottom-right vault: + +####### +#@.#Cd# +##.#@## +####### +##@#@## +#cB#.b# +####### + +Then, the bottom-right robot collects key b, unlocking door B in the bottom-left vault: + +####### +#@.#Cd# +##.#@## +####### +##@#.## +#c.#.@# +####### + +Then, the bottom-left robot collects key c: + +####### +#@.#.d# +##.#@## +####### +##.#.## +#@.#.@# +####### + +Finally, the top-right robot collects key d: + +####### +#@.#.@# +##.#.## +####### +##.#.## +#@.#.@# +####### + +In this example, it only took 8 steps to collect all of the keys. + +Sometimes, multiple robots might have keys available, or a robot might have to wait for multiple +keys to be collected: + +############### +#d.ABC.#.....a# +######@#@###### +############### +######@#@###### +#b.....#.....c# +############### + +First, the top-right, bottom-left, and bottom-right robots take turns collecting keys a, b, and c, a +total of 6 + 6 + 6 = 18 steps. Then, the top-left robot can access key d, spending another 6 steps; +collecting all of the keys here takes a minimum of 24 steps. + +Here's a more complex example: + +############# +#DcBa.#.GhKl# +#.###@#@#I### +#e#d#####j#k# +###C#@#@###J# +#fEbA.#.FgHi# +############# + + + - Top-left robot collects key a. + + - Bottom-left robot collects key b. + + - Top-left robot collects key c. + + - Bottom-left robot collects key d. + + - Top-left robot collects key e. + + - Bottom-left robot collects key f. + + - Bottom-right robot collects key g. + + - Top-right robot collects key h. + + - Bottom-right robot collects key i. + + - Top-right robot collects key j. + + - Bottom-right robot collects key k. + + - Top-right robot collects key l. + + +In the above example, the fewest steps to collect all of the keys is 32. + +Here's an example with more choices: + +############# +#g#f.D#..h#l# +#F###e#E###.# +#dCba@#@BcIJ# +############# +#nK.L@#@G...# +#M###N#H###.# +#o#m..#i#jk.# +############# + +One solution with the fewest steps is: + + + - Top-left robot collects key e. + + - Top-right robot collects key h. + + - Bottom-right robot collects key i. + + - Top-left robot collects key a. + + - Top-left robot collects key b. + + - Top-right robot collects key c. + + - Top-left robot collects key d. + + - Top-left robot collects key f. + + - Top-left robot collects key g. + + - Bottom-right robot collects key k. + + - Bottom-right robot collects key j. + + - Top-right robot collects key l. + + - Bottom-left robot collects key n. + + - Bottom-left robot collects key m. + + - Bottom-left robot collects key o. + + +This example requires at least 72 steps to collect all keys. + +After updating your map and using the remote-controlled robots, what is the fewest steps necessary +to collect all of the keys? + + diff --git a/src/18/solve.py b/src/18/solve.py new file mode 100644 index 0000000..f209429 --- /dev/null +++ b/src/18/solve.py @@ -0,0 +1,81 @@ +import sys +sys.path.append("../common") +import aoc +from copy import deepcopy +from collections import deque + +states = (".", "|", "#") + +ivals = dict() +ivals["#"] = 0 +ivals["."] = 0 +ivals["|"] = 0 + +def pasrse_line(l): + return tuple([states.index(c) for c in l]) + +vmap = [pasrse_line(l) for l in aoc.data.split("\n")] +xlen, ylen = len(vmap[0]), len(vmap) + +def get_at(x, y): + if y < 0 or y >= ylen or x < 0 or x >= xlen: + return None + return vmap[y][x] + +def next(x, y): + v = vmap[y][x] + around = list() + [[around.append(get_at(x+i-1, y+j-1)) for j in range(3) if not (i == 1 and j == 1)] for i in range(3)] + if v == 0: + if len([v for v in around if v == 1]) >= 3: + return 1 + elif v == 1: + if len([v for v in around if v == 2]) >= 3: + return 2 + elif v == 2: + if len([v for v in around if v == 1]) < 1 or len([v for v in around if v == 2]) < 1: + return 0 + return v + +def get_vals(): + vals = [0 for x in range(3)] + for y in range(ylen): + for x in range(xlen): + vals[vmap[y][x]] += 1 + return vals + +def draw_map(cmap): + for y in range(ylen): + aoc.debug("".join([str(c) for c in cmap[y]])) + +def iterate(n): + global vmap + for i in range(n): + omap = [deque() for y in range(ylen)] + for y in range(ylen): + for x in range(xlen): + omap[y].append(next(x, y)) + vmap = omap + +def get_res(): + vals = get_vals() + return (vals[1] * vals[2]) + +def solve1(args): + iterate(10) + vals = get_vals() + return vals[1] * vals[2] + +def solve2(args): + iterate(1000) + omap = deepcopy(vmap) + counter = 0 + while True: + iterate(1) + counter += 1 + if vmap == omap: + break + + return get_res() + +aoc.run(solve1, solve2, sols=[574590, 183787]) diff --git a/src/18/test1 b/src/18/test1 new file mode 100644 index 0000000..13d299d --- /dev/null +++ b/src/18/test1 @@ -0,0 +1,10 @@ +.#.#...|#. +.....#|##| +.|..|...#. +..|#.....# +#.#|||#|#| +...#.||... +.|....|... +||...#|.#| +|.||||..|. +...#.|..|. -- cgit v1.2.3-71-gd317