Add solution for 2015 Day 24

This commit is contained in:
Thraix
2026-08-04 23:13:43 +02:00
parent e8eb238682
commit 4de110a517
2 changed files with 127 additions and 11 deletions
+10
View File
@@ -0,0 +1,10 @@
1
2
3
4
5
7
8
9
10
11
+117 -11
View File
@@ -2,30 +2,136 @@
namespace y2015::day24
{
REGISTER_DAY(2015, Day24, std::vector<int>, int);
REGISTER_DAY(2015, Day24, std::vector<int>, uint64_t);
REGISTER_TEST_EXAMPLE(2015, Day24, ExampleInput, 1, 0);
REGISTER_TEST(2015, Day24, Input, 1, 0);
REGISTER_TEST_EXAMPLE(2015, Day24, ExampleInput, 2, 0);
REGISTER_TEST(2015, Day24, Input, 2, 0);
REGISTER_TEST_EXAMPLE(2015, Day24, ExampleInput, 1, 99);
REGISTER_TEST(2015, Day24, Input, 1, 11266889531);
REGISTER_TEST_EXAMPLE(2015, Day24, ExampleInput, 2, 44);
REGISTER_TEST(2015, Day24, Input, 2, 77387711);
READ_INPUT(input)
{
std::vector<int> vec;
std::string str;
while (getline(input, str))
return Input::ReadInts(input);
}
void GetAllSumCombinations(std::vector<int>& listLeft,
std::vector<int>& currentList,
std::vector<std::vector<int>>& result,
int sumLeft,
size_t offset)
{
if (sumLeft < 0)
return;
if (sumLeft == 0)
{
result.emplace_back(currentList);
return;
}
return vec;
for (size_t i = offset; i < listLeft.size(); i++)
{
if (listLeft[i] == 0)
continue;
if (sumLeft < listLeft[i])
break;
currentList.emplace_back(listLeft[i]);
int number = listLeft[i];
listLeft[i] = 0;
GetAllSumCombinations(listLeft, currentList, result, sumLeft - number, i + 1);
currentList.pop_back();
listLeft[i] = number;
}
}
std::vector<std::vector<int>> GetAllSumCombinations(std::vector<int> list, int sum, int groups)
{
std::vector<int> currentList{};
std::vector<std::vector<int>> result{};
GetAllSumCombinations(list, currentList, result, sum / groups, 0);
return result;
}
bool Overlap(const std::vector<int>& list1, const std::vector<int>& list2)
{
size_t i1 = 0;
size_t i2 = 0;
while (i1 < list1.size() && i2 < list2.size())
{
if (list1[i1] == list2[i2])
return true;
if (list1[i1] < list2[i2])
i1++;
else
i2++;
}
return false;
}
bool Overlap(const std::vector<int>& combination, const std::vector<const std::vector<int>*>& combinationList)
{
for (const auto& elem : combinationList)
{
if (Overlap(combination, *elem))
return true;
}
return false;
}
bool HasSolution(const std::vector<std::vector<int>>& sumCombinations,
const std::vector<const std::vector<int>*>& list,
size_t offset,
int groupsLeft)
{
for (size_t i = offset; i < sumCombinations.size(); i++)
{
if (Overlap(sumCombinations[i], list))
continue;
if (groupsLeft == 1)
return true;
std::vector<const std::vector<int>*> newList = list;
newList.emplace_back(&sumCombinations[i]);
if (HasSolution(sumCombinations, newList, i + 1, groupsLeft - 1))
return true;
}
return false;
}
uint64_t Solve(const std::vector<int>& list, int groups)
{
int sum = Helper::Sum<int>(list);
std::vector<std::vector<int>> sumCombinations = GetAllSumCombinations(list, sum, groups);
size_t minSize = std::numeric_limits<size_t>::max();
for (size_t i = 0; i < sumCombinations.size(); i++)
{
minSize = std::min(minSize, sumCombinations[i].size());
}
uint64_t minProd = std::numeric_limits<uint64_t>::max();
for (size_t i = 0; i < sumCombinations.size(); i++)
{
if (sumCombinations[i].size() != minSize)
continue;
size_t product = Helper::Product<uint64_t>(sumCombinations[i]);
if (product >= minProd)
continue;
if (HasSolution(sumCombinations, {&sumCombinations[i]}, 0, groups - 1))
minProd = product;
}
return minProd;
}
OUTPUT1(input)
{
return 0;
return Solve(input, 3);
}
OUTPUT2(input)
{
return 0;
return Solve(input, 4);
}
}