From cdf00cb66aef4fad57f3d1356c5c9feb9821b361 Mon Sep 17 00:00:00 2001 From: Thraix Date: Sun, 30 Aug 2026 22:50:54 +0200 Subject: [PATCH] Add solution for 2016 Day 16 - Fix Md5 algorithm --- res/2016/day17/test_input.txt | 1 + src/2016/Day17.cpp | 76 ++++++++++++++++++++++++++++++----- src/common/lib/Md5.cpp | 32 ++++++++++++++- 3 files changed, 97 insertions(+), 12 deletions(-) diff --git a/res/2016/day17/test_input.txt b/res/2016/day17/test_input.txt index e69de29..d1f0ba9 100644 --- a/res/2016/day17/test_input.txt +++ b/res/2016/day17/test_input.txt @@ -0,0 +1 @@ +ulqzkmiv diff --git a/src/2016/Day17.cpp b/src/2016/Day17.cpp index ed2fa22..2ea9f98 100644 --- a/src/2016/Day17.cpp +++ b/src/2016/Day17.cpp @@ -2,30 +2,84 @@ namespace y2016::day17 { - REGISTER_DAY(2016, Day17, std::vector, int); + REGISTER_DAY(2016, Day17, std::string, std::string); - REGISTER_TEST_EXAMPLE(2016, Day17, ExampleInput, 1, 0); - REGISTER_TEST(2016, Day17, Input, 1, 0); - REGISTER_TEST_EXAMPLE(2016, Day17, ExampleInput, 2, 0); - REGISTER_TEST(2016, Day17, Input, 2, 0); + REGISTER_TEST_EXAMPLE(2016, Day17, ExampleInput, 1, "DRURDRUDDLLDLUURRDULRLDUUDDDRR"); + REGISTER_TEST(2016, Day17, Input, 1, "DUDDRLRRRD"); + REGISTER_TEST_EXAMPLE(2016, Day17, ExampleInput, 2, "830"); + REGISTER_TEST(2016, Day17, Input, 2, "578"); READ_INPUT(input) { std::vector vec; std::string str; - while (getline(input, str)) - { - } - return vec; + getline(input, str); + return str; + } + + struct State + { + std::string str{""}; + int x{0}; + int y{0}; + }; + + bool IsOpen(char c) + { + return c >= 'b' && c <= 'f'; + } + + void Branch(const State& state, std::queue& queue) + { + std::string hash = Md5::Hash(state.str); + if (state.y > 0 && IsOpen(hash[0])) + queue.emplace(State{state.str + "U", state.x, state.y - 1}); + if (state.y < 3 && IsOpen(hash[1])) + queue.emplace(State{state.str + "D", state.x, state.y + 1}); + if (state.x > 0 && IsOpen(hash[2])) + queue.emplace(State{state.str + "L", state.x - 1, state.y}); + if (state.x < 3 && IsOpen(hash[3])) + queue.emplace(State{state.str + "R", state.x + 1, state.y}); + } + + bool IsGoal(const State& state) + { + return state.x == 3 && state.y == 3; } OUTPUT1(input) { - return 0; + std::queue queue; + queue.emplace(State{input, 0, 0}); + while (!queue.empty()) + { + State state = queue.front(); + queue.pop(); + if (IsGoal(state)) + return state.str.substr(input.size()); + Branch(state, queue); + } + + return ""; } OUTPUT2(input) { - return 0; + std::queue queue; + queue.emplace(State{input, 0, 0}); + int longest = 0; + while (!queue.empty()) + { + State state = queue.front(); + queue.pop(); + if (IsGoal(state)) + { + longest = state.str.size() - input.size(); + continue; + } + Branch(state, queue); + } + + return std::to_string(longest); } } diff --git a/src/common/lib/Md5.cpp b/src/common/lib/Md5.cpp index de8218a..2db3908 100644 --- a/src/common/lib/Md5.cpp +++ b/src/common/lib/Md5.cpp @@ -5,6 +5,30 @@ #include #include +#undef AOC_MD5_TESTING + +void PrintData(uint8_t* data) +{ + for (int i = 0; i < 8; i++) + { + for (int j = 0; j < 8; j++) + { + std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)data[i * 8 + j]; + } + std::cout << " "; + for (int j = 0; j < 8; j++) + { + if (data[i * 8 + j] >= 32 && data[i * 8 + j] < 126) + std::cout << data[i * 8 + j]; + else + std::cout << "?"; + } + std::cout << std::endl; + } + + std::cout << std::dec << std::endl; +} + uint32_t Md5::BytesToUint32(uint8_t* data) { return ((uint32_t)data[3] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[1] << 8) | (uint32_t)data[0]; @@ -17,6 +41,9 @@ uint32_t Md5::LeftRotate(uint32_t x, uint32_t n) void Md5::Transform(uint8_t* data, uint32_t& a0, uint32_t& b0, uint32_t& c0, uint32_t& d0) { +#ifdef AOC_MD5_TESTING + PrintData(data); +#endif // clang-format off const static std::array K { @@ -116,7 +143,10 @@ std::string Md5::Hash(std::string str) uint64_t offset = 0; for (int i = 0; i < loops - 1; i++) { - Transform((uint8_t*)(str.c_str() + offset), a0, b0, c0, d0); + uint8_t data[64]; + std::memset(data, 0x0, 64); + std::memcpy(data, str.c_str() + offset, std::min(str.size() - offset, 64)); + Transform(data, a0, b0, c0, d0); offset += 64; }