思いついた解法のうち、短時間で実現可能そうなものを検討しているうちに1時間が経過してしまいました。
ハイゼンバグと、条件の勘違いに捕まって実装で2時間ほど。
合計3時間ほどかかりました。
最初に辞書を作っておいて、入力と突き合わせるという乱暴な方法をとっています。
お題はこちら
#include <iostream>
#include <sstream>
#include <vector>
#include <bitset>
#include <algorithm>
#include <iterator>
class Sanwa
{
public:
static const int UPPER_LIMIT = 120;
static const int u[][3];
struct Element
{
int e1;
int e2;
int e3;
Element(int e1, int e2, int e3) : e1(e1), e2(e2), e3(e3) {}
};
static Sanwa& get()
{
static Sanwa sanwa;
return sanwa;
}
const std::vector<Element>& getElements() const
{
return elements_;
}
const std::vector<std::bitset<400> >& getValues() const
{
return values_;
}
static std::bitset<400> getValueSet(const Element& e)
{
std::bitset<400> result;
for(int i = 0; i < 19; ++i)
{
result.set(e.e1 * u[i][0] + e.e2 * u[i][1] + e.e3 * u[i][2]);
}
return result;
}
private:
Sanwa()
{
for(int e1 = 1; e1 < UPPER_LIMIT; ++e1)
{
for(int e2 = e1 + 1; e2 < UPPER_LIMIT; ++e2)
{
// この条件要らなかった
// if((e2 == e1*2) || (e2 == e1*3))
// {
// continue;
// }
for(int e3 = e2 + 1; e3 < UPPER_LIMIT; ++e3)
{
// この条件要らなかった
// if((e3 == e1*2) || (e3 == e1*3) || (e3 == e2*2) || (e3 == e2*3) || (e3 == e1+e2))
// {
// continue;
// }
Element e(e1, e2, e3);
elements_.push_back(e);
values_.push_back(getValueSet(e));
}
}
}
}
Sanwa(const Sanwa&);
Sanwa& operator = (const Sanwa&);
std::vector<Element> elements_;
std::vector<std::bitset<400> > values_;
};
const int Sanwa::u[19][3] =
{
{ 0,0,1 }, { 0,1,0 }, { 1,0,0 },
{ 0,0,2 }, { 0,2,0 }, { 2,0,0 },
{ 0,1,1 }, { 1,0,1 }, { 1,1,0 },
{ 0,0,3 }, { 0,3,0 }, { 3,0,0 },
{ 0,1,2 }, { 1,0,2 }, { 1,2,0 },
{ 0,2,1 }, { 2,0,1 }, { 2,1,0 },
{ 1,1,1 }
};
std::ostream& operator << (std::ostream& out, const Sanwa::Element& e)
{
return out << e.e1 << "," << e.e2 << "," << e.e3;
}
struct Includes
{
const std::bitset<400>& source;
Includes(const std::bitset<400>& source) : source(source) {}
bool operator() (const std::bitset<400>& other) const
{
return (other & source) == source;
}
};
static Sanwa& sanwa = Sanwa::get();
std::string solve(const std::string& s)
{
std::bitset<400> source;
std::istringstream iss(s);
while(iss.good())
{
int i;
char separator;
iss >> i;
source.set(i);
iss >> separator;
}
std::vector<std::bitset<400> >::const_iterator i = std::find_if(sanwa.getValues().begin(), sanwa.getValues().end(), Includes(source));
if(i == sanwa.getValues().end())
{
return "none";
}
if(std::find_if(std::next(i), sanwa.getValues().end(), Includes(source)) != sanwa.getValues().end())
{
return "many";
}
std::ostringstream oss;
oss << sanwa.getElements()[std::distance(sanwa.getValues().begin(), i)];
return oss.str();
}
void test(const std::string& source, const std::string& expected)
{
std::cout << "source: " << source << ", expected: " << expected << std::flush;
std::string actual = solve(source);
if(expected == actual)
{
std::cout << " => o" << std::endl;
}
else
{
std::cout << ", actual: " << actual << " => x" << std::endl;
}
}
int main(int, char* [])
{
/*0*/ test( "3,11,12,102,111,120", "1,10,100" );
/*1*/ test( "10,20,30,35,70", "many" );
/*2*/ test( "1,5,20,80", "none" );
/*3*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14", "many" );
/*4*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15", "1,4,5" );
/*5*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14,17", "none" );
/*6*/ test( "1,2,3,4,5,6,7,8,9,10,11,12,13,14,18", "1,4,6" );
/*7*/ test( "5,6,7,8,9,10,11,12,13,14,15,16", "2,5,6" );
/*8*/ test( "9,10,11,12,13,14,15,16,17,18,19", "4,5,7" );
/*9*/ test( "11,36,37,45,55,70,71", "1,10,35" );
/*10*/ test( "92,93,94,95,96,97,98,99", "30,32,33" );
/*11*/ test( "95,96,97,98,99,100", "many" );
/*12*/ test( "27,30,34,37,43,44,46,51,57", "10,17,23" );
/*13*/ test( "6,10,13,17,65,73,76,80", "none" );
/*14*/ test( "12,19,21,29,85", "none" );
/*15*/ test( "1,2,8,10,14,23,58,62,64", "none" );
/*16*/ test( "4,22,25,31,44,50,58,69,71,72,73,77", "none" );
/*17*/ test( "8,16,26,27,42,53,65,69,81,83,88,99", "none" );
/*18*/ test( "9,10,23,24,28,33,38,39,58,68,84", "none" );
/*19*/ test( "11,16,24,26,88", "none" );
/*20*/ test( "24,33,47,56,63,66,75,78,89,93", "none" );
/*21*/ test( "7,26,72,77", "many" );
/*22*/ test( "69,88,95,97", "many" );
/*23*/ test( "9,14,48,89", "many" );
/*24*/ test( "69,76,77,83", "many" );
/*25*/ test( "11,14,24", "many" );
/*26*/ test( "8,25,75,93", "many" );
/*27*/ test( "11,55,93,98,99", "many" );
/*28*/ test( "71,83,87", "many" );
/*29*/ test( "22,76,77,92", "7,15,62" );
/*30*/ test( "33,61,66,83,95", "17,33,61" );
/*31*/ test( "6,16,49,55,72", "6,16,33" );
/*32*/ test( "62,85,97,98", "12,25,73" );
/*33*/ test( "54,60,67,70,72", "20,25,27" );
/*34*/ test( "54,61,68,84,87", "27,30,34" );
/*35*/ test( "65,67,69,75,79,89,99", "21,23,33" );
/*36*/ test( "69,72,80,81,89", "23,24,33" );
/*37*/ test( "1,2,3", "many" );
return 0;
}