From 0da8029686fa991123e6fdebdcd4070cd53e38bc Mon Sep 17 00:00:00 2001 From: felixm Date: Wed, 6 Dec 2023 11:47:04 -0500 Subject: [PATCH] Do days 5 and 6. --- README.md | 5 +- d4.py | 49 ++++++++++++---- d5.py | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ d6.py | 57 +++++++++++++++++++ dx.py | 44 +++++++++++++++ 5 files changed, 307 insertions(+), 11 deletions(-) create mode 100644 d5.py create mode 100644 d6.py create mode 100644 dx.py diff --git a/README.md b/README.md index a002ba3..b308099 100644 --- a/README.md +++ b/README.md @@ -3,4 +3,7 @@ - Day 1: 40:00 (I don't know what I am doing.) - Day 2: 14:15 (Okay, but far way from leaderboard.) - Day 3: 1st 20:00, 2nd 70:00... (I had a logic error that took me a while to find.) -- Day 4: +- Day 4: 1st 9:06, 2nd 22:31; it wasn't hard but I didn't think quick enough :/ +- Day 5: 1st 25:00, 2nd 1:55:00; Required patience and accuracy +- Day 6: 13:54; I was slow because I thought it is much harder? +- Day 7: diff --git a/d4.py b/d4.py index 734a77c..f8fac01 100644 --- a/d4.py +++ b/d4.py @@ -1,36 +1,65 @@ +from string import ascii_lowercase, ascii_uppercase, digits import re EXAMPLE = """ - +Card 1: 41 48 83 86 17 | 83 86 6 31 17 9 48 53 +Card 2: 13 32 20 16 61 | 61 30 68 82 17 32 24 19 +Card 3: 1 21 53 59 44 | 69 82 63 72 16 21 14 1 +Card 4: 41 92 73 84 69 | 59 84 76 51 58 5 54 83 +Card 5: 87 83 26 28 32 | 88 30 70 12 93 22 82 36 +Card 6: 31 18 13 56 72 | 74 77 10 23 35 67 36 11 """ def clean(text: str) -> list[str]: return list(filter(lambda l: l.strip() != "", text.splitlines())) def solve(lines: list[str]): - s = 0 + res = 0 for (i, line) in enumerate(lines): - print(i, line) - return s + c, s = line.split(":") + w, y = s.split("|") + w = set([int(c) for c in w.strip().split()]) + y = set([int(c) for c in y.strip().split()]) + z = w.intersection(y) + + if z: + ps = 1 + else: + ps = 0 + for _ in range(len(z) - 1): + ps *= 2 + res += ps + return res def solve2(lines: list[str]): - s = 0 + res = 0 + matches = [] for (i, line) in enumerate(lines): - print(i, line) - return s + c, s = line.split(":") + w, y = s.split("|") + w = set([int(c) for c in w.strip().split()]) + y = set([int(c) for c in y.strip().split()]) + z = w.intersection(y) + matches.append(len(z)) + + scratchcards = list(range(len(matches))) + while scratchcards: + sc = scratchcards.pop() + res += 1 + for i in range(matches[sc]): + if sc + i + 1 < len(matches): + scratchcards.append(sc + i + 1) + return res def main(): example = clean(EXAMPLE) print("Example 1:", solve(example)) - return data = clean(open("i4.txt").read()) print("Solution 1:", solve(data)) - return example = clean(EXAMPLE) print("Example 2:", solve2(example)) - return data = clean(open("i4.txt").read()) print("Solution 2:", solve2(data)) diff --git a/d5.py b/d5.py new file mode 100644 index 0000000..9bf9570 --- /dev/null +++ b/d5.py @@ -0,0 +1,163 @@ +EXAMPLE = """ +seeds: 79 14 55 13 + +seed-to-soil map: +50 98 2 +52 50 48 + +soil-to-fertilizer map: +0 15 37 +37 52 2 +39 0 15 + +fertilizer-to-water map: +49 53 8 +0 11 42 +42 0 7 +57 7 4 + +water-to-light map: +88 18 7 +18 25 70 + +light-to-temperature map: +45 77 23 +81 45 19 +68 64 13 + +temperature-to-humidity map: +0 69 1 +1 0 69 + +humidity-to-location map: +60 56 37 +56 93 4 +""" + +def clean(text: str) -> list[str]: + return list(text.splitlines()) + +def solve(lines: list[str]): + seeds = [] + idx = -1 + maps = [] + + for (_, line) in enumerate(lines): + if line.startswith("seeds:"): + seeds = map(int, line.replace("seeds:", "").strip().split(" ")) + continue + if line.strip() == "": + continue + if "map" in line: + maps.append([]) + idx += 1 + continue + else: + maps[idx].append(list(map(int, line.split(" ")))) + + locs = [] + for current in seeds: + for m in maps: + for mapping in m: + dest_range_start, source_range_start, range_len = mapping + if current >= source_range_start and current < source_range_start + range_len: + current = dest_range_start + (current - source_range_start) + break + else: + current = current + locs.append(current) + return min(locs) + +def solve2(lines: list[str]): + seeds = [] + idx = -1 + maps = [] + + for (_, line) in enumerate(lines): + if line.startswith("seeds:"): + all_seeds = [] + seeds = list(map(int, line.replace("seeds:", "").strip().split(" "))) + for i in range(0, len(seeds), 2): + all_seeds.append(seeds[i:i+2]) + seeds = all_seeds + continue + if line.strip() == "": + continue + if "map" in line: + maps.append([]) + idx += 1 + continue + else: + maps[idx].append(list(map(int, line.split(" ")))) + + # source: |---------------------| + # seeds: + # |---| + # aaaaaabbbb + # aaaaaabbbbbbbbbbbbbbbbbbbbbbcccc + # aaaaaaaaaaaaaaaa + # aaaaaaaaaaaaaaaaaaaccccc + # |-------| + + for m in maps: + next_seeds = [] + while seeds: + seed_start, seed_range = seeds.pop() + seed_end = seed_start + seed_range + for mapping in m: + dest_start, source_start, m_range = mapping + source_end = source_start + m_range + + if seed_end <= source_start: + continue + elif seed_start < source_start and seed_end <= source_end: + a_range = source_start - seed_start + seeds.append([seed_start, a_range]) + b_range = seed_end - source_start + next_seeds.append([dest_start, b_range]) + break + elif seed_start < source_start and seed_end > source_end: + a_range = source_start - seed_start + seeds.append([seed_start, a_range]) + next_seeds.append([dest_start, m_range]) # b range + c_range = seed_end - source_end + next_seeds.append([source_end, c_range]) + break + elif seed_start >= source_start and seed_end <= source_end: + new_seed_start = dest_start + (seed_start - source_start) + next_seeds.append([new_seed_start, seed_range]) + break + elif seed_start >= source_start and seed_start < source_end: + new_seed_start = dest_start + (seed_start - source_start) + a_range = source_end - seed_start + next_seeds.append([new_seed_start, a_range]) + c_range = seed_end - source_end + seeds.append([source_end, c_range]) + break + elif seed_start >= source_end: + continue + else: + print(f"{seed_start=} {seed_range=} {seed_end=}") + print(f"{source_start=} {source_end=}") + raise Exception("Unexpected case") + else: + next_seeds.append([seed_start, seed_range]) + seeds = next_seeds + return min(seeds)[0] + +def main(): + example = clean(EXAMPLE) + print("Example 1:", solve(example)) + + data = clean(open("i5.txt").read()) + print("Solution 1:", solve(data)) + + example = clean(EXAMPLE) + print("Example 2:", solve2(example)) + + data = clean(open("i5.txt").read()) + print("Solution 2:", solve2(data)) + assert(solve2(data) == 63179500) + +if __name__ == "__main__": + main() diff --git a/d6.py b/d6.py new file mode 100644 index 0000000..619c3a8 --- /dev/null +++ b/d6.py @@ -0,0 +1,57 @@ +EXAMPLE = """ +Time: 7 15 30 +Distance: 9 40 200 +""" + +def str_to_int_lst(s): + return list(map(int, s.split())) + +def clean(text: str) -> list[str]: + return list(filter(lambda l: l.strip() != "", text.splitlines())) + +def solve(lines: list[str]): + res = 1 + t = [] + for (_, line) in enumerate(lines): + numbers = str_to_int_lst(line.replace("Time:", "").replace("Distance:", "").strip()) + t.append(numbers) + + t = list(zip(*t)) + for time, dist in t: + opt = 0 + for press_time in range(1, time): + dist_trav = press_time * (time - press_time) + if dist_trav > dist: + opt += 1 + res *= opt + return res + +def solve2(lines: list[str]): + t = [] + for (_, line) in enumerate(lines): + numbers = str_to_int_lst(line.replace("Time:", "").replace("Distance:", "").replace(" ", "").strip()) + t.append(numbers[0]) + time, dist = t + opt = 0 + for press_time in range(1, time): + dist_trav = press_time * (time - press_time) + if dist_trav > dist: + opt += 1 + return opt + +def main(): + example = clean(EXAMPLE) + print("Example 1:", solve(example)) + + data = clean(open("i6.txt").read()) + print("Solution 1:", solve(data)) + + example = clean(EXAMPLE) + print("Example 2:", solve2(example)) + + data = clean(open("i6.txt").read()) + print("Solution 2:", solve2(data)) + return + +if __name__ == "__main__": + main() diff --git a/dx.py b/dx.py new file mode 100644 index 0000000..af29049 --- /dev/null +++ b/dx.py @@ -0,0 +1,44 @@ +from string import ascii_lowercase, ascii_uppercase, digits +import re + +EXAMPLE = """ +""" + +def str_to_int_lst(s): + return list(map(int, s.split())) + +def clean(text: str) -> list[str]: + return list(filter(lambda l: l.strip() != "", text.splitlines())) + # return list(text.splitlines()) + +def solve(lines: list[str]): + res = 0 + for (i, line) in enumerate(lines): + print(i, line) + return res + +def solve2(lines: list[str]): + res = 0 + for (i, line) in enumerate(lines): + print(i, line) + return res + +def main(): + example = clean(EXAMPLE) + print("Example 1:", solve(example)) + return + + data = clean(open("i5.txt").read()) + print("Solution 1:", solve(data)) + return + + example = clean(EXAMPLE) + print("Example 2:", solve2(example)) + return + + data = clean(open("i5.txt").read()) + print("Solution 2:", solve2(data)) + return + +if __name__ == "__main__": + main()