y2024d9
This commit is contained in:
		
							
								
								
									
										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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user