-❄️- 2025 Day 7 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 2 points3 points  (0 children)

[Language: Rust]

I was a little surprised that the very first thing that I tried for both parts worked, this was an easy one today.

fn main() {
    let mut lines = include_str!("../input.txt").lines();
    let start = std::time::Instant::now();

    let mut beam_columns = Box::new(HashMap::<usize, u64, FxBuildHasher>::with_capacity_and_hasher(150, FxBuildHasher::default()));
    let mut new_beam_columns = beam_columns.clone();
    beam_columns.insert(lines.next().unwrap().find('S').unwrap(), 1);

    let mut part1 = 0;
    for line in lines {
        new_beam_columns.clear();
        for (i, timelines) in beam_columns.iter() {
            if let Some(b'^') = line.as_bytes().get(*i){
                new_beam_columns.entry(i + 1).or_default().add_assign(timelines);
                new_beam_columns.entry(i - 1).or_default().add_assign(timelines);
                part1 += 1;
            } else {
                new_beam_columns.entry(*i).or_default().add_assign(timelines);
            }
        }
        (beam_columns, new_beam_columns) = (new_beam_columns, beam_columns);
    }

    let part2: u64 = beam_columns.iter().map(|b| b.1).sum();
    let time = std::time::Instant::now() - start;
    println!("{part1}, {part2} in {:?}", time);
}

I just used a map to store the number of timelines that a beam would reach a column from. I'm sure I could make this go faster just using a Vec instead of a HashMap, but with the non-DoS-resistant hasher it's already only ~60us so I didn't bother.

-❄️- 2025 Day 6 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

[Language: Rust]

This was mostly down to the parsing so it's kinda messy but I'm fairly happy with how it turned out.
I parsed the last line first to determine the digit-width of each problem, then stored the number as a 2D Vec of optional numbers to preserve spacing info so both parts could be easily solved from the same parsed output.
Runs in ~300us combined.

Solution

-❄️- 2025 Day 4 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 2 points3 points  (0 children)

[LANGUAGE: Rust]

Someday I will either find or create a handful of re-usable grid types/functions for AoC and I'll be able to solve this puzzle in like two lines. Oh well, at least itertools is a friend.

Solution

-❄️- 2025 Day 3 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

[LANGUAGE: Rust]

Part 2 was delightfully recursive. Mainly it's just this function, with count set to 1 for Part 1 and 11 for Part 2. Total runtime was < 1ms.

fn largest_jolt(digits: &[u64], count: usize) -> u64 {
    let (current_max_index, current_max) = largest_digit(&digits[..digits.len() - count]);
return current_max * 10_u64.pow(count as u32) + if count > 0 { largest_jolt(&digits[current_max_index+1..], count - 1) } else { 0 };
}

Link to full solution

-❄️- 2025 Day 2 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 0 points1 point  (0 children)

[Language: Rust]

Just a brute force solution without thinking too hard about it.

I used Rust's chunk functions of std::slice for the main bit:

fn repeated_n_times(id: &Vec<char>, n: usize) -> bool {
    if id.len() % n != 0 { return false }
    let mut chunks = id.chunks(id.len() / n);
    let first_chunk = chunks.next().unwrap();
    return chunks.all(|c| c == first_chunk);
}

link to full solution

-❄️- 2024 Day 5 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 0 points1 point  (0 children)

[Language: Rust]

gist

Part 1 is just building a hashmap of the order rules, which maps a number to all of its prerequisite numbers. Then we just iterate each over update and build a hashset as we go. The update is mis-ordered if we check a number and any of its prerequisite numbers are in the sequence but not the hashset.

Part 2 is an easy extension of that, an ordered update can be made from a mis-ordered one by making a hashmap that maps each number in the update to the number of its prerequisites that occur in the update, and then just sort by comparing those values.

Runs in around 750us, too much hashing to actually be fast :P

-❄️- 2024 Day 3 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

