Part 2 done
This commit is contained in:
parent
6f86208041
commit
772478e4fb
|
@ -6,10 +6,20 @@ fn main() {
|
|||
show_answers(part1(&input), part2(&input));
|
||||
}
|
||||
|
||||
fn part1(input: &str) -> usize {
|
||||
struct Disk {
|
||||
blocks: Vec<Option<usize>>,
|
||||
files: Vec<(usize, u8)>,
|
||||
free_blocks: usize,
|
||||
}
|
||||
|
||||
impl FromStr for Disk {
|
||||
type Err = Infallible;
|
||||
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut blocks: Vec<Option<usize>> = vec![];
|
||||
let mut files = vec![];
|
||||
let mut free_blocks: usize = 0;
|
||||
for (i, len) in input.trim().bytes().map(|len| len - b'0').enumerate() {
|
||||
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)
|
||||
|
@ -17,32 +27,65 @@ fn part1(input: &str) -> usize {
|
|||
free_blocks += len as usize;
|
||||
None
|
||||
};
|
||||
if file_id.is_some() {
|
||||
files.push((blocks.len(), len));
|
||||
}
|
||||
for _ in 0..len {
|
||||
blocks.push(file_id);
|
||||
}
|
||||
}
|
||||
println!("{blocks:?}");
|
||||
let mut right = blocks.len() - 1;
|
||||
for left in 0..(right.clone() - free_blocks + 1) {
|
||||
if blocks[left].is_some() {
|
||||
continue;
|
||||
Ok(Self {
|
||||
files,
|
||||
blocks,
|
||||
free_blocks,
|
||||
})
|
||||
}
|
||||
while blocks[right].is_none() {
|
||||
right -= 1;
|
||||
}
|
||||
(blocks[left], blocks[right]) = (blocks[right], blocks[left]);
|
||||
}
|
||||
println!("{blocks:?}");
|
||||
}
|
||||
|
||||
blocks
|
||||
impl Disk {
|
||||
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;
|
||||
}
|
||||
while disk.blocks[right].is_none() {
|
||||
right -= 1;
|
||||
}
|
||||
(disk.blocks[left], disk.blocks[right]) = (disk.blocks[right], disk.blocks[left]);
|
||||
}
|
||||
|
||||
disk.checksum()
|
||||
}
|
||||
|
||||
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)]
|
||||
|
@ -53,6 +96,6 @@ mod tests {
|
|||
fn test() {
|
||||
let input = r#"2333133121414131402"#;
|
||||
assert_eq!(part1(input), 1928);
|
||||
assert_eq!(part2(input), 1);
|
||||
assert_eq!(part2(input), 2858);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue