[TASK] Cleaned up the Day 10 code (no need for 2D array, removed commented out code, using bitshift instead of switch/case)

This commit is contained in:
2020-12-10 21:36:00 +01:00
parent 921039f07e
commit 7910024d93

View File

@@ -17,9 +17,8 @@ pub fn solve() {
adapters.insert(0, 0);
adapters.push(device_jolt);
let mut solution_grid = Grid::init(-1, adapters.len(), adapters.len());
let part2 = count_arrangements(&adapters, 0, adapters.len() - 1, &mut solution_grid);
// solution_grid.print();
let mut solutions_from_idx_to_end = vec!(-1; adapters.len());
let part2 = count_arrangements(&adapters, 0, adapters.len() - 1, &mut solutions_from_idx_to_end);
println!("Day 10 Part 2: {}", part2);
}
@@ -34,7 +33,7 @@ fn count_diffs(adapters: &Vec<u32>) -> Vec<usize> {
}
fn count_arrangements(adapters: &Vec<u32>, start_idx: usize, end_idx: usize, solution_grid: &mut Grid) -> i64 {
fn count_arrangements(adapters: &Vec<u32>, start_idx: usize, end_idx: usize, solution_cache: &mut Vec<i64>) -> i64 {
if start_idx > end_idx {
panic!("Invalid range?")
@@ -43,7 +42,7 @@ fn count_arrangements(adapters: &Vec<u32>, start_idx: usize, end_idx: usize, sol
let start = adapters[start_idx];
let end = adapters[end_idx];
let cached = solution_grid.get(start_idx, end_idx);
let cached = solution_cache[start_idx];
if cached != -1 {
return cached;
}
@@ -52,95 +51,30 @@ fn count_arrangements(adapters: &Vec<u32>, start_idx: usize, end_idx: usize, sol
if end - start <= 3 {
res = match end_idx - start_idx {
0 => 1, // Start == End, and the adapter exists, so 1 way to arrange it
1 => 1, // There are no adapters between the start and the end, there is only 1 way to arrange them
2 => 2, // There is 1 adapter between the start and the end, that we can either include or not
3 => 4, // There are 2 adapters between start and end. So we can include them both, either one of them, or none of them
_ => panic!("More adapters between start and end then expected??")
}
// match end_idx - start_idx
// 0 -> 1: Start == End, and the adapter exists, so 1 way to arrange it
// 1 -> 1: There are no adapters between the start and the end, there is only 1 way to arrange them
// 1 -> 2: There is 1 adapter between the start and the end, that we can either include or not
// 2 -> 4: There are 2 adapters between start and end. So we can include them both, either one of them, or none of them
res = if end == start { 1 } else { 1 << (end - start - 1) }
} else {
let mut next_start_idx = start_idx + 1;
let mut next_start = adapters[next_start_idx];
while next_start <= start + 3 {
// We can either try to include the adapter at next_start_idx, or not:
res += count_arrangements(adapters, next_start_idx, end_idx, solution_grid);
res += count_arrangements(adapters, next_start_idx, end_idx, solution_cache);
next_start_idx += 1;
next_start = adapters[next_start_idx];
}
}
// if end - start <= 3 {
//
// let start_adapter_idx = adapters.binary_search(&start);
// let end_adapter_idx = adapters.binary_search(&end);
//
// if start_adapter_idx.is_err() || end_adapter_idx.is_err() {
// res = 0;
// } else {
// res = match end_adapter_idx.unwrap() - start_adapter_idx.unwrap() {
// 0 => 1, // Start == End, and the adapter exists, so 1 way to arrange it
// 1 => 1, // There are no adapters between the start and the end, there is only 1 way to arrange them
// 2 => 2, // There is 1 adapter between the start and the end, that we can either include or not
// 3 => 4, // There are 2 adapters between start and end. So we can include them both, either one of them, or none of them
// _ => panic!("More adapters between start and end then expected??")
// }
// }
//
// } else {
// for last_diff in 1..4 {
//
// let split = end - last_diff;
// let split1 = count_arrangements(&adapters, start, split, solution_grid);
// if split1 == 0 { continue; }
// let split2 = count_arrangements(&adapters, split, end, solution_grid);
// println!("From start {} to split {}: {}, from split {} to end {}: {}", start, split, split1, split, end, split2);
// res += split1 * split2;
// }
// }
solution_grid.set(start_idx, end_idx, res);
solution_cache[start_idx] = res;
return res;
}
struct Grid {
matrix: Vec<i64>,
width: usize,
height: usize
}
impl Grid {
fn init(default: i64, width: usize, height: usize) -> Grid {
return Grid {
matrix: vec!(default; width * height),
width,
height
}
}
fn get(&self, x: usize, y: usize) -> i64 {
return self.matrix[x + y * self.width];
}
fn set(&mut self, x: usize, y: usize, val: i64) {
self.matrix[x + y * self.width] = val;
}
fn print(&self) {
for y in 0..self.height {
for x in 0..self.width {
print!(" {:>4}", self.get(x, y));
}
println!();
}
}
}