day 02 - advent of code 2024

แชร์
ฝัง
  • เผยแพร่เมื่อ 3 ธ.ค. 2024

ความคิดเห็น • 31

  • @omarmagdy1075
    @omarmagdy1075 2 วันที่ผ่านมา +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

  • @zkeltonETH
    @zkeltonETH วันที่ผ่านมา +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!

  • @flwi
    @flwi 2 วันที่ผ่านมา +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.

  • @nguyen_tim
    @nguyen_tim 5 ชั่วโมงที่ผ่านมา

    Hey Chris, thanks for including the troubleshooting process! It was very helpful as someone learning Rust.

    • @chrisbiscardi
      @chrisbiscardi  4 ชั่วโมงที่ผ่านมา

      glad you're finding it useful! that's definitely why I keep it in the videos.

  • @gbegerow
    @gbegerow 2 วันที่ผ่านมา +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. ;-)

  • @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!

  • @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.

  • @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 วันที่ผ่านมา

    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 วันที่ผ่านมา

      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  วันที่ผ่านมา +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.

  • @Alex-bv5se
    @Alex-bv5se 2 วันที่ผ่านมา

    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  2 วันที่ผ่านมา

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

  • @nel_tu_
    @nel_tu_ วันที่ผ่านมา

    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 วันที่ผ่านมา +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 วันที่ผ่านมา +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 วันที่ผ่านมา

    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 (th-cam.com/video/zBwuu6uGwaE/w-d-xo.html) for that safety method. For me, it's brilliant 🙂. Rust vec stdlib has all the methods to do something like that.

  • @KurtSchwind
    @KurtSchwind 2 วันที่ผ่านมา

    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 2 วันที่ผ่านมา +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.

  • @EduarteBDO
    @EduarteBDO 2 วันที่ผ่านมา

    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  2 วันที่ผ่านมา +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 2 วันที่ผ่านมา +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 2 วันที่ผ่านมา

    advent of what
    where's Bevy

    • @chrisbiscardi
      @chrisbiscardi  2 วันที่ผ่านมา

      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!

  • @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

  • @RoamingAdhocrat
    @RoamingAdhocrat 2 วันที่ผ่านมา

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