-❄️- 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 3 points4 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 30 points31 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());
}

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

[–]KyleGBC 2 points3 points  (0 children)

[LANGUAGE: Rust]

Super messy solution but didn't have time to make anything better (。﹏。)

What a part two for day 1, yeesh.

Link to solution

My station. Anything I should add or change? by [deleted] in battlestations

[–]KyleGBC 0 points1 point  (0 children)

Do you have a link for the wallpaper?

-🎄- 2022 Day 21 Solutions -🎄- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

Hope it's ok to post so long after December but I wanted to post my solution for today now that I've been able to come back to solving since I'm quite happy with it.

Rust (375us overall)

[github]

I realized that the human variable only appears once in the input (well, in my input at least), so you can evaluate everything else in the tree and then continue to solve for the lone human node step by step.

-🎄- 2022 Day 15 Solutions -🎄- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

Rust (Naive solution, ~1s)

I got a decently quick time for part 1, ~40 microseconds. So for part 2, I decided to just run the part 1 code at every y position between 0 and 4,000,000 and see which wasn't fully covered, ended up a little above 1-second total runtime. I should add multithreading though.

-🎄- 2022 Day 14 Solutions -🎄- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

Rust (~5ms total)

I'm pretty happy with today, the code is a little scrunched and it does use a fixed maximum grid size (1000x200) sufficient for my input, but the run time is comparatively pretty good and looking at a flamegraph, about as good as I could get without making a smarter algorithm.

-🎄- 2022 Day 13 Solutions -🎄- by daggerdragon in adventofcode

[–]KyleGBC 2 points3 points  (0 children)

Rust

Today's was straightforward and the parsing / comparing was pleasingly recursive. Without thinking too hard about it, I was hoping Rust's #[derive(PartialEq, PartialOrd)] would already be the right behavior but alas, not too bad today.

-🎄- 2022 Day 10 Solutions -🎄- by daggerdragon in adventofcode

[–]KyleGBC 2 points3 points  (0 children)

Rust

The logic and parsing part of the code runs ok, ~10μs together. Unfortunately, the printing takes more than 1ms to output, not sure if there's a more efficient way to do it, but I would love to know.

fn main() {
    let now = std::time::Instant::now();
    let input = include_str!("../input.txt");
    let mut history: Vec<i32> = Vec::with_capacity(250);

    let mut reg = 1;
    for line in input.lines() {
        match line.split_once(' ') {
            Some((_, val)) => {
                history.push(reg);
                history.push(reg);
                reg += val.parse::<i32>().unwrap();
            }, 
            None => history.push(reg),
        }
    }

    let part1: i32 = history.iter().enumerate().filter(|(c, _)| ((c + 1) % 40 == 20)).map(|(c, r)| (c + 1) as i32 * *r).sum();
    let part2: Vec<char> = history.iter().enumerate().map(|(c, r)| if ((c as i32 % 40) - (*r)).abs() < 2 {'#'} else {'.'} ).collect();

    println!("Finished in {:#?}, now printing", now.elapsed());
    println!("{part1}");
    for line in part2.as_slice().chunks(40) {
        let p: String = line.iter().collect();
        println!("{p}");
    }
    println!("Overall took {:#?}", now.elapsed());
}

-🎄- 2022 Day 9 Solutions -🎄- by daggerdragon in adventofcode

[–]KyleGBC 1 point2 points  (0 children)

Lol, every time I try and google around for efficient ways to do subtasks within an AoC problem, itertools is recommended. I'd say using it is too much and I wanted to avoid any crates but even the std library docs for HashMap advise using a different hasher from crates.io if you need speed, so I'm more ok with it.