diff --git a/res/2016/day14/test_input.txt b/res/2016/day14/test_input.txt index e69de29..8baef1b 100644 --- a/res/2016/day14/test_input.txt +++ b/res/2016/day14/test_input.txt @@ -0,0 +1 @@ +abc diff --git a/src/2016/Day14.cpp b/src/2016/Day14.cpp index 448e544..b2f8d86 100644 --- a/src/2016/Day14.cpp +++ b/src/2016/Day14.cpp @@ -2,30 +2,112 @@ namespace y2016::day14 { - REGISTER_DAY(2016, Day14, std::vector, int); + REGISTER_DAY(2016, Day14, std::string, int); - REGISTER_TEST_EXAMPLE(2016, Day14, ExampleInput, 1, 0); - REGISTER_TEST(2016, Day14, Input, 1, 0); - REGISTER_TEST_EXAMPLE(2016, Day14, ExampleInput, 2, 0); - REGISTER_TEST(2016, Day14, Input, 2, 0); + REGISTER_TEST_EXAMPLE(2016, Day14, ExampleInput, 1, 22728); + REGISTER_TEST(2016, Day14, Input, 1, 15035); + REGISTER_TEST_EXAMPLE(2016, Day14, ExampleInput, 2, 22551); + REGISTER_TEST(2016, Day14, Input, 2, 19968); READ_INPUT(input) { - std::vector vec; std::string str; - while (getline(input, str)) + getline(input, str); + return str; + } + + char GetConsecutive(const std::string& s, int count) + { + for (size_t i = 0; i < s.size(); i++) { + bool found = true; + char c = s[i]; + for (int j = 1; j < count; j++) + { + if (s[i + j] != c) + { + found = false; + break; + } + } + if (found) + return c; } - return vec; + return '\0'; + } + + std::set GetConsecutives(const std::string& s, int count) + { + std::set consecutives; + for (size_t i = 0; i < s.size(); i++) + { + char c = s[i]; + bool found = true; + for (int j = 0; j < count; j++) + { + if (s[i + j] != c) + { + found = false; + break; + } + } + if (found) + consecutives.emplace(c); + } + return consecutives; + } + + void Hash(std::string& s, int count) + { + for (int i = 0; i < count; i++) + s = Md5::Hash(s); + } + + int FindKeys(const std::string& str, int repeat) + { + std::vector foundKeys; + std::map keys; + int i = 0; + int upperLimit = std::numeric_limits::max(); + while (i < upperLimit) + { + keys.erase(i - 1000); + + std::string hash = str + std::to_string(i); + Hash(hash, repeat + 1); + char c = GetConsecutive(hash, 3); + std::set consecutives = GetConsecutives(hash, 5); + + for (auto it = keys.begin(); it != keys.end();) + { + if (consecutives.count(it->second) != 0) + { + foundKeys.emplace_back(it->first); + if (foundKeys.size() == 64) + upperLimit = it->first + 1000; + it = keys.erase(it); + } + else + { + it++; + } + } + + if (c != '\0') + keys.emplace(i, c); + i++; + } + std::sort(foundKeys.begin(), foundKeys.end()); + return foundKeys[63]; } OUTPUT1(input) { - return 0; + return FindKeys(input, 0); } OUTPUT2(input) { - return 0; + return FindKeys(input, 2016); } }