Skip to content

Instantly share code, notes, and snippets.

@gatchamix
Created November 17, 2017 18:48
Show Gist options
  • Save gatchamix/30917c1c8823a0070067e8a779dca0c6 to your computer and use it in GitHub Desktop.
Save gatchamix/30917c1c8823a0070067e8a779dca0c6 to your computer and use it in GitHub Desktop.
Implementation of Cows and Bulls game
#include <cstdint>
#include <algorithm>
#include <tuple>
template <class... Ts>
auto constexpr persist(Ts volatile... ts)
{ std::tuple{ ts... }; }
auto constexpr hamming_weight(std::uint16_t const mask,
std::uint16_t const value)
{
auto ret = value & mask;
ret = ((ret & 0xAAAA) >> 1) + (ret & 0x5555);
ret = ((ret & 0xCCCC) >> 2) + (ret & 0x3333);
ret = ((ret & 0xF0F0) >> 4) + (ret & 0x0F0F);
ret = ((ret & 0xFF00) >> 8) + (ret & 0x00FF);
return ret;
}
auto constexpr generate(std::size_t const n,
std::uint16_t const key, std::uint16_t const guess)
{
auto const mask = 0xFFFF >> (16 - n);
auto const diff = key ^ guess;
auto const key_misplaced = hamming_weight(mask, key & diff);
auto const guess_misplaced = hamming_weight(mask, guess & diff);
auto const bulls = n - key_misplaced - guess_misplaced;
auto const cows = std::min(key_misplaced, guess_misplaced) * 2;
return std::tuple{ bulls, cows };
}
int main(int argc, char **argv)
{
#if 1
auto const key = static_cast<std::uint16_t>(argv[0][0]);
auto const guess = static_cast<std::uint16_t>(argv[0][1]);
#else
auto constexpr key = std::uint16_t{ 0b1011'1111 };
auto constexpr guess = std::uint16_t{ 0b1101'1110 };
#endif
auto const [bulls, cows] = generate(8, key, guess);
persist(bulls, cows);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment