fork download
  1. #include <functional>
  2. #include <iostream>
  3. #include <sstream>
  4. #include <iomanip>
  5. #include <string>
  6. #include <random>
  7. #include <map>
  8. using namespace std;
  9.  
  10. class PersonalIdentificationNumber{
  11. public:
  12. static constexpr unsigned LENGTH = 4;
  13.  
  14. explicit PersonalIdentificationNumber(unsigned number): _number(number){
  15. cut_if_necessary(_number);
  16. }
  17.  
  18. operator unsigned() const{ return _number; }
  19.  
  20. string formatted() const{
  21. ostringstream ss;
  22. ss << setw(LENGTH) << setfill('0') << _number;
  23. return ss.str();
  24. }
  25. private:
  26. void cut_if_necessary(unsigned &number) const{
  27. while(number >= 10000)
  28. number /= 10;
  29. }
  30. unsigned _number;
  31. };
  32.  
  33. using PID = PersonalIdentificationNumber;
  34.  
  35. bool operator==(const PID &lhs, const PID &rhs){
  36. return (unsigned)lhs == (unsigned)rhs;
  37. }
  38.  
  39. template<typename T>
  40. class LoginAttemptor{
  41. public:
  42. struct Actions{
  43. function<T()> in;
  44. function<bool(T)> onCheck;
  45. function<void(T)> onSuccess;
  46. function<void(T)> onPartialFailure;
  47. function<void(T)> onTotalFailure;
  48. function<void()> onNoMoreAttemptsLeft;
  49. };
  50.  
  51. LoginAttemptor(Actions actions, size_t maxFailures)
  52. : _actions(actions), _maxFailures(maxFailures), _failures(0){}
  53.  
  54. bool canAttempt() const{
  55. return _maxFailures > _failures;
  56. }
  57.  
  58. bool attempt(){
  59. if(!canAttempt()){
  60. _actions.onNoMoreAttemptsLeft();
  61. return false;
  62. };
  63. T in_result = _actions.in();
  64. if(_actions.onCheck(in_result)){
  65. _actions.onSuccess(in_result);
  66. return true;
  67. }
  68. _failures += 1;
  69. if(canAttempt()) _actions.onPartialFailure(in_result);
  70. else _actions.onTotalFailure(in_result);
  71. }
  72. private:
  73. const Actions _actions;
  74. const size_t _maxFailures;
  75. size_t _failures;
  76. };
  77.  
  78. int main(){
  79. const size_t maxNumberOfLoginAttempts = 3;
  80. PersonalIdentificationNumber a(1), b(10000);
  81. cout << a.formatted() << " " << b.formatted() << endl;
  82.  
  83. auto loginAttemptor = LoginAttemptor<PID>({
  84. []{unsigned in; cin >> in; return PID(in);},
  85. [](PID r){return r == PID(133);},
  86. [](PID r){cout << "Success with " << r.formatted() << "!" << endl;},
  87. [](PID r){cout << "Partial failure with " << r.formatted() << "." << endl;},
  88. [](PID r){cout << "Total failure with " << r.formatted() << "!" << endl;},
  89. []{cout << "No more attempts left!" << endl;}
  90. }, maxNumberOfLoginAttempts
  91. ), copy = loginAttemptor;
  92.  
  93. for(size_t i = 0; i <= maxNumberOfLoginAttempts; ++i)
  94. loginAttemptor.attempt();
  95.  
  96. while(!copy.attempt());
  97. return 0;
  98. }
Success #stdin #stdout 0s 3444KB
stdin
1 2 3 4 133
stdout
0001 1000
Partial failure with 0001.
Partial failure with 0002.
Total failure with 0003!
No more attempts left!
Partial failure with 0004.
Success with 0133!