Clean up code
This commit is contained in:
parent
03bc848853
commit
5845e11772
@ -1,86 +1,48 @@
|
|||||||
use std::{cmp::Ordering, fmt::Display};
|
fn parse(input: &str) -> Vec<isize> {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
|
||||||
struct Space {
|
|
||||||
id: Option<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Display for Space {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(
|
|
||||||
f,
|
|
||||||
"{}",
|
|
||||||
if let Some(i) = self.id {
|
|
||||||
i.to_string()
|
|
||||||
} else {
|
|
||||||
".".to_string()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialOrd for Space {
|
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
||||||
Some(self.cmp(other))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Ord for Space {
|
|
||||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
|
||||||
if self.id.is_none() {
|
|
||||||
return Ordering::Less;
|
|
||||||
}
|
|
||||||
if other.id.is_none() {
|
|
||||||
return Ordering::Greater;
|
|
||||||
}
|
|
||||||
self.id.unwrap().cmp(&other.id.unwrap())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse(input: &str) -> Vec<Space> {
|
|
||||||
input
|
input
|
||||||
.chars()
|
.chars()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|(_, c)| c.is_ascii_digit())
|
.filter(|(_, c)| c.is_ascii_digit())
|
||||||
.flat_map(|(c_idx, c)| {
|
.flat_map(|(c_idx, c)| {
|
||||||
(0..c.to_digit(10).unwrap()).map(move |_| Space {
|
(0..c.to_digit(10).unwrap()).map(move |_| {
|
||||||
id: if c_idx % 2 == 0 {
|
if c_idx % 2 == 0 {
|
||||||
Some(c_idx / 2)
|
c_idx as isize / 2
|
||||||
} else {
|
} else {
|
||||||
None
|
-1
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn checksum(filesystem: &[Space]) -> usize {
|
fn checksum(filesystem: &[isize]) -> usize {
|
||||||
filesystem
|
filesystem
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(c_idx, c)| if let Some(v) = c.id { c_idx * v } else { 0 })
|
.map(|(c_idx, c)| if c >= &0 { c_idx * *c as usize } else { 0 })
|
||||||
.sum()
|
.sum()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part1(filesystem: &mut [Space]) -> usize {
|
fn part1(filesystem: &mut [isize]) -> usize {
|
||||||
for space_idx in 0..filesystem.len() {
|
for space_idx in 0..filesystem.len() {
|
||||||
if filesystem[space_idx].id.is_none() {
|
if filesystem[space_idx] >= 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
let last = filesystem
|
let last = filesystem
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.rev()
|
.rev()
|
||||||
.find(|(_, n)| n.id.is_some())
|
.find(|(_, n)| n >= &&0)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
if last.0 < space_idx {
|
if last.0 < space_idx {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
filesystem.swap(space_idx, last.0);
|
filesystem.swap(space_idx, last.0);
|
||||||
};
|
|
||||||
}
|
}
|
||||||
checksum(filesystem)
|
checksum(filesystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_chunk_size(filesystem: &[Space], idx: usize) -> usize {
|
fn get_chunk_size(filesystem: &[isize], idx: usize) -> usize {
|
||||||
let mut chunk_size = 0;
|
let mut chunk_size = 0;
|
||||||
while idx + chunk_size < filesystem.len() && filesystem[idx + chunk_size] == filesystem[idx] {
|
while idx + chunk_size < filesystem.len() && filesystem[idx + chunk_size] == filesystem[idx] {
|
||||||
chunk_size += 1;
|
chunk_size += 1;
|
||||||
@ -88,17 +50,17 @@ fn get_chunk_size(filesystem: &[Space], idx: usize) -> usize {
|
|||||||
chunk_size
|
chunk_size
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part2(filesystem: &mut [Space]) -> usize {
|
fn part2(filesystem: &mut [isize]) -> usize {
|
||||||
for move_id in (0..=filesystem.iter().max().unwrap().id.unwrap()).rev() {
|
for move_id in (0..=*filesystem.iter().max().unwrap()).rev() {
|
||||||
let move_idx = filesystem
|
let move_idx = filesystem
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_, c)| c.id.unwrap_or(move_id + 1) == move_id)
|
.find(|(_, c)| c == &&move_id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0;
|
.0;
|
||||||
let move_chunk_size = get_chunk_size(filesystem, move_idx);
|
let move_chunk_size = get_chunk_size(filesystem, move_idx);
|
||||||
for free_idx in 0..move_idx {
|
for free_idx in 0..move_idx {
|
||||||
if filesystem[free_idx].id.is_some() {
|
if filesystem[free_idx] >= 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if get_chunk_size(filesystem, free_idx) >= move_chunk_size {
|
if get_chunk_size(filesystem, free_idx) >= move_chunk_size {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user