fork download
  1. #include <iostream>
  2. #include <initializer_list>
  3. #include <type_traits>
  4. #include <utility>
  5. #include <memory>
  6. #include <functional>
  7.  
  8. template <typename Allocator, typename... Args>
  9. typename Allocator::pointer allocator_new(Allocator& allocator, Args&&... args)
  10. {
  11. auto p = std::allocator_traits<Allocator>::allocate( allocator, 1 );
  12. try
  13. {
  14. std::allocator_traits<Allocator>::construct( allocator, p , std::forward<Args>( args )... );
  15. }
  16. catch (...)
  17. {
  18. std::allocator_traits<Allocator>::destroy( allocator, p );
  19. throw;
  20. }
  21. return p;
  22. }
  23.  
  24. template <typename Allocator>
  25. void allocator_delete(Allocator& allocator, typename Allocator::pointer p)
  26. {
  27. std::allocator_traits<Allocator>::destroy( allocator, p );
  28. std::allocator_traits<Allocator>::deallocate( allocator, p, 1 );
  29. }
  30.  
  31. class ring_node
  32. {
  33. public:
  34. struct linkup_tag {};
  35. ring_node(ring_node* prev, ring_node* next) noexcept
  36. : next_( next ), prev_( prev ) {}
  37. ring_node(ring_node* prev, ring_node* next, linkup_tag ) noexcept
  38. : ring_node( prev, next )
  39. {
  40. prev_->next_ = this;
  41. next_->prev_ = this;
  42. }
  43.  
  44. ring_node(const ring_node&) = delete;
  45. ring_node& operator=(const ring_node&) = delete;
  46.  
  47. ring_node* next() const noexcept { return next_; }
  48. ring_node* prev() const noexcept { return prev_; }
  49.  
  50. friend void link(ring_node* prev, ring_node* next) noexcept
  51. {
  52. next->prev_ = prev;
  53. prev->next_ = next;
  54. }
  55. friend void intersect(ring_node* a, ring_node* b) noexcept
  56. {
  57. ring_node* a_prev = a->prev();
  58. link( b->prev(), a );
  59. link( a_prev, b );
  60. }
  61. friend void flip(ring_node* p)
  62. {
  63. std::swap( p->prev_, p->next_ );
  64. }
  65. private:
  66. ring_node* next_;
  67. ring_node* prev_;
  68. };
  69.  
  70. template <typename T>
  71. class list_node : public ring_node
  72. {
  73. public:
  74. using type = T;
  75. T data;
  76.  
  77. template <typename... Args>
  78. list_node(ring_node* next, Args&&... args) noexcept( noexcept( T( std::declval<Args>()... ) ) )
  79. : ring_node( next->prev(), next, linkup_tag() ), data( std::forward<Args>( args )... )
  80. {}
  81.  
  82. template <typename Allocator, typename... Args>
  83. static list_node* make(Allocator& alloc, ring_node* next, Args&&... args)
  84. {
  85. return allocator_new( alloc, next, std::forward<Args>( args )... );
  86. }
  87. template <typename Allocator>
  88. static void retire(Allocator& alloc, list_node* node)
  89. {
  90. link( node->prev(), node->next() );
  91. allocator_delete( alloc, node );
  92. }
  93. };
  94.  
  95. template <typename Allocator>
  96. class list_iterator;
  97. template <typename Allocator>
  98. class const_list_iterator;
  99. template <typename Allocator>
  100. void splice(const_list_iterator<Allocator> pos, const_list_iterator<Allocator> first, const_list_iterator<Allocator> last);
  101.  
  102. template <typename Allocator>
  103. class const_list_iterator
  104. : public std::iterator<std::bidirectional_iterator_tag,
  105. typename Allocator::value_type::type,
  106. typename Allocator::difference_type,
  107. typename Allocator::value_type::type*,
  108. typename Allocator::value_type::type&>
  109. {
  110. template <typename, typename> friend class list;
  111. friend void splice<>(const_list_iterator, const_list_iterator, const_list_iterator);
  112. public:
  113. using value_type = typename Allocator::value_type::type;
  114. const_list_iterator() noexcept
  115. {}
  116. const value_type& operator*() const noexcept { return static_cast<list_node<value_type>*>( node )->data; }
  117. const value_type* operator->() const noexcept { return &**this; }
  118. const_list_iterator& operator++() noexcept { return node = node->next(), *this; }
  119. const_list_iterator operator++(int) noexcept { return node = node->next(), node->prev(); }
  120. const_list_iterator& operator--() noexcept { return node = node->prev(), *this; }
  121. const_list_iterator operator--(int) noexcept { return node = node->prev(), node->next(); }
  122.  
  123. friend bool operator==(const_list_iterator a, const_list_iterator b) noexcept
  124. {
  125. return a.node == b.node;
  126. }
  127. friend bool operator!=(const_list_iterator a, const_list_iterator b) noexcept
  128. {
  129. return !( a == b );
  130. }
  131. protected:
  132. const_list_iterator(ring_node* node) noexcept
  133. : node( node )
  134. {}
  135. ring_node* node;
  136. };
  137.  
  138. template <typename Allocator>
  139. class list_iterator
  140. : public const_list_iterator<Allocator>
  141. {
  142. template <typename, typename> friend class list;
  143. public:
  144. using value_type = typename Allocator::value_type::type;
  145. list_iterator() noexcept
  146. {}
  147. private:
  148. list_iterator(ring_node* node) noexcept
  149. : const_list_iterator<Allocator>( node )
  150. {}
  151. public:
  152. value_type& operator*() const noexcept { return static_cast<list_node<value_type>*>( this->node )->data; }
  153. value_type* operator->() const noexcept { return &**this; }
  154. list_iterator& operator++() noexcept { return this->node = this->node->next(), *this; }
  155. list_iterator operator++(int) noexcept { return this->node = this->node->next(), this->node->prev(); }
  156. list_iterator& operator--() noexcept { return this->node = this->node->prev(), *this; }
  157. list_iterator operator--(int) noexcept { return this->node = this->node->prev(), this->node->next(); }
  158. };
  159.  
  160. template <typename Allocator>
  161. void splice(const_list_iterator<Allocator> pos, const_list_iterator<Allocator> first, const_list_iterator<Allocator> last)
  162. {
  163. intersect( last.node, pos.node );
  164. intersect( last.node, first.node );
  165. }
  166. template <typename Allocator>
  167. void splice(const_list_iterator<Allocator> pos, const_list_iterator<Allocator> i)
  168. {
  169. splice( pos, i, std::next( i ) );
  170. }
  171.  
  172. template <typename T, typename Allocator = std::allocator<T>>
  173. class list_base : protected std::allocator_traits<Allocator>::template rebind_alloc<list_node<T>>
  174. {
  175. protected:
  176. using node_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<list_node<T>>;
  177. ring_node anchor;
  178. explicit list_base(const Allocator& allocator)
  179. : node_allocator_type( allocator ), anchor( &anchor, &anchor )
  180. {}
  181.  
  182. ~list_base() noexcept
  183. {
  184. for ( ring_node* p = anchor.prev(); p != &anchor; )
  185. {
  186. list_node<T>* q = static_cast<list_node<T>*>( p );
  187. p = p->prev();
  188. allocator_delete<node_allocator_type>( *this, q );
  189. }
  190. }
  191. };
  192.  
  193. template <typename T, typename Allocator = std::allocator<T>>
  194. class list : private list_base<T, Allocator>
  195. {
  196. using base = list_base<T, Allocator>;
  197. using node_type = list_node<T>;
  198. using node_allocator_type = typename std::allocator_traits<Allocator>::template rebind_alloc<node_type>;
  199. public:
  200. // types:
  201. typedef T value_type;
  202. typedef Allocator allocator_type;
  203. typedef typename allocator_type::reference reference;
  204. typedef typename allocator_type::const_reference const_reference;
  205. typedef typename allocator_type::pointer pointer;
  206. typedef typename allocator_type::const_pointer const_pointer;
  207. typedef typename allocator_type::size_type size_type;
  208. typedef typename allocator_type::difference_type difference_type;
  209. typedef list_iterator<node_allocator_type> iterator;
  210. typedef list_iterator<node_allocator_type> const_iterator;
  211. typedef std::reverse_iterator<iterator> reverse_iterator;
  212. typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
  213.  
  214. // construct/copy/destroy:
  215. explicit list(const allocator_type& allocator = allocator_type())
  216. : base( allocator )
  217. {}
  218. explicit list(size_type n, const value_type& value = value_type(), const allocator_type& allocator = allocator_type())
  219. : list( allocator )
  220. {
  221. while ( n-- )
  222. push_back( value );
  223. }
  224. template <typename InputIterator, typename std::enable_if<!std::is_arithmetic<InputIterator>::value, int>::type = 0>
  225. list(InputIterator first, InputIterator last, const allocator_type& allocator = allocator_type())
  226. : list( allocator )
  227. {
  228. for ( ; first != last; ++first )
  229. push_back( *first );
  230. }
  231. list(const list& other)
  232. : list( other.begin(), other.end(),
  233. std::allocator_traits<node_allocator_type>::select_on_container_copy_construction( other.node_alloc() ) )
  234. {}
  235. list(list&& other)
  236. : base( other.node_alloc() )
  237. {
  238. swap( other );
  239. }
  240. list(const list& other, const allocator_type& allocator)
  241. : list( other.begin(), other.end(), allocator )
  242. {}
  243. list(list&& other, const allocator_type& allocator)
  244. : list( allocator )
  245. {
  246. swap( other );
  247. }
  248. list(std::initializer_list<T> init_list, const allocator_type& allocator = allocator_type())
  249. : list( init_list.begin(), init_list.end(), allocator )
  250. {}
  251.  
  252. list& operator=(list rhs) noexcept
  253. {
  254. swap( rhs );
  255. return *this;
  256. }
  257.  
  258. list& operator=(std::initializer_list<T> init_list)
  259. {
  260. assign( init_list );
  261. return *this;
  262. }
  263.  
  264. template <typename InputIterator, typename std::enable_if<!std::is_arithmetic<InputIterator>::value, int>::type = 0>
  265. void assign(InputIterator first, InputIterator last)
  266. {
  267. for ( auto it = begin(); it != end(); ++it )
  268. if ( first == last )
  269. return (void)erase( it, end() );
  270. else
  271. *it = *first++;
  272. insert( end(), first, last );
  273. }
  274. void assign(size_type n, const value_type& value)
  275. {
  276. for ( auto it = begin(); it != end(); ++it )
  277. if ( n-- == 0 )
  278. return erase( it, end() );
  279. else
  280. *it = value;
  281. insert( end(), n, value );
  282. }
  283. void assign(std::initializer_list<T> init)
  284. {
  285. assign( init.begin(), init.end() );
  286. }
  287.  
  288. allocator_type get_allocator() const noexcept { return node_alloc(); }
  289.  
  290. // iterators:
  291. iterator begin() noexcept { return this->anchor.next(); }
  292. const_iterator begin() const noexcept { return this->anchor.next(); }
  293. const_iterator cbegin() const noexcept { return this->anchor.next(); }
  294. iterator end() noexcept { return &this->anchor; }
  295. const_iterator end() const noexcept { return const_cast<ring_node*>( &this->anchor ); }
  296. const_iterator cend() const noexcept { return const_cast<ring_node*>( &this->anchor ); }
  297. reverse_iterator rbegin() noexcept { return reverse_iterator( begin() ); }
  298. const_reverse_iterator rbegin() const noexcept { return const_reverse_iterator( begin() ); }
  299. const_reverse_iterator crbegin() const noexcept { return crbegin(); }
  300. reverse_iterator rend() noexcept { return reverse_iterator( end() ); }
  301. const_reverse_iterator rend() const noexcept { return const_reverse_iterator( end() ); }
  302. const_reverse_iterator crend() const noexcept { return crend(); }
  303.  
  304. // 23.3.5.3, capacity:
  305. bool empty() const noexcept { return begin() == end(); }
  306. size_type size() const noexcept { return std::distance( begin(), end() ); }
  307. size_type max_size() const noexcept { return node_alloc().max_size(); }
  308. void resize(size_type n) { return resize( n, value_type() ); }
  309. void resize(size_type n, const value_type& value)
  310. {
  311. for ( auto it = begin(); it != end(); ++it )
  312. if ( n-- == 0 )
  313. return (void)erase( it, end() );
  314. while ( n-- != 0 )
  315. push_back( value );
  316. }
  317.  
  318. // element access:
  319. value_type& front() noexcept { return *begin(); }
  320. const value_type& front() const noexcept { return *begin(); }
  321. value_type& back() noexcept { return *std::prev( end() ); }
  322. const value_type& back() const noexcept { return *std::prev( end() ); }
  323.  
  324. void pop_front() { erase( begin() ); }
  325. template <class... Args>
  326. void emplace_front(Args&&... args) { return emplace( cbegin(), std::forward<Args>( args )... ); }
  327. void push_front(const value_type& value) { insert( cbegin(), value ); }
  328. void push_front(value_type&& value) { insert( cbegin(), std::move( value ) ); }
  329. void pop_back() { erase( std::prev( end() ) ); }
  330. template <class... Args>
  331. void emplace_back(Args&&... args) { return emplace( cend(), std::forward<Args>( args )... ); }
  332. void push_back(const value_type& value) { insert( cend(), value ); }
  333. void push_back(value_type&& value) { insert( cend(), std::move( value ) ); }
  334.  
  335.  
  336. template <class... Args>
  337. iterator emplace(const_iterator position, Args&&... args)
  338. {
  339. return node_type::make( node_alloc(), position.node, std::forward<Args>( args )... );
  340. }
  341. iterator insert(const_iterator pos, const T& value) { return emplace( pos, value ); }
  342.  
  343. iterator insert(const_iterator position, T&& x) { return emplace( position, std::move( x ) ); }
  344. iterator insert(const_iterator position, size_type n, const T& x)
  345. {
  346. return splice( position--, list( n, x, get_allocator() ) ), ++position;
  347. }
  348.  
  349. template <class InputIterator, typename std::enable_if<!std::is_arithmetic<InputIterator>::value, int>::type = 0>
  350. iterator insert(const_iterator position, InputIterator first, InputIterator last)
  351. {
  352. return splice( position--, list( first, last, get_allocator() ) ), ++position;
  353. }
  354.  
  355. iterator insert(const_iterator position, std::initializer_list<T> il)
  356. {
  357. return splice( position--, list( il.begin(), il.end(), get_allocator() ) ), ++position;
  358. }
  359.  
  360. iterator erase(const_iterator pos) noexcept
  361. {
  362. return node_type::retire( node_alloc(), static_cast<node_type*>( pos++.node ) ), pos;
  363. }
  364. iterator erase(const_iterator pos, const_iterator last) noexcept
  365. {
  366. splice( list( get_allocator() ).end(), pos, last );
  367. return last;
  368. }
  369.  
  370. void swap(list& other) noexcept
  371. {
  372. intersect( &this->anchor, &other.anchor );
  373. intersect( this->anchor.next(), other.anchor.next() );
  374. }
  375. friend void swap(list& a, list& b)
  376. {
  377. a.swap( b );
  378. }
  379.  
  380. void clear() noexcept
  381. {
  382. erase( begin(), end() );
  383. }
  384.  
  385. // 23.3.5.5, list operations:
  386. friend void splice(const_iterator pos, list& x)
  387. {
  388. splice( pos, x.begin(), x.end() );
  389. }
  390. friend void splice(const_iterator pos, list&& x)
  391. {
  392. splice( pos, x.begin(), x.end() );
  393. }
  394.  
  395. void remove(const T& value)
  396. {
  397. remove_if( [&](const T& v) { return v == value; } );
  398. }
  399.  
  400. template <typename Predicate>
  401. void remove_if(Predicate pred)
  402. {
  403. for ( auto it = begin(); it != end(); )
  404. if ( pred( *it ) )
  405. it = erase( it );
  406. else
  407. ++it;
  408. }
  409.  
  410. void unique()
  411. {
  412. unique( std::equal_to<T>() );
  413. }
  414. template <typename BinaryPredicate>
  415. void unique(BinaryPredicate binary_pred)
  416. {
  417. auto it = cbegin();
  418. if ( it != cend() )
  419. for ( ;; )
  420. {
  421. auto it2 = std::next( it );
  422. if ( it2 == cend() )
  423. return;
  424. else if ( binary_pred( *it, *it2 ) )
  425. erase( it2 );
  426. else
  427. ++it;
  428. }
  429. }
  430.  
  431. void merge(list& x) { merge( x, std::less<T>() ); }
  432. void merge(list&& x) { merge( x ); }
  433. template <typename Compare>
  434. void merge(list& x, Compare comp)
  435. {
  436. auto it = cbegin(), it2 = x.cbegin();
  437. for ( ;; )
  438. {
  439. if ( it == cend() )
  440. return splice( it, x );
  441. else if ( it2 == x.cend() )
  442. return;
  443. else if ( !comp( *it2, *it ) )
  444. ++it;
  445. else
  446. splice( it, it2++ );
  447. }
  448. }
  449. template <typename Compare>
  450. void merge(list&& x, Compare comp) { merge( x, comp ); };
  451.  
  452. void reverse() noexcept
  453. {
  454. ring_node* p = const_cast<ring_node*>( &this->anchor );
  455. do {
  456. flip( p );
  457. p = p->next();
  458. } while ( p != &this->anchor );
  459. }
  460.  
  461. void sort() { sort( std::less<T>() ); }
  462. template <typename Compare>
  463. void sort(Compare comp);
  464. private:
  465. node_allocator_type& node_alloc()
  466. {
  467. return *this;
  468. }
  469. const node_allocator_type& node_alloc() const
  470. {
  471. return *this;
  472. }
  473. };
  474.  
  475. #include <iostream>
  476. #include <iterator>
  477. #include <algorithm>
  478.  
  479. struct foo_t {
  480.  
  481. unsigned value;
  482.  
  483. foo_t() : value() {}
  484. foo_t( unsigned value ) : value( value ) {}
  485. operator unsigned() const { return value; }
  486.  
  487. void tell() { std::cout << value; }
  488. };
  489.  
  490. int main()
  491. {
  492. // ein paar Tests ...
  493.  
  494. list< foo_t > list_1;
  495.  
  496. for( unsigned i = 0; i < 20; ++i )
  497. list_1.push_back( foo_t( i ) );
  498.  
  499. for( auto it = list_1.begin(); it != list_1.end(); ++it ) {
  500.  
  501. it->tell();
  502. std::cout << " ";
  503. }
  504. std::cout.put( '\n' );
  505.  
  506. list< foo_t > list_2;
  507.  
  508. std::copy( list_1.begin(), list_1.end(), std::back_inserter( list_2 ) );
  509. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  510. std::cout.put( '\n' );
  511.  
  512. std::for_each( std::begin( list_2 ), std::end( list_2 ), []( foo_t &foo ) { foo.value *= 2; } );
  513. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  514. std::cout.put( '\n' );
  515.  
  516. list_1 = list_2;
  517. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  518. std::cout.put( '\n' );
  519.  
  520. list_1.reverse();
  521. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  522. std::cout.put( '\n' );
  523.  
  524. auto head = list_1.cbegin();
  525. auto tail = list_1.cend();
  526.  
  527. for( unsigned i = 0; i < 3; ++i ) {
  528.  
  529. ++head;
  530. --tail;
  531. }
  532.  
  533. list_1.erase( head, tail );
  534. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  535. std::cout.put( '\n' );
  536.  
  537. list_1.resize( 12, 42 );
  538. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  539. std::cout.put( '\n' );
  540.  
  541. list_1.resize( 7 );
  542. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  543. std::cout.put( '\n' );
  544.  
  545. list_1.erase( list_1.cbegin() );
  546. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  547. std::cout.put( '\n' );
  548.  
  549. list_1.erase( --list_1.cend() );
  550. std::copy( list_1.begin(), list_1.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  551. std::cout.put( '\n' );
  552.  
  553. auto it = list_2.begin();
  554. while( it != list_2.end() ) {
  555.  
  556. if( *it > 15 )
  557. it = list_2.erase( it );
  558. else
  559. ++it;
  560. }
  561. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  562. std::cout.put( '\n' );
  563.  
  564. std::vector< foo_t > vec( list_2.cbegin(), list_2.cend() );
  565. std::copy( vec.begin(), vec.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  566. std::cout.put( '\n' );
  567.  
  568. list_2.insert( ++list_2.cbegin(), 1 );
  569. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  570. std::cout.put( '\n' );
  571.  
  572. list_2.insert( --list_2.cend(), 13 );
  573. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  574. std::cout.put( '\n' );
  575.  
  576. list_2.insert( list_2.cbegin(), 4, foo_t( 42 ) );
  577. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  578. std::cout.put( '\n' );
  579.  
  580. list_2.insert( list_2.cend(), 4, foo_t( 42 ) );
  581. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  582. std::cout.put( '\n' );
  583.  
  584. list_2.insert( ++list_2.cbegin(), 3, foo_t( 17 ) );
  585. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  586. std::cout.put( '\n' );
  587.  
  588. list_2.insert( --list_2.cend(), 2, foo_t( 17 ) );
  589. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  590. std::cout.put( '\n' );
  591.  
  592. list_2.insert( --list_2.cend(), vec.cbegin(), vec.cend() );
  593. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  594. std::cout.put( '\n' );
  595.  
  596. list_2.insert( list_2.cbegin(), --vec.cend(), vec.cend() );
  597. std::copy( list_2.begin(), list_2.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  598. std::cout.put( '\n' );
  599.  
  600. list< foo_t > list_3( vec.cbegin(), vec.cend() );
  601. std::copy( list_3.begin(), list_3.end(), std::ostream_iterator< unsigned >( std::cout, " " ) );
  602. std::cout.put( '\n' );
  603. }
  604.  
Success #stdin #stdout 0s 3032KB
stdin
Standard input is empty
stdout
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 
0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 
38 36 34 32 30 28 26 24 22 20 18 16 14 12 10 8 6 4 2 0 
38 36 34 4 2 0 
38 36 34 4 2 0 42 42 42 42 42 42 
38 36 34 4 2 0 42 
36 34 4 2 0 42 
36 34 4 2 0 
0 2 4 6 8 10 12 14 
0 2 4 6 8 10 12 14 
0 1 2 4 6 8 10 12 14 
0 1 2 4 6 8 10 12 13 14 
42 42 42 42 0 1 2 4 6 8 10 12 13 14 
42 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 42 
42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 42 
42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 17 17 42 
42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 17 17 0 2 4 6 8 10 12 14 42 
14 42 17 17 17 42 42 42 0 1 2 4 6 8 10 12 13 14 42 42 42 17 17 0 2 4 6 8 10 12 14 42 
0 2 4 6 8 10 12 14