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