Advertisement
M1ngXU

25

Dec 25th, 2021
555
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 2.96 KB | None | 0 0
  1. use std::collections::HashMap;
  2. use std::fmt::Debug;
  3. use std::fmt;
  4.  
  5. #[derive(Copy, Clone, Eq, PartialEq)]
  6. enum Direction {
  7.     Right,
  8.     Down,
  9.     None
  10. }
  11. impl Direction {
  12.     fn new(c: char) -> Self {
  13.         match c {
  14.             '>' => Direction::Right,
  15.             'v' => Direction::Down,
  16.             '.' => Direction::None,
  17.             _ => panic!("Unknown Direction {}!", c)
  18.         }
  19.     }
  20.  
  21.     fn to_str(&self) -> &str {
  22.         match self {
  23.             Direction::Right => ">",
  24.             Direction::Down => "v",
  25.             Direction::None => "."
  26.         }
  27.     }
  28. }
  29. struct Grid {
  30.     grid: HashMap<usize, HashMap<usize, Direction>>,
  31.     width: usize,
  32.     height: usize
  33. }
  34.  
  35. impl Debug for Grid {
  36.     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  37.         write!(f, "{}", self.to_string())
  38.     }
  39. }
  40.  
  41. impl Grid {
  42.     fn new(width: usize, height: usize) -> Self {
  43.         Grid {
  44.             grid: HashMap::new(),
  45.             width,
  46.             height
  47.         }
  48.     }
  49.  
  50.     fn to_string(&self) -> String {
  51.         let mut s = String::new();
  52.         for y in 0..self.height {
  53.             for x in 0..self.width {
  54.                 s += &self.get(x, y).to_str();
  55.             }
  56.             s += "\n";
  57.         }
  58.         s
  59.     }
  60.  
  61.     fn check_x_y(&self, x: usize, y: usize) {
  62.         if x >= self.width {
  63.             panic!("Width is {}, but tried to access {}.", self.width, x);
  64.         }
  65.         if y >= self.height {
  66.             panic!("Height is {}, but tried to access {}.", self.height, y);
  67.         }
  68.     }
  69.  
  70.     fn get(&self, x: usize, y: usize) -> Direction {
  71.         self.check_x_y(x, y);
  72.         if let Some(gy) = self.grid.get(&y) {
  73.             if let Some(gx) = gy.get(&x) {
  74.                 return *gx;
  75.             }
  76.         }
  77.         Direction::None
  78.     }
  79.  
  80.     fn get_mut(&mut self, x: usize, y: usize) -> &mut Direction {
  81.         self.grid.entry(y).or_insert(HashMap::new()).entry(x).or_insert(Direction::None)
  82.     }
  83.  
  84.     fn set(&mut self, x: usize, y: usize, d: Direction) {
  85.         *self.get_mut(x, y) = d;
  86.     }
  87. }
  88.  
  89. fn main() {
  90.     let input = tools::parser::string("25");
  91.  
  92.     let width = input.split("\n").next().unwrap().len();
  93.     let height = input.len() / width;
  94.    
  95.     let mut grid = Grid::new(width, height);
  96.     for (y, s) in input.split("\n").enumerate() {
  97.         for (x, d) in s.chars().map(| c | Direction::new(c)).enumerate() {
  98.             grid.set(x, y, d);
  99.         }
  100.     }
  101.  
  102.     let mut tick = 0;
  103.     let mut moved = true;
  104.  
  105.     while moved == true {
  106.         moved = false;
  107.         let mut new_grid = Grid::new(width, height);
  108.        
  109.         for y in 0..height {
  110.             for x in 0..width {
  111.                 if grid.get(x, y) == Direction::Right {
  112.                     let new_x = (x + 1) % width;
  113.                     if grid.get(new_x, y) == Direction::None {
  114.                         *new_grid.get_mut(new_x, y) = Direction::Right;
  115.                         moved = true;
  116.                     } else {
  117.                         *new_grid.get_mut(x, y) = Direction::Right;
  118.                     }
  119.                 }
  120.             }
  121.         }
  122.         for y in 0..height {
  123.             for x in 0..width {
  124.                 if grid.get(x, y) == Direction::Down {
  125.                     let new_y = (y + 1) % height;
  126.                     if new_grid.get(x, new_y) == Direction::None && grid.get(x, new_y) != Direction::Down {
  127.                         *new_grid.get_mut(x, new_y) = Direction::Down;
  128.                         moved = true;
  129.                     } else {
  130.                         *new_grid.get_mut(x, y) = Direction::Down;
  131.                     }
  132.                 }
  133.             }
  134.         }
  135.         grid = new_grid;
  136.         tick += 1;
  137.     }
  138.  
  139.     println!("{}", tick);
  140. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement