Guest User

my rust code for day 9. Only have to read the part 2 function to help me.

a guest
Dec 9th, 2024
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.41 KB | None | 0 0
  1. use std::fs;
  2.  
  3. #[derive(Clone, PartialEq, Debug)]
  4. enum DiskStuff {
  5.     FreeSpace,
  6.     FileBlock(i32),
  7. }
  8.  
  9. fn main() {
  10.     let input: Vec<DiskStuff> = fs::read_to_string("input")
  11.         .expect("couldn't read the file")
  12.         .trim()
  13.         .chars()
  14.         .enumerate()
  15.         .map(|(i, character)| {
  16.             let num: u32 = character.to_digit(10).unwrap();
  17.             if i % 2 == 0 {
  18.                 (0..num)
  19.                     .map(|_| DiskStuff::FileBlock(i as i32 / 2))
  20.                     .collect::<Vec<DiskStuff>>()
  21.             } else {
  22.                 (0..num)
  23.                     .map(|_| DiskStuff::FreeSpace)
  24.                     .collect::<Vec<DiskStuff>>()
  25.             }
  26.         })
  27.         .flatten()
  28.         .collect::<Vec<DiskStuff>>();
  29.  
  30.     // inpu2 is the input passed to the part2 function.
  31.     // here's how the program will parse 133
  32.     // [[FileBlock(0)], [FreeSpace, FreeSpace, FreeSpace], [FileBlock(1), FileBlock(1), FileBlock(1)]]
  33.     let input2: Vec<Vec<DiskStuff>> = fs::read_to_string("input")
  34.         .expect("couldn't read the file")
  35.         .trim()
  36.         .chars()
  37.         .enumerate()
  38.         .map(|(i, character)| {
  39.             let num: u32 = character.to_digit(10).unwrap();
  40.             if i % 2 == 0 {
  41.                 (0..num)
  42.                     .map(|_| DiskStuff::FileBlock(i as i32/2))
  43.                     .collect::<Vec<DiskStuff>>()
  44.             } else {
  45.                 (0..num)
  46.                     .map(|_| DiskStuff::FreeSpace)
  47.                     .collect::<Vec<DiskStuff>>()
  48.             }
  49.         })
  50.         .filter(|x| !x.is_empty())
  51.         .collect::<Vec<Vec<DiskStuff>>>();
  52.  
  53.     println!("{:?}", input2);
  54.     part1(&input);
  55.     part2(&input2);
  56. }
  57.  
  58. fn part1(input: &Vec<DiskStuff>) {
  59.     let mut defragged = input.clone();
  60.     while defragged.contains(&DiskStuff::FreeSpace) {
  61.         let last = defragged.pop().expect("couldn't pop");
  62.         if last == DiskStuff::FreeSpace {
  63.             continue;
  64.         }
  65.         let first_free_space = defragged
  66.             .iter()
  67.             .position(|x| x == &DiskStuff::FreeSpace)
  68.             .expect("couldn't find first free space");
  69.         defragged.remove(first_free_space);
  70.         defragged.insert(first_free_space, last);
  71.     }
  72.  
  73.     let checksum = defragged
  74.         .iter()
  75.         .enumerate()
  76.         .fold(0 as i64, |acc, (i, x)| {
  77.             if let DiskStuff::FileBlock(val) = x {
  78.                 acc + i as i64 * *val as i64
  79.             } else {
  80.                 acc
  81.             }
  82.         });
  83.  
  84.     println!("Part 1: {}", checksum);
  85. }
  86.  
  87. fn part2(input: &Vec<Vec<DiskStuff>>) {
  88.     let mut defragged: Vec<Vec<_>> = input.clone();
  89.     for file_i in (0..defragged.len()).rev() { // loop through the files in reversed order
  90.         let file = defragged[file_i].clone();
  91.         if let DiskStuff::FileBlock(_) = file[0] { // checks if the file chunk is type of FileBlock
  92.             let needed_space = file.len(); // needed space is basically the amount of fileblocks a file contains
  93.             if let Some(free_space_index) = defragged.iter().enumerate().position(|(i, x)| {
  94.                 // this if statement checks for the first position with enough free space.
  95.                 matches!(x[0], DiskStuff::FreeSpace) && x.len() >= needed_space && i < file_i
  96.                 // the conditions it should satisfy are:
  97.                 // 1. it's a type FreeSpace
  98.                 // 2. The free space length is bigger or equal to the needed space
  99.                 // 3. the index is smaller than the current file index
  100.             }) {
  101.                 defragged[free_space_index] = (0..(defragged[free_space_index].len() - needed_space))
  102.                     .map(|_| DiskStuff::FreeSpace)
  103.                     .collect(); // susbstracts the needed_space from the free space it found.
  104.                 defragged.remove(file_i); // removes the file from its current position
  105.                 let leave_blank: Vec<_> = (0..needed_space).map(|_| DiskStuff::FreeSpace).collect();
  106.                 // leave_blank is a temporary variable that creates a free space chunk that's the same size as the file
  107.                 defragged.insert(file_i, leave_blank);
  108.                 // leave the blank space created where the file previously was
  109.                 if defragged[free_space_index].is_empty() {
  110.                     // if the free space we found is empty after removing its contents remove the entire thing.
  111.                     defragged.remove(free_space_index);
  112.                 }
  113.                 // finally insert the file at the position where the free space was
  114.                 defragged.insert(free_space_index, file.clone());
  115.             }
  116.         }
  117.     }
  118.     // this creates a visual reperesentation of the final disk layout
  119.     println!(
  120.         "{}",
  121.         defragged
  122.             .iter()
  123.             .flatten()
  124.             .map(|i| match i {
  125.                 DiskStuff::FreeSpace => ".".to_string(),
  126.                 DiskStuff::FileBlock(x) => x.to_string(),
  127.             })
  128.             .collect::<String>()
  129.     );
  130.    
  131.     // calculates the final checksum
  132.     let checksum = defragged
  133.         .iter()
  134.         .flatten()
  135.         .enumerate()
  136.         .fold(0 as i128, |acc, (i, x)| {
  137.             if let DiskStuff::FileBlock(val) = x {
  138.                 acc + i as i128 * *val as i128
  139.             } else {
  140.                 acc
  141.             }
  142.         });
  143.  
  144.     println!("Part 2: {}", checksum);
  145. }
Advertisement
Add Comment
Please, Sign In to add comment