Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2023
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.26 KB | None | 0 0
  1. #include <string>
  2. #include <vector>
  3. #include <cstdint>
  4. #include <exception>
  5. #include <unordered_map>
  6. #include <iostream>
  7. #include <cctype>
  8.  
  9. class sequence
  10. {
  11.     size_t _size;
  12.     std::vector<uint8_t> _data;
  13.  
  14. public:
  15.     enum step { up, down, left, right };
  16.  
  17.     struct _step_wrapper
  18.     {
  19.         uint8_t& _data;
  20.         int _position;
  21.    
  22.         _step_wrapper(uint8_t& data, int position): _data(data), _position(position) { /* Nothing to do */ }
  23.  
  24.         operator step() const {return step((_data >> _position) & 3); }
  25.         const step& operator=(const step& s) const { _data = (_data & ~(0x3 << _position)) | (s << _position); return s; }
  26.     };
  27.  
  28.  
  29.     sequence(size_t n): _size(n), _data( (n + 3) / 4, 0){ /*Nothing to do */ }
  30.     sequence(): sequence(0) { /*Nothing to do */ };
  31.  
  32.     size_t size() const { return _size; }
  33.  
  34.     _step_wrapper operator[](size_t i) {
  35.         return _step_wrapper(_data[i / 4], (i % 4) * 2);
  36.     }
  37.  
  38.     //TODO: make enumerator interface
  39. };
  40.  
  41. std::istream& operator>>(std::istream& is, const sequence::_step_wrapper& rhs)
  42. {
  43.     using namespace std::string_literals;
  44.  
  45.     char c = ' ';
  46.  
  47.     while (std::isspace(c))
  48.         is >> c;
  49.  
  50.     switch (c)
  51.     {
  52.         case '^': rhs = sequence::up; break;
  53.         case 'v': rhs = sequence::down; break;
  54.         case '<': rhs = sequence::left; break;
  55.         case '>': rhs = sequence::right; break;
  56.         default:
  57.             throw std::invalid_argument("Invalid sequence char "s + c);
  58.     }
  59.  
  60.     return is;
  61. }
  62.  
  63. std::ostream& operator<<(std::ostream& os, const sequence::_step_wrapper& rhs)
  64. {
  65.     switch (rhs)
  66.     {
  67.         case sequence::up: os << "^"; break;
  68.         case sequence::down: os << "v"; break;
  69.         case sequence::left: os << "<"; break;
  70.         case sequence::right: os << ">"; break;
  71.     }
  72.    
  73.     return os;
  74. }
  75.  
  76.  
  77. bool inizializza_sequenza(size_t n, sequence& old_sequence)
  78. {
  79.     //allocation of [n/4] bytes
  80.     sequence new_seq(n);
  81.  
  82.     try
  83.     {
  84.         for (size_t i = 0; i != n; i++)
  85.             std::cin >> new_seq[i];
  86.  
  87.         //no allocation or copy here, old_seq is deallocated
  88.         old_sequence = std::move(new_seq);
  89.         return true;
  90.     }
  91.     catch (const std::invalid_argument&)
  92.     {
  93.         return false;
  94.     }
  95. }
  96.  
  97. bool inizializza_sequenza(size_t n, std::vector<char>& old_sequence)
  98. {
  99.     using namespace std::string_literals;
  100.  
  101.     //allocation of n bytes
  102.     std::vector<char> new_seq;
  103.     new_seq.resize(n);
  104.  
  105.     for (size_t i = 0; i != n; i++)
  106.     {
  107.         char c;
  108.         std::cin >> c;
  109.        
  110.         switch (c)
  111.         {
  112.             case '^':
  113.             case 'v':
  114.             case '<':
  115.             case '>': new_seq[i] = c; break;
  116.             default:
  117.                 std::cerr << "Invalid sequence char '"s + c + "'\n"s;
  118.                 return false;
  119.         }
  120.     }
  121.  
  122.     old_sequence = std::move(new_seq);
  123.     return true;
  124. }
  125.  
  126. bool inizializza_sequenza(size_t n, char*& old_sequence)
  127. {
  128.     using namespace std::string_literals;
  129.  
  130.     //allocation of n bytes
  131.     char* new_seq = new char[n];
  132.  
  133.     for (size_t i = 0; i != n; i++)
  134.     {
  135.         char c;
  136.         std::cin >> c;
  137.  
  138.         switch (c)
  139.         {
  140.             case '^':
  141.             case 'v':
  142.             case '<':
  143.             case '>': new_seq[i] = c; break;
  144.             default:
  145.                 std::cerr << "Invalid sequence char '"s + c + "'\n"s;
  146.                 return false;
  147.         }
  148.     }
  149.  
  150.     delete [] old_sequence;
  151.     old_sequence = new_seq;
  152.     return true;
  153. }
  154.  
  155.  
  156. #ifdef T1
  157. typedef sequence sequence_t;
  158. #elif T2
  159. typedef std::vector<char> sequence_t;
  160. #else
  161. #define T3
  162. typedef char* sequence_t;
  163. #endif
  164.  
  165.  
  166. int main()
  167. {
  168.     using namespace std::string_literals;
  169.    
  170.     size_t new_size = 7;
  171.  
  172.     #ifdef T3
  173.     sequence_t cur_seq = nullptr;
  174.     #else
  175.     sequence_t cur_seq;
  176.     #endif
  177.  
  178.     bool is_new = inizializza_sequenza(7, cur_seq);
  179.  
  180.     #ifdef T3
  181.     new_size = is_new ? new_size : 0;
  182.     #else
  183.     (void)is_new;
  184.     new_size = cur_seq.size();
  185.     #endif
  186.  
  187.     std::cout << "There are "s << new_size << " element(s) in the sequence:\n"s;
  188.     for (unsigned int i = 0; i != new_size; i++)
  189.         std::cout << cur_seq[i] << " ";
  190.     std::cout << "\n";
  191.  
  192.     return 0;
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement