PapaNachos's recent activity

  1. Comment on Police in this tiny Alabama town suck drivers into legal ‘black hole’ in ~life

    PapaNachos
    Link Parent
    The entire US legal system is comically bad, but in such convoluted and self-sustaining ways that it essentially can't be fixed. I hate it so much.

    The entire US legal system is comically bad, but in such convoluted and self-sustaining ways that it essentially can't be fixed. I hate it so much.

    8 votes
  2. Comment on How do you feel about social media archiving tools such as Pushshift? in ~talk

    PapaNachos
    (edited )
    Link
    I know the guy that runs Pushshift. He's an interesting fellow and we've had some discussions about how his tool can be both used and misused. There are definitely both pros and cons to it, such...

    I know the guy that runs Pushshift. He's an interesting fellow and we've had some discussions about how his tool can be both used and misused. There are definitely both pros and cons to it, such as enabling research projects as well as harassment campaigns. It's been a minute since I've talked to him about it though.

    The strange thing is that in the grand scheme of surveillance capitalism, Pushshift is a very small operation compared to what tech companies and governments do. But because it's much more open to the public it creates a unique threat. I don't trust facebook with my data, but in practical terms I don't have a choice and was never given one. If you know enough about the internet, you can hide large parts of your online presence, but that gets harder every year, takes extreme discipline and takes a great deal of specialized knowledge that can only really be acquired by going on the internet in the first place. But even then facebook is less likely to be actively malicious than some reactionary asshole looking for someone to dogpile on.

    It's complicated and the internet as it exists today is basically a nightmare if you value privacy. But that's the result of billions of tiny decisions "we've" made over the last ~40 years. I certainly hope more efforts are made to roll back pervasive surveillance. But at least in my opinion Pushshift isn't a primary offender, it only archives a portion of what's publicly posted on specific sites, rather than the deeply creepy shit that other organizations do.

    Edit: I'll put it this way. If I decided I wanted to evade Pushshift's tracking it would be relatively simple. If I wanted to evade Facebook's tracking, time travelling and stopping my younger self from making an account wouldn't be sufficient to stop them from tracking me and building a profile on me.

    6 votes
  3. Comment on Is there a way to globally switch out a word in ~comp

    PapaNachos
    Link
    If you know Javascript you could fork cloud-to-butt and change the words it uses

    If you know Javascript you could fork cloud-to-butt and change the words it uses

    3 votes
  4. Comment on Elon Musk’s ‘Vegas Loop’ called a ‘death trap’ as traffic piles up in ~tech

    PapaNachos
    (edited )
    Link Parent
    I'm a engineer that works on hybrid and electric vehicle safety for a major OEM and while the information in that article is correct it's somewhat lacking: EV fires are much more dangerous than...

    I'm a engineer that works on hybrid and electric vehicle safety for a major OEM and while the information in that article is correct it's somewhat lacking:

    • EV fires are much more dangerous than gas fires, it's not just a matter of duration and difficulty to extinguish, but the fumes they give off are incredibly dangerous. This is particularly relevant in an enclosed space like a tunnel
    • It very briefly mentions the average age of ICE vehicles vs EV/HEV but actual data presented (Car Fires by Vehicle Type) doesn't appear to correct for vehicle age. Which is a very important factor. I don't have the actual numbers myself but fire risk increases with vehicle age and ICE vehicles are much older on average
    • It mentions that batteries need to be watched for a "long time" to make sure they're cool. I read that as implying they only need to be watched for a day, but it's much, much longer than that. We're talking months-range if something serious happened to the pack
    • The article directly quotes Tesla, but in my professional experience Tesla "massages" any data they release, so I recommend not taking that "11 times" number at face value. And yeah, a lot of corporations can't be trusted, I get that, but Tesla in particular plays fast and loose with truth.

    All that is to say it's less clear than the article claims. I'm still very pro-EV, but they carry unique risks that shouldn't be downplayed. But cars are also an inherently dangerous technology and so some risk is assumed regardless of powertrain type. Part of the reason my lab exists is to try to reduce those risks as much as possible, but it's a very complicated process and cars have a lot of external variables that make our jobs particularly difficult. Some of the comments I've made are based on my own experiences and knowledge and some is second hand from talking with other experts in the field, but I can't really get more specific than that. Even being inside the field it's still hard for me to get the full picture.

    And I would absolutely not set foot in that fucking tunnel, it's a disaster waiting to happen.

    27 votes
  5. Comment on Biden accuses Trump and his allies of holding ‘a dagger at the throat of America.’ in ~news

    PapaNachos
    (edited )
    Link Parent
    It's not disagreeing with the revolutionary war that I think implies that the US should still be a colony, so much as believing that violence against the government is never justified. I don't see...

    It's not disagreeing with the revolutionary war that I think implies that the US should still be a colony, so much as believing that violence against the government is never justified. I don't see how someone can say violence is never justified while simultaneously thinking a violent revolution was a good thing. It seems hypocritical to me.

    And to be clear I'm coming from the perspective of someone who thinks that violence is sometimes justified as a means of creating political change. It comes with a high price, because it can cause a lot of collateral damage and potentially make things a whole lot worse. But historically it's one of the prime ways that governments rise and fall. It's efficacy can't really be disputed.

    I think a lot of people have a knee-jerk reaction to denounce violence in all forms. And that's probably a good thing. But my point was that I don't think those beliefs actually hold up to even casual scrutiny. And I don't think the question being asked really engages with that nuance.

    As far as my personal views on whether the revolutionary war was justified, you're right that it was complicated. On one hand the promise of equality and freedom that the founding fathers laid out was a lie from the beginning. But on the other hand both monarchy and imperialism can go die in a fire. Like you said, people have the right to self determination.

    Edit: The question doesn't distinguish between "There is a point where eventually violence is necessary to ensure the government represents the will of the people" and "IMMA GET MAH GUNN AN SHOOT SUM LIBS". Which uh... seems like an important distinction.

    2 votes
  6. Comment on Biden accuses Trump and his allies of holding ‘a dagger at the throat of America.’ in ~news

    PapaNachos
    Link Parent
    That's basically my point about why it's a bad question, it doesn't hold up to scrutiny and is really just there to sound scary. I don't have data on it, but I would bet literally any amount of...

    That's basically my point about why it's a bad question, it doesn't hold up to scrutiny and is really just there to sound scary.

    I don't have data on it, but I would bet literally any amount of money that 2/3 of the country doesn't think the revolutionary war was some kind of moral failing.

    Which indicates the answer we're getting from the question is not in line with what people actually believe. So it shouldn't be taken at face value.

    Or I have horribly underestimated the number of US citizens that think we would be better off as British colonists. Technically that's possible.

    15 votes
  7. Comment on Biden accuses Trump and his allies of holding ‘a dagger at the throat of America.’ in ~news

    PapaNachos
    Link Parent
    The United States was founded by violence against the government. Anyone who doesn't think it can be justified at times is essentially implying that the US should still be a colony. So yeah, bad...

    The United States was founded by violence against the government. Anyone who doesn't think it can be justified at times is essentially implying that the US should still be a colony.

    So yeah, bad question

    19 votes
  8. Comment on "Free will" is an illusion: Your life runs on a pre-destined trajectory in ~life

    PapaNachos
    (edited )
    Link
    Computers are deterministic therefore people are deterministic isn't really as clear cut as the author is claiming. We've put in a great deal of effort trying to make computers as deterministic as...

    Computers are deterministic therefore people are deterministic isn't really as clear cut as the author is claiming. We've put in a great deal of effort trying to make computers as deterministic as possible. "We" understand how they work and you can incorporate non-deterministic processes into computers via quantum noise. It's useful for certain methods where pseudo-random number generators aren't good enough. Based on "our" understanding of the universe, that's truly random, as far as I'm aware anyway.

    As far as how we work and where our consciousness comes from? Unless I'm missing something, we have no real, measurable answer, to that question. So it doesn't really make sense to say "what if this thing we do understand was conscious, it can be understood, therefore we can draw conclusions about consciousness too". It's a massive leap that doesn't hold up. The author is essentially claiming the entire universe is deterministic, therefore we, as part of it, must be.

    But we aren't actually certain that the universe is deterministic. It certainly appears to behave that way at a macro scale, but at a micro scale, not so much.

    Edit: All of that is to say: It's not just that we don't know. We don't even know if it's possible to ever know the answer to that question.

    1 vote
  9. Comment on What games have you been playing, and what's your opinion on them? in ~games

    PapaNachos
    Link
    I booted Amazing Cultivation Simulator up again and definitely fell down a rabbit hole. If you haven't heard of it, it got a similar foundation to RimWorld, but once you get past the "build base...

    I booted Amazing Cultivation Simulator up again and definitely fell down a rabbit hole. If you haven't heard of it, it got a similar foundation to RimWorld, but once you get past the "build base with dudes, manage their jobs, slowly tech up and face random events" the similarities stop. I've heard it described as Taoist DBZ RimWorld and yeah, that checks out.

    Anyway ACS is heavily influenced by Wuxia and your goal is to develop your disciples into immortal gods through the process of cultivation, which in this game involves lots of meditating, chugging magic pills, performing miracles and reincarnating. And using and abusing Feng Shui and the five elements. And flying around doing battle with enchanted handkerchiefs. I don't know if you can tell by now, but there are a lot of interacting systems and the learning curve is a bit like running into a wall. You'll probably have to restart a few times after finding out you horribly fucked your run somehow. But each time you learn a bit more and get a bit further. And there's a pretty useful wiki and some good guides out there. Of course there are also bad guides that will give you the sort of advice that sounds good at first, but ends up accidentally cooking or freezing your strongest cultivator.

    Anyway, I'm mostly ignoring the story because the conversation mechanics are some of the worst I've ever seen in a game, but other than that I'm having a great time. This game is absolutely absurd and I love it

    6 votes
  10. Comment on Christmas thread in ~talk

    PapaNachos
    Link Parent
    Apparently my SO's mom has a box full of rapid tests, so she'll be bringing some back with her. So maybe we'll have the chance to celebrate afterward.

    Apparently my SO's mom has a box full of rapid tests, so she'll be bringing some back with her. So maybe we'll have the chance to celebrate afterward.

    6 votes
  11. Comment on Christmas thread in ~talk

    PapaNachos
    Link
    Normally my SO and I go and see our respective families for Christmas, so she's visiting them, but my extended family has some anti-vaxxers so I'm staying home. We're friends with the couple that...

    Normally my SO and I go and see our respective families for Christmas, so she's visiting them, but my extended family has some anti-vaxxers so I'm staying home. We're friends with the couple that lives downstairs and they invited me to dinner, but I travelled recently and there aren't any test kits to be found anywhere near my city, so I'll have to eat away from them. So I'm kinda bummed right now TBH. Probably just gonna watch movies and play video games, maybe get some reading in. It doesn't feel great, but it could definitely be worse.

    9 votes
  12. Comment on The Matrix Resurrections: A review in ~movies

    PapaNachos
    Link Parent
    That's encouraging to hear. Younger me didn't really know how to analyze media or hold strong opinions in the face of The Discourse, so I suspect I just accepted that they were bad because people...

    That's encouraging to hear. Younger me didn't really know how to analyze media or hold strong opinions in the face of The Discourse, so I suspect I just accepted that they were bad because people on the internet said they were bad.

    3 votes
  13. Comment on The Matrix Resurrections: A review in ~movies

    PapaNachos
    Link Parent
    Definitely agree. I went in expecting it to be a mediocre to bad action movie because I'm deeply jaded about sequels. But ended up absolutely loving it. It was so good it made me want to rewatch...

    Definitely agree. I went in expecting it to be a mediocre to bad action movie because I'm deeply jaded about sequels. But ended up absolutely loving it.

    It was so good it made me want to rewatch the original trilogy to see if the sequels were actually better than I remembered, but in a way that younger-me wasn't able to parse. Probably going to do that this weekend.

    4 votes
  14. Comment on Day 19: Beacon Scanner in ~comp.advent_of_code

    PapaNachos
    Link
    This might be where I bow out for this year. I don't know if I'm just burned our or if it's this problem in particular, but every time I read the problem description I just wanted to do basically...

    This might be where I bow out for this year. I don't know if I'm just burned our or if it's this problem in particular, but every time I read the problem description I just wanted to do basically anything else. I probably could solve it with a few hours work, but I don't think I would enjoy it.

    It's been fun so far (for the most part) and I wish the rest of you luck going forward!

    5 votes
  15. Comment on Day 18: Snailfish in ~comp.advent_of_code

    PapaNachos
    (edited )
    Link Parent
    My split code worked fine almost immediately, my explode code is a pile of hot garbage that is really fucking with me and this problem is really hard to debug Edit: So I did some string reversal...

    My split code worked fine almost immediately, my explode code is a pile of hot garbage that is really fucking with me and this problem is really hard to debug

    Edit: So I did some string reversal to find the 'first' number when you go to the left during an explosion, but I didn't account for reversing the digits of a 2-character number. So 17 + 8 became 79. Fuck.

    Edit 2:You were right, part 2 was basically trivial

    2 votes
  16. Comment on Day 18: Snailfish in ~comp.advent_of_code

    PapaNachos
    (edited )
    Link Parent
    I'm making slow but steady progress. My explode segment is substantially longer than any of my other sections, but I'm pretty sure it works as long as there is only one pair that needs to explode...

    I'm making slow but steady progress. My explode segment is substantially longer than any of my other sections, but I'm pretty sure it works as long as there is only one pair that needs to explode at a time. I used a combination of regex and "normal" string manipulation to get where I needed, but in the process I lose track of the order of the top-level pairs, so I'm relying on there only being one that needs to go boom

    I think I'll be able to finish part A soon, but I have no idea what surprises are waiting in part B

    Edit: OH HEY LOOK THAT ASSUMPTION I MENTION ISN'T VALID asdgasdgaghrjkaehtgjklhsaegrklhawrg FFFFFFFUUUUUUCCCCCCCKKKKK

    4 votes
  17. Comment on Day 18: Snailfish in ~comp.advent_of_code

    PapaNachos
    (edited )
    Link
    Uhhhhhhhh... What the actual fuck is this problem? Now that I've finished it: This is conceptually an interesting puzzle, but personally the complexity of it made debugging absolute hell for me. I...

    Uhhhhhhhh... What the actual fuck is this problem?


    Now that I've finished it:
    This is conceptually an interesting puzzle, but personally the complexity of it made debugging absolute hell for me. I had a few small errors that took literal hours to track down and find because I basically had to do the calculations by hand until I found something that wasn't right. So definitely a mixed bag in my case.

    Day 18 Part A - Python

    Lots of regex and string parsing. I broke each operation into its own function, with explode being the bulk of it. I used regex to detect the top level pairs, then did a depth calculation for each pair in order. If it was greater that 4 it went boom. The biggest trick here was keeping them in order. I was hoping it wouldn't be necessary within the explode operation, but it definitely was. The OTHER major mistake I made was how I added numbers to the left of an explosion. I decided the easiest way to find the first number in that direction was to reverse the string and do a number search with regex. That worked fine, but I didn't account for 2 digit numbers having their values flipped. That took a reallllllly long time to track down and basically required me stepping through the calculations one by one.

    import re
    from collections import defaultdict
    
    #data = test_data
    data = real_data
    
    #debug_mode = True
    debug_mode = False
    
    data = data.split('\n')
    
    explode_pattern = re.compile(r'(\[\d+,\d+\])')
    digits = re.compile(r'(\d+)')
    split_pattern = re.compile(r'(\d{2})')
    magnitude_pattern = re.compile(r'\[(\d+),(\d+)\]')
    
    #Add
    def addition(left, right):
        return "[" + left +","+right+"]"
    #Explode
    def explode(explode_string):
        results = explode_pattern.findall(explode_string)
        duplicate_workaround = defaultdict(int)
    
        for top_level in results:
            string_split = explode_string.split(top_level)
            first_num = int(top_level.split(',')[0][1:])
            second_num = int(top_level.split(',')[1][:-1])
            #print(top_level, first_num, second_num)
            duplicate_workaround[top_level] = duplicate_workaround[top_level] + 1
            i = duplicate_workaround[top_level]
            left = top_level.join(map(str,string_split[:i]))
            right = top_level.join(map(str,string_split[i:]))
            depth = left.count('[') - left.count(']')
            #if debug_mode:
            #    print(left, ' <-- ',top_level,' --> ', right, ' Depth = ', depth)
            if depth >= 4:
                #We're exploding, I really hope only 1 needs to be exploded at a time
                #Under certain circumstances this can explode multiple times in a row...
                #...I don't think that's a problem. I really hope it's not
                left_rev = left[::-1]
                left_nums = digits.findall(left_rev)
                if len(left_nums) > 0:
                    summed = str(int(left_nums[0][::-1]) + first_num)[::-1]
                    left_rev = re.sub(digits, summed, left_rev, 1)
                    left = left_rev[::-1]
                    #print(left)
                right_nums = digits.findall(right)
                if len(right_nums) > 0:
                    summed = str(int(right_nums[0]) + second_num)
                    right = re.sub(digits, summed, right, 1)
                    #print(right)
                return left+'0'+right
        return explode_string
    
    #Split
    def split_num(split_string):
        double_digits = split_pattern.findall(split_string)
        if len(double_digits) == 0:
            return split_string
        round_down = str(int(double_digits[0])//2)
        round_up = str(int(double_digits[0])//2 + int(double_digits[0]) % 2)
        replacement_string = '['+round_down+','+round_up+']'
        new_string = re.sub(split_pattern, replacement_string, split_string, 1)
        #print(new_string)
        return new_string
    
    
    #Reduce
    def reduce(reduce_string):
        working_string = str(reduce_string)
        keep_reducing = True
        while keep_reducing:
            keep_reducing = False
            #print(working_string)
            exploded = explode(working_string)
            spliting = split_num(working_string)
            #print(spliting)
            if exploded != working_string:
                if debug_mode:
                    print("Exploding")
                    print("Old: ", working_string)
                    print("New: ", exploded)
                keep_reducing = True
                working_string = str(exploded)
            elif spliting != working_string:
                if debug_mode:
                    print("Splitting")
                    print("Old: ", working_string)
                    print("New: ", spliting)
                keep_reducing = True
                working_string = str(spliting)
            else:
                #print("Done")
                keep_reducing = False
        return working_string
                
    
    
    #Magnitude
    def magnitude(magnitude_string):
        working_string = str(magnitude_string)
        keep_going = True
        while keep_going:
            #print(working_string)
            pair = magnitude_pattern.search(working_string)
            if pair:
                #print(pair[0], pair[1], pair[2])
                replacement_number = str((int(pair[1])*3)+(int(pair[2])*2))
                #print(replacement_number)
                working_string = working_string.replace(pair[0], replacement_number)
            else:
                keep_going = False
        return working_string
    
    #Main Loops
    running_sum = data[0]
    for row in data[1:]:
        running_sum = addition(running_sum, row)
        #print(running_sum)
        running_sum = reduce(running_sum)
        #print(running_sum)
        #print("-------")
    
    
    #running_sum = addition(data[0], data[1])
    #print(running_sum)
    #running_sum = reduce(running_sum)
    print(running_sum)
    print(magnitude(running_sum))
    
    Day 18 Part B - Python

    After the hell that was part A, part B was basically trivial. I replaced the end of my program with this and made my magnitude function so that it output an int instead of a string

    #Main Loops
    max_magnitude = 0
    for row in data:
        for col in data:
            mag1 = magnitude(reduce(addition(row, col)))
            mag2 = magnitude(reduce(addition(col, row)))
            max_magnitude = max(max_magnitude, mag1, mag2)
    print(max_magnitude)
    
    Tips
    • There's a lot going on in this one. Definitely break the problem down into manageable chunks so you can tackle it one piece at a time

    • Read through the problem descriptions a few times to make sure you understand them

    • Order does matter, this is one where you can't really simplify it. A + B is not equal to B + A in snailfish math. Same with reducing the numbers, The order you perform the operations in is important, even if it's just running the same operation twice. If there are multiple candidates, order can make a huge difference

    • Watch carefully when your're writing your explode operation, carefully consider how you want to find the first number to the left of a pair. I didn't consider 2-digit numbers and got burned when I tried to do some fancy string reversal

    • If you're having trouble finding an error, add some debugging code and try walking through the operations one by one to find your mistake. Hopefully whatever's wrong will jump out at you when you get to it

    • The details really matter in this one, not only will a small change cascade out of control, it'll also be hard to track down where things went wrong. The way that the numbers move around and transform makes it so they obfuscate the source of any errors. At least that was my experience.

    3 votes
  18. Comment on Day 17: Trick Shot in ~comp.advent_of_code

    PapaNachos
    Link
    I'm sure there's an elegant, mathy solution to this problem. I couldn't find it, so I went with some jank. Day 17 Part A - Python After giving up on finding an elegant solution, I looked for all...

    I'm sure there's an elegant, mathy solution to this problem. I couldn't find it, so I went with some jank.

    Day 17 Part A - Python

    After giving up on finding an elegant solution, I looked for all valid y trajectories between 0 and 1000. I only needed to care about positive ones, because we're aiming up. For each one I checked it's max height and if it ever landed in the target zone. I recorded the max height and however many turns it was inside the target zone. Once I had the turn number I was looking for, I searched for an x-velocity that would land in the target within that many turns. Fingers crossed that the best result would have an accompanying x velocity that worked, but I felt good about it because eventually x movement will stabilize and all future turns will be valid.

    import re
    from collections import defaultdict
    
    #data = test_data
    data = real_data
    
    pattern = re.compile(r'target area: x=(-?\d+)..(-?\d+), y=(-?\d+)..(-?\d+)')
    
    bounds = pattern.search(data)
    
    x_min = int(bounds[1])
    x_max = int(bounds[2])
    y_min = int(bounds[3])
    y_max = int(bounds[4])
    
    
    best_y_max_height = 0
    best_y = 0
    best_y_valid_turns = []
    for init_y_vel in range(1000):
        y_pos = 0
        num_turns = 0
        y_vel = init_y_vel
        max_height = 0
        valid_turns = []
        while y_pos >= y_min:
            #print(y_pos)
            num_turns = num_turns + 1
            y_pos = y_pos + y_vel
            y_vel = y_vel - 1
            max_height = max(max_height, y_pos)
            if y_pos <= y_max and y_pos >= y_min:
                valid_turns.append(num_turns)
        if max_height > best_y_max_height and len(valid_turns) > 0:
            best_y = init_y_vel
            best_y_valid_turns = valid_turns
            best_y_max_height = max_height
    valid_x = None
    for init_x_vel in range(1000):
        x_pos = 0
        x_vel = init_x_vel
        for i in range(max(best_y_valid_turns)+1):
            x_pos = x_pos + x_vel
            #print(i, x_pos, x_vel)
            if x_vel > 0:
                x_vel = x_vel - 1
            elif x_vel < 0:
                x_vel = x_vel + 1
            if i in best_y_valid_turns and x_pos > x_min and x_pos < x_max:
                valid_x = init_x_vel
    print(best_y_max_height)
    print(best_y)
    print(valid_x)
    
    Day 17 Part B - Python

    I modified my code to instead look for all x and y values that would eventually fall within the target zone. And recorded what turns they were within the zone. Then I took the lists and compared them against each other and recorded any matches were a given x velocity and y velocity had overlapping turns in the target area. The answer was how many unique entries were in that list.

    import re
    from collections import defaultdict
    
    #data = test_data
    data = real_data
    
    pattern = re.compile(r'target area: x=(-?\d+)..(-?\d+), y=(-?\d+)..(-?\d+)')
    
    bounds = pattern.search(data)
    
    x_min = int(bounds[1])
    x_max = int(bounds[2])
    y_min = int(bounds[3])
    y_max = int(bounds[4])
    
    
    valid_ys = defaultdict(list)
    valid_y_turns = []
    for init_y_vel in range(-100, 100):
        y_pos = 0
        num_turns = 0
        y_vel = init_y_vel
        while y_pos >= y_min:
            #print(y_pos)
            num_turns = num_turns + 1
            y_pos = y_pos + y_vel
            y_vel = y_vel - 1
            if y_pos <= y_max and y_pos >= y_min:
                valid_ys[init_y_vel].append(num_turns)
                valid_y_turns.append(num_turns)
    valid_y_turns = list(set(valid_y_turns))
    
    valid_xs = defaultdict(list)
    valid_x_turns = []
    
    for init_x_vel in range(305):
        x_pos = 0
        x_vel = init_x_vel
        for i in range(1,max(valid_y_turns)+1):
            x_pos = x_pos + x_vel
            #print(i, x_pos, x_vel)
            if x_vel > 0:
                x_vel = x_vel - 1
            elif x_vel < 0:
                x_vel = x_vel + 1
            if x_pos >= x_min and x_pos <= x_max:
                valid_xs[init_x_vel].append(i)
                valid_x_turns.append(i)
                
    valid_x_turns = list(set(valid_x_turns))
    
    valid_combos = []
    for x_key in valid_xs.keys():
        for y_key in valid_ys.keys():
            for turn_y in valid_ys[y_key]:
                if turn_y in valid_xs[x_key]:
                    valid_combos.append((x_key, y_key))
    
    valid_combos = list(set(valid_combos))
    #print(valid_combos)
    
    #print(valid_x_turns)
    #print(valid_y_turns)
    
    print(len(valid_combos))
    
    Tips
    • X movement and Y movement don't affect each other, you can break them out and handle them individually

    • A given trajectory may have multiple turns where it's within the target area, especially if you're looking at x and y separately

    • Eventually x slows down and stabilizes

    • I found thinking about it in terms of turns was very helpful

    2 votes
  19. Comment on Day 16: Packet Decoder in ~comp.advent_of_code

    PapaNachos
    Link Parent
    Yeah, the problem description definitely could have used a few more editorial passes. For the literal values you look at 5-bit chunks. The leading bit determines if you keep reading or it this...

    Yeah, the problem description definitely could have used a few more editorial passes. For the literal values you look at 5-bit chunks. The leading bit determines if you keep reading or it this will be the last one. The other 4 bits are data.

    Edit: You keep going until you hit a 0 leading bit

    3 votes
  20. Comment on Day 16: Packet Decoder in ~comp.advent_of_code

    PapaNachos
    Link
    After being Big Mad about yesterday's problem I really enjoyed this one. It was much more satisfying, for me at least. It definitely took a few tries to understand part of the problem description...

    After being Big Mad about yesterday's problem I really enjoyed this one. It was much more satisfying, for me at least. It definitely took a few tries to understand part of the problem description though

    Day 16 Part A - Python

    I built a recursive read packet function that basically returns anything it doesn't use. Just sliced everything up with a bunch of string manipulation and walked my way through the nested packets

    import re
    from collections import defaultdict
    
    #data = test_data
    data = real_data
    
    data_len = len(data)
    
    data = bin(int(data,16))[2:]
    data = data.zfill(data_len*4)
    
    #print(data)
    #print(int(data[0:3],2))
    #print(int(data[3:6],2))
    
    version_num_sum = 0
    
    def read_packet(packet):
        print("--------------")
        print("Packet: ", packet)
        if not packet or len(packet) < 11: #figure out what this number should be
            return ""
        #reads a single packet and subpackets. Returns any leftover bits
        version = int(packet[0:3],2)
        global version_num_sum
        version_num_sum = version_num_sum + version
        identity = int(packet[3:6],2)
        payload = packet[6:]
        
        print("Version: ", version)
        print("Identity: ", identity)
        print("Payload: ", payload)
        
        if identity == 4: #literal packet
            keep_reading = True
            bin_number = ""
            while keep_reading:
                segment = payload[0:5]
                payload = payload[5:]
                bin_number = bin_number + segment[1:]
                if segment[0] == '0':
                    keep_reading = False
            print("Literal Value: ", int(bin_number, 2))
            return payload
            
        else: #operator packet
            length_id = payload[0]
            payload = payload[1:]
            if length_id == '0': #next 15 bits list total length in bits of subpackets
                num_subpacket_bits = int(payload[:15],2)
                payload = payload[15:]
                sub_payload = payload[:num_subpacket_bits]
                while sub_payload and len(sub_payload) > 0:
                    print("Sub Packet:", sub_payload)
                    sub_payload = read_packet(sub_payload)
                return payload[num_subpacket_bits:]
            else: #next 11 bits list number of sub packets
                num_subpackets = int(payload[:11],2)
                payload = payload[11:]
                for i in range(num_subpackets):
                    print("Sub Packet:", payload)
                    payload = read_packet(payload)
                return payload
    
                    
    
    read_packet(data)
            
    print(version_num_sum)
    
    Day 16 Part B - Python

    Part A left me in a really good position, I just updated my return functions to pass the values between the levels, gathered them for anything with sub packets and added the operation to the end so that it could work with any gathered subpackets. It worked great

    import re
    from collections import defaultdict
    
    #data = test_data
    data = real_data
    
    data_len = len(data)
    
    data = bin(int(data,16))[2:]
    data = data.zfill(data_len*4)
    
    #print(data)
    #print(int(data[0:3],2))
    #print(int(data[3:6],2))
    
    def read_packet(packet):
        #print("--------------")
        #print("Packet: ", packet)
        if not packet or len(packet) < 11: #figure out what this number should be
            return "", None
        #reads a single packet and subpackets. Returns any leftover bits
        version = int(packet[0:3],2)
        global version_num_sum
        identity = int(packet[3:6],2)
        payload = packet[6:]
        
        #print("Version: ", version)
        #print("Identity: ", identity)
        #print("Payload: ", payload)
        
        if identity == 4: #literal packet
            keep_reading = True
            bin_number = ""
            while keep_reading:
                segment = payload[0:5]
                payload = payload[5:]
                bin_number = bin_number + segment[1:]
                if segment[0] == '0':
                    keep_reading = False
            #print("Literal Value: ", int(bin_number, 2))
            value = int(bin_number, 2)
            return payload, value
            
        else: #operator packet
            length_id = payload[0]
            payload = payload[1:]
            values = []
            if length_id == '0': #next 15 bits list total length in bits of subpackets
                num_subpacket_bits = int(payload[:15],2)
                payload = payload[15:]
                sub_payload = payload[:num_subpacket_bits]
                while sub_payload and len(sub_payload) > 0:
                    #print("Sub Packet:", sub_payload)
                    sub_payload, val = read_packet(sub_payload)
                    values.append(val)
                payload =  payload[num_subpacket_bits:]
            else: #next 11 bits list number of sub packets
                num_subpackets = int(payload[:11],2)
                payload = payload[11:]
                for i in range(num_subpackets):
                    #print("Sub Packet:", payload)
                    payload, val = read_packet(payload)
                    values.append(val)
            if identity == 0: #Sum
                value = sum(values)
            elif identity == 1: #Product
                value = 1
                for val in values:
                    value = value * val
            elif identity == 2:
                value = min(values)
            elif identity == 3:
                value = max(values)
            elif identity == 5: #greater than
                if values[0] > values[1]:
                    value = 1
                else:
                    value = 0
            elif identity == 6: #less than
                if values[0] < values[1]:
                    value = 1
                else:
                    value = 0
            elif identity == 7: #equal to
                if values[0] == values[1]:
                    value = 1
                else:
                    value = 0
            return payload, value
    
                    
    
    remaining, result = read_packet(data)
            
    print(result)
    
    Tips
    • It took me several reads to figure out what the hell the problem was asking and how to divide up sub packets. I particularly got stuck on the "38006F45291200" example. The first 11 bits are a fully formed packet and the next 16 are what's left over. And you can tell the difference between them because the first one ends

    • For the most part you can't tell how long a packet is until you're done reading it. You need a way to keep track of what is and isn't being used so you don't lose what you're not looking at at the moment

    • Make sure not to lose track of your leading zeros when you convert from hex to binary. It will definitely mess up your results, if you do lose them you should be able to add them back in

    • For me, recursion handled the bulk of traveling between different packet levels.

    • For part B, each packet will only ever pass one value up

    • I think this code will get expanded upon in later challenges, but I'm not sure

    2 votes