Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cstdlib>
- #include <vector>
- #include <set>
- #include <map>
- #include <sstream>
- #include <string>
- #include "subprocess.h"
- #include "copter.h"
- #include <unistd.h>
- namespace
- {
- constexpr int MAX_COPTER_COUNT = 20;
- constexpr int TURN_LIMIT = 100;
- auto make_set(const std::vector<CopterState> &copters)
- {
- int min_x = std::numeric_limits<int>::max();
- int min_y = std::numeric_limits<int>::max();
- for (const auto &c : copters) {
- min_x = std::min(min_x, c.x());
- min_y = std::min(min_y, c.y());
- }
- std::set<std::pair<int, int>> res;
- for (const auto &c : copters) {
- res.emplace(c.x() - min_x, c.y() - min_y);
- }
- return res;
- }
- }
- using std::cin;
- using std::cout;
- using std::cerr;
- using std::endl;
- using std::vector;
- using std::set;
- using std::map;
- using std::pair;
- using std::ostringstream;
- using std::string;
- int main(int argc, char *argv[])
- {
- /*
- if (argc != 2) {
- cerr << "wrong number of arguments" << endl;
- exit(1);
- }
- string copterfile(argv[1]);
- cerr << "copter: " << copterfile << endl;
- */
- // read the copter count
- int copter_count = 0;
- cin >> copter_count;
- if (!cin || copter_count <= 0 || copter_count > MAX_COPTER_COUNT) {
- cerr << "invalid copter count" << endl;
- exit(1);
- }
- // read the original state (x, y)
- vector<CopterState> copters;
- for (int i = 0; i < copter_count; ++i) {
- int x = 0, y = 0;
- cin >> x >> y;
- if (!cin) {
- cerr << "failed to read initial copter position" << endl;
- exit(1);
- }
- copters.emplace_back(x, y);
- }
- // read the target state
- vector<CopterState> target;
- for (int i = 0; i < copter_count; ++i) {
- int x = 0, y = 0;
- cin >> x >> y;
- if (!cin) {
- cerr << "failed to read target copter position" << endl;
- exit(1);
- }
- target.emplace_back(x, y);
- }
- auto target_set = make_set(target);
- // FIXME: the turn limit must be settable
- int turn_limit = TURN_LIMIT;
- int current_turn = 0;
- int retval = 0;
- // movements
- while (1) {
- ++current_turn;
- cerr << "Turn: " << current_turn << endl;
- cerr << "States:" << endl;
- for (int i = 0; i < copter_count; ++i) {
- cerr << " " << i << ": " << copters[i].x() << " " << copters[i].y() << " ";
- copters[i].dump_mem(cerr);
- }
- if (current_turn > turn_limit) {
- cerr << "turn limit of " << turn_limit << " exceeded" << endl;
- current_turn = -2;
- break;
- }
- vector<CopterState> new_copters(copter_count);
- int failure_count = 0;
- for (int i = 0; i < copter_count; ++i) {
- cerr << " Copter: " << i << endl;
- const auto &c = copters[i];
- // prepare copter input
- ostringstream cfg;
- cfg << copter_count << endl;
- for (const auto &t : target) {
- cfg << t.x() << " " << t.y() << endl;
- }
- c.dump_mem(cfg);
- int neighbours = 0;
- for (int j = 0; j < copter_count; ++j) {
- if (i != j) {
- neighbours += c.neighbour_kind(copters[j]) != CopterState::Direction::AWAY;
- }
- }
- cfg << neighbours << endl;
- for (int j = 0; j < copter_count; ++j) {
- if (i != j) {
- const auto &other = copters[j];
- if (auto kind = c.neighbour_kind(other); kind != CopterState::Direction::AWAY) {
- cfg << int(kind) << " ";
- other.dump_mem(cfg);
- }
- }
- }
- string copter_input = cfg.str();
- //cerr << " Input: <" << copter_input << ">" << endl;
- /*
- for (int j = 0; argv[j]; ++j) {
- cerr << "<" << argv[j] << ">" << endl;
- }
- */
- Subprocess prc;
- prc.set_cmd(argv + 1);
- //prc.set_cmd(copterfile);
- prc.set_input(std::move(copter_input));
- prc.set_max_cpu_time(1);
- bool success = prc.run_and_wait();
- if (!success) {
- cerr << "copter failed" << endl;
- cerr << " Errors: <" << prc.move_error() << ">" << endl;
- ++failure_count;
- continue;
- }
- string copter_output = prc.move_output();
- cerr << " Output: <" << copter_output << ">" << endl;
- cerr << " Errors: <" << prc.move_error() << ">" << endl;
- try {
- new_copters[i].parse_copter_output(c.x(), c.y(), copter_output);
- } catch (const std::exception &ex) {
- cerr << ex.what() << endl;
- ++failure_count;
- continue;
- }
- cerr << " New position: " << new_copters[i].x() << ", " << new_copters[i].y() << endl;
- }
- if (failure_count > 0) {
- cerr << "Turn " << current_turn << " unsuccessful: " << failure_count << " copters crashed" << endl;
- current_turn = -1;
- break;
- }
- copters.swap(new_copters);
- auto copter_set = make_set(copters);
- if (copter_set == target_set) {
- cerr << "target configuration achieved in " << current_turn << " turns" << endl;
- for (int i = 0; i < copter_count; ++i) {
- cerr << " " << i << ": " << copters[i].x() << " " << copters[i].y() << " ";
- copters[i].dump_mem(cerr);
- }
- break;
- }
- cerr << "Turn " << current_turn << " ended" << endl;
- //sleep(1);
- }
- cout << current_turn << endl;
- return retval;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement