lily's recent activity

  1. Comment on System76's COSMIC desktop environment enters public alpha in ~comp

    lily
    Link Parent
    Plasma doesn't really fit these characteristics, though...? It's quite dense (almost to a fault), and I suppose it does have rounded corners but they're not as prevalent as in like, GNOME. It's...

    Plasma doesn't really fit these characteristics, though...? It's quite dense (almost to a fault), and I suppose it does have rounded corners but they're not as prevalent as in like, GNOME. It's not perfect but it's the most comfortable modern environment I've found - I prefer it to Windows, nowadays.

    1 vote
  2. Comment on Braid: Anniversary Edition "sold like dog s***", says creator Jonathan Blow in ~games

    lily
    Link Parent
    I personally love The Witness, but yeah, that's maybe not the best way to respond to criticism of it. I don't think it needs to be talked about like a "masterpiece that people don't understand" or...

    I personally love The Witness, but yeah, that's maybe not the best way to respond to criticism of it. I don't think it needs to be talked about like a "masterpiece that people don't understand" or whatever. For me, I just really enjoyed the atmosphere and visuals of the island, and thought the puzzles were well-designed. Nothing more, nothing less. It's not a transcendent or incredibly innovative game necessarily. There were some parts I wasn't as much of a fan of, like the audio logs and a few annoying puzzles, but the nice part about the game's design was I could just skip those parts without issue.

    2 votes
  3. Comment on Tildes Game Giveaway: June/July 2024 in ~games

    lily
    Link Parent
    This is so nice of you, thank you! I'd be interested in Braid and ElecHead - I hadn't heard of the latter before, but it looks really neat and I love puzzle-platformers.

    This is so nice of you, thank you! I'd be interested in Braid and ElecHead - I hadn't heard of the latter before, but it looks really neat and I love puzzle-platformers.

    1 vote
  4. Comment on Tildes Game Giveaway: June/July 2024 in ~games

    lily
    Link Parent
    I'd like Slay the Spire if possible! I've been eyeing it for a while and have heard great things about it.

    I'd like Slay the Spire if possible! I've been eyeing it for a while and have heard great things about it.

    1 vote
  5. Comment on What programming/technical projects have you been working on? in ~comp

    lily
    Link
    Still working on my video game I posted here, like, a year ago (very slowly). I've been trying to get it working better on Wayland, specifically regarding display scaling - I'm having trouble...

    Still working on my video game I posted here, like, a year ago (very slowly). I've been trying to get it working better on Wayland, specifically regarding display scaling - I'm having trouble keeping a 1:1 pixel scale, since ignoring the DPI like that doesn't seem to be something you're supposed to do.

    4 votes
  6. Comment on Day 25: Snowverload in ~comp.advent_of_code

    lily
    Link
    I should've been faster with this one. I haven't done a great job at finishing the last few problems, but today's wasn't too bad thanks to NetworkX doing most of the work for me. I might go back...

    I should've been faster with this one. I haven't done a great job at finishing the last few problems, but today's wasn't too bad thanks to NetworkX doing most of the work for me. I might go back to this at some point and try to implement the algorithm myself, but I don't have time for that right now.

    Solution
    # Advent of Code 2023
    # Day 25: Snowverload
    
    import networkx
    
    graph = {}
    
    with open("inputs/day_25.txt") as file:
        for line in file:
            component = line[:3]
    
            if component in graph:
                graph[component].update(set(line[5:].rstrip("\n").split(" ")))
            else:
                graph[component] = set(line[5:].rstrip("\n").split(" "))
    
            for other in graph[component]:
                if other not in graph:
                    graph[other] = set([component])
                else:
                    graph[other].add(component)
    
    to_remove = tuple(networkx.minimum_edge_cut(networkx.from_dict_of_lists(graph)))
    
    for edge in to_remove:
        graph[edge[0]].remove(edge[1])
        graph[edge[1]].remove(edge[0])
    
    product = 1
    
    for edge in to_remove[0]:
        queue = [edge]
        seen = set()
    
        while queue:
            current = queue.pop(0)
    
            for next_ in graph[current]:
                if next_ not in seen:
                    queue.append(next_)
                    seen.add(next_)
    
        product *= len(seen)
    
    print(f"Part 1: {product}")
    
    2 votes
  7. Comment on Day 20: Pulse Propagation in ~comp.advent_of_code

    lily
    (edited )
    Link
    Tricky part 2 today. I honestly wasn't the hugest fan of today's problem, since the solution ended up being dependent on a quirk in the input, and so it took me longer to figure out than it...

    Tricky part 2 today. I honestly wasn't the hugest fan of today's problem, since the solution ended up being dependent on a quirk in the input, and so it took me longer to figure out than it probably should have.

    Solution
    # Advent of Code 2023
    # Day 20: Pulse Propagation
    
    from math import lcm
    
    class FlipFlop:
        def __init__(self, destinations):
            self.destinations = destinations
            self.on = False
    
        def recieve(self, name, pulse):
            if pulse == "low":
                self.on = not self.on
    
                if self.on:
                    return [(name, "high") for name in self.destinations]
                else:
                    return [(name, "low") for name in self.destinations]
            else:
                return []
    
    class Conjunction:
        def __init__(self, destinations):
            self.destinations = destinations
        
        def init_memory(self, connected_modules):
            self.memory = {name: "low" for name in connected_modules}
    
        def recieve(self, name, pulse):
            self.memory[name] = pulse
    
            if all(pulse == "high" for pulse in self.memory.values()):
                return [(name, "low") for name in self.destinations]
            else:
                return [(name, "high") for name in self.destinations]
    
    modules = {}
    conjunctions = {}
    
    with open("inputs/day_20.txt") as file:
        for line in file:
            if line.startswith("broadcaster"):
                starting_destinations = (
                    line.split(" -> ")[1].rstrip("\n").split(", ")
                )
            else:
                halves = line.split(" -> ")
                kind = (FlipFlop, Conjunction)[halves[0][0] == "&"]
                name = halves[0][1:]
                destinations = halves[1].rstrip("\n").split(", ")
    
                modules[name] = kind(destinations)
    
                if kind == Conjunction:
                    conjunctions[name] = modules[name]
    
                if "rx" in destinations:
                    final_conjunction = modules[name]
    
    for conjunction_name, conjunction in conjunctions.items():
        connected_modules = []
    
        if conjunction_name in starting_destinations:
            connected_modules.append("broadcaster")
    
        for name, module in modules.items():
            if conjunction_name in module.destinations:
                connected_modules.append(name)
    
        conjunction.init_memory(connected_modules)
    
    low_pulses = 1000
    high_pulses = 0
    
    presses = 1
    cycles = {name:None for name in final_conjunction.memory}
    
    while presses <= 1000 or any(cycle is None for cycle in cycles.values()):
        pulses = [("broadcaster", name, "low") for name in starting_destinations]
    
        while pulses:
            next_pulses = []
    
            for pulse in pulses:
                if (
                    pulse[0] in cycles and pulse[2] == "high"
                    and cycles[pulse[0]] is None
                ):
                    cycles[pulse[0]] = presses
    
                if pulse[1] in modules:
                    for next_pulse in modules[pulse[1]].recieve(
                        pulse[0], pulse[2]
                    ):
                        next_pulses.append((pulse[1],) + next_pulse)
    
                if presses <= 1000:
                    if pulse[2] == "low":
                        low_pulses += 1
                    else:
                        high_pulses += 1
    
            pulses = next_pulses
    
        presses += 1
    
    print(f"Part 1: {low_pulses * high_pulses}")
    print(f"Part 2: {lcm(*cycles.values())}")
    
    1 vote
  8. Comment on Day 19: Aplenty in ~comp.advent_of_code

    lily
    (edited )
    Link
    Today's problem was a lot of fun. I was glad for the easier problem after not having time to finish yesterday's part 2. This one reminded me a bit of day 5, what with having to use ranges for part...

    Today's problem was a lot of fun. I was glad for the easier problem after not having time to finish yesterday's part 2. This one reminded me a bit of day 5, what with having to use ranges for part 2. My solution ended up being pretty long, but I think it's reasonably efficient.

    Solution
    # Advent of Code 2023
    # Day 19: Aplenty
    
    from copy import deepcopy
    from functools import reduce
    from json import loads
    from operator import mul
    from re import sub
    
    workflows = {}
    parts = []
    
    with open("inputs/day_19.txt") as file:
        half = 0
    
        for line in file:
            if half == 0:
                if line == "\n":
                    half = 1
                else:
                    halves = line.split("{")
                    halves[1] = halves[1].rstrip("\n")[:-1]
    
                    conditions = []
    
                    for condition in halves[1].split(","):
                        if condition == "A":
                            conditions.append(True)
                        elif condition == "R":
                            conditions.append(False)
                        elif ":" not in condition:
                            conditions.append(condition)
                        else:
                            condition_halves = condition.split(":")
    
                            if condition_halves[1] == "A":
                                result = True
                            elif condition_halves[1] == "R":
                                result = False
                            else:
                                result = condition_halves[1]
    
                            conditions.append((
                                condition_halves[0][1],
                                "xmas".index(condition_halves[0][0]),
                                int(condition_halves[0][2:]),
                                result
                            ))
    
                    workflows[halves[0]] = conditions
            else:
                parts.append(list(loads(sub(
                    r"([xmas])=", r'"\g<1>": ', line.rstrip("\n")
                )).values()))
    
    rating_sum = 0
    
    for part in parts:
        workflow = workflows["in"]
        done = False
    
        while not done:
            for condition in workflow:
                if condition == True:
                    rating_sum += sum(part)
                    done = True
                    break
                elif condition == False:
                    done = True
                    break
                elif isinstance(condition, str):
                    workflow = workflows[condition]
                else:
                    if condition[0] == "<":
                        pass_ = part[condition[1]] < condition[2]
                    else:
                        pass_ = part[condition[1]] > condition[2]
    
                    if pass_:
                        if condition[3] == True:
                            rating_sum += sum(part)
                            done = True
                        elif condition[3] == False:
                            done = True
                        else:
                            workflow = workflows[condition[3]]
    
                        break
    
    print(f"Part 1: {rating_sum}")
    
    states = (["in", [1, 4000], [1, 4000], [1, 4000], [1, 4000]],)
    combinations = 0
    
    while states:
        new_states = []
    
        for state in states:
            for condition in workflows[state[0]]:
                if condition == True:
                    combinations += reduce(
                        mul, (range_[1] - range_[0] + 1 for range_ in state[1:])
                    )
    
                    break
                elif isinstance(condition, str):
                    state[0] = condition
                    new_states.append(state)
                    break
                elif condition != False:
                    state_pass = deepcopy(state)
                    range_pass = state_pass[condition[1] + 1]
    
                    range_pass[condition[0] == "<"] = (
                        condition[2] + (1, -1)[condition[0] == "<"]
                    )
    
                    state[condition[1] + 1][condition[0] == ">"] = condition[2]
    
                    if range_pass[0] <= range_pass[1]:
                        if condition[3] == True:
                            combinations += reduce(mul, (
                                range_[1] - range_[0] + 1
                                for range_ in state_pass[1:]
                            ))
                        elif condition[3] != False:
                            state_pass[0] = condition[3]
                            new_states.append(state_pass)
    
        states = new_states
    
    print(f"Part 2: {combinations}")
    
    2 votes
  9. Comment on Tildes Game Giveaway: Holiday 2023 in ~games

    lily
    Link Parent
    If Broken Age is still available that would be great. As for a holiday tradition, as a kid I always used to get two stockings: one on Christmas Day, and one on New Year's Eve. I never really...

    If Broken Age is still available that would be great. As for a holiday tradition, as a kid I always used to get two stockings: one on Christmas Day, and one on New Year's Eve. I never really thought much about it, to be honest. But other than that I don't think we ever did much interesting.

    1 vote
  10. Comment on Day 17: Clumsy Crucible in ~comp.advent_of_code

    lily
    Link
    Forgot to post this last night. It could've been a lot faster if I'd used another algorithm like A*, but I was lazy and Djikstra was fast enough that I didn't think I needed to bother implementing...

    Forgot to post this last night. It could've been a lot faster if I'd used another algorithm like A*, but I was lazy and Djikstra was fast enough that I didn't think I needed to bother implementing anything else. I was glad to finally see this year's requisite pathfinding problem, though I thought it wasn't an especially interesting example of one.

    Solution
    # Advent of Code 2023
    # Day 17: Clumsy Crucible
    
    import heapq
    
    with open("inputs/day_17.txt") as file:
        loss_map = [[int(char) for char in line.rstrip("\n")] for line in file]
        width = len(loss_map[0])
        height = len(loss_map)
    
    class Node:
        def __init__(self, x, y, direction, consecutive, heat_loss, part):
            self.x = x
            self.y = y
            self.direction = direction
            self.consecutive = consecutive
            self.heat_loss = heat_loss
            self.part = part
    
        def __lt__(self, other):
            return self.heat_loss < other.heat_loss
    
    heap = [Node(0, 0, None, 0, 0, 1), Node(0, 0, None, 0, 0, 2)]
    heapq.heapify(heap)
    seen = set()
    
    end_x = width - 1
    end_y = height - 1
    
    while heap:
        current = heapq.heappop(heap)
    
        if current.x == end_x and current.y == end_y:
            print(f"Part {current.part}: {current.heat_loss}")
    
            for node in heap.copy():
                if node.part == current.part:
                    heap.remove(node)
    
            continue
    
        for new_pos in (
            (current.x + 1, current.y, "right"),
            (current.x, current.y + 1, "down"),
            (current.x - 1, current.y, "left"),
            (current.x, current.y - 1, "up")
        ):
            if (
                0 <= new_pos[0] < width and 0 <= new_pos[1] < height
                and not (
                    current.direction == "right" and new_pos[2] == "left"
                    or current.direction == "down" and new_pos[2] == "up"
                    or current.direction == "left" and new_pos[2] == "right"
                    or current.direction == "up" and new_pos[2] == "down"
                )
                and not (
                    current.direction == new_pos[2]
                    and current.consecutive == (3, 10)[current.part - 1]
                )
            ):
                node = Node(
                    *new_pos,
                    (
                        current.consecutive + 1
                        if current.direction == new_pos[2] else 1
                    ),
                    current.heat_loss + loss_map[new_pos[1]][new_pos[0]],
                    current.part
                )
    
                if current.part == 2 and node.consecutive == 1:
                    if node.direction == "right":
                        change = (1, 0)
                    elif node.direction == "down":
                        change = (0, 1)
                    elif node.direction == "left":
                        change = (-1, 0)
                    else:
                        change = (0, -1)
    
                    for i in range(3):
                        node.x += change[0]
                        node.y += change[1]
    
                        try:
                            node.heat_loss += loss_map[node.y][node.x]
                        except IndexError:
                            pass
    
                    node.consecutive = 4
    
                values = (node.x, node.y, node.direction, node.consecutive)
    
                if values not in seen:
                    heapq.heappush(heap, node)
                    seen.add(values)
    
    1 vote
  11. Comment on Tildes Game Giveaway: Holiday 2023 in ~games

    lily
    Link Parent
    Xer Kzesfrums Istyms Hocktoo sounds lovely; those are all genres I enjoy. As for an upbeat song, I never get tired of the VVVVVV soundtrack. Thanks for your generosity!

    Xer Kzesfrums Istyms Hocktoo sounds lovely; those are all genres I enjoy. As for an upbeat song, I never get tired of the VVVVVV soundtrack. Thanks for your generosity!

    2 votes
  12. Comment on Tildes Game Giveaway: Holiday 2023 in ~games

    lily
    Link Parent
    I'd be interested in Rakuen and Cocoon. I'll do the opening quote from a game I just played recently, Slay the Princess (which I recommend highly if you haven't tried it, by the way): "Whatever...

    I'd be interested in Rakuen and Cocoon. I'll do the opening quote from a game I just played recently, Slay the Princess (which I recommend highly if you haven't tried it, by the way): "Whatever horrors you may find in these dark spaces, have heart and see them through. There are no premature endings. There are no wrong answers. There are only fresh perspectives and new beginnings. This is a love story."

    Thanks for doing this!

    1 vote
  13. Comment on Day 16: The Floor Will Be Lava in ~comp.advent_of_code

    lily
    Link
    Only just got to this problem now, but it really didn't take long. Didn't have time to make my solution any faster, but it's not slow enough to be a big deal, so I don't mind keeping it like this....

    Only just got to this problem now, but it really didn't take long. Didn't have time to make my solution any faster, but it's not slow enough to be a big deal, so I don't mind keeping it like this. I was honestly a bit disappointed the naïve solution was enough for today, but to be fair, if it wasn't, I might not have been able to finish the problem before midnight, so I guess I should be grateful. Hopefully tomorrow is a bit more interesting.

    Solution
    # Advent of Code 2023
    # Day 16: The Floor Will Be Lava
    
    with open("inputs/day_16.txt") as file:
        machine = [list(line.rstrip("\n")) for line in file]
        width = len(machine[0])
        height = len(machine)
    
    def energized_tiles(x, y, direction):
        beams = [[x, y, direction]]
        seen_beams = set()
        energized = set()
    
        while beams:
            for beam in beams.copy():
                if (
                    beam[0] < 0 or beam[0] >= width
                    or beam[1] < 0 or beam[1] >= height
                    or tuple(beam) in seen_beams
                ):
                    beams.remove(beam)
                    continue
    
                seen_beams.add(tuple(beam))
                energized.add((beam[0], beam[1]))
    
                tile = machine[beam[1]][beam[0]]
    
                if tile == "/":
                    if beam[2] == "right":
                        beam[2] = "up"
                    elif beam[2] == "down":
                        beam[2] = "left"
                    elif beam[2] == "left":
                        beam[2] = "down"
                    else:
                        beam[2] = "right"
                elif tile == "\\":
                    if beam[2] == "right":
                        beam[2] = "down"
                    elif beam[2] == "down":
                        beam[2] = "right"
                    elif beam[2] == "left":
                        beam[2] = "up"
                    else:
                        beam[2] = "left"
                elif tile == "|" and beam[2] in ("right", "left"):
                    beam[2] = "down"
                    beams.append([beam[0], beam[1] - 1, "up"])
                elif tile == "-" and beam[2] in ("down", "up"):
                    beam[2] = "right"
                    beams.append([beam[0] - 1, beam[1], "left"])
    
                if beam[2] == "right":
                    beam[0] += 1
                elif beam[2] == "down":
                    beam[1] += 1
                elif beam[2] == "left":
                    beam[0] -= 1
                else:
                    beam[1] -= 1
    
        return len(energized)
    
    print(f"Part 1: {energized_tiles(0, 0, 'right')}")
    
    starts = []
    
    for x in range(width):
        starts.append([x, 0, "down"])
        starts.append([x, height - 1, "up"])
    
    for y in range(height):
        starts.append([0, y, "right"])
        starts.append([width - 1, y, "left"])
    
    print(f"Part 2: {max(energized_tiles(*start) for start in starts)}")
    
    1 vote
  14. Comment on Day 15: Lens Library in ~comp.advent_of_code

    lily
    Link
    Surprisingly easy for day 15, though I wasn't quite as fast as I would've liked (I'm posting quite a bit later, but I finished in around 22 minutes or so). I expected the part 2 twist to be more...

    Surprisingly easy for day 15, though I wasn't quite as fast as I would've liked (I'm posting quite a bit later, but I finished in around 22 minutes or so). I expected the part 2 twist to be more difficult than it ended up being.

    Solution
    # Advent of Code 2023
    # Day 15: Lens Library
    
    def hash_(s):
        current = 0
    
        for char in s:
            current += ord(char)
            current *= 17
            current %= 256
    
        return current
    
    hash_sum = 0
    boxes = [[] for _ in range(256)]
    
    with open("inputs/day_15.txt") as file:
        for step in file.read().rstrip("\n").split(","):
            hash_sum += hash_(step)
    
            label = "".join(char for char in step if char.isalpha())
            label_len = len(label)
    
            box = boxes[hash_(label)]
    
            if step[label_len] == "=":
                existing = False
    
                for lens in box:
                    if lens[0] == label:
                        lens[1] = int(step[label_len + 1])
                        existing = True
                        break
    
                if not existing:
                    box.append([label, int(step[label_len + 1])])
            else:
                for lens in box:
                    if lens[0] == label:
                        box.remove(lens)
                        break
    
    print(f"Part 1: {hash_sum}")
    
    focusing_power = 0
    
    for i, box in enumerate(boxes):
        for j, lens in enumerate(box):
            old = focusing_power
            focusing_power += (i + 1) * (j + 1) * lens[1]
    
    print(f"Part 2: {focusing_power}")
    
    1 vote
  15. Comment on Day 14: Reflector Dish in ~comp.advent_of_code

    lily
    Link
    Forgot to post this last night. I wasn't quite able to get top 1000 on part 2, but thought I did pretty well otherwise. Part 2 was pretty simple once I realized I needed to detect cycles. Solution...

    Forgot to post this last night. I wasn't quite able to get top 1000 on part 2, but thought I did pretty well otherwise. Part 2 was pretty simple once I realized I needed to detect cycles.

    Solution
    # Advent of Code 2023
    # Day 14: Parabolic Reflector Dish
    
    with open("inputs/day_14.txt") as file:
        platform = [list(line.rstrip("\n")) for line in file.readlines()]
        size = len(platform)
    
    def total_load(platform):
        total_load = 0
    
        for y, row in enumerate(platform):
            for char in row:
                if char == "O":
                    total_load += size - y
    
        return total_load
    
    seen = {}
    part_1_finished = False
    iteration = 0
    
    while iteration < 1000000000:
        for _ in range(4):
            for x in range(size):
                for y in range(1, size):
                    if platform[y][x] == "O" and platform[y - 1][x] == ".":
                        for new_y in range(y - 1, -1, -1):
                            if platform[new_y][x] != ".":
                                new_y += 1
                                break
    
                        platform[y][x] = "."
                        platform[new_y][x] = "O"
    
            if not part_1_finished:
                print(f"Part 1: {total_load(platform)}")
                part_1_finished = True
    
            platform = [list(reversed(row)) for row in zip(*platform)]
    
        key = "".join("".join(row) for row in platform)
    
        if key in seen:
            cycle_length = iteration - seen[key]
            iteration += (1000000000 - iteration) // cycle_length * cycle_length
        else:
            seen[key] = iteration
    
        iteration += 1
    
    print(f"Part 2: {total_load(platform)}")
    
    1 vote
  16. Comment on Day 12: Hot Spring in ~comp.advent_of_code

    lily
    Link
    Wondering if anyone could point me in the right direction for this day's part 2? I tried for hours to get it working but hadn't ever done dynamic programming before and so wasn't able to figure...

    Wondering if anyone could point me in the right direction for this day's part 2? I tried for hours to get it working but hadn't ever done dynamic programming before and so wasn't able to figure out what to memoize to make my program fast enough.

    2 votes
  17. Comment on Day 13: Point of Incidence in ~comp.advent_of_code

    lily
    Link
    Was glad for the break after how hard yesterday was (I wasn't able to solve part 2 yesterday, unfortunately, which is why I didn't post my solution). I could probably optimize this quite a bit...

    Was glad for the break after how hard yesterday was (I wasn't able to solve part 2 yesterday, unfortunately, which is why I didn't post my solution). I could probably optimize this quite a bit further, but I don't really see the need to; it's plenty fast enough as it is. Hopefully the difficulty is a bit more consistent from here on out.

    Solution
    # Advent of Code 2023
    # Day 13: Point of Incidence
    
    def find_vertical_reflection(pattern, compare):
        for x in range(1, len(pattern[0])):
            left_side = [row[:x] for row in pattern]
            right_side = [list(reversed(row[x:])) for row in pattern]
    
            left_width = len(left_side[0])
            right_width = len(right_side[0])
    
            if left_width > right_width:
                difference = left_width - right_width
                left_side_adjusted = [row[difference:] for row in left_side]
                right_side_adjusted = right_side
            elif right_width > left_width:
                difference = right_width - left_width
                left_side_adjusted = left_side
                right_side_adjusted = [row[difference:] for row in right_side]
            else:
                left_side_adjusted = left_side
                right_side_adjusted = right_side
    
            if compare(left_side_adjusted, right_side_adjusted):
                return left_width
    
        return 0
    
    def smudged_compare(left_side, right_side):
        left_side = [char for row in left_side for char in row]
        right_side = [char for row in right_side for char in row]
    
        return sum(
            left_side[i] != right_side[i] for i in range(len(left_side))
        ) == 1
    
    notes_sum = 0
    notes_sum_smudged = 0
    
    with open("inputs/day_13.txt") as file:
        for pattern in file.read().split("\n\n"):
            pattern = [list(row.rstrip("\n")) for row in pattern.splitlines()]
    
            notes_sum += find_vertical_reflection(pattern, list.__eq__)
            notes_sum += find_vertical_reflection(
                [list(row) for row in list(zip(*pattern))[::-1]], list.__eq__
            ) * 100
    
            notes_sum_smudged += find_vertical_reflection(pattern, smudged_compare)
            notes_sum_smudged += find_vertical_reflection(
                [list(row) for row in list(zip(*pattern))[::-1]], smudged_compare
            ) * 100
    
    print(f"Part 1: {notes_sum}")
    print(f"Part 2: {notes_sum_smudged}")
    
    2 votes
  18. Comment on Day 11: Cosmic Expansion in ~comp.advent_of_code

    lily
    Link
    Had an irritating error that prevented me from getting a leaderboard spot on part 2, but other than that, today was a nice break after yesterday. I did part 1 pretty naïvely, so had to rewrite my...

    Had an irritating error that prevented me from getting a leaderboard spot on part 2, but other than that, today was a nice break after yesterday. I did part 1 pretty naïvely, so had to rewrite my solution for part 2.

    Solution
    # Advent of Code 2023
    # Day 11: Cosmic Expansion
    
    from itertools import combinations
    
    with open("inputs/day_11.txt") as file:
        image = [list(line[:-1]) for line in file.readlines()]
    
    galaxies = []
    
    for y, row in enumerate(image):
        for x, tile in enumerate(row):
            if tile == "#":
                galaxies.append([x, y])
    
    moved_galaxies_part_1 = [galaxy.copy() for galaxy in galaxies]
    moved_galaxies_part_2 = [galaxy.copy() for galaxy in galaxies]
    
    for y, row in enumerate(image):
        if "#" not in row:
            for i, galaxy in enumerate(galaxies):
                if galaxy[1] > y:
                    moved_galaxies_part_1[i][1] += 1
                    moved_galaxies_part_2[i][1] += 999999
    
    for x in range(len(image[0])):
        if not any(image[y][x] == "#" for y in range(len(image))):
            for i, galaxy in enumerate(galaxies):
                if galaxy[0] > x:
                    moved_galaxies_part_1[i][0] += 1
                    moved_galaxies_part_2[i][0] += 999999
    
    distance_sum_part_1 = 0
    
    for pair in combinations(moved_galaxies_part_1, 2):
        distance_sum_part_1 += (
            abs(pair[1][0] - pair[0][0]) + abs(pair[1][1] - pair[0][1])
        )
    
    print(f"Part 1: {distance_sum_part_1}")
    
    distance_sum_part_2 = 0
    
    for pair in combinations(moved_galaxies_part_2, 2):
        distance_sum_part_2 += (
            abs(pair[1][0] - pair[0][0]) + abs(pair[1][1] - pair[0][1])
        )
    
    print(f"Part 2: {distance_sum_part_2}")
    
    2 votes
  19. Comment on Day 10: Pipe Maze in ~comp.advent_of_code

    lily
    Link
    I was a complete idiot solving this one. I spent multiple hours trying to solve part 2 without increasing the resolution of the grid and without raycasting like @Hvv (I was basically special...

    I was a complete idiot solving this one. I spent multiple hours trying to solve part 2 without increasing the resolution of the grid and without raycasting like @Hvv (I was basically special casing the individual combinations of characters that could be "squeezed" through; it was horrible), and ended up writing an insanely long and complicated program that didn't actually work. I eventually figured out that I could increase the resolution, and once I did I solved part 2 in about 10 minutes. If I'd figured that out earlier I might've been able to snag a leaderboard spot. But oh well. At least I got top 300 for part 1. I'm not very happy with my solution (it's slow and inelegant), but it works and I don't think I have the energy to improve it any further, haha.

    Solution
    # Advent of Code 2023
    # Day 10: Pipe Maze
    
    with open("inputs/day_10.txt") as file:
        sketch = [list(line[:-1]) for line in file.readlines()]
    
    for y, row in enumerate(sketch):
        for x, tile in enumerate(row):
            if tile == "S":
                start_x = x
                start_y = y
    
    width = len(sketch[0])
    height = len(sketch)
    
    current_x = start_x
    current_y = start_y
    
    if current_x < len(sketch[0]) and sketch[current_y][current_x + 1] in "-J7":
        current_x += 1
        current_dir = "right"
    elif current_y < height and sketch[current_y + 1][current_x] in "|LJ":
        current_y += 1
        current_dir = "down"
    elif current_x > 0 and sketch[current_y][current_x - 1] in "-LF":
        current_x -= 1
        current_dir = "left"
    else:
        current_y -= 1
        current_dir = "up"
    
    start_dir = current_dir
    loop = [(current_x, current_y)]
    
    while current_x != start_x or current_y != start_y:
        tile = sketch[current_y][current_x]
    
        if tile == "|":
            if current_dir == "down":
                current_y += 1
            elif current_dir == "up":
                current_y -= 1
        elif tile == "-":
            if current_dir == "right":
                current_x += 1
            elif current_dir == "left":
                current_x -= 1
        elif tile == "L":
            if current_dir == "down":
                current_x += 1
                current_dir = "right"
            elif current_dir == "left":
                current_y -= 1
                current_dir = "up"
        elif tile == "J":
            if current_dir == "right":
                current_y -= 1
                current_dir = "up"
            elif current_dir == "down":
                current_x -= 1
                current_dir = "left"
        elif tile == "7":
            if current_dir == "right":
                current_y += 1
                current_dir = "down"
            elif current_dir == "up":
                current_x -= 1
                current_dir = "left"
        elif tile == "F":
            if current_dir == "left":
                current_y += 1
                current_dir = "down"
            elif current_dir == "up":
                current_x += 1
                current_dir = "right"
    
        loop.append((current_x, current_y))
    
    print(f"Part 1: {len(loop) // 2}")
    
    if current_dir == "right":
        if start_dir == "right":
            sketch[start_y][start_x] = "-"
        elif start_dir == "down":
            sketch[start_y][start_x] = "7"
        elif start_dir == "up":
            sketch[start_y][start_x] = "J"
    elif current_dir == "down":
        if start_dir == "right":
            sketch[start_y][start_x] = "L"
        elif start_dir == "down":
            sketch[start_y][start_x] = "|"
        elif start_dir == "left":
            sketch[start_y][start_x] = "J"
    elif current_dir == "left":
        if start_dir == "down":
            sketch[start_y][start_x] = "F"
        elif start_dir == "left":
            sketch[start_y][start_x] = "-"
        elif start_dir == "up":
            sketch[start_y][start_x] = "L"
    elif start_dir == "right":
        sketch[start_y][start_x] = "F"
    elif start_dir == "left":
        sketch[start_y][start_x] = "7"
    else:
        sketch[start_y][start_x] = "|"
    
    detailed = [[False for _ in range(width * 3)] for _ in range(height * 3)]
    
    for y, row in enumerate(sketch):
        for x, tile in enumerate(row):
            if (x, y) in loop:
                if tile == "|":
                    detailed[y * 3][x * 3:x * 3 + 3] = False, True, False
                    detailed[y * 3 + 1][x * 3:x * 3 + 3] = False, True, False
                    detailed[y * 3 + 2][x * 3:x * 3 + 3] = False, True, False
                elif tile == "-":
                    detailed[y * 3][x * 3:x * 3 + 3] = False, False, False
                    detailed[y * 3 + 1][x * 3:x * 3 + 3] = True, True, True
                    detailed[y * 3 + 2][x * 3:x * 3 + 3] = False, False, False
                elif tile == "L":
                    detailed[y * 3][x * 3:x * 3 + 3] = False, True, False
                    detailed[y * 3 + 1][x * 3:x * 3 + 3] = False, True, True
                    detailed[y * 3 + 2][x * 3:x * 3 + 3] = False, False, False
                elif tile == "J":
                    detailed[y * 3][x * 3:x * 3 + 3] = False, True, False
                    detailed[y * 3 + 1][x * 3:x * 3 + 3] = True, True, False
                    detailed[y * 3 + 2][x * 3:x * 3 + 3] = False, False, False
                elif tile == "7":
                    detailed[y * 3][x * 3:x * 3 + 3] = False, False, False
                    detailed[y * 3 + 1][x * 3:x * 3 + 3] = True, True, False
                    detailed[y * 3 + 2][x * 3:x * 3 + 3] = False, True, False
                elif tile == "F":
                    detailed[y * 3][x * 3:x * 3 + 3] = False, False, False
                    detailed[y * 3 + 1][x * 3:x * 3 + 3] = False, True, True
                    detailed[y * 3 + 2][x * 3:x * 3 + 3] = False, True, False
    
    queue = []
    
    for y, row in enumerate(detailed):
        if y in (0, height * 3 - 1):
            search = range(width * 3)
        else:
            search = (0, width * 3 - 1)
    
        for x in search:
            if not row[x]:
                queue.append((x, y))
    
    visited = set()
    
    while queue:
        pos = queue.pop(0)
    
        for new_pos in (
            (pos[0] + 1, pos[1]),
            (pos[0], pos[1] + 1),
            (pos[0] - 1, pos[1]),
            (pos[0], pos[1] - 1)
        ):
            try:
                if not detailed[new_pos[1]][new_pos[0]] and new_pos not in visited:
                    queue.append(new_pos)
                    visited.add(new_pos)
            except IndexError:
                pass
    
    inside = 0
    
    for y in range(height):
        for x in range(width):
            if (
                (x * 3 + 1, y * 3 + 1) not in visited
                and not detailed[y * 3 + 1][x * 3 + 1]
            ):
                inside += 1
    
    print(f"Part 2: {inside}")
    
    1 vote
  20. Comment on Day 9: Mirage Maintenance in ~comp.advent_of_code

    lily
    Link Parent
    Now that I think about it, part of what made this problem feel so easy was that the entire solution was basically described in the problem text itself. I feel like that wasn't really necessary...

    Now that I think about it, part of what made this problem feel so easy was that the entire solution was basically described in the problem text itself. I feel like that wasn't really necessary...

    2 votes