#include <vector>
#include <array>
#include <iostream>
enum class outcome {
crit_fail,
fail,
marginal,
degree1,
degree2,
degree3,
degree4,
};
struct pool_result {
int log2_weight = 0;
outcome result = outcome::fail;
};
enum class die_result {
one,
fail,
success,
six,
};
die_result unpack_one(unsigned x) {
return static_cast<die_result>(x & 3);
}
// 2 bits per die result
std::vector<die_result> unpack(unsigned x, std::size_t count) {
std::vector<die_result> retval;
retval.reserve(count);
for (std::size_t i = 0; i < count; ++i) {
retval.push_back(unpack_one(x));
x = x >> 2;
}
return retval;
}
pool_result evaluate( std::vector<die_result> const& r, int difficulty, int auto_success )
{
int ones = 0;
int failures = 0;
int successes = 0;
int sixes = 0;
for (auto x : r)
{
switch (x) {
case die_result::one: ++ones; ++failures; break;
case die_result::fail: ++failures; break;
case die_result::success: ++successes; break;
case die_result::six: ++successes; ++sixes; break;
}
}
pool_result retval;
retval.log2_weight = failures - ones + successes - sixes;
bool success = (successes + auto_success) >= difficulty;
if (!success && ones > successes)
retval.result = outcome::crit_fail;
else if (!success)
retval.result = outcome::fail;
else if (sixes == 0)
retval.result = outcome::marginal;
else if (sixes == 1)
retval.result = outcome::degree1;
else if (sixes == 2)
retval.result = outcome::degree2;
else if (sixes == 3)
retval.result = outcome::degree3;
else if (sixes >= 4)
retval.result = outcome::degree4;
return retval;
}
using table = std::array< pool_result, (1<<24) >;
table solve( int dice, int difficulty) {
int bonus_dice = (std::max)(dice-12, 0);
if (dice > 12) dice = 12;
int table_size = (1 << (dice*2));
table retval;
for (int x = 0; x < table_size; ++x)
{
retval[x] = evaluate( unpack(x, dice), difficulty, bonus_dice );
}
return retval;
}
int main() {
printf("Hello\n");
std::cerr << "Working...\n";
auto result = solve(12, 4);
int prob[7] = {0};
for (auto r : result)
{
prob[static_cast<int>(r.result)] += (1<<r.log2_weight);
}
for (auto p:prob)
std::cout << (p/double(1<<24)) << "\n";
}
I2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8aW9zdHJlYW0+CgplbnVtIGNsYXNzIG91dGNvbWUgewogIGNyaXRfZmFpbCwKICBmYWlsLAogIG1hcmdpbmFsLAogIGRlZ3JlZTEsCiAgZGVncmVlMiwKICBkZWdyZWUzLAogIGRlZ3JlZTQsCn07CgpzdHJ1Y3QgcG9vbF9yZXN1bHQgewogIGludCBsb2cyX3dlaWdodCA9IDA7CiAgb3V0Y29tZSByZXN1bHQgPSBvdXRjb21lOjpmYWlsOwp9OwoKZW51bSBjbGFzcyBkaWVfcmVzdWx0IHsKICBvbmUsCiAgZmFpbCwKICBzdWNjZXNzLAogIHNpeCwKfTsKCmRpZV9yZXN1bHQgdW5wYWNrX29uZSh1bnNpZ25lZCB4KSB7CiAgcmV0dXJuIHN0YXRpY19jYXN0PGRpZV9yZXN1bHQ+KHggJiAzKTsKfQoKLy8gMiBiaXRzIHBlciBkaWUgcmVzdWx0CnN0ZDo6dmVjdG9yPGRpZV9yZXN1bHQ+IHVucGFjayh1bnNpZ25lZCB4LCBzdGQ6OnNpemVfdCBjb3VudCkgewogIHN0ZDo6dmVjdG9yPGRpZV9yZXN1bHQ+IHJldHZhbDsKICByZXR2YWwucmVzZXJ2ZShjb3VudCk7CiAgZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKICAgIHJldHZhbC5wdXNoX2JhY2sodW5wYWNrX29uZSh4KSk7CiAgICB4ID0geCA+PiAyOwogIH0KICByZXR1cm4gcmV0dmFsOwp9Cgpwb29sX3Jlc3VsdCBldmFsdWF0ZSggc3RkOjp2ZWN0b3I8ZGllX3Jlc3VsdD4gY29uc3QmIHIsIGludCBkaWZmaWN1bHR5LCBpbnQgYXV0b19zdWNjZXNzICkKewogIGludCBvbmVzID0gMDsKICBpbnQgZmFpbHVyZXMgPSAwOwogIGludCBzdWNjZXNzZXMgPSAwOwogIGludCBzaXhlcyA9IDA7CiAgZm9yIChhdXRvIHggOiByKQogIHsKICAgIHN3aXRjaCAoeCkgewogICAgICBjYXNlIGRpZV9yZXN1bHQ6Om9uZTogKytvbmVzOyArK2ZhaWx1cmVzOyBicmVhazsKICAgICAgY2FzZSBkaWVfcmVzdWx0OjpmYWlsOiArK2ZhaWx1cmVzOyBicmVhazsKICAgICAgY2FzZSBkaWVfcmVzdWx0OjpzdWNjZXNzOiArK3N1Y2Nlc3NlczsgYnJlYWs7CiAgICAgIGNhc2UgZGllX3Jlc3VsdDo6c2l4OiArK3N1Y2Nlc3NlczsgKytzaXhlczsgYnJlYWs7CiAgICB9CiAgfQogIHBvb2xfcmVzdWx0IHJldHZhbDsKICByZXR2YWwubG9nMl93ZWlnaHQgPSBmYWlsdXJlcyAtIG9uZXMgKyBzdWNjZXNzZXMgLSBzaXhlczsKCiAgYm9vbCBzdWNjZXNzID0gKHN1Y2Nlc3NlcyArIGF1dG9fc3VjY2VzcykgPj0gZGlmZmljdWx0eTsKCiAgaWYgKCFzdWNjZXNzICYmIG9uZXMgPiBzdWNjZXNzZXMpCiAgICByZXR2YWwucmVzdWx0ID0gb3V0Y29tZTo6Y3JpdF9mYWlsOwogIGVsc2UgaWYgKCFzdWNjZXNzKQogICAgcmV0dmFsLnJlc3VsdCA9IG91dGNvbWU6OmZhaWw7CiAgZWxzZSBpZiAoc2l4ZXMgPT0gMCkKICAgIHJldHZhbC5yZXN1bHQgPSBvdXRjb21lOjptYXJnaW5hbDsKICBlbHNlIGlmIChzaXhlcyA9PSAxKQogICAgcmV0dmFsLnJlc3VsdCA9IG91dGNvbWU6OmRlZ3JlZTE7CiAgZWxzZSBpZiAoc2l4ZXMgPT0gMikKICAgIHJldHZhbC5yZXN1bHQgPSBvdXRjb21lOjpkZWdyZWUyOwogIGVsc2UgaWYgKHNpeGVzID09IDMpCiAgICByZXR2YWwucmVzdWx0ID0gb3V0Y29tZTo6ZGVncmVlMzsKICBlbHNlIGlmIChzaXhlcyA+PSA0KQogICAgcmV0dmFsLnJlc3VsdCA9IG91dGNvbWU6OmRlZ3JlZTQ7CiAgcmV0dXJuIHJldHZhbDsKfQoKdXNpbmcgdGFibGUgPSBzdGQ6OmFycmF5PCBwb29sX3Jlc3VsdCwgKDE8PDI0KSA+OwoKdGFibGUgc29sdmUoIGludCBkaWNlLCBpbnQgZGlmZmljdWx0eSkgewogIGludCBib251c19kaWNlID0gKHN0ZDo6bWF4KShkaWNlLTEyLCAwKTsKICBpZiAoZGljZSA+IDEyKSBkaWNlID0gMTI7CiAgaW50IHRhYmxlX3NpemUgPSAoMSA8PCAoZGljZSoyKSk7CiAgdGFibGUgcmV0dmFsOwogIGZvciAoaW50IHggPSAwOyB4IDwgdGFibGVfc2l6ZTsgKyt4KQogIHsKICAgIHJldHZhbFt4XSA9IGV2YWx1YXRlKCB1bnBhY2soeCwgZGljZSksIGRpZmZpY3VsdHksIGJvbnVzX2RpY2UgKTsKICB9CiAgcmV0dXJuIHJldHZhbDsKfQoKCmludCBtYWluKCkgewogIHByaW50ZigiSGVsbG9cbiIpOwogIHN0ZDo6Y2VyciA8PCAiV29ya2luZy4uLlxuIjsKICAKICBhdXRvIHJlc3VsdCA9IHNvbHZlKDEyLCA0KTsKICBpbnQgcHJvYls3XSA9IHswfTsKICBmb3IgKGF1dG8gciA6IHJlc3VsdCkKICB7CiAgICBwcm9iW3N0YXRpY19jYXN0PGludD4oci5yZXN1bHQpXSArPSAoMTw8ci5sb2cyX3dlaWdodCk7CiAgfQoKICBmb3IgKGF1dG8gcDpwcm9iKQogICAgc3RkOjpjb3V0IDw8IChwL2RvdWJsZSgxPDwyNCkpIDw8ICJcbiI7Cn0=