Skip to content

Instantly share code, notes, and snippets.

@skeeto
Last active November 24, 2020 11:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skeeto/1718d6613dc47a7aff13333942a40776 to your computer and use it in GitHub Desktop.
Save skeeto/1718d6613dc47a7aff13333942a40776 to your computer and use it in GitHub Desktop.
6x6 Hotel Key Card Counter
/* 6x6 Hotel Key Card Counter
* $ cc -fopenmp -O3 -march=native keycount.c
* Ref: https://possiblywrong.wordpress.com/2020/10/24/counting-hotel-key-cards/
*/
#include <stdio.h>
static long long
transpose(long long x)
{
return (x << 5 & 0x408102040) |
(x << 10 & 0x204081000) |
(x << 15 & 0x102040000) |
(x << 20 & 0x081000000) |
(x << 25 & 0x040000000) |
(x >> 0 & 0x810204081) |
(x >> 5 & 0x020408102) |
(x >> 10 & 0x000810204) |
(x >> 15 & 0x000020408) |
(x >> 20 & 0x000000810) |
(x >> 25 & 0x000000020);
}
static long long
flipv(long long x)
{
return (x >> 30 & 0x00000003f) |
(x >> 18 & 0x000000fc0) |
(x >> 6 & 0x00003f000) |
(x << 6 & 0x000fc0000) |
(x << 18 & 0x03f000000) |
(x << 30 & 0xfc0000000);
}
static int
valid(long long x)
{
int v = 0;
long long a[7];
a[0] = x;
a[1] = x = transpose(x);
v += x < a[0];
v += x == a[0];
a[2] = x = flipv(x);
v += x < a[0];
v += x == a[0];
v += x == a[1];
a[3] = x = transpose(x);
v += x < a[0];
v += x == a[0];
v += x == a[1];
v += x == a[2];
a[4] = x = flipv(x);
v += x < a[0];
v += x == a[0];
v += x == a[1];
v += x == a[2];
v += x == a[3];
a[5] = x = transpose(x);
v += x < a[0];
v += x == a[0];
v += x == a[1];
v += x == a[2];
v += x == a[3];
v += x == a[4];
a[6] = x = flipv(x);
v += x < a[0];
v += x == a[0];
v += x == a[1];
v += x == a[2];
v += x == a[3];
v += x == a[4];
v += x == a[5];
x = transpose(x);
v += x < a[0];
v += x == a[0];
v += x == a[1];
v += x == a[2];
v += x == a[3];
v += x == a[4];
v += x == a[5];
v += x == a[6];
return !v;
}
int
main(void)
{
long long total = 0;
#pragma omp parallel for
for (int n = 0; n < 1<<8; n++) {
long long subtotal = 0;
for (long long i = 0; i < 1LL<<28; i++) {
subtotal += valid(i<<8 | n);
}
#pragma omp atomic
total += subtotal;
}
printf("%lld\n", total);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment