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 d2;
|
||||
|
||||
pub mod d3;
|
||||
|
||||
pub mod d4;
|
||||
|
||||
pub mod d5;
|
||||
|
||||
pub mod d6;
|
||||
|
||||
pub mod d7;
|
||||
|
||||
pub mod d8;
|
||||
pub mod d9;
|
||||
|
Loading…
Reference in New Issue
Block a user