[TASK] Solved Day 10 (finally)

This commit is contained in:
2020-12-10 21:25:31 +01:00
parent e053e4ed61
commit 921039f07e
4 changed files with 252 additions and 1 deletions

92
input/day10.txt Normal file
View File

@@ -0,0 +1,92 @@
56
139
42
28
3
87
142
57
147
6
117
95
2
112
107
54
146
104
40
26
136
127
111
47
8
24
13
92
18
130
141
37
81
148
31
62
50
80
91
33
77
1
96
100
9
120
27
97
60
102
25
83
55
118
19
113
49
133
14
119
88
124
110
145
65
21
7
74
72
61
103
20
41
53
32
44
10
34
121
114
67
69
66
82
101
68
84
48
73
17
43
140

11
input/day10_example.txt Normal file
View File

@@ -0,0 +1,11 @@
16
10
15
5
1
11
7
19
6
12
4

146
src/day10.rs Normal file
View File

@@ -0,0 +1,146 @@
use super::util;
pub fn solve() {
let lines = util::read_file("input/day10.txt");
let mut adapters = lines.iter().map(|s| s.parse::<u32>().unwrap()).collect::<Vec<_>>();
adapters.sort();
let diffs = count_diffs(&adapters);
println!("{:?}", diffs);
let part1 = (diffs[0] + 1) * (diffs[2] + 1);
println!("Day 10 Part 1: {}", part1);
// Time for some dynamic programming!
let device_jolt = adapters.last().unwrap() + 3;
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();
println!("Day 10 Part 2: {}", part2);
}
fn count_diffs(adapters: &Vec<u32>) -> Vec<usize> {
let mut res = vec!(0,0,0);
for i in 1..adapters.len() {
res[(adapters[i] - adapters[i-1] - 1) as usize] += 1;
}
return res;
}
fn count_arrangements(adapters: &Vec<u32>, start_idx: usize, end_idx: usize, solution_grid: &mut Grid) -> i64 {
if start_idx > end_idx {
panic!("Invalid range?")
}
let start = adapters[start_idx];
let end = adapters[end_idx];
let cached = solution_grid.get(start_idx, end_idx);
if cached != -1 {
return cached;
}
let mut res = 0;
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??")
}
} 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);
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);
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!();
}
}
}

View File

@@ -11,8 +11,9 @@ mod day6;
mod day7;
mod day8;
mod day9;
mod day10;
const MAX_DAY: u8 = 9;
const MAX_DAY: u8 = 10;
const BENCHMARK_AMOUNT: u32 = 100;
fn solve(day: u8) {
@@ -26,6 +27,7 @@ fn solve(day: u8) {
7 => day7::solve(),
8 => day8::solve(),
9 => day9::solve(),
10 => day10::solve(),
_ => println!("This day is not yet implemented")
}
}