Advent of Code 2023 Day 5: If You Give A Seed A Fertilizer

Sdílet
Vložit
  • čas přidán 1. 06. 2024
  • Pretty challenging problems today, especially part 2! I'm sort of surprised considering it's only day 5 and it's not a weekend.
    My AoC repository: github.com/hyper-neutrino/adv...
    Join my Discord! / discord
    0:00 Intro
    2:00 Part 1
    7:21 Codecrafters Promotional Segment
    9:18 Part 2
    Want to improve your mastery or learn a new language? Try Codecrafters, a platform where you learn by building your own project! I've always believed that learning by doing is the best way to learn to code by far, so check them out with my link! app.codecrafters.io/join?via=.... You can sign up for free and try out some of their streams including full beta projects for free (no credit card required) and you'll get a 40% discount on annual subscriptions!
    (Disclaimer: I receive commissions on paid memberships through my link, but Codecrafters is not a sponsor of this channel, does not endorse any of my content, and does not review any of my videos.)

Komentáře • 87

  • @hyper-neutrino
    @hyper-neutrino  Před 6 měsíci +2

    Sign up at app.codecrafters.io/join?via=hyper-neutrino and try out Codecrafters today! You can get a taste of their many learning streams and try out their beta courses all completely for free (no credit card needed), and when you go to sign up, you'll get 40% off at checkout and support the channel! Thank you for watching :)
    (Codecrafters has not sponsored this video directly and they did not have the opportunity to review any of this video, including the promotional segment.)

  • @xxxxyyyy-ll3hz
    @xxxxyyyy-ll3hz Před 6 měsíci +17

    What makes the explanation so good is that you print the result of most code changes. Thanks!

    • @hyper-neutrino
      @hyper-neutrino  Před 6 měsíci +5

      Glad you find that helpful! I'll be sure to keep doing that to make my solutions easier to understand. Thanks for the feedback!

  • @SharunKumar
    @SharunKumar Před 5 měsíci +11

    Difficulty is all over the place this year. I was recommending 2022 for people who wanted to learn a new language because of the gradual difficulty increase

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci +4

      That's a good idea. Also removes the pressure of the leaderboard but I definitely agree that the difficulty levels made a lot more sense than this year...

  • @aaronteodorpanaitescu1289
    @aaronteodorpanaitescu1289 Před 6 měsíci +10

    i did everything exactly the same but then got stuck on calcualting those intersections. The idea to add back into seeds the outer parts of the interval intersection is very elegant

  • @unclerojelio6320
    @unclerojelio6320 Před 4 měsíci

    I appreciate that your are posting of your solutions here. I'm learning quite a few new Python tricks.

  • @YukamsGaming
    @YukamsGaming Před 6 měsíci +7

    Wow I really feel ashamed not to Even be able to complete part 1 when I see such clever solutions and so many people doing them. Thanks for the explanation

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci +7

      We all start somewhere; nothing to be ashamed of! Thanks for watching :)

  • @yodua8193
    @yodua8193 Před 5 měsíci +1

    This was very helpful. I've almost given up when I saw this one and I just left the part 2 for later. I've solved it today thanks to your explanation.
    I'm new to the channel but I'll deffinitely stay longer because your videos are very clear

  • @timothyhumphreys1231
    @timothyhumphreys1231 Před 5 měsíci

    Great video! Excellent solution which is both simple to understand and also sophisticated. I had already spent around 6 hours trying to work through part 2 and kept getting close but not quite there yet. Your drawings really helped visualize the problem as well. Subbed and looking forward to the rest of your 2023 videos!

  • @gradientO
    @gradientO Před 6 měsíci +2

    Thanks a lot man! The explanation was so clear

  • @user-uy2kc4rg5u
    @user-uy2kc4rg5u Před 5 měsíci

    Thanks, I solved it but I had an 08:22:46.998 run I went through all the seeds as in part 1. This was enlightning.

  • @klif_n
    @klif_n Před 5 měsíci

    This was an excellent description. Very much appreciated!

  • @paolostet6450
    @paolostet6450 Před 5 měsíci +1

    I don't usually comment on videos, but your explanation was extremely helpful after this problem fried my brain xD. Massive props, keep doing what you're doing!

  • @stoufa
    @stoufa Před 5 měsíci

    Thanks for sharing!
    Now, I understand why my approach didn't work ... I only considered the overlap and discarded the remaining! 😅

  • @MrRoms83
    @MrRoms83 Před 6 měsíci +2

    Wow man, I managed to pull something that works today but had real performance issues (my script ran for 10000sec on part 2), you provides really good insights on Python in your explanation and I see I have much space for improvment. Keep up the good work and thx very much !

  • @luigidabro
    @luigidabro Před 5 měsíci +1

    I like your big-brain-words big-brain-man. Converting this to C++ will be fun...

  • @purpleysound
    @purpleysound Před 6 měsíci +1

    I appreciate the drawings of the intersections they really helped visualise the problem, I did it using the start and length rather than start and end and also used recursion when the range got split into 2 and it took maybe 2-3 hours to solve but seeing your solution just makes it look so easy and elegant lol

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      Good to hear! Recursion is a good approach as well; I hadn't actually thought of that. Thanks for the feedback!

  • @HeliosRSPS
    @HeliosRSPS Před 5 měsíci +1

    Thank you. I would really love it if you can create another explainer for part 2. Preferbely by running some example numbers in excalidraw.

  • @atosh502
    @atosh502 Před 5 měsíci

    My naive solution was not going to finish anytime soon. I watched your video and then started implementing the solution based on a vague understanding of ranges/intervals and their mapping. I was able to get the sample solution right though. Still there were issues with my final implementation. I rewatched the explanation for part two of this video a couple of times, still nothing. Then I saw your "short" on intervals. That gave me some idea about the calculation of offset intervals and I was able to get the offsets and limits right. I had to draw the complete mapping of intervals on paper for the sample input while debugging my code. While rewatching the video again I noticed I wasn't using the queues, as once the seed interval is split into two, the non overlapping interval needs to be mapped again. And finally I was able to get the correct answer.
    Thank you for the clear explanations, nice visuals and printing out the intermediate variable values as you implemented+explained your code in the video.

  • @AledD2000
    @AledD2000 Před 6 měsíci

    So helpful. Thank you!

  • @mkrichey1
    @mkrichey1 Před 6 měsíci

    Learned a few new tricks so thank you very much! My initial run at part 2 took about 2 min to complete which I thought was ok .... until I found your video and learned just how fast you can make it!

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      Glad to hear! Yeah, with interval manipulation it runs literally instantly because the input size is actually very small if you aren't constructing the ranges themselves; the numbers are big but the size is not. Thanks for watching!

  • @YaelSercomanens
    @YaelSercomanens Před 5 měsíci

    THANK YOU!

  • @thedoodler882
    @thedoodler882 Před 5 měsíci

    good vid, thanks.

  • @DapsSenpai
    @DapsSenpai Před 6 měsíci +5

    Great video, helped me understand how to approach the second part. One thing that could be helpful to understand what exactly are you doing and what do variables mean - could you try to use more descriptive names for variables instead of a, b, c? Like source, destination, length or something. Other than that, thank you very much!

    • @hyper-neutrino
      @hyper-neutrino  Před 6 měsíci +5

      Sure, that's a good suggestion! I can also maybe leave some comments to help with keeping track of everything in longer solutions.

    • @carlturland6202
      @carlturland6202 Před 6 měsíci +1

      I agree... following a, b, c etc becomes pretty difficult

    • @thedoodler882
      @thedoodler882 Před 5 měsíci +1

      agree with this, more descriptive variable names would be very helpful.

  • @charitygrey
    @charitygrey Před 5 měsíci +1

    In part two wouldn't the overlapping ranges be solved if when you appended the seed range on the end of seeds you added or subtracted 1? (ie: (s, os -1) and (oe + 1, e))

  • @user-hf7ef6nm4s
    @user-hf7ef6nm4s Před 5 měsíci

    Beautiful

  • @afterschool2594
    @afterschool2594 Před 6 měsíci +3

    Finally, I have finished the part 2. It took me 1 hour to do the part 1 and 8 hour to make the part 2 working even though it still takes 2 minutes for my program to solve the part 2 thanks to Rust's Release Mode (since my objective doing AOC is to learn rust). If I'm using Python, JS, or other interpreted language maybe it will be very slow.

    • @CentroidYT
      @CentroidYT Před 5 měsíci

      8 Hours? it took me far more than that lol

  • @MikeM8891
    @MikeM8891 Před 4 měsíci

    I just checked every seed in the ranges. Writing it in Rust, it took about 2 mins to find the solution.

  • @jasonsoares326
    @jasonsoares326 Před 5 měsíci +1

    This is an obviously very clear explanation that I don't really understand, at least part 2. How is it that range overlaps help us get to the final answer? I'm so confused. 🙂 I think I just don't grasp the basic idea of the part 2 solution at all.

    • @jasonsoares326
      @jasonsoares326 Před 5 měsíci +1

      OK, so I think I'm starting to understand this. Let me see if I can articulate what you've done. (Sorry, I'm not a programmer, so I'm new to concepts like this.)
      Just thinking about the first step here for simplicity: For each seed range, you are looking for segments of that seed range that are within the corresponding ranges of the next step (soil in this case). Then, you are applying the transformation (source - destination) to that seed segment into the next (soil) segment? And then the unmapped segments go into the next step unchanged? I think I'm still kind of confusing myself.

    • @jasonsoares326
      @jasonsoares326 Před 4 měsíci

      The part of the code that took me the longest to understand was the if os > s: and if e > oe:
      Sorry, I know I'm probably spamming CZcams comments, but maybe this might help someone else?
      The code block is popping off the seed at the start of the loop, then it takes out any overlaps, shifts them, and then adds them to the output. Then the if statements at the end "clean up" the rest of the seed range and add them back into the input for evaluation in the next loop (since they might get picked up by another range in the current set of ranges.)
      This video has been invaluable to me. That said, the second case you drew with the overlap of the input range confused me because you have to do this "cleanup" operation whether the overlap is on the left, right, or entirely inside the input range. Maybe this was just obvious to everyone else though.

  • @terryaney73
    @terryaney73 Před 4 měsíci

    By the time you do min(seeds) at the end to find the result, how many entries would you expect in the seeds array?

  • @nidefawl2552
    @nidefawl2552 Před 6 měsíci

    Well done. I failed part 2 because I thought ranges could overlap

  • @zweitekonto9654
    @zweitekonto9654 Před měsícem

    Since the range in [s,e) e non inclusive, shouldn't you take min(e-1, b+c-1)?

  • @mrchomik2001
    @mrchomik2001 Před 5 měsíci +1

    Never seen bluetooth parierd if-else in my life before (15:18) I will never write a flag again

  • @lupita3689
    @lupita3689 Před 6 měsíci

    I did an inverse search from location to check if seed present, reducing the range by checking overlap is an optimization but it would still be costly to know what the eventual location is for ALL of them.
    Since you're using Python, how much time did it take you to get a return without multi-threading?

    • @hyper-neutrino
      @hyper-neutrino  Před 6 měsíci +1

      My solution for part 2 runs instantly. Because the mapping is just a linear transformation on the ranges, you can store all of the seeds as ranges and then just manipulate them as such. There may be a more efficient way but the runtime of my solution is totally negligible.

    • @lupita3689
      @lupita3689 Před 5 měsíci

      @@hyper-neutrino I might have missed part of the video, if you’re mapping ranges from one source to the next it’s quite linear yeah.

  • @RaabNicklas
    @RaabNicklas Před 5 měsíci

    Nice walkthrough and explanation 😊 Could you shed some light at other problems that are like this that you've encountered? What's the real world application in other words 😊

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci +1

      I honestly can't really think of any situations in which I've needed interval manipulation outside of programming challenges, lol

    • @RaabNicklas
      @RaabNicklas Před 5 měsíci

      @@hyper-neutrino thanks! :D

  • @R10D10
    @R10D10 Před 5 měsíci

    I don't understand the b

  • @sholtronicsaaa101010
    @sholtronicsaaa101010 Před 6 měsíci

    For part 1 is there a guarantee that the source ranges don't overlap? I was under the impression you would have to take the min of all source values rather than just taking the first match and breaking? (Guess in hindsight it's easy to verify)

    • @hyper-neutrino
      @hyper-neutrino  Před 6 měsíci

      I don't think the problem states that it's guaranteed, but it also doesn't define how to handle that. I think it's safe to assume that there will be no overlap in the source ranges.

    • @Kroppeb
      @Kroppeb Před 6 měsíci +1

      Overlapping ranges didn't make sense in my mind given the explanation.
      I think technically the explanation does disallow overlapping ranges as it mentions that it a map converts "a seed number" into "a soil number" so it wouldn't make sense for a seed number to be mapped to multiple soil numbers

  • @jizosgoescrazy
    @jizosgoescrazy Před 6 měsíci +1

    this was so hard for being day 5, did part 1 just fine but couldn't even think about doing part 2

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      Yeah, I was caught off guard with the difficulty spike too. If it were a weekend, it would be a bit less surprising, but this seemed unusually difficult for a weekday day 5

  • @Zoronoa01
    @Zoronoa01 Před 6 měsíci +2

    Can you please make a youtube short about how to merge those intervals?

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci +1

      Sure! czcams.com/users/shortsIaPaQ5heqZs Hope this helps :)

    • @Zoronoa01
      @Zoronoa01 Před 5 měsíci

      @@hyper-neutrino thank you so much.

  • @brianbrenner4288
    @brianbrenner4288 Před 5 měsíci

    Maybe I'm missing something, but for part 2 what happens if a seed range overlaps with two different ranges? I would think this code wouldn't work since the break would cause the second range to not get checked. I'm imagining the scenario you show in the drawing at 12:07

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      If it overlaps two different ranges, it will match one, the remainder will get chopped off and reinserted, and then later on that remainder will get checked again, and it will match the other map range.

  • @CentroidYT
    @CentroidYT Před 5 měsíci

    How do you get to a level where you are able to comprehend your code this well? Is it just practice? Its honestly incredible how you can look at all the variables in the range and understand exactly what they are and where they go.

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      It's just practice; I've been coding for over a decade now so I've gotten a pretty intuitive understanding of code as I literally don't remember much of my life before I started. Let me know if anything's confusing or if my pace is too fast to easily understand!

    • @CentroidYT
      @CentroidYT Před 5 měsíci

      No its perfect, your a gret teacher and your skills are very impressive@@hyper-neutrino

  • @stoched
    @stoched Před 5 měsíci

    Would it be quicker or slower to take the input, start at the end, find the lowest “destination” and see the range that the source needs to be in, then walk backwards up the input redoing that process to basically have it output the optimal “range” the starting seeds need to be in? Then you’d just check the starting seeds + offset and see which seeds fulfill the criteria then take their minimum?

    • @stoched
      @stoched Před 5 měsíci

      This is what my thought process was when solving, although I kept getting myself messed up trying to walk through the input backwards so I ended up brute forcing it just so I can move on hahaha. But I really want to know if doing it that way would also be “fast”.

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      I think it would be a lot more complicated, since the potential range of locations is infinite so you don't really have a starting point because not all locations can necessarily be reached and the way the seeds map to the locations may not be able to be determined just from the last map input.

    • @stoched
      @stoched Před 5 měsíci

      @@hyper-neutrino
      Edit: oh I see what you mean the starting seeds might not necessarily map to the lowest possible destination.
      Disregard
      I see what you're saying, but I think it's still feasible, even though yes it probably is way more complicated. If you start from the final set of maps, sort them by the "destination" value so then you can find which range of inputs maps to the lowest destination value on the last step.
      Now that you have the input range you need, you go back a level then find the maps that contain your range, if none of them fit your range then you just keep bubbling up the previous range that was required.
      So the first iteration you just want to sort by the minimum output value and get the range you need to do that. All the rest of the steps are just trying to match your range to one of their maps. If it matches you update your range that bubbles up to the next level, if it doesn't match you bubble up the same range you already have. Once you get to the top then you can find which seed + offset pairs fit within that range and take the minimum.
      Like it seems very possible to do to me unless I'm completely overlooking a condition hahaha

  • @maxxbrandt5822
    @maxxbrandt5822 Před 6 měsíci

    Wasted too much time on bruteforce solutions for part 2, ended up solving it using reverse lookup starting from location '0' with jump search of decreasing steps, which can still give wrong minimum with large steps... Wonder how many solved or even thought of solving it this way 😄
    You found a way better solution and made a perfect video explanation for it! Amazing work!👍

    • @maxxbrandt5822
      @maxxbrandt5822 Před 6 měsíci

      Also interestingly enough, in my input the maximum location value is a perfect square (√4294967296 = 65536) which makes it very convenient to find optimal step for jump search = √n, can jump search actually be intended? 🤔

    • @hyper-neutrino
      @hyper-neutrino  Před 6 měsíci

      That's an interesting approach; I thought of that afterwards but it doesn't sound like it would be the most straightforward way to do it, but it might be faster, and it's definitely a good strategy to keep in mind in general (working backwards is a good trick to keep in mind)

    • @TheIronmanJourney
      @TheIronmanJourney Před 5 měsíci

      I come up with the exact same solution. 😅 runs for about 20 sec on my side … depends abit on how „big“ the answer is

    • @maxxbrandt5822
      @maxxbrandt5822 Před 5 měsíci

      @@TheIronmanJourney all i can say is my jump search with steps from 100k to 1 with progression of 1/10 (devide by 10) finds it in 0.714 msec with 1028 lookups 😃
      What went wrong with yours? 20s is a lot!

  • @stackercoding2054
    @stackercoding2054 Před 5 měsíci

    I left my solution for part 2 running all night and it wasn't even close to finish when I woke up 😅

  • @filk3654
    @filk3654 Před 6 měsíci

    Yo, what font do you use?

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      This is Monaspace Radon from GitHub Next

    • @filk3654
      @filk3654 Před 5 měsíci

      Gracias @@hyper-neutrino

  • @MrKapeleone
    @MrKapeleone Před 5 měsíci

    Your entire solution for this problem has less lines of code than my input parsing section in Java, lol

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      Haha, yeah there's a reason I use Python. Lower level languages are just too much of a pain to work with with parsing and typing and similar things; it's nice to just be able to throw together some higher level ideas and worry less about implementation specifics. Also better for teaching because even people with less experience can more or less read what's going on

  • @leumon
    @leumon Před 5 měsíci

    2:42 Isn't python already taking care of that?

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      I don't think so; I ran into this issue last year and that's why I only got #300 on P1. Maybe I'm using the wrong built-in though?

  • @DavidPTUS
    @DavidPTUS Před 5 měsíci

    Your code on this video gives me a number too low according to AoC. Guess I'll just have to live with a silver star on day 5.

    • @hyper-neutrino
      @hyper-neutrino  Před 5 měsíci

      send me your input and I can take a look

    • @DavidPTUS
      @DavidPTUS Před 5 měsíci

      @@hyper-neutrino I found a line of code that wasn't indented to the same level as yours. That made it return a number below 27000. I fixed that and the program returned the correct answer.

  • @pulgamecanica
    @pulgamecanica Před 5 měsíci

    pls dont use new as a var name, gives me anxiety ahahah, good video

  • @SharunKumar
    @SharunKumar Před 5 měsíci +1

    os.linesep instead of

    or