Advertisement
Guest User

Untitled

a guest
Oct 23rd, 2019
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.06 KB | None | 0 0
  1. // Parking Lot excercise
  2.  
  3. // - The parking lot has multiple levels.
  4. // - Each level has multiple rows of spots.
  5. // - The parking lot can park motorcycles, cars, and buses.
  6. // - The parking lot has motorcycle spots, compact spots, and large spots.
  7. // - A motorcycle can park in any spot.
  8. // - A car can park in either a single compact spot or a single large spot.
  9. // - A bus can park in five large spots that are consecutive and within the same row. It cannot park in small spots
  10.  
  11.  
  12. #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
  13. enum VehicleSize {
  14. Motorcycle,
  15. Compact,
  16. Large,
  17. }
  18.  
  19. #[derive(Debug, Clone, Copy, PartialEq)]
  20. struct SpotId(usize);
  21.  
  22. #[derive(Debug)]
  23. struct Spot {
  24. size: VehicleSize,
  25. is_available: bool,
  26. row: u8,
  27. id: SpotId,
  28. }
  29.  
  30. struct Level {
  31. floor: usize,
  32. spots: Vec<Spot>,
  33. }
  34.  
  35. const ROWS_IN_LEVEL: u8 = 4;
  36. const SPOTS_IN_ROW: u8 = 12;
  37. impl Level {
  38. fn new(floor: usize) -> Self {
  39. let motos_per_row = SPOTS_IN_ROW / 4;
  40. let compacts_per_row = SPOTS_IN_ROW / 4;
  41. Level {
  42. floor,
  43. spots: (0..ROWS_IN_LEVEL * SPOTS_IN_ROW)
  44. .map(|i| {
  45. let size = if (i % SPOTS_IN_ROW) < motos_per_row {
  46. VehicleSize::Motorcycle
  47. } else if (i % SPOTS_IN_ROW) < compacts_per_row + motos_per_row {
  48. VehicleSize::Compact
  49. } else {
  50. VehicleSize::Large
  51. };
  52. Spot {
  53. size,
  54. is_available: true,
  55. row: i / SPOTS_IN_ROW,
  56. id: SpotId(usize::from(i)),
  57. }
  58. })
  59. .collect(),
  60. }
  61. }
  62.  
  63. fn available_spots(&self) -> usize {
  64. println!("spots: {:?}", self.spots);
  65. self.spots.iter().filter(|spot| spot.is_available).count()
  66. }
  67.  
  68. fn park_vehicle(&mut self, vehicle: &mut impl Parkable) -> Result<(), String> {
  69. let mut prev_row = 0;
  70. let mut prev_i = 0;
  71. let mut spots: Vec<&mut Spot> = vec![];
  72. for (i, spot) in self.spots.iter_mut().enumerate() {
  73. if prev_row != spot.row || i != prev_i + 1 {
  74. spots.clear();
  75. }
  76. prev_row = spot.row;
  77. prev_i = i;
  78.  
  79. if spot.is_available && vehicle.can_fit_in_spot(spot) {
  80. spots.push(spot);
  81. if spots.len() == vehicle.slots_needed() {
  82. break;
  83. }
  84. }
  85. }
  86.  
  87. if spots.len() == vehicle.slots_needed() {
  88. for spot in spots.iter_mut() {
  89. spot.is_available = false;
  90. }
  91. vehicle.park(self.floor, spots.into_iter().map(|s| s.id).collect());
  92. Ok(())
  93. } else {
  94. Err(String::from("No parking available on this level!"))
  95. }
  96. }
  97.  
  98. fn clear_vehicle(&mut self, parked_vehicle: &ParkedVehicle) {
  99. let spots: Vec<&mut Spot> = self
  100. .spots
  101. .iter_mut()
  102. .filter(|spot| parked_vehicle.spots.contains(&spot.id))
  103. .collect();
  104. for spot in spots {
  105. spot.is_available = true;
  106. }
  107. }
  108. }
  109.  
  110. struct ParkingLot {
  111. levels: Vec<Level>,
  112. }
  113. impl ParkingLot {
  114. fn new(levels: usize) -> Self {
  115. ParkingLot {
  116. levels: (0..levels).map(|level| Level::new(level)).collect(),
  117. }
  118. }
  119. fn park_vehicle(&mut self, vehicle: &mut impl Parkable) -> Result<(), String> {
  120. self.levels
  121. .iter_mut()
  122. .find_map(|level| level.park_vehicle(vehicle).ok())
  123. .ok_or(String::from("No parking in this lot!"))
  124. }
  125.  
  126. fn clear_vehicle(&mut self, vehicle: &mut impl Parkable) -> Result<ParkedVehicle, String> {
  127. match vehicle.leave() {
  128. Ok(parked_vehicle) => {
  129. if let Some(level) = self
  130. .levels
  131. .iter_mut()
  132. .find(|level| level.floor == parked_vehicle.level)
  133. {
  134. level.clear_vehicle(&parked_vehicle);
  135. Ok(parked_vehicle)
  136. } else {
  137. Err(String::from("no parking level found!"))
  138. }
  139. }
  140. Err(e) => Err(e),
  141. }
  142. }
  143. }
  144.  
  145. trait Parkable {
  146. fn slots_needed(&self) -> usize;
  147. fn can_fit_in_spot(&self, spot: &Spot) -> bool;
  148. fn park(&mut self, level: usize, spots: Vec<SpotId>);
  149. fn leave(&mut self) -> Result<ParkedVehicle, String>;
  150. }
  151.  
  152. #[derive(Debug, PartialEq)]
  153. struct ParkedVehicle {
  154. level: usize,
  155. spots: Vec<SpotId>,
  156. }
  157.  
  158. struct Motorcycle {
  159. parked: Option<ParkedVehicle>,
  160. }
  161. impl Motorcycle {
  162. fn new() -> Self {
  163. Motorcycle { parked: None }
  164. }
  165. }
  166.  
  167. impl Parkable for Motorcycle {
  168. fn slots_needed(&self) -> usize {
  169. 1
  170. }
  171. fn can_fit_in_spot(&self, spot: &Spot) -> bool {
  172. spot.size >= VehicleSize::Motorcycle
  173. }
  174. fn park(&mut self, level: usize, spots: Vec<SpotId>) {
  175. self.parked = Some(ParkedVehicle { level, spots });
  176. }
  177. fn leave(&mut self) -> Result<ParkedVehicle, String> {
  178. if let Some(parked) = self.parked.take() {
  179. self.parked = None;
  180. Ok(parked)
  181. } else {
  182. Err(String::from("Wasn't parked!"))
  183. }
  184. }
  185. }
  186.  
  187. struct Car {
  188. parked: Option<ParkedVehicle>,
  189. }
  190. impl Car {
  191. fn new() -> Self {
  192. Car { parked: None }
  193. }
  194. }
  195. impl Parkable for Car {
  196. fn slots_needed(&self) -> usize {
  197. 1
  198. }
  199. fn can_fit_in_spot(&self, spot: &Spot) -> bool {
  200. spot.size >= VehicleSize::Compact
  201. }
  202. fn park(&mut self, level: usize, spots: Vec<SpotId>) {
  203. self.parked = Some(ParkedVehicle { level, spots });
  204. }
  205. fn leave(&mut self) -> Result<ParkedVehicle, String> {
  206. if let Some(parked) = self.parked.take() {
  207. self.parked = None;
  208. Ok(parked)
  209. } else {
  210. Err(String::from("Wasn't parked!"))
  211. }
  212. }
  213. }
  214.  
  215. struct Bus {
  216. parked: Option<ParkedVehicle>,
  217. }
  218. impl Bus {
  219. fn new() -> Self {
  220. Bus { parked: None }
  221. }
  222. }
  223. impl Parkable for Bus {
  224. fn slots_needed(&self) -> usize {
  225. 5
  226. }
  227. fn can_fit_in_spot(&self, spot: &Spot) -> bool {
  228. spot.size >= VehicleSize::Large
  229. }
  230. fn park(&mut self, level: usize, spots: Vec<SpotId>) {
  231. self.parked = Some(ParkedVehicle { level, spots });
  232. }
  233. fn leave(&mut self) -> Result<ParkedVehicle, String> {
  234. if let Some(parked) = self.parked.take() {
  235. self.parked = None;
  236. Ok(parked)
  237. } else {
  238. Err(String::from("Wasn't parked!"))
  239. }
  240. }
  241. }
  242.  
  243. #[test]
  244. fn test_level_park() {
  245. let mut level: Level = Level::new(1);
  246. assert_eq!(level.available_spots(), 48);
  247. assert!(level.park_vehicle(&mut Motorcycle::new()).is_ok());
  248. assert_eq!(level.available_spots(), 47);
  249. assert!(level.park_vehicle(&mut Bus::new()).is_ok());
  250. assert_eq!(level.available_spots(), 42);
  251. assert!(level.park_vehicle(&mut Car::new()).is_ok());
  252. assert_eq!(level.available_spots(), 41);
  253.  
  254. assert!(level.park_vehicle(&mut Bus::new()).is_ok());
  255. assert_eq!(level.available_spots(), 36);
  256. assert!(level.park_vehicle(&mut Bus::new()).is_ok());
  257. assert_eq!(level.available_spots(), 31);
  258. assert!(level.park_vehicle(&mut Bus::new()).is_ok());
  259. assert_eq!(level.available_spots(), 26);
  260. assert!(level.park_vehicle(&mut Bus::new()).is_err());
  261. assert!(level.park_vehicle(&mut Car::new()).is_ok());
  262. assert!(level.park_vehicle(&mut Car::new()).is_ok());
  263. assert!(level.park_vehicle(&mut Car::new()).is_ok());
  264. assert!(level.park_vehicle(&mut Car::new()).is_ok());
  265. }
  266.  
  267. #[test]
  268. fn test_level_unpark() {
  269. let mut level: Level = Level::new(1);
  270. assert_eq!(level.available_spots(), 48);
  271. let mut motorcycle = Motorcycle::new();
  272. assert!(level.park_vehicle(&mut motorcycle).is_ok());
  273. assert_eq!(level.available_spots(), 47);
  274.  
  275. let mut bus = Bus::new();
  276. assert!(level.park_vehicle(&mut bus).is_ok());
  277. assert_eq!(level.available_spots(), 42);
  278.  
  279. assert_eq!(
  280. &motorcycle.parked,
  281. &Some(ParkedVehicle {
  282. level: 1,
  283. spots: vec![SpotId(0)]
  284. })
  285. );
  286. level.clear_vehicle(&motorcycle.parked.unwrap());
  287. assert_eq!(level.available_spots(), 43);
  288. assert_eq!(
  289. &bus.parked,
  290. &Some(ParkedVehicle {
  291. level: 1,
  292. spots: vec![SpotId(6), SpotId(7), SpotId(8), SpotId(9), SpotId(10)]
  293. })
  294. );
  295. level.clear_vehicle(&bus.parked.unwrap());
  296. assert_eq!(level.available_spots(), 48);
  297. }
  298.  
  299. #[test]
  300. fn test_parking_lot() {
  301. let mut lot = ParkingLot::new(2);
  302.  
  303. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  304. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  305. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  306. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  307. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  308. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  309. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  310. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  311. assert!(lot.park_vehicle(&mut Bus::new()).is_err());
  312. }
  313.  
  314. #[test]
  315. fn test_parking_lot_unpark() {
  316. let mut lot = ParkingLot::new(3);
  317.  
  318. // level 0:
  319. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  320. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  321. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  322. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  323. // level 1:
  324. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  325. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  326. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  327. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  328. // level 2:
  329. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  330. assert!(lot.park_vehicle(&mut Bus::new()).is_ok());
  331.  
  332. let mut bus = Bus::new();
  333. assert!(lot.park_vehicle(&mut bus).is_ok());
  334. assert_eq!(
  335. &bus.parked,
  336. &Some(ParkedVehicle {
  337. level: 2,
  338. spots: vec![SpotId(30), SpotId(31), SpotId(32), SpotId(33), SpotId(34)]
  339. })
  340. );
  341. assert!(lot.clear_vehicle(&mut bus).is_ok());
  342. assert_eq!(bus.parked, None);
  343. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement