├── README.md └── src └── solution.cpp /README.md: -------------------------------------------------------------------------------- 1 | # akuna_sh_code_test 2 | 3 | This repository for Akuna Coding Challenge source code. 4 | Everyone can show the code you wrote down in this fucking challenge. 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | using namespace std; 26 | 27 | #define DONE 10 28 | #define IOC 11 29 | #define GFD 12 30 | 31 | #define CANCEL 0 32 | #define PRINT 1 33 | #define BUY 2 34 | #define SELL 3 35 | #define MODIFY 4 36 | 37 | #define COMMAND_SIZE 6 38 | #define COMMAND_INDEX 0 39 | 40 | #define ORDER_ID_INDEX_IN_BUY 4 41 | #define ORDER_TYPE_INDEX_IN_BUY 1 42 | #define ORDER_PRICE_INDEX_IN_BUY 2 43 | #define ORDER_QUANTITY_INDEX_IN_BUY 3 44 | 45 | #define ORDER_ID_INDEX_IN_SELL 4 46 | #define ORDER_TYPE_INDEX_IN_SELL 1 47 | #define ORDER_PRICE_INDEX_IN_SELL 2 48 | #define ORDER_QUANTITY_INDEX_IN_SELL 3 49 | 50 | #define ORDER_ID_IN_CANCEL 1 51 | 52 | #define ORDER_ID_IN_MODIFY 1 53 | #define ORDER_TYPE_IN_MODIFY 2 54 | #define ORDER_PRICE_IN_MODIFY 3 55 | #define ORDER_QUANTITY_IN_MODIFY 4 56 | 57 | struct Order { 58 | string id; 59 | int type; 60 | int price; 61 | int quantity; 62 | }; 63 | 64 | struct Action { 65 | int action_type; 66 | Order action_input; 67 | }; 68 | 69 | struct Trade { 70 | Order trade_1; 71 | Order trade_2; 72 | }; 73 | 74 | 75 | namespace Data { 76 | vector trades; 77 | map > order_index_buy; 78 | map > order_index_sell; 79 | map order_buy; 80 | map order_sell; 81 | 82 | int in_order_map(map &map_order, Order order) { 83 | return map_order.count(order.id); 84 | } 85 | int merge_order(map &map_order, Order order) { 86 | if (map_order.count(order.id)) { 87 | Order order_already_in = map_order[order.id]; 88 | map_order[order.id] = order; 89 | } 90 | else 91 | map_order.insert(pair(order.id, order)); 92 | return 0; 93 | } 94 | int add_order_index(map > &map_list_order, Order order) { 95 | if (map_list_order.count(order.price)) { 96 | map_list_order[order.price].push_back(order); 97 | } 98 | else { 99 | list order_list; 100 | order_list.push_back(order); 101 | map_list_order.insert(pair >(order.price, order_list)); 102 | } 103 | return 0; 104 | } 105 | int add_buy(Order order) { 106 | if (!in_order_map(order_buy, order)) { 107 | merge_order(order_buy, order); 108 | if (order.type == GFD) 109 | add_order_index(order_index_buy, order); 110 | return 0; 111 | } 112 | return 1; 113 | } 114 | 115 | int add_sell(Order order) { 116 | if (!in_order_map(order_sell, order)) { 117 | merge_order(order_sell, order); 118 | if (order.type == GFD) 119 | add_order_index(order_index_sell, order); 120 | return 0; 121 | } 122 | return 1; 123 | } 124 | bool compare_up(int a, int b) { 125 | return ab; 129 | } 130 | 131 | Trade make_trade(Order trade_1, Order trade_2) { 132 | cout << "TRADE " << trade_1.id << " " << trade_1.price << " " << trade_1.quantity << " " << trade_2.id << " " << trade_2.price << " " << trade_2.quantity << endl; 133 | struct Trade result = { 134 | trade_1, 135 | trade_2 136 | }; 137 | return result; 138 | } 139 | 140 | Order do_buy(Order &order) { 141 | vector prices; 142 | for (map< int, list >::iterator orders = order_index_sell.begin(); orders != order_index_sell.end(); ++orders) { 143 | prices.push_back(orders->first); 144 | } 145 | sort(prices.begin(), prices.end(), compare_down); 146 | for (vector::iterator price = prices.begin(); price != prices.end(); ++price) { 147 | for (list::iterator sell_order = order_index_sell[*price].begin(); sell_order != order_index_sell[*price].end(); ) { 148 | if ((sell_order->quantity > order.quantity) && (sell_order->price <= order.price) && order.quantity > 0) { 149 | // frash order list 150 | sell_order->quantity -= order.quantity; 151 | // frash order map 152 | order_sell[sell_order->id].quantity = sell_order->quantity; 153 | struct Order s_order = { 154 | sell_order->id, 155 | sell_order->type, 156 | sell_order->price, 157 | order.quantity 158 | }; 159 | //frash trades list 160 | trades.push_back(make_trade(s_order, order)); 161 | order.quantity = 0; 162 | } 163 | if ((sell_order->quantity <= order.quantity) && (sell_order->price <= order.price)) { 164 | struct Order s_order = { 165 | order.id, 166 | order.type, 167 | order.price, 168 | sell_order->quantity 169 | }; 170 | //frash trades list 171 | trades.push_back(make_trade(*sell_order, s_order)); 172 | // frash order status 173 | order.quantity -= sell_order->quantity; 174 | // frash order list 175 | sell_order->quantity = 0; 176 | // frash order map 177 | order_sell[sell_order->id].quantity = sell_order->quantity; 178 | order_sell[sell_order->id].type = DONE; 179 | } 180 | if (sell_order->quantity == 0) 181 | sell_order = order_index_sell[*price].erase(sell_order); 182 | else 183 | ++sell_order; 184 | if (order.quantity == 0) { 185 | // frash order status 186 | order.type = DONE; 187 | return order; 188 | } 189 | } 190 | } 191 | return order; 192 | } 193 | 194 | Order do_sell(Order order) { 195 | vector prices; 196 | for (map< int, list >::iterator orders = order_index_buy.begin(); orders != order_index_buy.end(); ++orders) { 197 | prices.push_back(orders->first); 198 | } 199 | sort(prices.begin(), prices.end(), compare_down); 200 | for (vector::iterator price = prices.begin(); price != prices.end(); ++price) { 201 | for (list::iterator buy_order = order_index_buy[*price].begin(); buy_order != order_index_buy[*price].end(); ) { 202 | if ((buy_order->quantity > order.quantity) && (buy_order->price >= order.price) && order.quantity > 0) { 203 | // frash order list 204 | buy_order->quantity -= order.quantity; 205 | // frash order map 206 | order_buy[buy_order->id].quantity = buy_order->quantity; 207 | struct Order b_order = { 208 | buy_order->id, 209 | buy_order->type, 210 | buy_order->price, 211 | order.quantity 212 | }; 213 | //frash trades list 214 | trades.push_back(make_trade(b_order, order)); 215 | order.quantity = 0; 216 | } 217 | if ((buy_order->quantity <= order.quantity) && (buy_order->price >= order.price)) { 218 | struct Order b_order = { 219 | order.id, 220 | order.type, 221 | order.price, 222 | buy_order->quantity 223 | }; 224 | //frash trades list 225 | trades.push_back(make_trade(*buy_order, b_order)); 226 | // frash order status 227 | order.quantity -= buy_order->quantity; 228 | // frash order list 229 | buy_order->quantity = 0; 230 | // frash order map 231 | order_buy[buy_order->id].quantity = buy_order->quantity; 232 | order_buy[buy_order->id].type = DONE; 233 | } 234 | if (buy_order->quantity == 0) 235 | buy_order = order_index_buy[*price].erase(buy_order); 236 | else 237 | ++buy_order; 238 | if (order.quantity == 0) { 239 | // frash order status 240 | order.type = DONE; 241 | return order; 242 | } 243 | } 244 | } 245 | return order; 246 | } 247 | 248 | int do_modify(Order order) { 249 | if (in_order_map(order_buy, order)) { 250 | Order old_order = order_buy[order.id]; 251 | // remove from list 252 | for (list::iterator buy_order = order_index_buy[old_order.price].begin(); buy_order != order_index_buy[old_order.price].end(); ) { 253 | if (buy_order->id == old_order.id) 254 | buy_order = order_index_buy[buy_order->price].erase(buy_order); 255 | else 256 | ++buy_order; 257 | } 258 | // remove form map 259 | order_buy.erase(order.id); 260 | return 0; 261 | } 262 | if (in_order_map(order_sell, order)) { 263 | Order old_order = order_sell[order.id]; 264 | // remove from list 265 | for (list::iterator sell_order = order_index_sell[old_order.price].begin(); sell_order != order_index_sell[old_order.price].end(); ) { 266 | if (sell_order->id == old_order.id) 267 | sell_order = order_index_buy[sell_order->price].erase(sell_order); 268 | else 269 | ++sell_order; 270 | } 271 | // remove form map 272 | order_sell.erase(order.id); 273 | return 0; 274 | } 275 | return 0; 276 | } 277 | 278 | int do_cancel(Order order) { 279 | if (in_order_map(order_buy, order)) { 280 | Order old_order = order_buy[order.id]; 281 | // remove from list 282 | for (list::iterator buy_order = order_index_buy[old_order.price].begin(); buy_order != order_index_buy[old_order.price].end(); ) { 283 | if (buy_order->id == old_order.id) 284 | buy_order = order_index_buy[old_order.price].erase(buy_order); 285 | else 286 | ++buy_order; 287 | } 288 | order_buy[order.id].quantity = 0; 289 | order_buy[order.id].type = DONE; 290 | } 291 | if (in_order_map(order_sell, order)) { 292 | Order old_order = order_sell[order.id]; 293 | // remove from list 294 | for (list::iterator sell_order = order_index_sell[old_order.price].begin(); sell_order != order_index_sell[old_order.price].end(); ) { 295 | if (sell_order->id == old_order.id) 296 | sell_order = order_index_sell[sell_order->price].erase(sell_order); 297 | else 298 | ++sell_order; 299 | } 300 | order_sell[order.id].quantity = 0; 301 | order_sell[order.id].type = DONE; 302 | } 303 | return 0; 304 | } 305 | 306 | int do_print(Order) { 307 | cout << "SELL:" << endl; 308 | for (map< int, list >::iterator orders = order_index_sell.begin(); orders != order_index_sell.end(); ++orders) { 309 | int all_quantity = 0; 310 | for (list::iterator sell_order = orders->second.begin(); sell_order != orders->second.end(); sell_order++) { 311 | all_quantity += sell_order->quantity; 312 | } 313 | if (all_quantity > 0) 314 | cout << orders->first << " " << all_quantity << endl; 315 | } 316 | cout << "BUY:" << endl; 317 | for (map< int, list >::reverse_iterator orders = order_index_buy.rbegin(); orders != order_index_buy.rend(); ++orders) { 318 | int all_quantity = 0; 319 | for (list::iterator buy_order = orders->second.begin(); buy_order != orders->second.end(); buy_order++) { 320 | all_quantity += buy_order->quantity; 321 | } 322 | if (all_quantity > 0) 323 | cout << orders->first << " " << all_quantity << endl; 324 | } 325 | return 0; 326 | } 327 | }; 328 | 329 | bool is_digits(const std::string &str) 330 | { 331 | return all_of(str.begin(), str.end(), ::isdigit); 332 | } 333 | 334 | Action buy_action_build(vector words) { 335 | Action result; 336 | result.action_type = BUY; 337 | struct Order order = { 338 | words[ORDER_ID_INDEX_IN_BUY], 339 | 0, 340 | is_digits(words[ORDER_PRICE_INDEX_IN_BUY]) ? stoi(words[ORDER_PRICE_INDEX_IN_BUY]) : 0, 341 | is_digits(words[ORDER_QUANTITY_INDEX_IN_BUY]) ? stoi(words[ORDER_QUANTITY_INDEX_IN_BUY]) : 0 342 | }; 343 | if (words[ORDER_TYPE_INDEX_IN_BUY] == "IOC") 344 | order.type = IOC; 345 | if (words[ORDER_TYPE_INDEX_IN_BUY] == "GFD") 346 | order.type = GFD; 347 | result.action_input = order; 348 | return result; 349 | } 350 | 351 | Action sell_action_build(vector words) { 352 | Action result; 353 | result.action_type = SELL; 354 | struct Order order = { 355 | words[ORDER_ID_INDEX_IN_SELL], 356 | 0, 357 | is_digits(words[ORDER_PRICE_INDEX_IN_SELL]) ? stoi(words[ORDER_PRICE_INDEX_IN_SELL]) : 0, 358 | is_digits(words[ORDER_QUANTITY_INDEX_IN_SELL]) ? stoi(words[ORDER_QUANTITY_INDEX_IN_SELL]) : 0 359 | }; 360 | if (words[ORDER_TYPE_INDEX_IN_SELL] == "IOC") 361 | order.type = IOC; 362 | if (words[ORDER_TYPE_INDEX_IN_SELL] == "GFD") 363 | order.type = GFD; 364 | result.action_input = order; 365 | return result; 366 | } 367 | 368 | Action cancel_action_build(vector words) { 369 | Action result; 370 | result.action_type = CANCEL; 371 | struct Order order = { 372 | words[ORDER_ID_IN_CANCEL], 373 | 0, 374 | 0, 375 | 0, 376 | }; 377 | result.action_input = order; 378 | return result; 379 | } 380 | 381 | Action modify_action_build(vector words) { 382 | Action result; 383 | result.action_type = MODIFY; 384 | struct Order order = { 385 | words[ORDER_ID_IN_MODIFY], 386 | 0, 387 | is_digits(words[ORDER_PRICE_IN_MODIFY]) ? stoi(words[ORDER_PRICE_IN_MODIFY]) : 0, 388 | is_digits(words[ORDER_QUANTITY_IN_MODIFY]) ? stoi(words[ORDER_QUANTITY_IN_MODIFY]) : 0 389 | }; 390 | if (words[ORDER_TYPE_IN_MODIFY] == "BUY") 391 | order.type = BUY; 392 | if (words[ORDER_TYPE_IN_MODIFY] == "SELL") 393 | order.type = SELL; 394 | result.action_input = order; 395 | return result; 396 | } 397 | 398 | Action print_action_build(vector words) { 399 | Action result; 400 | result.action_type = PRINT; 401 | return result; 402 | } 403 | 404 | Action input_analysis(std::string section) { 405 | Action result; 406 | istringstream iss(section), end; 407 | vector words(COMMAND_SIZE); 408 | copy(istream_iterator(iss), istream_iterator(end), words.begin()); 409 | if (words[COMMAND_INDEX] == "BUY") 410 | result = buy_action_build(words); 411 | if (words[COMMAND_INDEX] == "SELL") 412 | result = sell_action_build(words); 413 | if (words[COMMAND_INDEX] == "CANCEL") 414 | result = cancel_action_build(words); 415 | if (words[COMMAND_INDEX] == "MODIFY") 416 | result = modify_action_build(words); 417 | if (words[COMMAND_INDEX] == "PRINT") 418 | result = print_action_build(words); 419 | return result; 420 | } 421 | 422 | int buy_process(Action action) { 423 | if (!Data::in_order_map(Data::order_buy, action.action_input) && !Data::in_order_map(Data::order_sell, action.action_input)) { 424 | struct Order order = Data::do_buy(action.action_input); 425 | if (order.type != IOC) 426 | Data::add_buy(order); 427 | } 428 | return 0; 429 | } 430 | 431 | int sell_process(Action action) { 432 | if (!Data::in_order_map(Data::order_sell, action.action_input) && !Data::in_order_map(Data::order_buy, action.action_input)) { 433 | struct Order order = Data::do_sell(action.action_input); 434 | if (order.type != IOC) 435 | Data::add_sell(order); 436 | } 437 | return 0; 438 | } 439 | 440 | int cancel_process(Action action) { 441 | Data::do_cancel(action.action_input); 442 | return 0; 443 | } 444 | 445 | int modify_process(Action action) { 446 | Data::do_modify(action.action_input); 447 | if (action.action_input.type == BUY) { 448 | struct Order order = Data::do_buy(action.action_input); 449 | if (order.type == BUY) { 450 | if (order.price != 0) 451 | order.type = GFD; 452 | else 453 | order.type = DONE; 454 | Data::add_buy(order); 455 | } 456 | 457 | } 458 | if (action.action_input.type == SELL) { 459 | struct Order order = Data::do_sell(action.action_input); 460 | if (order.type == SELL) { 461 | if (order.price != 0) 462 | order.type = GFD; 463 | else 464 | order.type = DONE; 465 | Data::add_sell(order); 466 | } 467 | } 468 | return 0; 469 | } 470 | 471 | int print_process(Action action) { 472 | Data::do_print(action.action_input); 473 | return 0; 474 | } 475 | 476 | int action_process(Action action) { 477 | int result = 0; 478 | if (action.action_type == BUY) 479 | result = buy_process(action); 480 | if (action.action_type == SELL) 481 | result = sell_process(action); 482 | if (action.action_type == CANCEL) 483 | result = cancel_process(action); 484 | if (action.action_type == MODIFY) 485 | result = modify_process(action); 486 | if (action.action_type == PRINT) 487 | result = print_process(action); 488 | return result; 489 | } 490 | 491 | int main() { 492 | /* Enter your code here. Read input from STDIN. Print output to STDOUT */ 493 | 494 | string section; 495 | while (getline(cin, section)) { 496 | Action ac = input_analysis(section); 497 | int result = action_process(ac); 498 | } 499 | return 0; 500 | } 501 | --------------------------------------------------------------------------------