Skip to content

Commit 1a3238b

Browse files
committed
Faster day 9.1
1 parent 8ed861d commit 1a3238b

File tree

1 file changed

+26
-41
lines changed

1 file changed

+26
-41
lines changed

src/bin/09.rs

Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -91,55 +91,40 @@ fn parse_blocks(input: &str) -> Vec<Block> {
9191
}
9292

9393
pub fn part_one(input: &str) -> Option<u64> {
94-
let mut blocks = parse_blocks(input);
95-
96-
// have 2 pointers, one at the start of the disk, one at the end
97-
// move the pointer at the end to the leftmost free space block
98-
// move the pointer at the start to the rightmost file block
99-
// if the pointers meet, we're done
100-
// if we have a free space block, we want to grab some of the file blocks to put in place of it
101-
102-
let mut left_block_idx = 0;
103-
let mut right_block_idx = blocks.len() - 1;
104-
while left_block_idx < right_block_idx {
105-
let left_block = &blocks[left_block_idx];
106-
let right_block = &blocks[right_block_idx];
107-
108-
if !left_block.is_free() {
109-
left_block_idx += 1;
94+
const EMPTY: usize = usize::MAX;
95+
let nums: Vec<usize> = input
96+
.chars()
97+
.map(|c| c.to_digit(10))
98+
.filter(|r| r.is_some())
99+
.map(|r| r.unwrap())
100+
.enumerate()
101+
// create the full disk with all the file ids
102+
.flat_map(|(i, num)| (0..num).map(move |_| if i % 2 == 0 { i / 2 } else { EMPTY }))
103+
.collect();
104+
105+
let mut left = 0;
106+
let mut right = nums.len() - 1;
107+
let mut checksum = 0;
108+
while left <= right {
109+
let left_num = nums[left];
110+
if left_num != EMPTY {
111+
checksum += (left * left_num) as u64;
112+
left += 1;
110113
continue;
111114
}
112115

113-
if !right_block.is_file() {
114-
right_block_idx -= 1;
116+
let right_num = nums[right];
117+
if right_num != EMPTY {
118+
checksum += (left * right_num) as u64;
119+
right -= 1;
120+
left += 1;
115121
continue;
116122
}
117123

118-
// now we have a free space block and a file block
119-
// we want to grab some of the file blocks to put in place of the free space block
120-
121-
let left_size = left_block.length;
122-
let (right_movable, maybe_right_unmovable) = right_block.split(left_size);
123-
let (_, maybe_left_additional_space) = left_block.split(right_movable.length);
124-
125-
// move the movable part
126-
if let Some(left_additional_space) = maybe_left_additional_space {
127-
blocks.insert(left_block_idx, right_movable);
128-
blocks[left_block_idx + 1] = left_additional_space;
129-
right_block_idx += 1;
130-
} else {
131-
blocks[left_block_idx] = right_movable;
132-
}
133-
134-
if let Some(right_unmovable) = maybe_right_unmovable {
135-
blocks[right_block_idx] = right_unmovable;
136-
} else {
137-
blocks.remove(right_block_idx);
138-
right_block_idx -= 1;
139-
}
124+
right -= 1;
140125
}
141126

142-
Some(checksum(&blocks))
127+
Some(checksum)
143128
}
144129

145130
pub fn part_two(input: &str) -> Option<u64> {

0 commit comments

Comments
 (0)