day 02 - advent of code 2024

Поделиться
HTML-код
  • Опубликовано: 3 дек 2024

Комментарии • 29

  • @zkeltonETH
    @zkeltonETH 21 час назад +3

    Wow, the tracing crate for debugging was such an awesome showcase here! I was fortunate enough to get by with just println!() statements lmao. Definitely gonna be using it for the next AoC days!

  • @omarmagdy1075
    @omarmagdy1075 День назад +10

    Kudos to you mate I always like how clean and readable your solution is. You write the code like you will maintain it for the next ten years

  • @flwi
    @flwi День назад +3

    It felt like watching myself, because you ran into similar issues :D I also had the range not including 3 at first :D
    I love that you showed the debugging part. I didn't know about the inspect combinator on iterators.
    14:18 Also haven't really used the tracing crate. Annotating the functions and showing their inputs and outputs is _super_ helpful.
    Appreciate you showing all the rust goodies!
    My approach was slightly different. I had an enum LevelCheckResult with three values (SafeIncreasing, SafeDecreasing, Unsafe). After the sliding window combinator I called counts() to get a HashMap. From there I checked if there no unsafe transitions and only (in|de)creasing values.

  • @Kiaulen
    @Kiaulen День назад +2

    I might have missed it, but why are you writing parsers here? Is it just for practice with them? It feels like a loop and a couple of predicate functions could solve this more simply.
    Regardless, thanks for doing these. I'm still pretty novice at rust, and it's nice to look over your shoulder. ❤

    • @chrisbiscardi
      @chrisbiscardi  День назад +2

      I actually started this year not using nom intending to start a bit later in the puzzles and then a bunch of people in discord wanted to use it so I switched to picking it up earlier.
      generally speaking I think that people have a much easier time figuring out how to .split() or .lines() their way through parsing and using crates like nom is harder to approach because its less familiar. So using it in videos is more useful than doing .lines()/.split(). The further we get into advent of code, the more relevant having a solid parsing library is. Day 3 is parsing an instruction set, for example.
      On the subject of a loop and predicates being simpler, I think that's probably more familiarity than simpleness. I didn't need a loop to write the parser for day 2, and the parser could be broken up and well tested. Its harder to do things like that as the parser get more complicated.
      ```
      fn parse(input: &str) -> IResult {
      separated_list1(
      line_ending,
      separated_list1(space1, complete::i32),
      )(input)
      }
      ```
      at the end of the day there's no "right choice" for advent of code, its all how you want to approach it. So if using .lines() and a loop makes you happy definitely keep doing that!

  • @gbegerow
    @gbegerow День назад +2

    Part 1 I had a little bit of luck my code digested any anomaly but Part 2 drove me crazy trying to optimize it. In the end got tired and copied around like no tomorrow. I doubt my solution is any faster than yours. ;-)

  • @avalagum7957
    @avalagum7957 День назад +1

    I really love your videos, esp. about all the crates you used and the functions in the stdlib.
    What I don't like about AOC is that we cannot read the part 2 requirement before we finish part 1. So, sometimes, doing part 2 is like writing a completely new program as there's nothing in part 1 we can modify so that it works with part 2.
    So, this year, I'll cheat a bit by watching your videos to know the requirements of 2 parts then start practicing 🙂

    • @chrisbiscardi
      @chrisbiscardi  День назад +1

      that's honestly a great idea. I've been telling people to only commit to doing part 1 every day and do part 2 if it feels good to do it so checking the requirements before getting into it is a nice approach.

  • @Alex-bv5se
    @Alex-bv5se День назад

    Definitely learnt something with your debugging through tracing!
    It was painful for you, but not for nothing! I'm setting that up first thing tomorrow 😋.
    And also didn't know about this iter_tool... I'll definitely have to dig into that for the next days 👌.
    Thank for sharing 🙏!

    • @chrisbiscardi
      @chrisbiscardi  День назад

      itertools is great! Its basically a bunch of extra functions for working with iterators -- docs.rs/itertools/0.13.0/itertools/trait.Itertools.html

  • @am_n_n
    @am_n_n День назад

    Here's a simpler way to write check_safety that doesn't involve as many edge cases (and still avoids nightly-only features):
    fn check_safety(xs: &[i32]) -> bool {
    let growing = xs.is_sorted_by(|a, b| a

  • @douglasgabriel99
    @douglasgabriel99 15 часов назад

    for part 2 I compared 4 levels (a ,b, c, d) and tried to move forward by either going a-b-c, a-b-d, a-c-d, or b-c-d if it was the first step (so the first level can be skipped if needed), then keeping track if a skip was already made or not and failing if a second skip is needed. Also, if no skip was made, "c" became the new "a". If a skip was made, "d" became the new "a"

    • @douglasgabriel99
      @douglasgabriel99 15 часов назад

      I think that's not 100% correct, since if a-b-c succeeds, but then c-d fails, c can no longer be skipped, but it worked on my input and that's the only thing that matters haha

    • @chrisbiscardi
      @chrisbiscardi  15 часов назад +1

      haha, a true aoc solution! I might go back and work on my day 2 to optimize it a bit but I'm happy enough with having it done.

  • @nel_tu_
    @nel_tu_ 22 часа назад

    Uses a parser combinator library, a tracing subscriber, a instrumentation framework, enums for safety and direction, type aliases, custom error and result types.
    Also: "I'm not going to create an error type because it's just AOC" 😂

  • @ikesau
    @ikesau День назад +2

    sounds like you were quite frustrated with the obscure edge case, but I'm really grateful you're making this videos and leaving the educational parts of the debugging process in. Thanks Chris!!

    • @chrisbiscardi
      @chrisbiscardi  День назад +2

      definitely frustrated! but I also know what I'm getting into and expect this to happen at least once. I try to flip it into educational material about debugging and error handling (as seen in this video)

  • @avalagum7957
    @avalagum7957 22 часа назад

    Last night, I did days 1 and 2 before going to bed. I implemented the safety method similar to what you did at 7:43. Then google introduced me a video of a Scala solution (ruclips.net/video/zBwuu6uGwaE/видео.html) for that safety method. For me, it's brilliant 🙂. Rust vec stdlib has all the methods to do something like that.

  • @KurtSchwind
    @KurtSchwind День назад

    I am unclear on what was different from your input data vs the example. I know you did a whole debugging run but most of it was off-camera and in the end I didnt’ track what was different for you or what edge case you suddenly had to account for.
    Keep up the great vids.

    • @shrugalic
      @shrugalic День назад +3

      There was a level diff outside the 1 to 3 window in the first 2 numbers (pair) of a report line.
      His original code only checked the diff for pairs after the first pair of a line, when direction was no longer None.
      This unsafe condition does not occur in the example.

  • @Barajamtg
    @Barajamtg День назад

    For part 1, I utilized zip(records.skip(1)).all to compare the values. It’s always fascinating to observe the variety of solutions people come up with

  • @EduarteBDO
    @EduarteBDO День назад

    super interesting solution. In my rust solution for parsing the file I did it in a pretty raw way converting the input to a Vec:
    fn solving_question_2() -> (i32, i32) {
    let mut input_q2: String = String::new();
    File::open("./src/q2_input.txt")
    .expect("error opening the file")
    .read_to_string(&mut input_q2)
    .expect("Some error converting to string");
    let mut input: Vec = vec![];
    for nums in input_q2.split('
    ') {
    let nums2: Vec = nums
    .split_whitespace()
    .map(|v| v.parse().unwrap())
    .collect();
    input.push(nums2);
    }
    (question02(input.clone()), question02_part_2(input))
    }

    • @chrisbiscardi
      @chrisbiscardi  День назад +1

      nice! yeah, that's the way I imagine most people would have ended up doing today's parsing. Probably also leaning on read_to_string instead of opening first: doc.rust-lang.org/stable/std/io/fn.read_to_string.html

    • @haemolacriaa
      @haemolacriaa День назад +1

      use BufReader instead, so u can do
      let buf = BufReader::new(File::open(path));
      then
      let lines = buf.lines().map(|l| l.expect("failed")).collect::();
      then you can iter over the lines vec and do the split whitespace and stuff

  • @sunofabeach9424
    @sunofabeach9424 День назад

    advent of what
    where's Bevy

    • @chrisbiscardi
      @chrisbiscardi  День назад

      haha the bevy'ing will continue as usual. I'm also doing advent of code this month. 0.15 is out and I shipped that video a couple days ago, so super exciting time for Bevy!

  • @RoamingAdhocrat
    @RoamingAdhocrat День назад

    I windowed the report and then `windowed.all(|(a, b)| (1..=3).contains(a-b)) || windowed.all(|a,b|(1..=3).contains(b-a))`