Solved day 9, with still very ugly code

This commit is contained in:
immortaly007 committed 2024-12-09 22:07:57 +01:00
1 parent c18e37d476
commit 5be2ca974e
3 files changed
+224 -2

No files matched your search

+1
View File
@@ -0,0 +1 @@
6967128031985339734736617280757038645745239290236581123874156665793751514720983617223858831792394521856119568164901557909564178891524619506666506195863925923014993023578874449690848884327968251127532261526073368241228992411935648185959886726847737539273014339031792790792181163051839724753167987312745189256012985096956465302299649632218176609140515847891570764951297112116773162211261180304738674164465189313169822290998065973987773519329134522837998977277795401965985111235892379859166544548520224968389423571472361776489613276127278129549321775058665191172457931730268248458944488752324062679047636539342011633567959256508397931398545527467667612596775360548544327439557146594531983927888755819778387135182176722477666223468574324931412377114749849943118511597585591951878321693622159731206251299725451260217825277179316870624526444285286618504385405933927184735432887376231168495240401479989280307715599967406448265096126268528998737643457885176674752226724147813478356498503199103821247485446662256272865360373548839825962624369223867028736696949890976630347080246094825594915668966939453080358862211921947782211051993580374011612635238245279646362326795988816653504285902983109486299911603193692558597124869762814068338572672760817282262867939895853091139150485810794664664152377932903447184983249462459626784359482660343463863392276675318244807463171287538793947799752174695482275016731270101212678135282810693420504127611162936136351139405084188230155355984562674250243995703719874755704812491040753412376721971169926356966893994518224925476926439679385357906661657087905048177095586863833021627724251497669913419599778759172623963133261383699942627149616868708529164197985565476080108310282573186348864792556864423597555431385371702120469770132428221340732285837473305843576917341391708632896720909716141826775814464345517485477860141087674390101367891265905190561534382232212520453553287793312683799643802596212445702939866495827499483259293675823623298018272552199310831939873412687441636993773993176512861127867892217748973877726269301031248545379892739016649972847452323045898710605121996085143069564994553893463697514552897093805272211340251799689887564074936740684915389491217265882727243360398328603164806793927371322099417449806731417716468728272796247046465795293590507055393152306539229283883099723471592885407343692264935434644737916545841069391563799514239121781277934850107638766198702917494593283194422926161384185369774831749981781335567731371551342694637030508962334381296568247286737594586735893533323927177413743710495282681646505575621624632681221073813954612357668794413815404829918193423235862078515215942296468865807159595315283257556916683791104187691334684227514563574465898488849224608449631185199257684968674765958311777149721924703576648647277377628627393730408899908841528995845812639571732438227464122016861099586969199552921253772338837195785951927287445980357771512445583172663152994756762631352633773558149429541912453799141363479465153478465457836716364217784321903780269619526253991323733814813142107069652356639854745650964944801831327686228968194922886213415632914940378012536727781631616923767178669788577043742066303027902126998184698739681032315789418355967250825348968125368050672452503385297952582581234595808644525812232252787199556143988975816814535495945147134352228298132135765135301389405460988333202875771521421889119220771876318161665384646715772718866789522862447034581533777181307439572696697078215311454713452099875572537750285032379487124281198361654669517473497944696621567675902365918212868998289444315591668779513088551650902157527640794045618050678974622641216184828179208128495290221615541050605672463318314593117927769472969744123088479446531844606691645062189917412370421083806969647182622846407192305787882268657029604860317144826512558967754225426581825186809399253382685399364551779883983556972635321328105673559220611722813066953537596297882756578847172956425568891590799377973713205026422710708262224388966270745154703354364374733078364019451972996393152122332426974748668294308371457041668837544386958745756028706430829480256815221267663688861566413175217683683955493017593041901476506161745399388994988151771166323572497924859065282055813957919285332797583081364642163375245057781973223633859740608894617065395940532399617389346752291193648157995940611615737473672229613934401974198178164252953491753113443059527347584832159937895178402316781718331811379143884325749981387979249934127824448729522817543480861188839127782890819782231685325020823985683151287724865453924258321377268932893948466691991540192942448634696786677578897149165942257746679376485490687826927296632322541875711279651550276968871946744440677563997233229318319785658768601641389927838657413335663793582878748829762233148036123184646369939131425874514531929450642168274341921911813115549125344849587421616395216565358513633176218559311914409776771957366466862663976881858094487010473790886423716163543874215915216341593146237638614588916527979617483352135Line truncated
+219
View File
@@ -0,0 +1,219 @@
use itertools::Itertools;
use crate::day_solver::DaySolver;
use num::Integer;
pub struct Day9 {
disk_map: Vec<u8>
}
impl Day9 {
pub fn create(input: String) -> Self {
Day9 {
disk_map: input.chars().map(|c| (c as u8) - b'0').collect()
}
}
fn print_layout(disk_blocks: &Vec<Block>) {
for block in disk_blocks {
match block {
Block::File(size, idx) => {
for _ in 0..*size {
print!("{}", idx);
}
}
Block::Empty(size) => {
print!("{}", ".".repeat(*size));
}
}
}
println!();
}
}
impl DaySolver for Day9 {
fn solve_part1(&mut self) -> String {
let mut cur_disk_idx = 0usize;
let mut disk_map_idx = 0usize;
let mut disk_map_idx_rev = self.disk_map.len() + (self.disk_map.len() % 2);
let mut left_to_move = 0u8;
let mut res = 0usize;
while disk_map_idx <= disk_map_idx_rev {
if disk_map_idx.is_even() {
// We're reading a file from the front of the disk map
let left_in_file = if disk_map_idx == disk_map_idx_rev { left_to_move } else { self.disk_map[disk_map_idx] };
for _ in 0..left_in_file {
// print!("{}({})", disk_map_idx / 2, cur_disk_idx);
res += cur_disk_idx * (disk_map_idx / 2);
cur_disk_idx += 1;
}
} else {
// We're reading empty space
for _ in 0..self.disk_map[disk_map_idx] {
// So let's grab some blocks from files at the end of the disk map
while left_to_move == 0 && disk_map_idx_rev > disk_map_idx {
disk_map_idx_rev -= 2;
left_to_move = self.disk_map[disk_map_idx_rev];
}
if disk_map_idx_rev < disk_map_idx {
break
}
// print!("{}({})", disk_map_idx_rev / 2, cur_disk_idx);
res += cur_disk_idx * (disk_map_idx_rev / 2);
cur_disk_idx += 1;
left_to_move -= 1;
}
}
disk_map_idx += 1;
}
res.to_string()
}
//
// fn solve_part2(&mut self) -> String {
// // Maybe I can code it using a vec of the actual disk?
// let mut disk: Vec<Option<usize>> = Vec::with_capacity(self.disk_map.len() * 8);
//
// for (i, b) in self.disk_map.iter().enumerate() {
// if i.is_even() {
// for _ in 0..*b {
// disk.push(Some(i / 2))
// }
// } else {
// for _ in 0..*b {
// disk.push(None)
// }
// }
// }
//
//
// let mut disk_blocks: Vec<Block> = Vec::new();
// for (i, b) in self.disk_map.iter().enumerate() {
// if i.is_even() {
// disk_blocks.push(Block::File(b.to_owned().into(), i / 2))
// } else if b > &0 {
// disk_blocks.push(Block::Empty(b.to_owned().into()))
// }
// }
//
// for block in disk_blocks.iter().rev() {
// if let Block::File(size, idx) = block {
//
// }
// }
//
// "0".to_string()
// }
fn solve_part2(&mut self) -> String {
// Maybe we build the disk
let mut disk_blocks: Vec<Block> = Vec::new();
for (i, b) in self.disk_map.iter().enumerate() {
if i.is_even() {
disk_blocks.push(Block::File(b.to_owned().into(), i / 2))
} else if b > &0 {
disk_blocks.push(Block::Empty(b.to_owned().into()))
}
}
Self::print_layout(&disk_blocks);
let original_disk = disk_blocks.clone();
for block in original_disk.iter().rev() {
if let Block::File(size, idx) = block {
// Self::print_layout(&disk_blocks);
// println!("{:?}", disk_blocks);
// Try to move the file
let move_target = disk_blocks.iter().enumerate()
.find(|(_, b) | if let Block::Empty(s) = b { s >= size } else { false })
// To prevent double borrowing, we need to clone the block here
.map(|(i, b)| (i, b.to_owned()));
if let Some((can_move_to_idx, b)) = move_target.to_owned() {
match b {
Block::Empty(empty_size) => {
let original_index = disk_blocks.iter().position(|b| b == block).unwrap();
if can_move_to_idx >= original_index { continue; }
// We need ot merge
let block_before = disk_blocks.get(original_index - 1).map(|b| b.to_owned());
let block_after = disk_blocks.get(original_index + 1).map(|b| b.to_owned());
// let mut new_empty_space = size.to_owned();
// if let Some(Block::Empty(empty_before)) = block_before {
// new_empty_space += empty_before.to_owned();
// }
// if let Some(Block::Empty(empty_after)) = block_after {
// new_empty_space += empty_after.to_owned();
// }
disk_blocks[original_index] = Block::Empty(size.to_owned());
// if let Some(Block::Empty(_)) = block_after {
// disk_blocks.remove(original_index + 1);
// }
// if let Some(Block::Empty(_)) = block_before {
// disk_blocks.remove(original_index - 1);
// }
disk_blocks[can_move_to_idx] = Block::File(size.to_owned(), idx.to_owned());
if &empty_size > size {
// Add additional empty space
disk_blocks.insert(can_move_to_idx + 1, Block::Empty(empty_size.to_owned() - size.to_owned()))
}
}
_ => panic!("uhm?")
}
}
}
}
Self::print_layout(&disk_blocks);
let mut checksum = 0usize;
let mut cur_disk_idx = 0usize;
for block in disk_blocks {
match block {
Block::File(size, idx) => {
for _ in 0..size {
checksum += cur_disk_idx * idx;
cur_disk_idx += 1;
}
}
Block::Empty(size) => {
cur_disk_idx += size;
}
}
}
checksum.to_string()
}
}
#[derive(Copy, Clone, PartialEq, Debug)]
enum Block {
Empty(usize),
File(usize, usize)
}
#[test]
fn test_part1_basic() {
let mut day = Day9::create("12345".to_string());
assert_eq!("60", day.solve_part1());
}
#[test]
fn test_part1() {
let mut day = Day9::create("2333133121414131402".to_string());
assert_eq!("1928", day.solve_part1());
}
#[test]
fn test_part2() {
let mut day = Day9::create("2333133121414131402".to_string());
assert_eq!("2858", day.solve_part2());
}
#[test]
fn test_part2_bonus() {
let mut day = Day9::create("2931514".to_string());
assert_eq!("180", day.solve_part2());
}
+4 -2
View File
@@ -9,6 +9,7 @@ use crate::day5::Day5;
use crate::day6::Day6; use crate::day6::Day6;
use crate::day7::Day7; use crate::day7::Day7;
use crate::day8::Day8; use crate::day8::Day8;
use crate::day9::Day9;
use crate::day_solver::DaySolver; use crate::day_solver::DaySolver;
use crate::util::read_file; use crate::util::read_file;
@@ -22,6 +23,7 @@ mod day5;
mod day6; mod day6;
mod day7; mod day7;
mod day8; mod day8;
mod day9;
const DEFAULT_BENCHMARK_AMOUNT: u32 = 100; const DEFAULT_BENCHMARK_AMOUNT: u32 = 100;
@@ -101,7 +103,7 @@ fn build_day_solver(day: u8, input: String) -> Option<Box<dyn DaySolver>> {
6 => Some(Box::new(Day6::create(input))), 6 => Some(Box::new(Day6::create(input))),
7 => Some(Box::new(Day7::create(input))), 7 => Some(Box::new(Day7::create(input))),
8 => Some(Box::new(Day8::create(input))), 8 => Some(Box::new(Day8::create(input))),
// 9 => Some(Box::new(Day9::create(input))), 9 => Some(Box::new(Day9::create(input))),
// 10 => Some(Box::new(Day10::create(input))), // 10 => Some(Box::new(Day10::create(input))),
// 11 => Some(Box::new(Day11::create(input))), // 11 => Some(Box::new(Day11::create(input))),
// 12 => Some(Box::new(Day12::create(input))), // 12 => Some(Box::new(Day12::create(input))),
@@ -188,7 +190,7 @@ fn solve_all(silent: bool) -> AocBenchResult {
for day in 1..(max_day + 1) { for day in 1..(max_day + 1) {
bench_results.push(solve(day, silent)); bench_results.push(solve(day, silent));
} }
return AocBenchResult { AocBenchResult {
read_file: bench_results.iter().map(|t| t.read_file).sum(), read_file: bench_results.iter().map(|t| t.read_file).sum(),
init: bench_results.iter().map(|t| t.init).sum(), init: bench_results.iter().map(|t| t.init).sum(),
part1: bench_results.iter().map(|t| t.part1).sum(), part1: bench_results.iter().map(|t| t.part1).sum(),