お題はこちら http://qiita.com/items/4c60f10b73812e86441c
ほとんど使ったことのないstd::bitset
で。std::bitset
に論理和、論理積があるのを今回始めて知った(あるとは思ってたけど、調べたことがなかった)。
answer.cpp
# include "answer.hpp"
# include <bitset>
# include <string>
# include <iostream>
# include <sstream>
# include <algorithm>
typedef std::bitset<100> Bitset;
struct El
{
int p1, p2, p3;
Bitset asBitset() const
{
int x1 = p1 / 10, y1 = p1 % 10;
int x2 = p2 / 10, y2 = p2 % 10;
int x3 = p3 / 10, y3 = p3 % 10;
Bitset b2, b3;
fill(b2, std::min(x1, x2), std::min(y1, y2), std::max(x1, x2), std::max(y1, y2));
fill(b3, std::min(x1, x3), std::min(y1, y3), std::max(x1, x3), std::max(y1, y3));
return b2 | b3;
}
static void fill(Bitset& b, int x1, int y1, int x2, int y2)
{
for(int y = y1; y <= y2; ++y)
{
for(int x = x1; x <= x2; ++x)
{
b.set(x * 10 + y);
}
}
}
};
std::istream& operator >> (std::istream& in, El& el)
{
int p1, p2, p3;
char d1, d2;
in >> p1 >> d1 >> p2 >> d2 >> p3;
if((d1 == '-') && (d2 == '-'))
{
el.p1 = p1; el.p2 = p2; el.p3 = p3;
}
return in;
}
std::string solve(const std::string& s)
{
std::istringstream iss(s);
El e1, e2;
char d;
iss >> e1 >> d >> e2;
std::ostringstream oss;
if((d == ',') && iss.eof())
{
oss << ((e1.asBitset() & e2.asBitset()).count());
}
else
{
oss << 0;
}
return oss.str();
}
answer.hpp
# ifndef DOUKAKU_ANSWER_HPP
# define DOUKAKU_ANSWER_HPP
# include <string>
std::string solve(const std::string& s);
# endif//DOUKAKU_ANSWER_HPP
test.cpp
# include "answer.hpp"
# include <string>
# include <iostream>
# include <fstream>
struct Pattern
{
Pattern(const std::string& s) : name(), input(), expected()
{
std::size_t d1 = s.find('\t');
std::size_t d2 = s.find('\t', d1 + 1);
if((d1 != std::string::npos) && (d2 != std::string::npos))
{
name = s.substr(0, d1);
input = s.substr(d1 + 1, d2 - d1 - 1);
expected = s.substr(d2 + 1);
}
}
std::string name;
std::string input;
std::string expected;
};
int main(int, char* [])
{
std::ifstream patterns("patterns.tsv");
int count_cases = 0;
int count_failures = 0;
std::string s;
while(std::getline(patterns, s).good())
{
++count_cases;
Pattern pattern(s);
std::string actual = solve(pattern.input);
if(actual != pattern.expected)
{
++count_failures;
std::cout << "Failure in " << pattern.name << "\n"
<< "expected: \"" << pattern.expected << "\"\n"
<< " actual: \"" << actual << "\"\n";
}
}
std::cout << "\nCases: " << count_cases << " Failures: " << count_failures << "\n";
return 0;
}