Function aoc::y15d07::y15d07

source ·
pub fn y15d07(input: &str, wire: &str, part: u32) -> u16
Expand description

The solution for the day seven challenge.

We take the usual input argument as a string as well as an argument for the final wire signal that we’re interested in. The final argument is for part 1 (normal) or for part 2 (override the signal of wire b with the signal of wire a calculated in part one).

We start by parsing our input and creating our std::collections::HashMap that will store wires as keys and their signals as the values. If we’re in part two then we calculate the signal for wire a in part one and then assign it to wire b immediately. This works because we only set new values if they don’t exist (implemented during part one as it appeared that instructions could come out-of-order).

Now we start a loop that we’ll use to run over the input until we’ve accounted for all of the wires. Each iteration of the loop assumes that we’re done (so that it will exit when it’s done) and then if we make any changes (i.e., assign a signal to a wire) then we mark it as not done so that we run the loop again. This lets us process the input even if there are some wires that we can’t calculate yet because we don’t have all of their input values.

From here it’s pretty easy: figure out the wire to which we want to assign a signal (always the final component of the instruction) and if we’ve already assigned it a value then move on, otherwise figure out which operation we want to perform and perform it. If we haven’t calculated the signal for any of the inputs then we skip it and try to calculate it again when we come back around on the next loop iteration.

Finally, return the signal of the wire that we asked for as an argument.

N.B. the use of u16 is important as it’s specified in the prompt that the integers are 16-bit which changes the values when performing bitwise operations and shifts.

§Example

// probably read this from the input file...
let input = "12 -> c\n14 -> d\nc AND d -> b\nb -> a\n";
assert_eq!(y15d07(input, "a", 1), 12);
assert_eq!(y15d07(input, "a", 2), 12);