2024 Day 24 Spelling, Indentation, and Doc comments
This commit is contained in:
parent
ababfcf16e
commit
0305b7caf0
1 changed files with 75 additions and 65 deletions
|
@ -193,10 +193,14 @@ fn is_loop_free(&self, name: &str, previous: &HashSet<&str>) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
/// Determines if the `idx`th least significant bit of z can be traced to input bits (x and y)
|
||||
/// on all paths (returning `true`), or if they form a loop (returning `false`).
|
||||
fn output_is_loop_free(&self, idx: usize) -> bool {
|
||||
self.is_loop_free(&Self::output_gate(idx)[..], &HashSet::new())
|
||||
}
|
||||
|
||||
/// Checks if the rightmost `z_idx` bits of z behave like an adder. Returns `None`, if they do,
|
||||
/// and `Some(idx)` otherwise, where `idx` is the first bit (from the right), which differs.
|
||||
fn check_until(&mut self, z_idx: usize) -> Option<usize> {
|
||||
let tests_0 = [(0, 0), (0, 1), (1, 0), (1, 1)];
|
||||
if tests_0.iter().any(|(l, r)| {
|
||||
|
@ -226,6 +230,9 @@ fn is_loop_free(&self, name: &str, previous: &HashSet<&str>) -> bool {
|
|||
})
|
||||
}
|
||||
|
||||
/// Try swapping all combinations of two gates, where at least one of them is contained in
|
||||
/// `must_include` and none of them in `swapped_before` and determine if their swap results in
|
||||
/// the rightmost `z_idx` bits of z are correct. Returns an unsorted Vec of all such pairs.
|
||||
fn try_swaps(&'a mut self, z_idx: usize, must_include: &[&'a str], swapped_before: &[&'a str]) -> Vec<Vec<String>> {
|
||||
let mut res = Vec::new();
|
||||
// We need to clone these so the borrow checker won't complain about concurrent borrows in the
|
||||
|
@ -237,7 +244,7 @@ fn is_loop_free(&self, name: &str, previous: &HashSet<&str>) -> bool {
|
|||
if swapped_before.contains(&gate_1) {
|
||||
continue;
|
||||
}
|
||||
// The unwrap()s below are safe because the constructor made shure all gates exist.
|
||||
// The unwrap()s below are safe because the constructor made sure all gates exist.
|
||||
let inputs_1 = *self.gates.get(gate_1).unwrap();
|
||||
for &gate_2 in all_inputs.iter().filter(|&&gate_2|
|
||||
gate_2 != gate_1 &&
|
||||
|
@ -256,6 +263,9 @@ fn is_loop_free(&self, name: &str, previous: &HashSet<&str>) -> bool {
|
|||
res
|
||||
}
|
||||
|
||||
/// Find the necessary (up to 8) swaps to turn this device into a binary adder.
|
||||
/// `swapped_before` contains the swaps already established (this should be an empty array at
|
||||
/// first). Returns a `Vec` of the affected gates, sorted alphabetically.
|
||||
fn swap_gates(&mut self, swapped_before: &[String]) -> Vec<String> {
|
||||
let mut swaps_performed = swapped_before.to_vec();
|
||||
loop {
|
||||
|
@ -266,7 +276,7 @@ fn swap_gates(&mut self, swapped_before: &[String]) -> Vec<String> {
|
|||
let mut next = self.clone();
|
||||
let new_possible_swaps = next.try_swaps(next_error, &must_include, &swapped_before);
|
||||
match new_possible_swaps.len() {
|
||||
// The unwrap()s below are safe because the constructor made shure all gates exist.
|
||||
// The unwrap()s below are safe because the constructor made sure all gates exist.
|
||||
0 => return Vec::new(), // If we found no solution, return early
|
||||
1 => {
|
||||
// We found one solution. Continue with it.
|
||||
|
@ -280,8 +290,8 @@ fn swap_gates(&mut self, swapped_before: &[String]) -> Vec<String> {
|
|||
}
|
||||
},
|
||||
_ => {
|
||||
// We found more than one solution. Spawn a new Device for each and try
|
||||
// them all.
|
||||
// We found more than one solution.
|
||||
// Spawn a new Device for each and try them all.
|
||||
for swaps in new_possible_swaps {
|
||||
if swaps.len() + swaps_performed.len() > 8 {
|
||||
continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue