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

```cpp:Hena.h
#pragma once

#include <string>

std::string solve(const std::string &src);  
```

```cpp:Hena.cpp
#include "Hena.h"
#include <map>
#include <sstream>
#include <bitset>
#include <cstdlib>
#include <cassert>
#include <iostream>

using namespace std;

string hex_to_bin(const string &hex) {   
    stringstream ss;
    for(size_t i = 0; i < hex.length(); ++i) {   
        ss << bitset<4>(strtol(hex.substr(i, 1).c_str(), NULL, 16));
    }
    return ss.str();
}

size_t search_pos(const string &src) {
    size_t pos = src.find('1');
    if( (string::npos != pos) && (pos % 2 != 0) ) {
        pos -= 1;
    }
    return pos;
}

string decode(const string &src, size_t &pos) {
    map<string, string> dictionary = {
        { "1101", "L" },
        { "1110", "R" },
        { "0111", "J" },
        { "101110", "T" },
        { "110111", "U" },
        { "111011", "N" },
        { "011110", "S" },
        { "101101", "Z" }
    }; 
    typedef map<string, string>::iterator it_t;
    pos = search_pos(src);
    if(string::npos == pos) {
        return "";
    }
    it_t it = dictionary.find(src.substr(pos, 6));
    if(dictionary.end() == it) {
        it = dictionary.find(src.substr(pos, 4));
    }
    if(dictionary.end() == it) { 
        return "";
    }
    return it->second;
}

string make_board(const string &src) {
    size_t pos = src.find('/');
    string upper_section = hex_to_bin(src.substr(0, pos));
    string lower_section = hex_to_bin(src.substr(pos + 1, src.length()));
    assert(upper_section.length() == lower_section.length());
    string board;
    for(size_t i = 0; i < upper_section.length(); ++i) {
        board += upper_section.substr(i, 1);
        board += lower_section.substr(i, 1);
    }
    return board;
}

string solve(const string &src) {
    string ret;
    size_t pos = 0;
    string board = make_board(src);
    string s = decode(board, pos);
    while("" != s) {
        ret += s;
        board = board.substr(
                string::npos == string("LRJ").find(s) ? pos + 6 : pos + 4,
                board.length());
        s = decode(board, pos);
    }
    return ret;
}
```

```cpp:HenaTest.hpp
#include <cppunit/TestCase.h>                                                                   
#include <cppunit/extensions/HelperMacros.h>                                                    
#include <cppunit/ui/text/TestRunner.h>                                                         

#include "Hena.h"

class HenaTest :
    public CppUnit::TestFixture                                                                 
{
    public:                                                                                     
        void setUp() {} 
    
        void tearDown() {}
        
        void test_solve0() {
            CPPUNIT_ASSERT(solve("2ed8aeed/34b0ea5b") == "LTRSUNTSJ");
        }

        void test_solve1() {
            CPPUNIT_ASSERT(solve("00000200/00000300") == "L");
        }
        
    private:
        CPPUNIT_TEST_SUITE(HenaTest);
        CPPUNIT_TEST(test_solve0);
        CPPUNIT_TEST(test_solve1);
        // 以下略
        CPPUNIT_TEST_SUITE_END();
}
```

```cpp:main.cpp
#include "HenaTest.hpp"
        
int main()
{       
    CppUnit::TextUi::TestRunner runner;
    runner.addTest(HenaTest::suite());
    runner.run();
    return 0;
}
```