Part 2 done

This commit is contained in:
Daniel Flanagan 2024-12-09 10:10:00 -06:00
parent 6f86208041
commit 772478e4fb

View file

@ -6,43 +6,86 @@ fn main() {
show_answers(part1(&input), part2(&input)); show_answers(part1(&input), part2(&input));
} }
fn part1(input: &str) -> usize { struct Disk {
let mut blocks: Vec<Option<usize>> = vec![]; blocks: Vec<Option<usize>>,
let mut free_blocks: usize = 0; files: Vec<(usize, u8)>,
for (i, len) in input.trim().bytes().map(|len| len - b'0').enumerate() { free_blocks: usize,
// every other iteration is "free space" }
let file_id = if i % 2 == 0 {
Some((i / 2) as usize) impl FromStr for Disk {
} else { type Err = Infallible;
free_blocks += len as usize;
None fn from_str(s: &str) -> Result<Self, Self::Err> {
}; let mut blocks: Vec<Option<usize>> = vec![];
for _ in 0..len { let mut files = vec![];
blocks.push(file_id); let mut free_blocks: usize = 0;
for (i, len) in s.trim().bytes().map(|len| len - b'0').enumerate() {
// every other iteration is "free space"
let file_id = if i % 2 == 0 {
Some((i / 2) as usize)
} else {
free_blocks += len as usize;
None
};
if file_id.is_some() {
files.push((blocks.len(), len));
}
for _ in 0..len {
blocks.push(file_id);
}
} }
Ok(Self {
files,
blocks,
free_blocks,
})
} }
println!("{blocks:?}"); }
let mut right = blocks.len() - 1;
for left in 0..(right.clone() - free_blocks + 1) { impl Disk {
if blocks[left].is_some() { fn checksum(&self) -> usize {
self.blocks
.iter()
.enumerate()
.map(|(i, b)| i * b.unwrap_or_default())
.sum()
}
}
fn part1(input: &str) -> usize {
let mut disk: Disk = input.parse().unwrap();
let mut right = disk.blocks.len() - 1;
for left in 0..(right.clone() - disk.free_blocks + 1) {
if disk.blocks[left].is_some() {
continue; continue;
} }
while blocks[right].is_none() { while disk.blocks[right].is_none() {
right -= 1; right -= 1;
} }
(blocks[left], blocks[right]) = (blocks[right], blocks[left]); (disk.blocks[left], disk.blocks[right]) = (disk.blocks[right], disk.blocks[left]);
} }
println!("{blocks:?}");
blocks disk.checksum()
.iter()
.enumerate()
.map(|(i, b)| i * b.unwrap_or_default())
.sum()
} }
fn part2(input: &str) -> usize { fn part2(input: &str) -> usize {
1 let mut disk: Disk = input.parse().unwrap();
for (cur_i, len) in disk.files.iter().rev() {
for left in 0..*cur_i {
if disk.blocks[left..(left + (*len as usize))]
.iter()
.all(|f| f.is_none())
{
for i in 0..*len {
let i = i as usize;
(disk.blocks[left + i], disk.blocks[cur_i + i]) =
(disk.blocks[cur_i + i], disk.blocks[left + i])
}
break;
}
}
}
disk.checksum()
} }
#[cfg(test)] #[cfg(test)]
@ -53,6 +96,6 @@ mod tests {
fn test() { fn test() {
let input = r#"2333133121414131402"#; let input = r#"2333133121414131402"#;
assert_eq!(part1(input), 1928); assert_eq!(part1(input), 1928);
assert_eq!(part2(input), 1); assert_eq!(part2(input), 2858);
} }
} }