Bauke's recent activity

  1. Comment on Day 4: Passport Processing in ~comp.advent_of_code

    Bauke
    (edited )
    Link Parent
    You could do something like this, where you map the lines and unwrap them, and then reference them (playground link): use std::io::{BufRead, Cursor}; fn main() { // This would be your input file....

    You could do something like this, where you map the lines and unwrap them, and then reference them (playground link):

    use std::io::{BufRead, Cursor};
    
    fn main() {
        // This would be your input file.
        let input = Cursor::new(b"abc:123 def:456\n\nextra:stuff");
    
        let mut lines = input.lines().map(|line| line.unwrap());
    
        // Reference them here ↓
        while let Some(line) = &lines.next() {
            // Also no need to specify usize here.
            if line.len() == 0 {
                dbg!("Next passport");
                continue;
            }
    
            for part in line.split_ascii_whitespace() {
                dbg!(part);
            }
        }
    }
    

    This would then output the key:value pairs and you can continue with your current code.

    [src/main.rs:18] part = "abc:123"
    [src/main.rs:18] part = "def:456"
    [src/main.rs:13] "Next passport" = "Next passport"
    [src/main.rs:18] part = "extra:stuff"
    
    3 votes
  2. Comment on Day 4: Passport Processing in ~comp.advent_of_code

    Bauke
    (edited )
    Link
    Language: Rust. Repository. Main function (run harness). Filters... Filters everywhere! And a bit of Regex too, making the hex colors and passport IDs validation very simple. Solution use...

    Filters... Filters everywhere! And a bit of Regex too, making the hex colors and passport IDs validation very simple.

    Solution
    use regex::Regex;
    
    use crate::DayResult;
    
    #[derive(Debug, Clone)]
    struct Passport {
      byr: Option<String>,
      iyr: Option<String>,
      eyr: Option<String>,
      hgt: Option<String>,
      hcl: Option<String>,
      ecl: Option<String>,
      pid: Option<String>,
      cid: Option<String>,
    }
    
    pub(crate) fn solve(data: String) -> DayResult {
      let mut passports = vec![];
      let blank = Passport {
        byr: None,
        iyr: None,
        eyr: None,
        hgt: None,
        hcl: None,
        ecl: None,
        pid: None,
        cid: None,
      };
      let mut intermediate = blank.clone();
    
      let hcl_regex = Regex::new("^#[a-fA-F0-9]{6}$").unwrap();
      let ecl_values = vec![
        "amb".to_string(),
        "blu".to_string(),
        "brn".to_string(),
        "gry".to_string(),
        "grn".to_string(),
        "hzl".to_string(),
        "oth".to_string(),
      ];
      let pid_regex = Regex::new("^[0-9]{9}$").unwrap();
    
      for line in data.lines() {
        if line == "" {
          passports.push(intermediate.clone());
          intermediate = blank.clone();
          continue;
        }
    
        let components = line.split(' ');
        for component in components {
          let colon_index = component.find(':').unwrap();
          let key = &component[0..colon_index];
          let value = &component[colon_index + 1..];
          match key {
            "byr" => intermediate.byr = Some(value.to_string()),
            "iyr" => intermediate.iyr = Some(value.to_string()),
            "eyr" => intermediate.eyr = Some(value.to_string()),
            "hgt" => intermediate.hgt = Some(value.to_string()),
            "hcl" => intermediate.hcl = Some(value.to_string()),
            "ecl" => intermediate.ecl = Some(value.to_string()),
            "pid" => intermediate.pid = Some(value.to_string()),
            "cid" => intermediate.cid = Some(value.to_string()),
            _ => unreachable!(key),
          };
        }
      }
    
      let result_one = passports
        .iter()
        .filter(|passport| {
          passport.byr.is_some()
            && passport.iyr.is_some()
            && passport.eyr.is_some()
            && passport.hgt.is_some()
            && passport.hcl.is_some()
            && passport.ecl.is_some()
            && passport.pid.is_some()
        })
        .count()
        .to_string();
    
      let result_two = passports
        .iter()
        .filter(|passport| {
          passport.byr.is_some()
            && passport.iyr.is_some()
            && passport.eyr.is_some()
            && passport.hgt.is_some()
            && passport.hcl.is_some()
            && passport.ecl.is_some()
            && passport.pid.is_some()
        })
        .filter(|passport| {
          let byr = passport
            .byr
            .as_ref()
            .unwrap()
            .parse::<i32>()
            .unwrap_or_default();
          byr >= 1920 && byr <= 2002
        })
        .filter(|passport| {
          let iyr = passport
            .iyr
            .as_ref()
            .unwrap()
            .parse::<i32>()
            .unwrap_or_default();
          iyr >= 2010 && iyr <= 2020
        })
        .filter(|passport| {
          let eyr = passport
            .eyr
            .as_ref()
            .unwrap()
            .parse::<i32>()
            .unwrap_or_default();
          eyr >= 2020 && eyr <= 2030
        })
        .filter(|passport| {
          let hgt = passport.hgt.as_ref().unwrap();
          match &hgt[hgt.len() - 2..] {
            "cm" => {
              let value = hgt[0..hgt.len() - 2].parse::<i32>().unwrap_or_default();
              value >= 150 && value <= 193
            }
            "in" => {
              let value = hgt[0..hgt.len() - 2].parse::<i32>().unwrap_or_default();
              value >= 59 && value <= 76
            }
            _ => false,
          }
        })
        .filter(|passport| {
          let hcl = passport.hcl.as_ref().unwrap();
          hcl_regex.is_match(&hcl)
        })
        .filter(|passport| {
          let ecl = passport.ecl.as_ref().unwrap();
          ecl_values.contains(&ecl)
        })
        .filter(|passport| {
          let pid = passport.pid.as_ref().unwrap();
          pid_regex.is_match(&pid)
        })
        .count()
        .to_string();
    
      Ok((Some(result_one), Some(result_two)))
    }
    
    Output
    🌟 Day 04  |
    🎆 Part 1  | 237
    🎇 Part 2  | 172
    🌠 Runtime | 0.011285259 seconds
    
    5 votes
  3. Comment on Day 3: Toboggan Trajectory in ~comp.advent_of_code

    Bauke
    (edited )
    Link Parent
    Well, today I learned about product(). I like that more, I'm gonna change it, thanks! :P

    Well, today I learned about product(). I like that more, I'm gonna change it, thanks! :P

    1 vote
  4. Comment on Day 3: Toboggan Trajectory in ~comp.advent_of_code

    Bauke
    Link Parent
    Yeah the complete input. Don't worry though, it took me a minute too when I first read the puzzle.

    Yeah the complete input. Don't worry though, it took me a minute too when I first read the puzzle.

    2 votes
  5. Comment on Day 3: Toboggan Trajectory in ~comp.advent_of_code

    Bauke
    Link Parent
    Are you talking about the pattern from this paragraph? If you are, the puzzle input basically copies itself to its right, for example if this is the puzzle input: 123 456 789 It would repeat to...

    Are you talking about the pattern from this paragraph?

    These aren't the only trees, though; due to something you read about once involving arboreal genetics and biome stability, the same pattern repeats to the right many times

    If you are, the puzzle input basically copies itself to its right, for example if this is the puzzle input:

    123
    456
    789
    

    It would repeat to become:

    123123123...
    456456456...
    789789789...
    
    4 votes
  6. Comment on Day 3: Toboggan Trajectory in ~comp.advent_of_code

    Bauke
    Link Parent
    If you try to open the puzzle input when you're not logged in, AoC says puzzle inputs do differ by user.

    I didn't know Advent of Code had multiple problem answers / puzzle inputs

    If you try to open the puzzle input when you're not logged in, AoC says puzzle inputs do differ by user.

    2 votes
  7. Comment on Day 3: Toboggan Trajectory in ~comp.advent_of_code

    Bauke
    (edited )
    Link
    Language: Rust. Repository. Main function (run harness). This one was pretty fun! While I was working out horizontal movement for the first part, I could smell vertical movement coming next, and...

    This one was pretty fun! While I was working out horizontal movement for the first part, I could smell vertical movement coming next, and sure enough it did. Thankfully all I had to add was a modulo check for the line number. :P

    Solution
    use crate::DayResult;
    
    const TREE: char = '#';
    
    pub(crate) fn solve(data: String) -> DayResult {
      let result_one = calculate(&data, (3, 1));
    
      let increments = vec![(1, 1), (3, 1), (5, 1), (7, 1), (1, 2)];
      let result_two = increments
        .iter()
        .map(|increment| calculate(&data, *increment))
        .product::<usize>();
    
      Ok((Some(result_one.to_string()), Some(result_two.to_string())))
    }
    
    fn calculate(data: &str, (horizontal, vertical): (usize, usize)) -> usize {
      let line_length = data.find('\n').unwrap();
      let mut result = 0;
    
      let mut x_position = 0;
      for (y_position, line) in data.lines().enumerate() {
        if y_position % vertical != 0 {
          continue;
        }
    
        if line.chars().nth(x_position) == Some(TREE) {
          result += 1;
        }
    
        x_position += horizontal;
        if x_position >= line_length {
          x_position -= line_length;
        }
      }
    
      result
    }
    
    Output
    🌟 Day 03  |
    🎆 Part 1  | 198
    🎇 Part 2  | 5140884672
    🌠 Runtime | 0.002815615 seconds
    
    3 votes
  8. Comment on I've created a temporary sub-group for Advent of Code 2020, subscribe if you're interested! in ~comp

    Bauke
    Link Parent
    Maybe that new Lua thing you added recently would be a neat place to add scraping (if that's even possible). :P

    Maybe that new Lua thing you added recently would be a neat place to add scraping (if that's even possible). :P

    2 votes
  9. Comment on Day 2: Password Philosophy in ~comp.advent_of_code

    Bauke
    Link
    Language: Rust. Repository. Main function (run harness). To parse the password policy from each line I went for a substring approach, going crazy with unwraps. Then, once I had all the policies...

    To parse the password policy from each line I went for a substring approach, going crazy with unwraps.

    Then, once I had all the policies parsed I used Rust's iterators and the filter() function to filter out the ones that don't match the specified conditions, and then just call count() to get the resulting amount of valid passwords.

    Part 2's logic comes out to an XOR check and when I was trying to write out the code for it, I must have entered like 6 different numbers in the puzzle answer before I got it right. I got myself so confused with how filter() worked and whether I was supposed to return true or false for it to work properly, and what needed to equal what in the actual XOR, but eventually I got it.

    Solution
    use anyhow::Result;
    
    #[derive(Debug)]
    struct Item {
      min: usize,
      max: usize,
      letter: String,
      password: String,
    }
    
    pub(crate) fn solve(data: String) -> Result<(Option<String>, Option<String>)> {
      let mut items = vec![];
    
      for line in data.lines() {
        let min = &line[0..line.find('-').unwrap()];
        let max = &line[line.find('-').unwrap() + 1..line.find(' ').unwrap()];
        let letter = &line[line.find(' ').unwrap() + 1..line.find(':').unwrap()];
        let password = &line[line.find(": ").unwrap() + 2..];
        items.push(Item {
          min: min.parse()?,
          max: max.parse()?,
          letter: letter.to_string(),
          password: password.to_string(),
        })
      }
    
      let result_one = items
        .iter()
        .filter(|item| item.password.matches(&item.letter).count() >= item.min)
        .filter(|item| item.password.matches(&item.letter).count() <= item.max)
        .count()
        .to_string();
    
      let result_two = items
        .iter()
        .filter(|item| {
          let letter = item.letter.chars().next();
          let target_one = item.password.chars().nth(item.min - 1);
          let target_two = item.password.chars().nth(item.max - 1);
          target_one != target_two && (target_one == letter || target_two == letter)
        })
        .count()
        .to_string();
    
      Ok((Some(result_one), Some(result_two)))
    }
    
    Output
    🌟 Day 02  |
    🎆 Part 1  | 638
    🎇 Part 2  | 699
    🌠 Runtime | 0.006969111 seconds
    
    4 votes
  10. Comment on Day 1: Report Repair in ~comp.advent_of_code

    Bauke
    Link
    Language: Rust. Repository. Main function (run harness). I don't think this needs much explanation, just iterate over all the numbers multiple times and check whether any combination of them...

    I don't think this needs much explanation, just iterate over all the numbers multiple times and check whether any combination of them equals 2020, and then of course multiply them to get the answer.

    One neat function I used to parse the input data to i32s was filter_map(). It filters out things that return None while also letting you map things to something else. So I try to parse each line of the data to an i32, converting the Result<T, E> to an Option<T> with ok() and then filter_map() does the rest. It's unnecessary when I know the input data is guaranteed to be completely valid i32s, but still a nice function to know about.

    Solution
    use anyhow::Result;
    
    pub(crate) fn solve(data: String) -> Result<(Option<String>, Option<String>)> {
      let target = 2020;
      let numbers = &data
        .lines()
        .filter_map(|v| v.parse().ok())
        .collect::<Vec<i32>>();
    
      let mut result_one = None;
      let mut result_two = None;
    
      'outer: for a in numbers {
        for b in numbers {
          if result_one.is_none() && a + b == target {
            result_one = Some((a * b).to_string());
          }
    
          for c in numbers {
            if result_two.is_none() && a + b + c == target {
              result_two = Some((a * b * c).to_string());
            }
    
            if result_one.is_some() && result_two.is_some() {
              break 'outer;
            }
          }
        }
      }
    
      Ok((result_one, result_two))
    }
    
    Output
    🌟 Day 01  |
    🎆 Part 1  | 605364
    🎇 Part 2  | 128397680
    🌠 Runtime | 0.045589815 seconds
    
    2 votes
  11. Comment on Day 1: Report Repair in ~comp.advent_of_code

    Bauke
    Link Parent
    Yep, still the same.

    Yep, still the same.

    1 vote
  12. Comment on Day 1: Report Repair in ~comp.advent_of_code

    Bauke
    Link
    @Deimos, the leaderboard link is still pointing to the 2019 AoC.

    @Deimos, the leaderboard link is still pointing to the 2019 AoC.

    1 vote
  13. Comment on Advent of Code 2020 has begun in ~comp.advent_of_code

    Bauke
    Link Parent
    I initially was going to do it like that too but figured I'd just use Rust's modules to separate everything instead, a bit less work than Cargo's workspaces. I figured making each day a function...

    I initially was going to do it like that too but figured I'd just use Rust's modules to separate everything instead, a bit less work than Cargo's workspaces. I figured making each day a function that returns its result would make it possible to output everything in a very clean way, as well as make it easy to run only the ones I'm developing, so that's what I did. 🌠

    I'd love to see your solutions to it as well, if you have them available anywhere. :D

    1 vote
  14. Comment on Advent of Code 2020 has begun in ~comp.advent_of_code

    Bauke
    (edited )
    Link
    I'll be attempting this year in Rust, hopefully I can make it all the way through. :P Old code moved to day 1 and day 2.

    I'll be attempting this year in Rust, hopefully I can make it all the way through. :P

    Old code moved to day 1 and day 2.

    4 votes
  15. Comment on Advent of Code 2020 has begun in ~comp.advent_of_code

    Bauke
    Link
    The private leaderboard I made last year is also still available, you can join it here with the following code 730956-de85ce0c.

    The private leaderboard I made last year is also still available, you can join it here with the following code 730956-de85ce0c.

    7 votes
  16. Comment on Mindustry 6.0 Released in ~games

    Bauke
    Link Parent
    I wrote a comment about Mindustry (and Shapez.io, funnily enough) a few months ago and you're pretty much right with the main focus being fighting enemies. You're defending your core which you...

    I wrote a comment about Mindustry (and Shapez.io, funnily enough) a few months ago and you're pretty much right with the main focus being fighting enemies.

    You're defending your core which you push resources into and use for building, and every 5 waves you have the chance to launch out of the level together with the resources you saved. You then use those resources to progress a tech tree and you can also use some of them in the next level, if you want to.

    It takes a bit to get through the tech tree but once you start unlocking some stuff it gets very crazy and a lot of fun.

    1 vote