tangled
alpha
login
or
join now
nove.dev
/
aoc-2024
0
fork
atom
retroactive, to derust my rust
0
fork
atom
overview
issues
pulls
pipelines
day9 part2
nove.dev
3 months ago
0f40f2ec
1310e988
+95
-14
2 changed files
expand all
collapse all
unified
split
src
day9.rs
lib.rs
+88
-7
src/day9.rs
···
2
let diskmap = parse(input);
3
let mut blocks = diskmap_to_blocks(&diskmap);
4
compact(&mut blocks);
5
-
let sum = blocks
6
-
.into_iter()
7
-
.flatten()
8
-
.enumerate()
9
-
.map(|(index, block)| index as u64 * block)
10
-
.sum::<u64>();
11
sum.to_string()
12
}
13
14
pub fn day9_part2(input: &str) -> String {
15
-
todo!()
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
16
}
17
18
fn diskmap_to_blocks(diskmap: &[usize]) -> Vec<Option<u64>> {
···
2
let diskmap = parse(input);
3
let mut blocks = diskmap_to_blocks(&diskmap);
4
compact(&mut blocks);
5
+
let sum = checksum(&blocks);
0
0
0
0
0
6
sum.to_string()
7
}
8
9
pub fn day9_part2(input: &str) -> String {
10
+
let diskmap = parse(input);
11
+
let compacted_diskmap = defrag_compact(&diskmap);
12
+
let blocks = compacted_diskmap_to_blocks(&compacted_diskmap);
13
+
let sum = checksum(&blocks);
14
+
sum.to_string()
15
+
}
16
+
17
+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
18
+
struct File {
19
+
id: u64,
20
+
length: usize,
21
+
free_space: usize,
22
+
}
23
+
24
+
fn compacted_diskmap_to_blocks(compacted_diskmap: &[File]) -> Vec<Option<u64>> {
25
+
compacted_diskmap
26
+
.iter()
27
+
.flat_map(|file| {
28
+
[
29
+
vec![Some(file.id); file.length],
30
+
vec![None; file.free_space],
31
+
]
32
+
})
33
+
.flatten()
34
+
.collect()
35
+
}
36
+
37
+
fn defrag_compact(diskmap: &[usize]) -> Vec<File> {
38
+
let files = diskmap_to_files(diskmap);
39
+
let mut compacted_files = files.clone();
40
+
41
+
for file in files.clone().into_iter().rev() {
42
+
let Some(insertable_index) = compacted_files
43
+
.iter()
44
+
.enumerate()
45
+
.find(|(_, insertable_file)| insertable_file.free_space >= file.length)
46
+
.map(|(i, _)| i)
47
+
else {
48
+
continue;
49
+
};
50
+
51
+
let prev_free_space = compacted_files[insertable_index].free_space;
52
+
compacted_files[insertable_index].free_space = 0;
53
+
compacted_files.insert(insertable_index + 1, file);
54
+
compacted_files[insertable_index + 1].free_space = prev_free_space - file.length;
55
+
56
+
let nullable_index = compacted_files
57
+
.iter()
58
+
.enumerate()
59
+
.rev()
60
+
.find(|(_, nullable_file)| nullable_file.id == file.id)
61
+
.map(|(i, _)| i)
62
+
.unwrap();
63
+
compacted_files[nullable_index - 1].free_space +=
64
+
compacted_files[nullable_index].length + compacted_files[nullable_index].free_space;
65
+
compacted_files.remove(nullable_index);
66
+
}
67
+
68
+
compacted_files
69
+
}
70
+
71
+
fn diskmap_to_files(diskmap: &[usize]) -> Vec<File> {
72
+
let mut id = 0u64;
73
+
let mut blocks = vec![];
74
+
75
+
for digit in diskmap {
76
+
if id % 2 == 0 {
77
+
blocks.push(File {
78
+
id: id / 2,
79
+
length: *digit,
80
+
free_space: 0,
81
+
});
82
+
} else {
83
+
blocks.last_mut().unwrap().free_space = *digit;
84
+
}
85
+
id += 1
86
+
}
87
+
88
+
blocks
89
+
}
90
+
91
+
fn checksum(blocks: &[Option<u64>]) -> u64 {
92
+
blocks
93
+
.iter()
94
+
.enumerate()
95
+
.map(|(index, block)| if let Some(block) = block {index as u64 * block} else {0})
96
+
.sum::<u64>()
97
}
98
99
fn diskmap_to_blocks(diskmap: &[usize]) -> Vec<Option<u64>> {
+7
-7
src/lib.rs
···
357
let result = day9::day9_part1(include_str!("../input/day9.txt"));
358
assert_eq!(result, "6448989155953");
359
}
360
-
// #[test]
361
-
// fn day9_part2_test() {
362
-
// let test_result = day9::day9_part2(include_str!("../input/day9.test.txt"));
363
-
// assert_eq!(test_result, "34");
364
-
// // let result = day9::day9_part2(include_str!("../input/day9.txt"));
365
-
// // assert_eq!(result, "1169");
366
-
// }
367
368
#[test]
369
fn day8_part1_test() {
···
357
let result = day9::day9_part1(include_str!("../input/day9.txt"));
358
assert_eq!(result, "6448989155953");
359
}
360
+
#[test]
361
+
fn day9_part2_test() {
362
+
let test_result = day9::day9_part2(include_str!("../input/day9.test.txt"));
363
+
assert_eq!(test_result, "2858");
364
+
let result = day9::day9_part2(include_str!("../input/day9.txt"));
365
+
assert_eq!(result, "6476642796832");
366
+
}
367
368
#[test]
369
fn day8_part1_test() {