<commit_before>#include <complex>
#include <vector>
#include <fstream>
#include <sstream>

#include "base/base.h"
#include "boost/rational.hpp"
#include "polygon.h"
#include "problem.h"
#include "solution.h"
#include <boost/geometry.hpp>
#include <boost/geometry/algorithms/union.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/iterators/closing_iterator.hpp>
#include <boost/multiprecision/gmp.hpp>

DEFINE_string(input, "/dev/stdin", "input solution file");

namespace bg = boost::geometry;

using boost::rational;
using gPoint = bg::model::d2::point_xy<Q>;
using ccwPolygon = bg::model::polygon<gPoint, false, false>;
using ccwMultiPolygon = bg::model::multi_polygon<ccwPolygon>;
using LineString = bg::model::linestring<gPoint>;
using MultiLineString = bg::model::multi_linestring<LineString>;
using namespace std;

Vertex ConvertToVertex(const gPoint& p) {
  Vertex v;
  v.x = p.x();
  v.y = p.y();
  return v;
}

int main(int argc, char** argv) {
  ParseCommandLineFlags(&argc, &argv);

  Solution solution;
  std::ifstream solution_ifs(FLAGS_input);
  ReadSolution(solution_ifs, &solution);

  ccwMultiPolygon mpoly, mpoly_tmp;
  MultiLineString mls, mls_tmp;
  for (const auto& facet : solution.facets) {
    ccwPolygon poly;
    for (const auto& i : facet) {
      bg::append(poly,
                 gPoint(solution.dst_verts[i].x, solution.dst_verts[i].y));
    }
    if (bg::area(poly) < 0) {
      bg::reverse(poly);
    }
    LOG(INFO) << "union polygon: " << bg::wkt(poly);
    bg::union_(mpoly, poly, mpoly_tmp);
    mpoly.swap(mpoly_tmp);
    bg::clear(mpoly_tmp);
    LOG(INFO) << "polygon: " << bg::wkt(mpoly);

    LineString ls;
    for (const auto& i : facet) {
      bg::append(ls, gPoint(solution.dst_verts[i].x, solution.dst_verts[i].y));
    }
    bg::append(ls, gPoint(solution.dst_verts[facet[0]].x,
                          solution.dst_verts[facet[0]].y));
    LOG(INFO) << "union line: " << bg::wkt(ls);
    bg::union_(mls, ls, mls_tmp);
    mls.swap(mls_tmp);
    bg::clear(mls_tmp);
    LOG(INFO) << "lines: " << bg::wkt(mls);
  }

  Problem problem;
  for (const auto& poly : mpoly) {
    const auto& xring = bg::exterior_ring(poly);
    problem.polygons.emplace_back(xring.size());
    std::transform(xring.begin(), xring.end(), problem.polygons.back().begin(),
                   &ConvertToVertex);
    const auto& irings = bg::interior_rings(poly);
    for (const auto& iring : irings) {
      problem.polygons.emplace_back(iring.size());
      std::transform(iring.rbegin(), iring.rend(),
                     problem.polygons.back().begin(), &ConvertToVertex);
    }
  }
  for (const auto& ls : mls) {
    for (int i = 0; i < ls.size() - 1; ++i) {
      problem.skelton.emplace_back(ConvertToVertex(ls[i]),
                                   ConvertToVertex(ls[i + 1]));
    }
  }
  WriteProblem(problem, cout);

  return 0;
}<commit_msg>bugfix: correct rotation of holes<commit_after>#include <complex>
#include <vector>
#include <fstream>
#include <sstream>

#include "base/base.h"
#include "boost/rational.hpp"
#include "polygon.h"
#include "problem.h"
#include "solution.h"
#include <boost/geometry.hpp>
#include <boost/geometry/algorithms/union.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/iterators/closing_iterator.hpp>
#include <boost/multiprecision/gmp.hpp>

DEFINE_string(input, "/dev/stdin", "input solution file");

namespace bg = boost::geometry;

using boost::rational;
using gPoint = bg::model::d2::point_xy<Q>;
using ccwPolygon = bg::model::polygon<gPoint, false, false>;
using ccwMultiPolygon = bg::model::multi_polygon<ccwPolygon>;
using LineString = bg::model::linestring<gPoint>;
using MultiLineString = bg::model::multi_linestring<LineString>;
using namespace std;

Vertex ConvertToVertex(const gPoint& p) {
  Vertex v;
  v.x = p.x();
  v.y = p.y();
  return v;
}

int main(int argc, char** argv) {
  ParseCommandLineFlags(&argc, &argv);

  Solution solution;
  std::ifstream solution_ifs(FLAGS_input);
  ReadSolution(solution_ifs, &solution);

  ccwMultiPolygon mpoly, mpoly_tmp;
  MultiLineString mls, mls_tmp;
  for (const auto& facet : solution.facets) {
    ccwPolygon poly;
    for (const auto& i : facet) {
      bg::append(poly,
                 gPoint(solution.dst_verts[i].x, solution.dst_verts[i].y));
    }
    if (bg::area(poly) < 0) {
      bg::reverse(poly);
    }
    LOG(INFO) << "union polygon: " << bg::wkt(poly);
    bg::union_(mpoly, poly, mpoly_tmp);
    mpoly.swap(mpoly_tmp);
    bg::clear(mpoly_tmp);
    LOG(INFO) << "polygon: " << bg::wkt(mpoly);

    LineString ls;
    for (const auto& i : facet) {
      bg::append(ls, gPoint(solution.dst_verts[i].x, solution.dst_verts[i].y));
    }
    bg::append(ls, gPoint(solution.dst_verts[facet[0]].x,
                          solution.dst_verts[facet[0]].y));
    LOG(INFO) << "union line: " << bg::wkt(ls);
    bg::union_(mls, ls, mls_tmp);
    mls.swap(mls_tmp);
    bg::clear(mls_tmp);
    LOG(INFO) << "lines: " << bg::wkt(mls);
  }

  Problem problem;
  for (const auto& poly : mpoly) {
    const auto& xring = bg::exterior_ring(poly);
    problem.polygons.emplace_back(xring.size());
    std::transform(xring.begin(), xring.end(), problem.polygons.back().begin(),
                   &ConvertToVertex);
    const auto& irings = bg::interior_rings(poly);
    for (const auto& iring : irings) {
      problem.polygons.emplace_back(iring.size());
      std::transform(iring.begin(), iring.end(),
                     problem.polygons.back().begin(), &ConvertToVertex);
    }
  }
  for (const auto& ls : mls) {
    for (int i = 0; i < ls.size() - 1; ++i) {
      problem.skelton.emplace_back(ConvertToVertex(ls[i]),
                                   ConvertToVertex(ls[i + 1]));
    }
  }
  WriteProblem(problem, cout);

  return 0;
}
{'fraction_non_alphanumeric': 0.16517561298873426, 'fraction_numerical': 0.0026507620941020544, 'mean_word_length': 3.7349019607843137, 'pattern_counts': {'":': 0, '<': 71, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5474373', 'n_tokens_mistral': 2220, 'n_tokens_neox': 2150, 'n_words': 402}