[TASK] Solved Day 10 (finally)
This commit is contained in:
92
input/day10.txt
Normal file
92
input/day10.txt
Normal 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
11
input/day10_example.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
16
|
||||||
|
10
|
||||||
|
15
|
||||||
|
5
|
||||||
|
1
|
||||||
|
11
|
||||||
|
7
|
||||||
|
19
|
||||||
|
6
|
||||||
|
12
|
||||||
|
4
|
||||||
146
src/day10.rs
Normal file
146
src/day10.rs
Normal 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!();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,8 +11,9 @@ mod day6;
|
|||||||
mod day7;
|
mod day7;
|
||||||
mod day8;
|
mod day8;
|
||||||
mod day9;
|
mod day9;
|
||||||
|
mod day10;
|
||||||
|
|
||||||
const MAX_DAY: u8 = 9;
|
const MAX_DAY: u8 = 10;
|
||||||
const BENCHMARK_AMOUNT: u32 = 100;
|
const BENCHMARK_AMOUNT: u32 = 100;
|
||||||
|
|
||||||
fn solve(day: u8) {
|
fn solve(day: u8) {
|
||||||
@@ -26,6 +27,7 @@ fn solve(day: u8) {
|
|||||||
7 => day7::solve(),
|
7 => day7::solve(),
|
||||||
8 => day8::solve(),
|
8 => day8::solve(),
|
||||||
9 => day9::solve(),
|
9 => day9::solve(),
|
||||||
|
10 => day10::solve(),
|
||||||
_ => println!("This day is not yet implemented")
|
_ => println!("This day is not yet implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user