Skip to content

Instantly share code, notes, and snippets.

@chenshuo
Created November 6, 2015 18:41
Show Gist options
  • Save chenshuo/47de4bdf2de9ab6ed852 to your computer and use it in GitHub Desktop.
Save chenshuo/47de4bdf2de9ab6ed852 to your computer and use it in GitHub Desktop.
Calculate 24 points.
#include <boost/rational.hpp>
#include <iostream>
#include <vector>
#include <stdio.h>
using boost::rational;
using std::cout;
using std::vector;
typedef vector<rational<int>> Numbers;
bool is_integer(rational<int> x)
{
return x.denominator() == 1;
}
void calc(rational<int> x, rational<int> y, Numbers& result)
{
result.clear();
result.push_back(x+y);
result.push_back(x*y);
if (x >= y)
result.push_back(x-y);
else
result.push_back(y-x);
const bool kAllowRational = true;
if (x != 0 && (kAllowRational || is_integer(y/x)))
result.push_back(y/x);
if (y != 0 && (kAllowRational || is_integer(x/y)))
result.push_back(x/y);
}
bool g_track = false;
bool check(const Numbers& input)
{
if (input.size() == 1)
{
if (input[0] == 24)
return true;
}
else
{
Numbers next;
Numbers result;
for (size_t i = 0; i < input.size(); ++i)
for (size_t j = i+1; j < input.size(); ++j)
{
calc(input[i], input[j], result);
for (auto x : result)
{
next.push_back(x);
for (size_t k = 0; k < input.size(); ++k)
{
if (k != i && k != j)
next.push_back(input[k]);
}
assert(next.size() == input.size() - 1);
if (check(next))
{
if (g_track)
{
for (auto x : input)
if (is_integer(x))
cout << x.numerator() << ' ';
else
cout << x << ' ';
cout << '\n';
}
return true;
}
next.clear();
}
}
}
return false;
}
bool check(int a, int b, int c, int d)
{
return check(Numbers{a, b, c, d});
}
int main(int argc, char* argv[])
{
if (argc == 5)
{
g_track = true;
printf("%d\n",
check(atoi(argv[1]),
atoi(argv[2]),
atoi(argv[3]),
atoi(argv[4])));
}
else
{
int count = 0;
int total = 0;
const int kMax = 10;
for (int a = 1; a <= kMax; ++a)
for (int b = a; b <= kMax; ++b)
for (int c = b; c <= kMax; ++c)
for (int d = c; d <= kMax; ++d)
{
++total;
if (check(a, b, c, d))
{
printf("%2d %2d %2d %2d\n", a, b, c, d);
++count;
}
}
printf("%d %d\n", count, total);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment