From fba918ba8f244d466d240341abe49a308fbf9156 Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Tue, 26 Jun 2018 14:07:24 +0800 Subject: 90, 315 --- euler315.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ euler90.c | 69 +++++++++++++++++++++++++++++++++ 2 files changed, 197 insertions(+) create mode 100644 euler315.c create mode 100644 euler90.c diff --git a/euler315.c b/euler315.c new file mode 100644 index 0000000..2d06cf4 --- /dev/null +++ b/euler315.c @@ -0,0 +1,128 @@ +#include + +/* The digital root (also repeated digital sum) of a non-negative + * integer is the (single digit) value obtained by an iterative process + * of summing digits, on each iteration using the result from the previous + * iteration to compute a digit sum. The process continues until a + * single-digit number is reached. + */ + +/* bit 0-2: top, mid, bottom + * bit 3-6: top-left, top-right, bottom-left, bottom-right + */ + +enum { + TOP = 1, + MID = 2, + BOTTOM = 4, + TL = 8, + TR = 16, + BL = 32, + BR = 64 +}; + +unsigned char lines[10] = { + TOP | BOTTOM | TL | TR | BL | BR, + TR | BR, + TOP | MID | BOTTOM | TR | BL, + TOP | MID | BOTTOM | TR | BR, + MID | TL | TR | BR, + TOP | MID | BOTTOM | TL | BR, + TOP | MID | BOTTOM | TL | BL | BR, + TOP | TL | TR | BR, + TOP | MID | BOTTOM | TL | TR | BL | BR, + TOP | MID | BOTTOM | TL | TR | BR +}; + +int popcount(unsigned char x) +{ + int count = 0; + while (x) { + count += (x&1); + x >>= 1; + } + return count; +} + +void get_digits(int x, int a[]) +{ + int i = 0; + do { + a[i] = x % 10; + x /= 10; + i++; + } while (x); + a[i] = -1; +} + +int clock_sam(int x) +{ + int digits[10]; + int l = 0; + while (x >= 10) { + get_digits(x, digits); + x = 0; + for (int i = 0; digits[i] != -1; i++) { + l += popcount(lines[digits[i]]) * 2; + x += digits[i]; + } + } + l += popcount(lines[x]) * 2; + return l; +} + +int clock_max(int x) +{ + int digits[10],next_digits[10], nx; + int l = 0; + get_digits(x, digits); + nx = 0; + for (int i = 0; digits[i] != -1; i++) { + l += popcount(lines[digits[i]]); + nx += digits[i]; + } + while (x >= 10) { + get_digits(nx, next_digits); + int i; + /* calculate the diff */ + for (i = 0; next_digits[i] != -1; i++) { + l += popcount(lines[digits[i]]^lines[next_digits[i]]); + } + while (digits[i] != -1) { + l += popcount(lines[digits[i]]); + i++; + } + /* get the next */ + x = nx; + nx = 0; + for (i = 0; next_digits[i] != -1; i++) { + digits[i] = next_digits[i]; + nx += next_digits[i]; + } + digits[i] = -1; + } + l += popcount(lines[x]); + return l; +} + +int isoddprime(int x) +{ + for (int i = 3; i*i <= x; i += 2) { + if (x % i == 0) + return 0; + } + return 1; +} + +int main() +{ + int sum = 0; + const int A = 10*1000*1000; + const int B = 20*1000*1000; + for (int i = A+1; i < B; i += 2) { + if (isoddprime(i)) { + sum += clock_sam(i) - clock_max(i); + } + } + printf("%d\n", sum); +} diff --git a/euler90.c b/euler90.c new file mode 100644 index 0000000..b514269 --- /dev/null +++ b/euler90.c @@ -0,0 +1,69 @@ +#include +#include +#include + +char dices[210][6]; + +#define FOR(i) for (a[i] = a[i-1]+1; a[i] < 10; a[i]++) + +void init() +{ + char a[6]; + int k = 0; + for (a[0] = 0; a[0] < 10; a[0]++) { + FOR(1) { + FOR(2) { + FOR(3) { + FOR(4) { + FOR(5) { + memcpy(dices[k], a, sizeof(a)); + k++; + } + } + } + } + } + } + assert(k == 210); +} + +int matches(char c, char dic[]) +{ + for (int i = 0; i < 6; i++) { + if (c == dic[i] || + ((c == 6 || c== 9) && (dic[i] == 6 || dic[i] == 9))) + return 1; + } + return 0; +} + +int ok(int x, int y) +{ + const char sqrs[9][2] = { + {0, 1}, {0, 4}, {0, 9}, {1, 6}, {2, 5}, {3, 6}, {4, 9}, + {6, 4}, {8, 1} + }; + for (int i = 0; i < 9; i++) { + if (matches(sqrs[i][0], dices[x]) + && matches(sqrs[i][1], dices[y])) + continue; + if (matches(sqrs[i][0], dices[y]) + && matches(sqrs[i][1], dices[x])) + continue; + return 0; + } + return 1; +} + +int main() +{ + int count = 0; + init(); + for (int i = 0; i < 210; i++) { + for (int j = i+1; j < 210; j++) { + if (ok(i, j)) + count++; + } + } + printf("%d\n", count); +} -- cgit v1.2.3