Skip to content

Commit 564bcba

Browse files
committed
Faster day 9
1 parent 3d61f8a commit 564bcba

File tree

2 files changed

+33
-56
lines changed

2 files changed

+33
-56
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
1919
| [Day 6](./src/bin/06.rs) | `48.5µs` | `4.2ms` |
2020
| [Day 7](./src/bin/07.rs) | `316.2µs` | `319.6µs` |
2121
| [Day 8](./src/bin/08.rs) | `7.4µs` | `15.5µs` |
22-
| [Day 9](./src/bin/09.rs) | `157.2µs` | `2.0ms` |
22+
| [Day 9](./src/bin/09.rs) | `152.3µs` | `141.1µs` |
2323
| [Day 10](./src/bin/10.rs) | `31.1µs` | `28.6µs` |
2424
| [Day 11](./src/bin/11.rs) | `71.0µs` | `766.0µs` |
2525
| [Day 12](./src/bin/12.rs) | `434.7µs` | `674.6µs` |
@@ -28,7 +28,7 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
2828
| [Day 15](./src/bin/15.rs) | `119.7µs` | `591.0µs` |
2929
| [Day 16](./src/bin/16.rs) | `158.9µs` | `202.6µs` |
3030

31-
**Total: 14.95ms**
31+
**Total: 13.08ms**
3232
<!--- benchmarking table --->
3333

3434
---

src/bin/09.rs

Lines changed: 31 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ advent_of_code::solution!(9);
44

55
#[derive(Debug, Clone)]
66
struct Block {
7+
start_idx: usize,
78
length: u32,
89
file_id: Option<u32>,
910
}
@@ -19,10 +20,12 @@ impl Block {
1920
} else {
2021
(
2122
Block {
22-
length: length,
23+
start_idx: self.start_idx,
24+
length,
2325
file_id: self.file_id,
2426
},
2527
Some(Block {
28+
start_idx: self.start_idx + length as usize,
2629
length: self.length - length,
2730
file_id: self.file_id,
2831
}),
@@ -31,36 +34,6 @@ impl Block {
3134
}
3235
}
3336

34-
// struct BlocksFmt<'a>(&'a Vec<Block>);
35-
36-
// impl Debug for BlocksFmt<'_> {
37-
// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38-
// for block in self.0 {
39-
// for _ in 0..block.length {
40-
// match block.file_id {
41-
// Some(id) => write!(f, "{}", id)?,
42-
// None => write!(f, ".")?,
43-
// }
44-
// }
45-
// }
46-
// Ok(())
47-
// }
48-
// }
49-
50-
fn checksum(blocks: &Vec<Block>) -> u64 {
51-
let mut sum: u64 = 0;
52-
let mut idx = 0;
53-
for block in blocks {
54-
for _ in 0..block.length {
55-
if let Some(file_id) = block.file_id {
56-
sum += idx * (file_id as u64);
57-
}
58-
idx += 1;
59-
}
60-
}
61-
sum
62-
}
63-
6437
fn parse_blocks(input: &str) -> Vec<Block> {
6538
let nums = input
6639
.chars()
@@ -69,6 +42,7 @@ fn parse_blocks(input: &str) -> Vec<Block> {
6942
.map(|r| r.unwrap());
7043

7144
let mut blocks = Vec::with_capacity(1000);
45+
let mut idx = 0;
7246
for (i, num) in nums.enumerate() {
7347
let file_id = if i % 2 == 0 {
7448
Some((i / 2) as u32)
@@ -81,11 +55,13 @@ fn parse_blocks(input: &str) -> Vec<Block> {
8155
}
8256

8357
let b = Block {
58+
start_idx: idx,
8459
file_id,
8560
length: num,
8661
};
8762

8863
blocks.push(b);
64+
idx += num as usize;
8965
}
9066

9167
blocks
@@ -149,11 +125,15 @@ pub fn part_two(input: &str) -> Option<u64> {
149125
spaces_block_indices_by_size[b.length as usize].push(i);
150126
});
151127

152-
let mut right_block_idx = blocks.len() - 1;
153-
while right_block_idx > 0 {
128+
let mut checksum = 0;
129+
130+
for right_block_idx in (0..blocks.len()).rev() {
154131
let right_block = &blocks[right_block_idx].clone();
155132
if right_block.is_free() {
156-
right_block_idx -= 1;
133+
continue;
134+
}
135+
136+
if right_block.length == 0 {
157137
continue;
158138
}
159139

@@ -167,50 +147,47 @@ pub fn part_two(input: &str) -> Option<u64> {
167147
}
168148
}
169149

150+
// can't move the file, so just add to the checksum
170151
if best_free_space_block_idx == usize::MAX {
171-
right_block_idx -= 1;
152+
checksum += (0..right_block.length as u64)
153+
.map(|i| (right_block.start_idx as u64 + i))
154+
.sum::<u64>()
155+
* right_block.file_id.unwrap() as u64;
172156
continue;
173157
}
174158

175159
let left_block_idx = best_free_space_block_idx;
176-
let left_block = &blocks[left_block_idx];
160+
let left_block = &blocks[left_block_idx].clone();
177161
spaces_block_indices_by_size[left_block.length as usize].pop();
178162

179163
let (_, maybe_left_additional_space) = left_block.split(right_block.length);
180164
if let Some(left_additional_space) = maybe_left_additional_space {
181-
let new_idx = left_block_idx + 1;
182-
blocks.insert(left_block_idx, right_block.clone());
183-
184-
// shift all the indices that are greater than the left block index
185-
spaces_block_indices_by_size
186-
.iter_mut()
187-
.flat_map(|space_list| space_list.iter_mut())
188-
.filter(|idx| **idx > left_block_idx)
189-
.for_each(|idx| *idx += 1);
190-
191165
// add the new space to the list
192166
let space_list =
193167
&mut spaces_block_indices_by_size[left_additional_space.length as usize];
194168
let mut insert_idx = space_list.len();
195169
for i in (0..space_list.len()).rev() {
196-
if space_list[i] > new_idx {
170+
if space_list[i] > left_block_idx {
197171
break;
198172
}
199173
insert_idx = i;
200174
}
201-
space_list.insert(insert_idx, new_idx);
175+
space_list.insert(insert_idx, left_block_idx);
202176

203-
blocks[new_idx] = left_additional_space;
204-
right_block_idx += 1;
177+
blocks[left_block_idx] = left_additional_space;
205178
} else {
206-
blocks[left_block_idx] = right_block.clone();
179+
blocks[left_block_idx].length = 0;
207180
}
208181

209-
blocks[right_block_idx].file_id = None;
210-
right_block_idx -= 1;
182+
let checksum_contribution = (0..right_block.length as u64)
183+
.map(|i| (left_block.start_idx as u64 + i))
184+
.sum::<u64>()
185+
* right_block.file_id.unwrap() as u64;
186+
187+
checksum += checksum_contribution
211188
}
212189

213-
Some(checksum(&blocks))
190+
Some(checksum)
214191
}
215192

216193
#[cfg(test)]

0 commit comments

Comments
 (0)