オフラインどう書く第10回解答例(C++)

時間内に解けたが、ひどすぎる。

```cpp
#include <iostream>
#include <string>
#include <map>

namespace
{
	typedef std::map<std::string, std::string> honeycomb_t;

	int no = 0;

	#define TEST(a, b) do{ std::cout << no++ << " : "; std::cout << (a == b ? "ok" : "***NG***"); std::cout << std::endl; }while(0)

	honeycomb_t get_honeycomb()
	{
		honeycomb_t honeycomb;
		honeycomb.insert(honeycomb_t::value_type("A", "BCDEFG"));
		honeycomb.insert(honeycomb_t::value_type("B", "HICAGS"));
		honeycomb.insert(honeycomb_t::value_type("C", "IJKDAB"));
		honeycomb.insert(honeycomb_t::value_type("D", "CKLMEA"));
		honeycomb.insert(honeycomb_t::value_type("E", "ADMNOF"));
		honeycomb.insert(honeycomb_t::value_type("F", "GAEOPQ"));
		honeycomb.insert(honeycomb_t::value_type("G", "SBAFQR"));
		honeycomb.insert(honeycomb_t::value_type("H", "TUIBSk"));
		honeycomb.insert(honeycomb_t::value_type("I", "UVJCBH"));
		honeycomb.insert(honeycomb_t::value_type("J", "VWXKCI"));
		honeycomb.insert(honeycomb_t::value_type("K", "JXYLDC"));
		honeycomb.insert(honeycomb_t::value_type("L", "KYZaMD"));
		honeycomb.insert(honeycomb_t::value_type("M", "DLabNE"));
		honeycomb.insert(honeycomb_t::value_type("N", "EMbcdO"));
		honeycomb.insert(honeycomb_t::value_type("O", "FENdeP"));
		honeycomb.insert(honeycomb_t::value_type("P", "QFOefg"));
		honeycomb.insert(honeycomb_t::value_type("Q", "RGFPgh"));
		honeycomb.insert(honeycomb_t::value_type("R", "jSGQhi"));
		honeycomb.insert(honeycomb_t::value_type("S", "kHBGRj"));
		honeycomb.insert(honeycomb_t::value_type("T", "!!UHk!"));
		honeycomb.insert(honeycomb_t::value_type("U", "!!VIHT"));
		honeycomb.insert(honeycomb_t::value_type("V", "!!WJIU"));
		honeycomb.insert(honeycomb_t::value_type("W", "!!!XJV"));
		honeycomb.insert(honeycomb_t::value_type("X", "W!!YKJ"));
		honeycomb.insert(honeycomb_t::value_type("Y", "X!!ZLK"));
		honeycomb.insert(honeycomb_t::value_type("Z", "Y!!!aL"));
		honeycomb.insert(honeycomb_t::value_type("a", "LZ!!bM"));
		honeycomb.insert(honeycomb_t::value_type("b", "Ma!!cN"));
		honeycomb.insert(honeycomb_t::value_type("c", "Nb!!!d"));
		honeycomb.insert(honeycomb_t::value_type("d", "ONc!!e"));
		honeycomb.insert(honeycomb_t::value_type("e", "POd!!f"));
		honeycomb.insert(honeycomb_t::value_type("f", "gPe!!!"));
		honeycomb.insert(honeycomb_t::value_type("g", "hQPf!!"));
		honeycomb.insert(honeycomb_t::value_type("h", "iRQg!!"));
		honeycomb.insert(honeycomb_t::value_type("i", "!jRh!!"));
		honeycomb.insert(honeycomb_t::value_type("j", "!kSRi!"));
		honeycomb.insert(honeycomb_t::value_type("k", "!THSj!"));
		return honeycomb;
	}

	std::string solve(const std::string& src)
	{
		honeycomb_t honeycomb = get_honeycomb();
		std::string answer = "A";
		std::string value;
		for(size_t i=0; i<src.length(); ++i)
		{
			std::string key = answer.substr(answer.length()-1, 1);
			if(key != "!")
			{
				value = honeycomb[key];
			}
			answer += value.substr(atoi(src.substr(i, 1).c_str()), 1);
		}
		return answer;
	}
}

int main()
{
	/*0*/ TEST(solve("135004"), "ACDABHS");
	/*1*/ TEST(solve("1"), "AC");
	/*2*/ TEST(solve("33333120"), "AENc!!b!M");
	//以下略
	return 0;
}
```

↑はあまりにもひどすぎるので、書き直した(↓)。

```cpp
#include <iostream>
#include <string>

namespace
{
    int no = 0;

    #define TEST(a, b) do{\
        std::cout << no++ << " : ";\
        std::cout << (a == b ? "ok" : "***NG***");\
        std::cout << std::endl;\
    }while(0)

    class Point
    {   
        int x_; 
        int y_; 
    public:
        Point(int x, int y) :x_(x), y_(y) {}
        void operator=(const Point& other)
        {   
            this->x_ = other.x_;
            this->y_ = other.y_;
        }   
        Point operator+(const Point& other)
        {   
            return Point(this->x_ + other.x_, this->y_ + other.y_);
        }   
        int x()const{ return x_; }
        int y()const{ return y_; }
    };  

    bool out_of_honeycomb(const Point& point)
    {   
        return (point.x() < 0 || 12 < point.x()) || (point.y() < 0 || 6 < point.y());
    }   

    std::string get_str(const Point& point)
    {   
        const std::string honeycomb[13][7] = { 
            { "!", "!", "!", "T", "!", "!", "!" },
            { "!", "!", "k", "!", "U", "!", "!" },
            { "!", "j", "!", "H", "!", "V", "!" },
            { "i", "!", "S", "!", "I", "!", "W" },
            { "!", "R", "!", "B", "!", "J", "!" },
            { "h", "!", "G", "!", "C", "!", "X" },
            { "!", "Q", "!", "A", "!", "K", "!" },
            { "g", "!", "F", "!", "D", "!", "Y" },
            { "!", "P", "!", "E", "!", "L", "!" },
            { "f", "!", "O", "!", "M", "!", "Z" },
            { "!", "e", "!", "N", "!", "a", "!" },
            { "!", "!", "d", "!", "b", "!", "!" },
            { "!", "!", "!", "c", "!", "!", "!" },
        };
        return out_of_honeycomb(point) ? "!" : honeycomb[point.x()][point.y()];
    }

    std::string solve(const std::string& src)
    {
        const Point directions[] = {
            Point(-2, 0), Point(-1, 1), Point(1, 1), Point(2, 0), Point(1, -1), Point(-1, -1)
        };
        Point point(6, 3);
        std::string answer = "A";
        for(size_t i=0; i<src.length(); ++i)
        {
            Point next_point = point + directions[atoi(src.substr(i,  1).c_str())];
            answer += get_str(next_point);
            point = answer.substr(answer.length()-1, 1) == "!" ? point : next_point;
        }
        return answer;
    }
}

int main()
{
    /*0*/ TEST(solve("135004"), "ACDABHS");
    /*1*/ TEST(solve("1"), "AC");
    /*2*/ TEST(solve("33333120"), "AENc!!b!M");
    //以下略
    return 0;
}
```