mirror of
https://github.com/Rhelvetican/aoc2024.git
synced 2025-01-10 20:31:36 +00:00
Compare commits
No commits in common. "15cf96bfb983957e6b25116821d7abc5c18e69f8" and "9c53f2858823ee8c727d736af325372cb53067a2" have entirely different histories.
15cf96bfb9
...
9c53f28588
5 changed files with 26 additions and 159 deletions
|
@ -30,7 +30,6 @@ fn main() -> Result<()> {
|
||||||
6 => AocDaySixSolution,
|
6 => AocDaySixSolution,
|
||||||
7 => AocDaySevenSolution,
|
7 => AocDaySevenSolution,
|
||||||
8 => AocDayEightSolution,
|
8 => AocDayEightSolution,
|
||||||
9 => AocDayNineSolution
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -154,3 +154,24 @@ impl AocSolution for AocDaySevenSolution {
|
||||||
Ok(sum)
|
Ok(sum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
let sol = AocDaySevenSolution;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
sol.part_one(
|
||||||
|
r#"190: 10 19
|
||||||
|
3267: 81 40 27
|
||||||
|
83: 17 5
|
||||||
|
156: 15 6
|
||||||
|
7290: 6 8 6 15
|
||||||
|
161011: 16 10 13
|
||||||
|
192: 17 8 14
|
||||||
|
21037: 9 7 18 13
|
||||||
|
292: 11 6 16 20"#
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
3749
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
|
@ -1,150 +1,8 @@
|
||||||
use std::{collections::HashMap, fs::read_to_string, iter::from_fn, path::Path};
|
use std::{fs::read_to_string, path::Path};
|
||||||
|
|
||||||
use super::AocSolution;
|
use super::AocSolution;
|
||||||
use crate::utils::Result;
|
use crate::utils::Result;
|
||||||
|
|
||||||
fn checksum(fs: &[Option<u64>]) -> u64 {
|
|
||||||
fs.iter()
|
|
||||||
.copied()
|
|
||||||
.zip(0..)
|
|
||||||
.filter_map(|(n, m)| n.map(|n| n * m))
|
|
||||||
.sum()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
|
||||||
struct Filedata {
|
|
||||||
size: usize,
|
|
||||||
ptr: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Filedata {
|
|
||||||
const fn new(size: usize, ptr: usize) -> Self {
|
|
||||||
Self { size, ptr }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct Disk {
|
|
||||||
pub id: u64,
|
|
||||||
pub metadata: HashMap<u64, Filedata>,
|
|
||||||
pub fs: Vec<Option<u64>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Disk {
|
|
||||||
fn new(src: &str) -> Self {
|
|
||||||
let total = src.len();
|
|
||||||
let mut flag = false;
|
|
||||||
|
|
||||||
let (fs, metadata, id) = src
|
|
||||||
.chars()
|
|
||||||
.zip(from_fn(move || {
|
|
||||||
flag = !flag;
|
|
||||||
Some(flag)
|
|
||||||
}))
|
|
||||||
.filter_map(|(ch, flag)| match ch {
|
|
||||||
'0' => Some((0, flag)),
|
|
||||||
'1' => Some((1, flag)),
|
|
||||||
'2' => Some((2, flag)),
|
|
||||||
'3' => Some((3, flag)),
|
|
||||||
'4' => Some((4, flag)),
|
|
||||||
'5' => Some((5, flag)),
|
|
||||||
'6' => Some((6, flag)),
|
|
||||||
'7' => Some((7, flag)),
|
|
||||||
'8' => Some((8, flag)),
|
|
||||||
'9' => Some((9, flag)),
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.fold(
|
|
||||||
(Vec::with_capacity(total), HashMap::new(), 0),
|
|
||||||
|(mut v, mut meta, mut id), (len, flag)| {
|
|
||||||
let idx = v.len();
|
|
||||||
for _ in 0..len {
|
|
||||||
if flag {
|
|
||||||
meta.insert(id, Filedata::new(len, idx));
|
|
||||||
}
|
|
||||||
|
|
||||||
v.push(if flag { Some(id) } else { None });
|
|
||||||
}
|
|
||||||
|
|
||||||
if flag {
|
|
||||||
id += 1
|
|
||||||
}
|
|
||||||
|
|
||||||
(v, meta, id)
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
Self { id, fs, metadata }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sort(&mut self) -> u64 {
|
|
||||||
let (mut first, mut last) = (0, self.fs.len() - 1);
|
|
||||||
|
|
||||||
fn _is_continous(fs: &[Option<u64>]) -> bool {
|
|
||||||
if let Some(first_none) = fs.iter().position(|o| o.is_none()) {
|
|
||||||
fs[first_none..].iter().all(|o| o.is_none())
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while !_is_continous(&self.fs) {
|
|
||||||
while self.fs[first].is_some() {
|
|
||||||
first += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while self.fs[last].is_none() {
|
|
||||||
last -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.fs.swap(first, last);
|
|
||||||
}
|
|
||||||
|
|
||||||
checksum(&self.fs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sort_block(&mut self) -> u64 {
|
|
||||||
fn swap_block(fs: &mut [Option<u64>], a: usize, b: usize, size: usize) {
|
|
||||||
for offset in 0..size {
|
|
||||||
if fs[a + offset].is_none() || fs[b + offset].is_some() {
|
|
||||||
fs.swap(a + offset, b + offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn allocate(fs: &[Option<u64>], size: usize, limit: usize) -> Option<usize> {
|
|
||||||
let mut offset = 0;
|
|
||||||
|
|
||||||
loop {
|
|
||||||
let slice = match fs.get(offset..(offset + size)) {
|
|
||||||
Some(sl) => sl,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if slice.iter().all(|o| o.is_none()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += 1;
|
|
||||||
if offset >= limit {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
for id in (0..self.id).rev() {
|
|
||||||
let metadata = &self.metadata[&id];
|
|
||||||
if let Some(ptr) = allocate(&self.fs, metadata.size, metadata.ptr) {
|
|
||||||
swap_block(&mut self.fs, ptr, metadata.ptr, metadata.size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checksum(&self.fs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AocDayNineSolution;
|
pub struct AocDayNineSolution;
|
||||||
|
|
||||||
impl AocSolution for AocDayNineSolution {
|
impl AocSolution for AocDayNineSolution {
|
||||||
|
@ -153,17 +11,15 @@ impl AocSolution for AocDayNineSolution {
|
||||||
fn get_input(&self, path: Option<&Path>) -> Result<String> {
|
fn get_input(&self, path: Option<&Path>) -> Result<String> {
|
||||||
Ok(match path {
|
Ok(match path {
|
||||||
Some(p) => read_to_string(p)?,
|
Some(p) => read_to_string(p)?,
|
||||||
None => read_to_string("./input/day_9.txt")?,
|
None => read_to_string("./input/day_day_9.txt")?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_one(&self, input: &str) -> Result<Self::Output> {
|
fn part_one(&self, input: &str) -> Result<Self::Output> {
|
||||||
let mut disk = Disk::new(input);
|
todo!()
|
||||||
Ok(disk.sort())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn part_two(&self, input: &str) -> Result<Self::Output> {
|
fn part_two(&self, input: &str) -> Result<Self::Output> {
|
||||||
let mut disk = Disk::new(input);
|
todo!()
|
||||||
Ok(disk.sort_block())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! map_solution {
|
macro_rules! map_solution {
|
||||||
($cli:ident : $($day:expr => $sol:expr),+ $(,)?) => {
|
($cli:ident : $($day:expr => $sol:expr,)+ $(,)?) => {
|
||||||
match $cli .day {
|
match $cli .day {
|
||||||
$($day => {
|
$($day => {
|
||||||
let sol = $sol;
|
let sol = $sol;
|
||||||
|
|
|
@ -21,13 +21,4 @@ pub enum Error {
|
||||||
InvalidInput,
|
InvalidInput,
|
||||||
#[error("Unsupported day.")]
|
#[error("Unsupported day.")]
|
||||||
UnsupportedDay,
|
UnsupportedDay,
|
||||||
#[error("{0}")]
|
|
||||||
CustomError(String),
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! err {
|
|
||||||
($lit:literal) => {
|
|
||||||
$crate::utils::Error::CustomError($lit.to_string())
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue