Parcourir la source

day 11 and day12.

na 12om eto pizdec, ya umer nahui
metya il y a 4 ans
Parent
commit
0c2759b04f

+ 8 - 0
day11_dumbo_octopus/Cargo.toml

@@ -0,0 +1,8 @@
+[package]
+name = "day11_dumbo_octopus"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]

+ 381 - 0
day11_dumbo_octopus/README.md

@@ -0,0 +1,381 @@
+--- Day 11: Dumbo Octopus ---
+-----------------------------
+
+You enter a large cavern full of rare bioluminescent [dumbo octopuses](https://www.youtube.com/watch?v=eih-VSaS2g0)! They seem to not like the Christmas lights on your submarine, so you turn them off for now.
+
+
+There are 100 octopuses arranged neatly in a 10 by 10 grid. Each octopus slowly gains *energy* over time and *flashes* brightly for a moment when its energy is full. Although your lights are off, maybe you could navigate through the cave without disturbing the octopuses if you could predict when the flashes of light will happen.
+
+
+Each octopus has an *energy level* - your submarine can remotely measure the energy level of each octopus (your puzzle input). For example:
+
+
+
+```
+5483143223
+2745854711
+5264556173
+6141336146
+6357385478
+4167524645
+2176841721
+6882881134
+4846848554
+5283751526
+
+```
+
+The energy level of each octopus is a value between `0` and `9`. Here, the top-left octopus has an energy level of `5`, the bottom-right one has an energy level of `6`, and so on.
+
+
+You can model the energy levels and flashes of light in *steps*. During a single step, the following occurs:
+
+
+* First, the energy level of each octopus increases by `1`.
+* Then, any octopus with an energy level greater than `9` *flashes*. This increases the energy level of all adjacent octopuses by `1`, including octopuses that are diagonally adjacent. If this causes an octopus to have an energy level greater than `9`, it *also flashes*. This process continues as long as new octopuses keep having their energy level increased beyond `9`. (An octopus can only flash *at most once per step*.)
+* Finally, any octopus that flashed during this step has its energy level set to `0`, as it used all of its energy to flash.
+
+
+Adjacent flashes can cause an octopus to flash on a step even if it begins that step with very little energy. Consider the middle octopus with `1` energy in this situation:
+
+
+
+```
+Before any steps:
+11111
+19991
+19191
+19991
+11111
+
+After step 1:
+34543
+4*000*4
+5*000*5
+4*000*4
+34543
+
+After step 2:
+45654
+51115
+61116
+51115
+45654
+
+```
+
+An octopus is *highlighted* when it flashed during the given step.
+
+
+Here is how the larger example above progresses:
+
+
+
+```
+Before any steps:
+5483143223
+2745854711
+5264556173
+6141336146
+6357385478
+4167524645
+2176841721
+6882881134
+4846848554
+5283751526
+
+After step 1:
+6594254334
+3856965822
+6375667284
+7252447257
+7468496589
+5278635756
+3287952832
+7993992245
+5957959665
+6394862637
+
+After step 2:
+88*0*7476555
+5*0*89*0*87*0*54
+85978896*0*8
+84857696*00*
+87*00*9*0*88*00*
+66*000*88989
+68*0000*5943
+*000000*7456
+9*000000*876
+87*0000*6848
+
+After step 3:
+*00*5*0*9*00*866
+85*00*8*00*575
+99*000000*39
+97*000000*41
+9935*0*8*00*63
+77123*00000*
+791125*000*9
+221113*0000*
+*0*421125*000*
+*00*21119*000*
+
+After step 4:
+2263*0*31977
+*0*923*0*31697
+*00*3222115*0*
+*00*41111163
+*00*76191174
+*00*53411122
+*00*4236112*0*
+5532241122
+1532247211
+113223*0*211
+
+After step 5:
+4484144*000*
+2*0*44144*000*
+2253333493
+1152333274
+11873*0*3285
+1164633233
+1153472231
+6643352233
+2643358322
+2243341322
+
+After step 6:
+5595255111
+3155255222
+33644446*0*5
+2263444496
+2298414396
+2275744344
+2264583342
+7754463344
+3754469433
+3354452433
+
+After step 7:
+67*0*7366222
+4377366333
+4475555827
+34966557*0*9
+35*00*6256*0*9
+35*0*9955566
+3486694453
+8865585555
+486558*0*644
+4465574644
+
+After step 8:
+7818477333
+5488477444
+5697666949
+46*0*876683*0*
+473494673*0*
+474*00*97688
+69*0000*7564
+*000000*9666
+8*00000*4755
+68*0000*7755
+
+After step 9:
+9*0*6*0000*644
+78*00000*976
+69*000000*8*0*
+584*00000*82
+5858*0000*93
+69624*00000*
+8*0*2125*000*9
+222113*000*9
+9111128*0*97
+7911119976
+
+After step 10:
+*0*481112976
+*00*31112*00*9
+*00*411125*0*4
+*00*811114*0*6
+*00*991113*0*6
+*00*93511233
+*0*44236113*0*
+553225235*0*
+*0*53225*0*6*00*
+*00*3224*0000*
+
+```
+
+After step 10, there have been a total of `204` flashes. Fast forwarding, here is the same configuration every 10 steps:
+
+
+
+```
+After step 20:
+3936556452
+56865568*0*6
+449655569*0*
+444865558*0*
+445686557*0*
+568*00*86577
+7*00000*9896
+*0000000*344
+6*000000*364
+46*0000*9543
+
+After step 30:
+*0*643334118
+4253334611
+3374333458
+2225333337
+2229333338
+2276733333
+2754574565
+5544458511
+9444447111
+7944446119
+
+After step 40:
+6211111981
+*0*421111119
+*00*42111115
+*000*3111115
+*000*3111116
+*00*65611111
+*0*532351111
+3322234597
+2222222976
+2222222762
+
+After step 50:
+9655556447
+48655568*0*5
+448655569*0*
+445865558*0*
+457486557*0*
+57*000*86566
+6*00000*9887
+8*000000*533
+68*00000*633
+568*0000*538
+
+After step 60:
+25333342*00*
+274333464*0*
+2264333458
+2225333337
+2225333338
+2287833333
+3854573455
+1854458611
+1175447111
+1115446111
+
+After step 70:
+8211111164
+*0*421111166
+*00*42111114
+*000*4211115
+*0000*211116
+*00*65611111
+*0*532351111
+7322235117
+5722223475
+4572222754
+
+After step 80:
+1755555697
+59655556*0*9
+448655568*0*
+445865558*0*
+457*0*86557*0*
+57*000*86566
+7*00000*8666
+*0000000*99*0*
+*0000000*8*00*
+*0000000000*
+
+After step 90:
+7433333522
+2643333522
+2264333458
+2226433337
+2222433338
+2287833333
+2854573333
+4854458333
+3387779333
+3333333333
+
+After step 100:
+*0*397666866
+*0*749766918
+*00*53976933
+*000*4297822
+*000*4229892
+*00*53222877
+*0*532222966
+9322228966
+7922286866
+6789998766
+
+```
+
+After 100 steps, there have been a total of `*1656*` flashes.
+
+
+Given the starting energy levels of the dumbo octopuses in your cavern, simulate 100 steps. *How many total flashes are there after 100 steps?*
+
+
+--- Part Two ---
+----------------
+
+It seems like the individual flashes aren't bright enough to navigate. However, you might have a better option: the flashes seem to be *synchronizing*!
+
+
+In the example above, the first time all octopuses flash simultaneously is step `*195*`:
+
+
+
+```
+After step 193:
+5877777777
+8877777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+7777777777
+
+After step 194:
+6988888888
+9988888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+8888888888
+
+After step 195:
+*0000000000*
+*0000000000*
+*0000000000*
+*0000000000*
+*0000000000*
+*0000000000*
+*0000000000*
+*0000000000*
+*0000000000*
+*0000000000*
+
+```
+
+If you can calculate the exact moments when the octopuses will all flash simultaneously, you should be able to navigate through the cavern. *What is the first step during which all octopuses flash?*
+
+

+ 10 - 0
day11_dumbo_octopus/example.txt

@@ -0,0 +1,10 @@
+5483143223
+2745854711
+5264556173
+6141336146
+6357385478
+4167524645
+2176841721
+6882881134
+4846848554
+5283751526

+ 10 - 0
day11_dumbo_octopus/input.txt

@@ -0,0 +1,10 @@
+3113284886
+2851876144
+2774664484
+6715112578
+7146272153
+6256656367
+3148666245
+3857446528
+7322422833
+8152175168

+ 54 - 0
day11_dumbo_octopus/main.py

@@ -0,0 +1,54 @@
+import os, sys
+import numpy as np
+
+task_dir = os.path.dirname(__file__)
+sys.path.append(f"{task_dir}/..")
+from get_tasks import get_input, generate_readme, check_example
+
+
+def update_step_count(step: np.ndarray) -> tuple[int, np.ndarray, bool]:
+    acc = 0
+    while len(np.where((step > 9) & (step < 1000))[0]) != 0:
+        x, y = np.where((step > 9) & (step < 1000))
+        for idx in range(len(x)):
+            step[max(0, x[idx] - 1) : x[idx] + 2, max(0, y[idx] - 1) : y[idx] + 2] += 1
+            step[x[idx], y[idx]] = 1000 + acc
+            acc += 1
+    return (
+        len(step[step > 9]),
+        np.where(step > 9, 0, step),
+        len(step[step > 9]) == step.size,
+    )
+
+
+def part1(input: list[str]):
+    octopuses = np.array([list(line.strip()) for line in input], dtype=int)
+    sum_flashes = 0
+    for _ in range(1, 101):
+        octopuses += 1
+        flashes, octopuses, _ = update_step_count(octopuses)
+        sum_flashes += flashes
+    print("The asnwer of part1 is:", sum_flashes)
+
+
+def part2(input: list[str]):
+    octopuses = np.array([list(line.strip()) for line in input], dtype=int)
+    step = 0
+    all_flash = False
+    while not all_flash:
+        octopuses += 1
+        _, _, all_flash = update_step_count(octopuses)
+        step += 1
+    print("The answer if part2 is:", step)
+
+
+if __name__ == "__main__":
+
+    input, example = get_input(task_dir, 11)
+
+    check_example(example, part1)
+    check_example(example, part2)
+    part1(input)
+    part2(input)
+
+    generate_readme(task_dir, 11)

+ 3 - 0
day11_dumbo_octopus/src/main.rs

@@ -0,0 +1,3 @@
+fn main() {
+    println!("Hello, world!");
+}

+ 8 - 0
day12_passage_pathing/Cargo.toml

@@ -0,0 +1,8 @@
+[package]
+name = "day12_passage_pathing"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]

+ 194 - 0
day12_passage_pathing/README.md

@@ -0,0 +1,194 @@
+--- Day 12: Passage Pathing ---
+-------------------------------
+
+With your submarine's subterranean subsystems subsisting suboptimally, the only way you're getting out of this cave anytime soon is by finding a path yourself. Not just *a* path - the only way to know if you've found the *best* path is to find *all* of them.
+
+
+Fortunately, the sensors are still mostly working, and so you build a rough map of the remaining caves (your puzzle input). For example:
+
+
+
+```
+start-A
+start-b
+A-c
+A-b
+b-d
+A-end
+b-end
+
+```
+
+This is a list of how all of the caves are connected. You start in the cave named `start`, and your destination is the cave named `end`. An entry like `b-d` means that cave `b` is connected to cave `d` - that is, you can move between them.
+
+
+So, the above cave system looks roughly like this:
+
+
+
+```
+    start
+    /   \
+c--A-----b--d
+    \   /
+     end
+
+```
+
+Your goal is to find the number of distinct *paths* that start at `start`, end at `end`, and don't visit small caves more than once. There are two types of caves: *big* caves (written in uppercase, like `A`) and *small* caves (written in lowercase, like `b`). It would be a waste of time to visit any small cave more than once, but big caves are large enough that it might be worth visiting them multiple times. So, all paths you find should *visit small caves at most once*, and can *visit big caves any number of times*.
+
+
+Given these rules, there are `*10*` paths through this example cave system:
+
+
+
+```
+start,A,b,A,c,A,end
+start,A,b,A,end
+start,A,b,end
+start,A,c,A,b,A,end
+start,A,c,A,b,end
+start,A,c,A,end
+start,A,end
+start,b,A,c,A,end
+start,b,A,end
+start,b,end
+
+```
+
+(Each line in the above list corresponds to a single path; the caves visited by that path are listed in the order they are visited and separated by commas.)
+
+
+Note that in this cave system, cave `d` is never visited by any path: to do so, cave `b` would need to be visited twice (once on the way to cave `d` and a second time when returning from cave `d`), and since cave `b` is small, this is not allowed.
+
+
+Here is a slightly larger example:
+
+
+
+```
+dc-end
+HN-start
+start-kj
+dc-start
+dc-HN
+LN-dc
+HN-end
+kj-sa
+kj-HN
+kj-dc
+
+```
+
+The `19` paths through it are as follows:
+
+
+
+```
+start,HN,dc,HN,end
+start,HN,dc,HN,kj,HN,end
+start,HN,dc,end
+start,HN,dc,kj,HN,end
+start,HN,end
+start,HN,kj,HN,dc,HN,end
+start,HN,kj,HN,dc,end
+start,HN,kj,HN,end
+start,HN,kj,dc,HN,end
+start,HN,kj,dc,end
+start,dc,HN,end
+start,dc,HN,kj,HN,end
+start,dc,end
+start,dc,kj,HN,end
+start,kj,HN,dc,HN,end
+start,kj,HN,dc,end
+start,kj,HN,end
+start,kj,dc,HN,end
+start,kj,dc,end
+
+```
+
+Finally, this even larger example has `226` paths through it:
+
+
+
+```
+fs-end
+he-DX
+fs-he
+start-DX
+pj-DX
+end-zg
+zg-sl
+zg-pj
+pj-he
+RW-he
+fs-DX
+pj-RW
+zg-RW
+start-pj
+he-WI
+zg-he
+pj-fs
+start-RW
+
+```
+
+*How many paths through this cave system are there that visit small caves at most once?*
+
+
+--- Part Two ---
+----------------
+
+After reviewing the available paths, you realize you might have time to visit a single small cave *twice*. Specifically, big caves can be visited any number of times, a single small cave can be visited at most twice, and the remaining small caves can be visited at most once. However, the caves named `start` and `end` can only be visited *exactly once each*: once you leave the `start` cave, you may not return to it, and once you reach the `end` cave, the path must end immediately.
+
+
+Now, the `36` possible paths through the first example above are:
+
+
+
+```
+start,A,b,A,b,A,c,A,end
+start,A,b,A,b,A,end
+start,A,b,A,b,end
+start,A,b,A,c,A,b,A,end
+start,A,b,A,c,A,b,end
+start,A,b,A,c,A,c,A,end
+start,A,b,A,c,A,end
+start,A,b,A,end
+start,A,b,d,b,A,c,A,end
+start,A,b,d,b,A,end
+start,A,b,d,b,end
+start,A,b,end
+start,A,c,A,b,A,b,A,end
+start,A,c,A,b,A,b,end
+start,A,c,A,b,A,c,A,end
+start,A,c,A,b,A,end
+start,A,c,A,b,d,b,A,end
+start,A,c,A,b,d,b,end
+start,A,c,A,b,end
+start,A,c,A,c,A,b,A,end
+start,A,c,A,c,A,b,end
+start,A,c,A,c,A,end
+start,A,c,A,end
+start,A,end
+start,b,A,b,A,c,A,end
+start,b,A,b,A,end
+start,b,A,b,end
+start,b,A,c,A,b,A,end
+start,b,A,c,A,b,end
+start,b,A,c,A,c,A,end
+start,b,A,c,A,end
+start,b,A,end
+start,b,d,b,A,c,A,end
+start,b,d,b,A,end
+start,b,d,b,end
+start,b,end
+
+```
+
+The slightly larger example above now has `103` paths through it, and the even larger example now has `3509` paths through it.
+
+
+Given these new rules, *how many paths through this cave system are there?*
+
+

+ 7 - 0
day12_passage_pathing/example.txt

@@ -0,0 +1,7 @@
+start-A
+start-b
+A-c
+A-b
+b-d
+A-end
+b-end

+ 23 - 0
day12_passage_pathing/input.txt

@@ -0,0 +1,23 @@
+he-JK
+wy-KY
+pc-XC
+vt-wy
+LJ-vt
+wy-end
+wy-JK
+end-LJ
+start-he
+JK-end
+pc-wy
+LJ-pc
+at-pc
+xf-XC
+XC-he
+pc-JK
+vt-XC
+at-he
+pc-he
+start-at
+start-XC
+at-LJ
+vt-JK

+ 76 - 0
day12_passage_pathing/main.py

@@ -0,0 +1,76 @@
+from doctest import Example
+import os, sys
+
+task_dir = os.path.dirname(__file__)
+sys.path.append(f"{task_dir}/..")
+from get_tasks import get_input, check_example, generate_readme
+from collections import deque, defaultdict
+
+
+def parse(input: list[str]) -> dict:
+    in_map_cave = defaultdict(list)
+    for line in input:
+        a, b = line.split("-")
+        in_map_cave[a].append(b)
+        if a != "start" and b != "end":
+            in_map_cave[b].append(a)
+    return dict(in_map_cave)
+
+
+def findpaths(map_cave: dict, twice=False) -> tuple[int, list]:
+    paths = []
+    path = ["start"]
+    q = deque([path])
+    state_q = deque([False])
+    while q:
+        path = q.popleft()
+        double_visited = state_q.popleft()
+        if path[-1] == "end":
+            paths.append(path)
+            continue
+        for cave in map_cave[path[-1]]:
+            if not (cave.islower() and (cave in path)):
+                q.append(path + [cave])
+                state_q.append(double_visited)
+            elif not double_visited and twice:
+                state_q.append(True)
+                q.append(path + [cave])
+    return len(paths), paths
+
+
+def findpaths_first_version(map_cave: dict) -> tuple[int, list]:
+    paths = []
+    path = ["start"]
+    q = deque([path])
+    while q:
+        path = q.popleft()
+        if path[-1] == "end":
+            paths.append(path)
+            continue
+        for cave in map_cave[path[-1]]:
+            if not (cave.islower() and (cave in path)):
+                newpath = path.copy()
+                newpath.append(cave)
+                q.append(newpath)
+    return len(paths), paths
+
+
+def part1(input: list[str]):
+    l, _ = findpaths(parse(input))
+    print("The answer of part1 is:", l)
+
+
+def part2(input: list[str]):
+    l, _ = findpaths(parse(input), twice=True)
+    print("The answer of part2 is:", l)
+
+
+if __name__ == "__main__":
+    input, example = get_input(task_dir, 12)
+
+    check_example(example, part1)
+    check_example(example, part2)
+    part1(input)
+    part2(input)
+
+    generate_readme(task_dir, 12)

