Shriram Balaji's Blog

Shriram Balaji's Blog

Rust Advent of Code 2020 - Day 10

Rust Advent of Code 2020 - Day 10

Subscribe to my newsletter and never miss my upcoming articles

Hello! We're on Day 10 of Advent of Code 2020.

Spoilers Ahead! The full solution to the problem is available here.

Problem - Part 01

Given a list of adapters marked with different joltages (akin to voltages in the real-world), find a chain of all of your adapters to connect them to your device which supports any adapter with a range -3 <= joltage <= 3, and connect the device with the adapter to a charger outlet (marked as 0J). Once you find the chain, count the number of joltages with 1 / 3 as difference

Although the problem sounds too wordy, the main idea behind it is to change uniquely identify a list of adapters, that have + or - 3 less than or greater than a specified target joltage. Once we have that we can calculate the adapters with the right difference in joltage.

Let's create a way to count and hold the joltage differences.

struct JoltageDifference {
    one: u64,
    two: u64,
    three: u64,
}

Alright, now that we have a way to store the differences let's write a function to get count of all the adapter differences from the target device joltage.

fn get_joltage_differences(device_joltage: u64, adapters: &Vec<u64>) -> JoltageDifference {
    let mut difference = JoltageDifference {
        one: 1,
        two: 1,
        three: 1,
    };

    // we use a hashset to keep track of unique joltages here
    let joltages: HashSet<u64> = HashSet::from_iter(adapters.clone());

    // we also need to keep track of whether an adapter was used before, to ensure that we don't reuse an adapter and form a chain of adapters.
    let mut used_adapters: HashSet<u64> = HashSet::new();


    let mut use_joltage_adapter = |joltage: u64, supported_difference: u64| {
        let target = &(joltage + supported_difference);
        // Check if the target joltage is part of the input, and if it has not already been used before, and if the it lies within the range of supported_difference from target joltage
        let is_compatible = joltages.contains(target)
            && !used_adapters.contains(&joltage)
            && *target <= device_joltage;
        if is_compatible {
            used_adapters.insert(joltage);
            match increment {
                1 => difference.one += 1,
                2 => difference.two += 1,
                3 => difference.three += 1,
                _ => {}
            }
        }
    };

    // count all adapters with 1, 2 and 3 difference from the current joltage
    for joltage in &joltages {
        use_joltage_adapter(*joltage, 1);
        use_joltage_adapter(*joltage, 2);
        use_joltage_adapter(*joltage, 3);
    }

    return difference;
}

From the problem it is also mentioned that the target device voltage is +3 of the max joltage adapter.

fn get_input_device_joltage(joltages: &Vec<u64>) -> u64 {
    let max_joltage = joltages.iter().max().unwrap();
    return max_joltage + 3;
}

To get the answer for Part 01 of our puzzle, we need to call these functions and find the count joltages with difference of 1 and 3 respectively.

    let device_joltage = get_input_device_joltage(&adapters);
    let differences = get_joltage_differences(device_joltage, &adapters);

    println!(
        "There are {} differences by 1 jolts and {} differences by 3 jolts",
        differences.one, differences.three
    );

Part 02 Coming Soon. Stay tuned!

#rust
 
Share this