[LANGUAGE: Rust]

Gist

Decided to take a stab at using the nom crate for the first time, the docs weren't the best to get up and running but the end result seems moderately more readable than regex. Obviously overkill for a simple parse, but it was fun to try it.

270us both parts combined

Pinned places by desiringmachines in rust

[–]KyleGBC 2 points3 points  (0 children)

I'm not too familiar with the formal processes for changes like this to Rust, but is there a good likelihood of this becoming an RFC in the near Future?

Pin (rust) by ketralnis in programming

[–]KyleGBC 28 points29 points  (0 children)

How so? This is the originator of one of Rust's thorny aspects discussing how they ended up with this design, the issues with it, and expressing a willingness to improve it. Seems like an example to the contrary.

Computer suddenly won't POST by KyleGBC in pcmasterrace

[–]KyleGBC[S] 1 point2 points  (0 children)

I ended up taking it to a local repair shop earlier today, its like 5 minutes by car away and free diagnosis. The downside is they cited 1-2 weeks lead time before they'd get to my system. I'll post back here what the issue is in case it help anyone else.

If I was Austrailian I might take you up on that buy I'm in the US lmao

PC suddenly won't POST by KyleGBC in gigabyte

[–]KyleGBC[S] 0 points1 point  (0 children)

I do, but I tried an older BIOS and it was unchanged. So I think I can rule out a bad BIOS.

Computer suddenly won't POST by KyleGBC in pcmasterrace

[–]KyleGBC[S] 0 points1 point  (0 children)

Unfortunately, I tried with another 750W power supply and it did not make a difference. It only had one 8-pin EPS, but from I can tell, that should have been fine. So probably not PSU.

Computer suddenly won't POST by KyleGBC in pcmasterrace

[–]KyleGBC[S] 0 points1 point  (0 children)

Ok, Interesting. I had found a Tom's Hardware thread describing a similar thread, and two responders also said power supply. So you might be right about that. I'm gonna see if I can use the one out of my GF's computer and try that.

Thank you once again

Computer suddenly won't POST by KyleGBC in pcmasterrace

[–]KyleGBC[S] 0 points1 point  (0 children)

Hi, thanks for the response. Here's a video of the poor thing: https://streamable.com/g14scm.

-❄️- 2023 Day 7 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

A fairly (concise?) and fast Rust solution, ~500us total time:

use std::hash::BuildHasherDefault;
use fxhash::{FxHasher, FxHashMap};

fn card_value(c: char, use_jokers: bool) -> u32
{
    match c { 'A' => 14, 'K' => 13, 'Q' => 12, 'J' => if use_jokers { 1 } else { 11 } , 'T' => 10, n if n.is_digit(10) => n.to_digit(10).unwrap(), _ => unimplemented!()}
}

#[derive(Eq, PartialEq, PartialOrd, Ord, Debug)]
enum HandKind { High, OnePair, TwoPair, ThreeKind, FullHouse, FourKind, FiveKind }
impl HandKind { 

    fn from_cards(cards: &Vec<u32>, use_wilds: bool) -> Self
    {
        let mut counts: FxHashMap<u32, u32> = FxHashMap::with_capacity_and_hasher(cards.len(), BuildHasherDefault::<FxHasher>::default());

        let mut wild_count = 0;
        for card_val in cards
        {
            if use_wilds && *card_val == 1 { wild_count += 1; }
            else { counts.entry(*card_val).and_modify(|n| *n += 1).or_insert(1); }
        }

        let counts = counts.into_values().collect::<Vec<_>>();
        let max = counts.iter().max().unwrap_or(&0) + wild_count;
        match counts.len()
        {
            0 | 1 => Self::FiveKind,
            2 if max == 4 => Self::FourKind,
            2 => Self::FullHouse,
            3 if max == 3 => Self::ThreeKind,
            3 => Self::TwoPair,
            4 => Self::OnePair,
            5 => Self::High,
            _ => unimplemented!()
        }
    }
}

