fork download
  1. // 1st day: Let's create door.
  2. // I think Door can be represented simply:
  3. struct Door { opened: bool, knob_turned: bool }
  4.  
  5. // Logic of Door.
  6. impl Door {
  7. fn new() -> Self { Door { opened: false, knob_turned: false } }
  8. fn is_open(&self) -> bool { self.opened }
  9.  
  10. #[allow(unused)]
  11. fn is_close(&mut self) -> bool { !self.opened }
  12. fn knob_turn(&mut self) { self.knob_turned = true; }
  13. fn knob_unturn(&mut self) { self.knob_turned = false; }
  14. fn push(&mut self) {
  15. if self.knob_turned { self.opened = true; }
  16. }
  17. fn pull(&mut self) { self.opened = false; self.knob_turned = false; }
  18. fn can_be_opened(&self) -> bool { self.knob_turned && !self.opened }
  19. }
  20.  
  21. // Day 2. We need another door.
  22. // Let's define common methods of Door.
  23. trait TDoor {
  24. fn is_open(&self) -> bool;
  25. fn knob_turn(&mut self);
  26. fn knob_unturn(&mut self);
  27. fn push(&mut self);
  28. fn pull(&mut self);
  29. fn can_be_opened(&self) -> bool;
  30. fn is_close(&self) -> bool { !self.is_open() }
  31. }
  32.  
  33. // .. and Door is a type of TDoor.
  34. impl TDoor for Door {
  35. fn is_open(&self) -> bool { Door::is_open(self) }
  36. fn knob_turn(&mut self) { Door::knob_turn(self) }
  37. fn knob_unturn(&mut self) { Door::knob_unturn(self) }
  38. fn push(&mut self) { Door::push(self) }
  39. fn pull(&mut self) { Door::pull(self) }
  40. fn can_be_opened(&self) -> bool { Door::can_be_opened(self) }
  41. }
  42. // Now we can manipulate any doors through TDoor.
  43.  
  44. // Next we define DoorWithCloser which will be closed automatically after 4 seconds.
  45. use std::time::Duration;
  46. use std::sync::{Arc, Mutex};
  47. struct DoorWithCloser<T: TDoor> {
  48. // Because door is modified by main thread and closer thread,
  49. // we need Atomic Reference Counting (Arc) and exclusive mutation (Mutex)
  50. door: Arc<Mutex<T>>,
  51. closer_sec: u64,
  52. }
  53.  
  54. // Constructor and basic operations.
  55. impl<T: TDoor> DoorWithCloser<T> {
  56. fn from_door(door: T) -> Self {
  57. DoorWithCloser { door: Arc::new(Mutex::new(door)), closer_sec: 4 }
  58. }
  59. #[allow(unused)]
  60. fn set_closer_timer(&mut self, sec: u64) { self.closer_sec = sec; }
  61. }
  62.  
  63. // For convenience, `new` can create previous `Door` with closer.
  64. impl DoorWithCloser<Door> {
  65. fn new() -> DoorWithCloser<Door> { DoorWithCloser::from_door(Door::new()) }
  66. }
  67.  
  68. // Logic of DoorWithCloser.
  69. // Rust is very strict about multithreading,
  70. // so you doesn't need to understand all notation below.
  71. impl<T: TDoor + Send + 'static> TDoor for DoorWithCloser<T> {
  72. fn is_open(&self) -> bool { self.door.lock().unwrap().is_open() }
  73. fn knob_turn(&mut self) { self.door.lock().unwrap().knob_turn() }
  74. fn knob_unturn(&mut self) { self.door.lock().unwrap().knob_unturn() }
  75. fn pull(&mut self) { self.door.lock().unwrap().pull() }
  76. fn can_be_opened(&self) -> bool { self.door.lock().unwrap().can_be_opened() }
  77.  
  78. // When door is opened, closer thread start.
  79. fn push(&mut self) {
  80. self.door.lock().unwrap().push();
  81. if self.door.lock().unwrap().is_open() {
  82. let door = Arc::downgrade(&self.door);
  83. let sec = self.closer_sec;
  84. std::thread::spawn(move || {
  85. std::thread::sleep(Duration::new(sec, 0));
  86. let door_rwlock = door.upgrade().unwrap();
  87. let mut door = door_rwlock.lock().unwrap();
  88. door.pull();
  89. });
  90. }
  91. }
  92.  
  93.  
  94. }
  95.  
  96. // Let's add another item to `Door`: stopper which prevents closing
  97. struct DoorWithStopper<T: TDoor> { door: T, stoppered: bool }
  98.  
  99. // Constructor and basic operations.
  100. impl<T: TDoor> DoorWithStopper<T> {
  101. fn from_door(door: T) -> Self { DoorWithStopper { door: door, stoppered: false } }
  102. fn be_stoppered_on(&mut self) { self.stoppered = true; }
  103. fn be_stoppered_off(&mut self) { self.stoppered = false; }
  104. }
  105.  
  106. // For convenience, `new` creates previous `Door` with stopper.
  107. impl DoorWithStopper<Door> { fn new() -> Self { DoorWithStopper::from_door(Door::new()) } }
  108.  
  109. // Logic of DoorWithStopper, which is simpler than DoorWithCloser...
  110. impl<T: TDoor> TDoor for DoorWithStopper<T> {
  111. fn is_open(&self) -> bool { self.door.is_open() }
  112. fn knob_turn(&mut self) { self.door.knob_turn() }
  113. fn knob_unturn(&mut self) { self.door.knob_unturn() }
  114. fn can_be_opened(&self) -> bool { self.door.can_be_opened() }
  115. fn push(&mut self) {
  116. self.door.push();
  117. if self.door.is_open() { self.be_stoppered_off() }
  118. }
  119. fn pull(&mut self) {
  120. if !self.stoppered { self.door.pull() }
  121. }
  122. }
  123.  
  124.  
  125. // 3rd day: Let's Combine stopper and closer.
  126.  
  127. // But it seems that stopper always precedes over closer,
  128. // So just define DoorWithStopperCloser like this:
  129. struct DoorWithStopperCloser { door: DoorWithStopper<DoorWithCloser<Door>> }
  130.  
  131. // Constructors and basic operations
  132. impl DoorWithStopperCloser {
  133. fn new() -> Self {
  134. DoorWithStopperCloser {
  135. door: DoorWithStopper {
  136. door: DoorWithCloser::new(),
  137. stoppered: false,
  138. }
  139. }
  140. }
  141. fn be_stoppered_on(&mut self) { self.door.be_stoppered_on() }
  142. fn be_stoppered_off(&mut self) { self.door.be_stoppered_off() }
  143. }
  144.  
  145. // Logic of DoorWithStopperCloser
  146. impl TDoor for DoorWithStopperCloser {
  147. fn is_open(&self) -> bool { self.door.is_open() }
  148. fn knob_turn(&mut self) { self.door.knob_turn() }
  149. fn knob_unturn(&mut self) { self.door.knob_unturn() }
  150. fn push(&mut self) { self.door.push() }
  151. fn pull(&mut self) { self.door.pull() }
  152. fn can_be_opened(&self) -> bool { self.door.can_be_opened() }
  153. }
  154.  
  155. fn main() {
  156. let mut door = Door::new();
  157. println!("door is a door...");
  158. door.knob_turn();
  159. println!("door.knob_turn(); door.can_be_opened(); => {}", door.can_be_opened());
  160. door.knob_unturn();
  161. println!("door.knob_unturn(); door.can_be_opened(); => {}", door.can_be_opened());
  162. door.push();
  163. println!("door.push(); door.is_open(); => {}", door.is_open());
  164. door.knob_turn(); door.push();
  165. println!("door.knob_turn(); door.push(); door.is_open(); => {}", door.is_open());
  166. door.pull();
  167. println!("door.pull; door.is_open(); => {}", door.is_open());
  168. println!("door.can_be_opened(); => {}\n", door.can_be_opened());
  169.  
  170. let mut door = DoorWithCloser::new();
  171. println!("door is doorWithCloser...");
  172. door.knob_turn(); door.push();
  173. println!("door.knob_turn(); door.push(); door.is_open(); => {}", door.is_open());
  174. std::thread::sleep(Duration::new(1, 0));
  175. println!("1 second after, door.is_open(); => {}", door.is_open());
  176. std::thread::sleep(Duration::new(4, 0));
  177. println!("4 seconds after, door.is_open(); => {}\n", door.is_open());
  178.  
  179. let mut door = DoorWithStopper::new();
  180. println!("door is DoorWithStopper...");
  181. door.knob_turn(); door.push();
  182. println!("door.knob_turn(); door.push(); door.is_open(); => {}", door.is_open());
  183. door.be_stoppered_on(); door.pull();
  184. println!("door.be_stoppered_on(); door.pull(); door.is_close(); => {}", door.is_close()); // => false
  185. door.be_stoppered_off(); door.pull();
  186. println!("door.be_stoppered_off(); door.pull(); door.is_close(); => {}", door.is_close()); // => true
  187. door.knob_turn(); door.push();
  188. println!("door.knob_turn(); door.push(); door.is_open(); => {}", door.is_open()); // => true
  189. door.be_stoppered_on(); door.pull();
  190. println!("door.be_stoppered_on(); door.pull(); door.is_close() => {}", door.is_close());
  191. door.push(); door.pull();
  192. println!("door.push(); door.pull(); door.is_close(); => {}\n", door.is_close());
  193.  
  194. let mut door = DoorWithStopperCloser::new();
  195. println!("door is a DoorWithStopperCloser...");
  196. door.knob_turn(); door.push();
  197. println!("door.knob_turn(); door.push(); door.is_open(); => {}", door.is_open()); // => true
  198. door.be_stoppered_on(); std::thread::sleep(Duration::new(4, 0));
  199. println!("door.be_stoppered_on(); then 4 seconds after, door.is_close(); => {}", door.is_close()); // => false
  200. door.be_stoppered_off(); std::thread::sleep(Duration::new(4, 0));
  201. println!("door.be_stoppered_off(); then 4 seconds after, door.is_close(); => {}", door.is_close()); // => true
  202. door.knob_turn(); door.push();
  203. println!("door.knob_turn(); door.push(); door.is_open(); => {}", door.is_open()); // => true
  204. door.be_stoppered_on(); std::thread::sleep(Duration::new(4, 0));
  205. println!("door.be_stoppered_on(); then 4 seconds after, door.is_close(); => {}", door.is_close()); // => false
  206. door.push(); std::thread::sleep(Duration::new(4, 0));
  207. println!("door.push(); then 4 seconds after, door.is_close(); => {}", door.is_close()); // => true
  208. }
  209.  
Time limit exceeded #stdin #stdout 5s 19024KB
stdin
Standard input is empty
stdout
door is a door...
door.knob_turn(); door.can_be_opened(); => true
door.knob_unturn(); door.can_be_opened(); => false
door.push(); door.is_open(); => false
door.knob_turn(); door.push(); door.is_open(); => true
door.pull; door.is_open(); => false
door.can_be_opened(); => false

door is doorWithCloser...
door.knob_turn(); door.push(); door.is_open(); => true
1 second after, door.is_open(); => true
4 seconds after, door.is_open(); => false

door is DoorWithStopper...
door.knob_turn(); door.push(); door.is_open(); => true
door.be_stoppered_on(); door.pull(); door.is_close(); => false
door.be_stoppered_off(); door.pull(); door.is_close(); => true
door.knob_turn(); door.push(); door.is_open(); => true
door.be_stoppered_on(); door.pull(); door.is_close() => false
door.push(); door.pull(); door.is_close(); => true

door is a DoorWithStopperCloser...
door.knob_turn(); door.push(); door.is_open(); => true
door.be_stoppered_on(); then 4 seconds after, door.is_close(); => false