#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <stdexcept>
#include<bits/stdc++.h>
using namespace std;
class BoardError : public runtime_error {
public :
BoardError( const string& message) : runtime_error( message) { }
} ;
class OOBDrawError : public BoardError {
public :
OOBDrawError( const string& message) : BoardError( message) { }
} ;
class Board {
private :
int m, n;
vector< vector< char >> board;
unordered_map< char , vector< vector< int >>> recordsByPosition;
int priority;
vector< vector< int >> getDrawCoordinates( const vector< int > & size, int pos_x, int pos_y) {
if ( pos_x + size[ 0 ] > m || pos_y + size[ 1 ] > n) {
throw OOBDrawError( "Size & positions would result in out-of-bounds drawing!" ) ;
}
vector< vector< int >> coordinates;
for ( int i = pos_x; i < pos_x + size[ 0 ] ; i++ ) {
for ( int j = pos_y; j < pos_y + size[ 1 ] ; j++ ) {
coordinates.push_back ( { i, j} ) ;
}
}
return coordinates;
}
public :
Board( int m, int n) : m( m) , n( n) , priority( 0 ) , board( m, vector< char > ( n, '0' ) ) { }
void display( ) {
cout << '\n ' ;
for ( const auto & row : board) {
for ( char cell : row) {
cout << cell << " " ;
}
cout << '\n ' ;
}
cout << '\n ' ;
}
void draw( char c, const vector< int > & size, int pos_x, int pos_y) {
if ( recordsByPosition.find ( c) ! = recordsByPosition.end ( ) ) {
cout << c << " already exists on the board. Cannot redraw, only move.\n " ;
return ;
}
vector< vector< int >> drawCoordinates;
try {
drawCoordinates = getDrawCoordinates( size, pos_x, pos_y) ;
} catch ( const OOBDrawError& e) {
cout << e.what ( ) << '\n ' ;
return ;
}
for ( const auto & coord : drawCoordinates) {
board[ coord[ 0 ] ] [ coord[ 1 ] ] = c;
recordsByPosition[ c] .push_back ( coord) ;
}
recordsByPosition[ c] = { { pos_x, pos_y} } ;
}
void move( char c, int new_pos_x, int new_pos_y) {
if ( recordsByPosition.find ( c) == recordsByPosition.end ( ) ) {
cout << "Cannot move character " << c << " that does not exist on the board.\n " ;
return ;
}
const auto & currPos = recordsByPosition[ c] ;
vector< vector< int >> newCoordinates;
try {
newCoordinates = getDrawCoordinates( { 1 , 1 } , new_pos_x, new_pos_y) ;
} catch ( const OOBDrawError& e) {
cout << e.what ( ) << '\n ' ;
return ;
}
for ( const auto & newCoord : newCoordinates) {
if ( find( currPos.begin ( ) , currPos.end ( ) , newCoord) == currPos.end ( ) ) {
board[ newCoord[ 0 ] ] [ newCoord[ 1 ] ] = c;
recordsByPosition[ c] = { newCoord } ;
}
}
for ( const auto & oldCoord : currPos) {
if ( find( newCoordinates.begin ( ) , newCoordinates.end ( ) , oldCoord) == newCoordinates.end ( ) ) {
board[ oldCoord[ 0 ] ] [ oldCoord[ 1 ] ] = '0' ;
}
}
}
} ;
int main( ) {
Board board( 4 , 5 ) ;
board.display ( ) ;
board.draw ( 'a' , { 2 , 2 } , 0 , 0 ) ;
board.display ( ) ;
board.draw ( 'b' , { 2 , 2 } , 0 , 1 ) ;
board.display ( ) ;
board.draw ( 'b' , { 2 , 2 } , 0 , 1 ) ;
board.move ( 'a' , 0 , 1 ) ;
board.display ( ) ;
board.draw ( 'c' , { 2 , 1 } , 2 , 3 ) ;
board.display ( ) ;
board.move ( 'b' , 2 , 1 ) ;
board.display ( ) ;
board.move ( 'a' , 2 , 3 ) ;
board.display ( ) ;
board.move ( 'c' , 2 , 1 ) ;
board.display ( ) ;
board.move ( 'a' , 0 , 3 ) ;
board.display ( ) ;
board.move ( 'c' , 0 , 0 ) ;
board.display ( ) ;
return 0 ;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8dW5vcmRlcmVkX21hcD4KI2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPHN0ZGV4Y2VwdD4KI2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCmNsYXNzIEJvYXJkRXJyb3IgOiBwdWJsaWMgcnVudGltZV9lcnJvciB7CnB1YmxpYzoKICAgIEJvYXJkRXJyb3IoY29uc3Qgc3RyaW5nJiBtZXNzYWdlKSA6IHJ1bnRpbWVfZXJyb3IobWVzc2FnZSkge30KfTsKCmNsYXNzIE9PQkRyYXdFcnJvciA6IHB1YmxpYyBCb2FyZEVycm9yIHsKcHVibGljOgogICAgT09CRHJhd0Vycm9yKGNvbnN0IHN0cmluZyYgbWVzc2FnZSkgOiBCb2FyZEVycm9yKG1lc3NhZ2UpIHt9Cn07CgpjbGFzcyBCb2FyZCB7CnByaXZhdGU6CiAgICBpbnQgbSwgbjsKICAgIHZlY3Rvcjx2ZWN0b3I8Y2hhcj4+IGJvYXJkOwogICAgdW5vcmRlcmVkX21hcDxjaGFyLCB2ZWN0b3I8dmVjdG9yPGludD4+PiByZWNvcmRzQnlQb3NpdGlvbjsKICAgIGludCBwcmlvcml0eTsKCiAgICB2ZWN0b3I8dmVjdG9yPGludD4+IGdldERyYXdDb29yZGluYXRlcyhjb25zdCB2ZWN0b3I8aW50PiYgc2l6ZSwgaW50IHBvc194LCBpbnQgcG9zX3kpIHsKICAgICAgICBpZiAocG9zX3ggKyBzaXplWzBdID4gbSB8fCBwb3NfeSArIHNpemVbMV0gPiBuKSB7CiAgICAgICAgICAgIHRocm93IE9PQkRyYXdFcnJvcigiU2l6ZSAmIHBvc2l0aW9ucyB3b3VsZCByZXN1bHQgaW4gb3V0LW9mLWJvdW5kcyBkcmF3aW5nISIpOwogICAgICAgIH0KCiAgICAgICAgdmVjdG9yPHZlY3RvcjxpbnQ+PiBjb29yZGluYXRlczsKICAgICAgICBmb3IgKGludCBpID0gcG9zX3g7IGkgPCBwb3NfeCArIHNpemVbMF07IGkrKykgewogICAgICAgICAgICBmb3IgKGludCBqID0gcG9zX3k7IGogPCBwb3NfeSArIHNpemVbMV07IGorKykgewogICAgICAgICAgICAgICAgY29vcmRpbmF0ZXMucHVzaF9iYWNrKHtpLCBqfSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIGNvb3JkaW5hdGVzOwogICAgfQoKcHVibGljOgogICAgQm9hcmQoaW50IG0sIGludCBuKSA6IG0obSksIG4obiksIHByaW9yaXR5KDApLCBib2FyZChtLCB2ZWN0b3I8Y2hhcj4obiwgJzAnKSkge30KCiAgICB2b2lkIGRpc3BsYXkoKSB7CiAgICAgICAgY291dCA8PCAnXG4nOwogICAgICAgIGZvciAoY29uc3QgYXV0byYgcm93IDogYm9hcmQpIHsKICAgICAgICAgICAgZm9yIChjaGFyIGNlbGwgOiByb3cpIHsKICAgICAgICAgICAgICAgIGNvdXQgPDwgY2VsbCA8PCAiICI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY291dCA8PCAnXG4nOwogICAgICAgIH0KICAgICAgICBjb3V0IDw8ICdcbic7CiAgICB9CgogICAgdm9pZCBkcmF3KGNoYXIgYywgY29uc3QgdmVjdG9yPGludD4mIHNpemUsIGludCBwb3NfeCwgaW50IHBvc195KSB7CiAgICAgICAgaWYgKHJlY29yZHNCeVBvc2l0aW9uLmZpbmQoYykgIT0gcmVjb3Jkc0J5UG9zaXRpb24uZW5kKCkpIHsKICAgICAgICAgICAgY291dCA8PCBjIDw8ICIgYWxyZWFkeSBleGlzdHMgb24gdGhlIGJvYXJkLiBDYW5ub3QgcmVkcmF3LCBvbmx5IG1vdmUuXG4iOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICB2ZWN0b3I8dmVjdG9yPGludD4+IGRyYXdDb29yZGluYXRlczsKICAgICAgICB0cnkgewogICAgICAgICAgICBkcmF3Q29vcmRpbmF0ZXMgPSBnZXREcmF3Q29vcmRpbmF0ZXMoc2l6ZSwgcG9zX3gsIHBvc195KTsKICAgICAgICB9IGNhdGNoIChjb25zdCBPT0JEcmF3RXJyb3ImIGUpIHsKICAgICAgICAgICAgY291dCA8PCBlLndoYXQoKSA8PCAnXG4nOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICBmb3IgKGNvbnN0IGF1dG8mIGNvb3JkIDogZHJhd0Nvb3JkaW5hdGVzKSB7CiAgICAgICAgICAgIGJvYXJkW2Nvb3JkWzBdXVtjb29yZFsxXV0gPSBjOwogICAgICAgICAgICByZWNvcmRzQnlQb3NpdGlvbltjXS5wdXNoX2JhY2soY29vcmQpOwogICAgICAgIH0KCiAgICAgICAgcmVjb3Jkc0J5UG9zaXRpb25bY10gPSB7IHtwb3NfeCwgcG9zX3l9IH07CiAgICB9CgogICAgdm9pZCBtb3ZlKGNoYXIgYywgaW50IG5ld19wb3NfeCwgaW50IG5ld19wb3NfeSkgewogICAgICAgIGlmIChyZWNvcmRzQnlQb3NpdGlvbi5maW5kKGMpID09IHJlY29yZHNCeVBvc2l0aW9uLmVuZCgpKSB7CiAgICAgICAgICAgIGNvdXQgPDwgIkNhbm5vdCBtb3ZlIGNoYXJhY3RlciAiIDw8IGMgPDwgIiB0aGF0IGRvZXMgbm90IGV4aXN0IG9uIHRoZSBib2FyZC5cbiI7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGNvbnN0IGF1dG8mIGN1cnJQb3MgPSByZWNvcmRzQnlQb3NpdGlvbltjXTsKICAgICAgICB2ZWN0b3I8dmVjdG9yPGludD4+IG5ld0Nvb3JkaW5hdGVzOwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIG5ld0Nvb3JkaW5hdGVzID0gZ2V0RHJhd0Nvb3JkaW5hdGVzKHsxLCAxfSwgbmV3X3Bvc194LCBuZXdfcG9zX3kpOwogICAgICAgIH0gY2F0Y2ggKGNvbnN0IE9PQkRyYXdFcnJvciYgZSkgewogICAgICAgICAgICBjb3V0IDw8IGUud2hhdCgpIDw8ICdcbic7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CgogICAgICAgIGZvciAoY29uc3QgYXV0byYgbmV3Q29vcmQgOiBuZXdDb29yZGluYXRlcykgewogICAgICAgICAgICBpZiAoZmluZChjdXJyUG9zLmJlZ2luKCksIGN1cnJQb3MuZW5kKCksIG5ld0Nvb3JkKSA9PSBjdXJyUG9zLmVuZCgpKSB7CiAgICAgICAgICAgICAgICBib2FyZFtuZXdDb29yZFswXV1bbmV3Q29vcmRbMV1dID0gYzsKICAgICAgICAgICAgICAgIHJlY29yZHNCeVBvc2l0aW9uW2NdID0geyBuZXdDb29yZCB9OwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBmb3IgKGNvbnN0IGF1dG8mIG9sZENvb3JkIDogY3VyclBvcykgewogICAgICAgICAgICBpZiAoZmluZChuZXdDb29yZGluYXRlcy5iZWdpbigpLCBuZXdDb29yZGluYXRlcy5lbmQoKSwgb2xkQ29vcmQpID09IG5ld0Nvb3JkaW5hdGVzLmVuZCgpKSB7CiAgICAgICAgICAgICAgICBib2FyZFtvbGRDb29yZFswXV1bb2xkQ29vcmRbMV1dID0gJzAnOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQp9OwoKaW50IG1haW4oKSB7CiAgICBCb2FyZCBib2FyZCg0LCA1KTsKCiAgICBib2FyZC5kaXNwbGF5KCk7CiAgICBib2FyZC5kcmF3KCdhJywgezIsIDJ9LCAwLCAwKTsKICAgIGJvYXJkLmRpc3BsYXkoKTsKICAgIGJvYXJkLmRyYXcoJ2InLCB7MiwgMn0sIDAsIDEpOwogICAgYm9hcmQuZGlzcGxheSgpOwogICAgYm9hcmQuZHJhdygnYicsIHsyLCAyfSwgMCwgMSk7CiAgICBib2FyZC5tb3ZlKCdhJywgMCwgMSk7CiAgICBib2FyZC5kaXNwbGF5KCk7CiAgICBib2FyZC5kcmF3KCdjJywgezIsIDF9LCAyLCAzKTsKICAgIGJvYXJkLmRpc3BsYXkoKTsKICAgIGJvYXJkLm1vdmUoJ2InLCAyLCAxKTsKICAgIGJvYXJkLmRpc3BsYXkoKTsKICAgIGJvYXJkLm1vdmUoJ2EnLCAyLCAzKTsKICAgIGJvYXJkLmRpc3BsYXkoKTsKICAgIGJvYXJkLm1vdmUoJ2MnLCAyLCAxKTsKICAgIGJvYXJkLmRpc3BsYXkoKTsKICAgIGJvYXJkLm1vdmUoJ2EnLCAwLCAzKTsKICAgIGJvYXJkLmRpc3BsYXkoKTsKICAgIGJvYXJkLm1vdmUoJ2MnLCAwLCAwKTsKICAgIGJvYXJkLmRpc3BsYXkoKTsKCiAgICByZXR1cm4gMDsKfQo=