diff --git a/res/2016/day13/test_input.txt b/res/2016/day13/test_input.txt index e69de29..f599e28 100644 --- a/res/2016/day13/test_input.txt +++ b/res/2016/day13/test_input.txt @@ -0,0 +1 @@ +10 diff --git a/src/2016/Day13.cpp b/src/2016/Day13.cpp index 6f0e596..4756c18 100644 --- a/src/2016/Day13.cpp +++ b/src/2016/Day13.cpp @@ -2,30 +2,102 @@ namespace y2016::day13 { - REGISTER_DAY(2016, Day13, std::vector, int); + REGISTER_DAY(2016, Day13, int, int); - REGISTER_TEST_EXAMPLE(2016, Day13, ExampleInput, 1, 0); - REGISTER_TEST(2016, Day13, Input, 1, 0); - REGISTER_TEST_EXAMPLE(2016, Day13, ExampleInput, 2, 0); - REGISTER_TEST(2016, Day13, Input, 2, 0); + REGISTER_TEST_EXAMPLE(2016, Day13, ExampleInput, 1, 11); + REGISTER_TEST(2016, Day13, Input, 1, 82); + REGISTER_TEST_EXAMPLE(2016, Day13, ExampleInput, 2, 151); + REGISTER_TEST(2016, Day13, Input, 2, 138); READ_INPUT(input) { - std::vector vec; - std::string str; - while (getline(input, str)) + int i; + input >> i; + return i; + } + + bool IsWall(int x, int y, int number) + { + int i = x * x + 3 * x + 2 * x * y + y + y * y; + i += number; + std::string str = std::bitset<32>(i).to_string(); + // std::cout << str << ": " << std::count(str.begin(), str.end(), '1') % 2 << std::endl; + return std::count(str.begin(), str.end(), '1') % 2 != 0; + } + + struct State + { + int x; + int y; + + bool operator==(const State& state) const { + return x == state.x && y == state.y; } - return vec; + + bool operator<(const State& state) const + { + if (x != state.x) + return x < state.x; + return y < state.y; + } + + friend std::ostream& operator<<(std::ostream& os, const State& state) + { + return os << "(" << state.x << ", " << state.y << ")"; + } + }; + + std::vector> Branch(int input, const State& state) + { + std::vector> branches; + if (state.x > 0 && !IsWall(state.x - 1, state.y, input)) + branches.emplace_back(1, State{state.x - 1, state.y}); + if (state.y > 0 && !IsWall(state.x, state.y - 1, input)) + branches.emplace_back(1, State{state.x, state.y - 1}); + if (!IsWall(state.x + 1, state.y, input)) + branches.emplace_back(1, State{state.x + 1, state.y}); + if (!IsWall(state.x, state.y + 1, input)) + branches.emplace_back(1, State{state.x, state.y + 1}); + return branches; + } + + bool Goal(int input, const State& state) + { + if (input == 10) + return state == State{7, 4}; + else + return state == State{31, 39}; } OUTPUT1(input) { - return 0; + State state{1, 1}; + return Helper::Dijkstras(input, state, Branch, Goal); } OUTPUT2(input) { - return 0; + std::queue> queue{}; + queue.emplace(0, State{1, 1}); + std::set visited; + while (!queue.empty()) + { + std::pair state = queue.front(); + queue.pop(); + + std::vector> branches = Branch(input, state.second); + for (const auto& branch : branches) + { + if (!visited.emplace(branch.second).second) + continue; + + if (state.first >= 49) + continue; + else + queue.emplace(state.first + 1, branch.second); + } + } + return visited.size(); } }