/*
* Michał Zagórski (C) 2017
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
const char* yes = "TAK";
const char* no = "NIE";
#define div_count 13
struct check_entry {
unsigned long long int n;
int prime;
int checked;
};
struct check_entry left_div[div_count];
struct check_entry right_div[div_count];
unsigned int size = 0;
unsigned long long int the_biggest;
inline void count_primes();
inline int check_primes();
int main()
{
unsigned long long int number;
unsigned int index = 0;
if (scanf("%llu", &number) < 0) {
return EXIT_FAILURE;
}
unsigned long long int divider = 10;
unsigned long long int left, right;
while (divider < number) {
left = number / divider;
right = number % divider;
left_div[index].n = left;
left_div[index].prime = 1;
left_div[index].checked = 0;
/*
* When the right number has zeros on begin it is smaller than 1/10
* of divider => Invalid split of number excusing it from check.
*/
if (right < divider / 10) {
right_div[index].n = right;
right_div[index].prime = 0;
right_div[index].checked = 1;
} else {
right_div[index].n = right;
right_div[index].prime = 1;
right_div[index].checked = 0;
index++;
}
divider *= 10;
}
the_biggest = left_div[0].n;
if (the_biggest < right_div[index - 1].n) {
the_biggest = right_div[index - 1].n;
}
size = index;
count_primes();
printf("%s\n", (check_primes() > 0) ? yes : no);
return 0;
}
inline void basic_check(struct check_entry* entry);
inline void check_num(struct check_entry* entry, unsigned long long int d);
inline void count_primes()
{
unsigned long long int div = 2;
for(unsigned int i = 0; i < size; i++) {
basic_check(&left_div[i]);
basic_check(&right_div[i]);
}
for(div = 5; div * div <= the_biggest; div += 2) {
for (unsigned int i = 0; i < size; i++) {
check_num(&left_div[i], div);
check_num(&right_div[i], div);
}
}
}
inline void basic_check(struct check_entry* entry) {
if(entry->n < 2) {
entry->checked = 1;
entry->prime = 0;
} else if (entry->n < 4) {
entry->checked = 1;
entry->prime = 1;
} else if (entry->n % 2 == 0 || entry->n % 3 == 0) {
entry->checked = 1;
entry->prime = 0;
}
}
inline void check_num(struct check_entry* entry, unsigned long long int d) {
if (entry->checked == 1)
return;
if (entry->n < d) {
entry->checked = 1;
return;
}
if (entry->n % d == 0) {
entry->prime = 0;
entry->checked = 1;
}
}
inline int check_primes() {
for (unsigned int i = 0; i < size; i++) {
if(left_div[i].prime == 1 && right_div[i].prime == 1) {
//fprintf(stderr, "%llu | %llu\n", left_div[i].n, right_div[i].n);
return 1;
}
}
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | /* * Michał Zagórski (C) 2017 */ #include <stdlib.h> #include <stdio.h> #include <string.h> const char* yes = "TAK"; const char* no = "NIE"; #define div_count 13 struct check_entry { unsigned long long int n; int prime; int checked; }; struct check_entry left_div[div_count]; struct check_entry right_div[div_count]; unsigned int size = 0; unsigned long long int the_biggest; inline void count_primes(); inline int check_primes(); int main() { unsigned long long int number; unsigned int index = 0; if (scanf("%llu", &number) < 0) { return EXIT_FAILURE; } unsigned long long int divider = 10; unsigned long long int left, right; while (divider < number) { left = number / divider; right = number % divider; left_div[index].n = left; left_div[index].prime = 1; left_div[index].checked = 0; /* * When the right number has zeros on begin it is smaller than 1/10 * of divider => Invalid split of number excusing it from check. */ if (right < divider / 10) { right_div[index].n = right; right_div[index].prime = 0; right_div[index].checked = 1; } else { right_div[index].n = right; right_div[index].prime = 1; right_div[index].checked = 0; index++; } divider *= 10; } the_biggest = left_div[0].n; if (the_biggest < right_div[index - 1].n) { the_biggest = right_div[index - 1].n; } size = index; count_primes(); printf("%s\n", (check_primes() > 0) ? yes : no); return 0; } inline void basic_check(struct check_entry* entry); inline void check_num(struct check_entry* entry, unsigned long long int d); inline void count_primes() { unsigned long long int div = 2; for(unsigned int i = 0; i < size; i++) { basic_check(&left_div[i]); basic_check(&right_div[i]); } for(div = 5; div * div <= the_biggest; div += 2) { for (unsigned int i = 0; i < size; i++) { check_num(&left_div[i], div); check_num(&right_div[i], div); } } } inline void basic_check(struct check_entry* entry) { if(entry->n < 2) { entry->checked = 1; entry->prime = 0; } else if (entry->n < 4) { entry->checked = 1; entry->prime = 1; } else if (entry->n % 2 == 0 || entry->n % 3 == 0) { entry->checked = 1; entry->prime = 0; } } inline void check_num(struct check_entry* entry, unsigned long long int d) { if (entry->checked == 1) return; if (entry->n < d) { entry->checked = 1; return; } if (entry->n % d == 0) { entry->prime = 0; entry->checked = 1; } } inline int check_primes() { for (unsigned int i = 0; i < size; i++) { if(left_div[i].prime == 1 && right_div[i].prime == 1) { //fprintf(stderr, "%llu | %llu\n", left_div[i].n, right_div[i].n); return 1; } } return 0; } |
English