y2016d9
This commit is contained in:
parent
b457e10a35
commit
03bc52e5ae
1
y2024/resources/9_input.txt
Normal file
1
y2024/resources/9_input.txt
Normal file
File diff suppressed because one or more lines are too long
20
y2024/src/bin/d9.rs
Normal file
20
y2024/src/bin/d9.rs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
use std::fs;
|
||||||
|
|
||||||
|
use y2024::days::d9;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
part1();
|
||||||
|
part2();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/9_input.txt")).unwrap();
|
||||||
|
println!("{}", d9::process_part1(&content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2() {
|
||||||
|
let root = env!("CARGO_MANIFEST_DIR");
|
||||||
|
let content = fs::read_to_string(format!("{root}/resources/9_input.txt")).unwrap();
|
||||||
|
println!("{}", d9::process_part2(&content));
|
||||||
|
}
|
129
y2024/src/days/d9.rs
Normal file
129
y2024/src/days/d9.rs
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
pub fn process_part1(input: &str) -> u64 {
|
||||||
|
let mut ids = Vec::new();
|
||||||
|
for (file_id, chunk) in input.trim_end().as_bytes().chunks(2).enumerate() {
|
||||||
|
let byte = chunk[0];
|
||||||
|
for _ in 0..(byte - 48) {
|
||||||
|
ids.push(file_id.to_string());
|
||||||
|
}
|
||||||
|
if let Some(&byte) = chunk.get(1) {
|
||||||
|
for _ in 0..(byte - 48) {
|
||||||
|
ids.push(".".into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut ordered = Vec::new();
|
||||||
|
while !ids.is_empty() {
|
||||||
|
let id = ids.remove(0);
|
||||||
|
if id == "." {
|
||||||
|
while let Some(id) = ids.pop() {
|
||||||
|
if id != "." {
|
||||||
|
ordered.push(id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ordered.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut res = 0;
|
||||||
|
for (multiplier, id) in ordered.iter().enumerate() {
|
||||||
|
res += multiplier * id.parse::<usize>().unwrap();
|
||||||
|
}
|
||||||
|
res as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn process_part2(input: &str) -> u64 {
|
||||||
|
let mut ids = Vec::new();
|
||||||
|
for (file_id, chunk) in input.trim_end().as_bytes().chunks(2).enumerate() {
|
||||||
|
let byte = chunk[0];
|
||||||
|
ids.push((file_id.to_string(), byte - 48));
|
||||||
|
if let Some(&byte) = chunk.get(1) {
|
||||||
|
ids.push((".".into(), byte - 48));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut from_idx = ids.len() - 1;
|
||||||
|
loop {
|
||||||
|
if from_idx == 0 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let (id, size) = ids[from_idx].clone();
|
||||||
|
if id == *"." {
|
||||||
|
from_idx -= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let to_idx = if let Some(idx) = ids.iter().position(|id| id.1 >= size && id.0 == ".") {
|
||||||
|
idx
|
||||||
|
} else {
|
||||||
|
from_idx -= 1;
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
if from_idx < to_idx {
|
||||||
|
from_idx -= 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let free_space = ids[to_idx].1;
|
||||||
|
match size.cmp(&free_space) {
|
||||||
|
std::cmp::Ordering::Less => {
|
||||||
|
let remaining_free_space = free_space - size;
|
||||||
|
ids[to_idx].1 = remaining_free_space;
|
||||||
|
ids[from_idx] = (".".to_string(), size);
|
||||||
|
ids.insert(to_idx, (id.clone(), size));
|
||||||
|
from_idx -= 1;
|
||||||
|
}
|
||||||
|
std::cmp::Ordering::Equal => {
|
||||||
|
ids[to_idx] = (id.clone(), size);
|
||||||
|
ids[from_idx] = (".".to_string(), size);
|
||||||
|
from_idx -= 1;
|
||||||
|
}
|
||||||
|
std::cmp::Ordering::Greater => {
|
||||||
|
from_idx -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut res = 0;
|
||||||
|
let mut multiplier = 0;
|
||||||
|
for (id, size) in ids.into_iter() {
|
||||||
|
if id == *"." {
|
||||||
|
multiplier += size as usize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for _idx in 0..size as usize {
|
||||||
|
res += multiplier * id.parse::<usize>().unwrap();
|
||||||
|
multiplier += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const INPUT_1: &str = "12345";
|
||||||
|
const INPUT_2: &str = "2333133121414131402";
|
||||||
|
const INPUT_3: &str = "23331331214141314020202";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_simple() {
|
||||||
|
let result = process_part1(INPUT_1);
|
||||||
|
assert_eq!(result, 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_complex_1() {
|
||||||
|
let result = process_part1(INPUT_2);
|
||||||
|
assert_eq!(result, 1928);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_complex_2() {
|
||||||
|
let result = process_part1(INPUT_3);
|
||||||
|
assert_eq!(result, 2842);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2() {
|
||||||
|
let result = process_part2(INPUT_2);
|
||||||
|
assert_eq!(result, 2858)
|
||||||
|
}
|
||||||
|
}
|
@ -1,15 +1,9 @@
|
|||||||
pub mod d1;
|
pub mod d1;
|
||||||
|
|
||||||
pub mod d2;
|
pub mod d2;
|
||||||
|
|
||||||
pub mod d3;
|
pub mod d3;
|
||||||
|
|
||||||
pub mod d4;
|
pub mod d4;
|
||||||
|
|
||||||
pub mod d5;
|
pub mod d5;
|
||||||
|
|
||||||
pub mod d6;
|
pub mod d6;
|
||||||
|
|
||||||
pub mod d7;
|
pub mod d7;
|
||||||
|
|
||||||
pub mod d8;
|
pub mod d8;
|
||||||
|
pub mod d9;
|
||||||
|
Loading…
Reference in New Issue
Block a user