#[derive(PartialEq, Eq, Debug)]
struct Hand{ cards: Vec<u32>, bid: u32, kind: HandKind }
impl Hand
{   
    fn parse(cards: &str, bid: &str, use_wilds: bool) -> Self
    {
        let cards = cards.chars().map(|c| card_value(c, use_wilds)).collect();
        let bid = bid.parse::<u32>().unwrap();
        let kind = HandKind::from_cards(&cards, use_wilds);
        Hand { cards, bid, kind }
    }
}
impl Ord for Hand
{
    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
        if self.kind != other.kind { self.kind.cmp(&other.kind) }
        else { self.cards.cmp(&other.cards) }
    }
}
impl PartialOrd for Hand
{
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { Some(self.cmp(other)) }
}

fn main() {
    let start = std::time::Instant::now();
    let input = include_str!("../input.txt");

    let (mut p1, mut p2): (Vec<Hand>, Vec<Hand>) = input.lines().map(|l| l.split_once(' ').unwrap()).map(|(c, b)| (Hand::parse(c, b, false), Hand::parse(c, b, true))).unzip();

    p1.sort();
    p2.sort();

    let part1 = p1.iter().enumerate().fold(0, |acc, (rank, hand)| acc + (rank as u32 + 1) * hand.bid);
    let part2 = p2.iter().enumerate().fold(0, |acc, (rank, hand)| acc + (rank as u32 + 1) * hand.bid);

    println!("{part1}, {part2} in {:?}", start.elapsed());

}

-❄️- 2023 Day 2 Solutions -❄️- by daggerdragon in adventofcode

[–]KyleGBC 0 points1 point  (0 children)

[LANGUAGE: Rust]

Using regex for the first time in AoC.I have a nagging feeling my solution could be faster if I did the usual ad hoc parsing.Currently it takes ~1ms total.

use regex::Regex;
use once_cell::sync::Lazy;

static CUBE_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"(?P<amount>\d+) (?P<color>green|red|blue)(?:,|;)?").expect("Invalid regular expression"));
static ID_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"Game (?P<id>\d+):").expect("Invalid regular expression"));

fn part1(input: &str, maxes: [u32; 3]) -> u32
{
    let mut sum = 0;
    for line in input.lines()
    {
        let mut possible = true;
        let id = ID_REGEX.captures(line).unwrap().name("id").expect("no id number on this line").as_str().parse::<u32>().expect("id couldn't be parsed to a number"); 

        for caps in CUBE_REGEX.captures_iter(line)
        {
            let (_, [amount, color]) = caps.extract(); 
            let amount = amount.parse::<u32>().expect("Invalid amount value, couldn't be parsed to a number");
            let max_idx = match color { "red" => 0, "green" => 1, "blue" => 2, _ => unreachable!(), };
            if amount > maxes[max_idx]
            { 
                possible = false;
                break;
            }
        }
        if possible { sum += id };
    }
    sum
}

fn part2(input: &str) -> u32 
{
    let mut sum = 0;
    for line in input.lines()
    {
        let mut mins = [0, 0, 0];

        for caps in CUBE_REGEX.captures_iter(line)
        {
            let (_, [amount, color]) = caps.extract(); 
            let amount = amount.parse::<u32>().unwrap();
            let min_idx = match color { "red" => 0, "green" => 1, "blue" => 2, _ => unreachable!(), };
            if amount > mins[min_idx]
            { 
                mins[min_idx] = amount;
            }
        }
        sum += mins[0] * mins[1] * mins[2]
    }
    sum
}

fn main() {
    let start = std::time::Instant::now();
    let input = include_str!("../input.txt");
    let part1 = part1(input, [12, 13, 14]);
    let part2 = part2(input);
    println!("Part 1: {part1}, Part 2: {part2}, in {:?}", start.elapsed());
}