+ 3 - 0
day12_passage_pathing/src/main.rs

@@ -0,0 +1,3 @@
+fn main() {
+    println!("Hello, world!");
+}

+ 4 - 7
get_tasks.py

@@ -5,7 +5,7 @@ import markdownify as md
 from typing import Any, Callable
 
 
-def generate_readme(task_dir, day):
+def generate_readme(task_dir: str, day: int):
 
     readme_path = os.path.join(task_dir, "README.md")
     cookies_dict = {
@@ -28,7 +28,7 @@ def generate_readme(task_dir, day):
                 readme.write(md.markdownify(str(soup.find_all("article")[1])))
 
 
-def get_input(task_dir, day):
+def get_input(task_dir: str, day: int) -> tuple[list[str], list[str]]:
     input_path = os.path.join(task_dir, "input.txt")
     example_path = os.path.join(task_dir, "example.txt")
 
@@ -38,20 +38,18 @@ def get_input(task_dir, day):
 
     if os.path.exists(input_path):
         with open(input_path, "r") as f:
-            input = f.readlines()
+            input = f.read().splitlines()
     else:
         input = requests.get(
             f"https://adventofcode.com/2021/day/{day}/input", cookies=cookies_dict
         ).text
-
         with open(input_path, "w") as f:
             f.write(input)
-
         input = input.splitlines()
 
     if os.path.exists(example_path):
         with open(example_path, "r") as e:
-            example = e.readlines()
+            example = e.read().splitlines()
     else:
         example = bs4.BeautifulSoup(
             requests.get(
@@ -62,7 +60,6 @@ def get_input(task_dir, day):
 
         with open(example_path, "w") as f:
             f.write(example)
-
         example = example.splitlines()
 
     return input, example