teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

アトキンの篩のコードに変更

2019/05/22 05:31

投稿

mather
mather

スコア6765

answer CHANGED
@@ -1,33 +1,110 @@
1
- 具体的に何が問題か指摘するのが大変なので、まずは関数の定義など基本的な文法から学び直してください。
1
+ まずは関数の定義など基本的な文法から学び直してください。
2
2
  また、定義に立ち返ってアルゴリズムをしっかり確認してみてください。
3
3
 
4
- 以下、ちょっと無駄サンプルコーです。
4
+ 処理複雑なら分解して関数化す、スコープを小さくして間違いにくくする、というのも手です。
5
5
 
6
+ 具体的に何が問題か指摘するのが大変なので、以下にアトキンの篩のコードを書いておきます。
7
+
6
8
  ```c
7
9
  #include <stdio.h>
8
10
 
9
- #define N 1000
11
+ #define N 1000000
12
+ #define TRUE 1
13
+ #define FALSE 0
10
14
 
11
- int calc(int i, int j) {
15
+ int is_in(int num, int set[], int length) {
12
- return i + j + 2 * i * j;
16
+ for(int i = 0; i < length; i++) {
17
+ if(num == set[i]) return TRUE;
18
+ }
19
+ return FALSE;
13
20
  }
14
21
 
15
- int main(int argc, char* argv[]) {
22
+ void toggle(int* target) {
23
+ if(*target == TRUE) {
24
+ *target = FALSE;
25
+ }
16
- int list[N+1] = {};
26
+ *target = TRUE;
17
- int i, j;
27
+ }
18
28
 
29
+ void step1(int is_prime[]) {
30
+ int n, n60;
31
+ int s[] = {1,13,17,29,37,41,49,53};
32
+ int s_len = sizeof(s) / sizeof(s[0]);
33
+
19
- for(i = 1; calc(i, i) <= N; i++) {
34
+ for(int x = 1; 4 * x * x < N; x++) {
20
- for(j = i; calc(i, j) <= N; j++) {
35
+ for(int y = 1; y < N; y = y + 2) {
36
+ n = 4 * x * x + y * y;
37
+ if (n > N) break;
38
+ n60 = n % 60;
39
+ if(is_in(n60, s, s_len) == TRUE) {
21
- list[calc(i,j)] = 1;
40
+ toggle(is_prime + n);
41
+ }
22
42
  }
23
43
  }
44
+ }
24
45
 
46
+ void step2(int is_prime[]) {
47
+ int n, n60;
25
- printf("2 ");
48
+ int s[] = {7,19,31,43};
49
+ int s_len = sizeof(s) / sizeof(s[0]);
50
+
51
+ for(int x = 1; 3 * x * x < N; x = x + 2) {
26
- for(i = 1; i <= N; i++) {
52
+ for(int y = 2; y < N; y = y + 2) {
53
+ n = 3 * x * x + y * y;
54
+ if (n > N) break;
55
+ n60 = n % 60;
56
+ if(is_in(n60, s, s_len) == TRUE) {
27
- if(list[i] == 0) {
57
+ toggle(is_prime + n);
28
- printf("%d ", 2*i + 1);
58
+ }
29
59
  }
30
60
  }
31
- printf("\n");
32
61
  }
62
+
63
+ void step3(int is_prime[]) {
64
+ int n, n60;
65
+ int s[] = {11,23,47,59};
66
+ int s_len = sizeof(s) / sizeof(s[0]);
67
+
68
+ for(int x = 2; 3 * x * x < N; x++) {
69
+ for(int y = x - 1; y > 0; y = y - 2) {
70
+ n = 3 * x * x - y * y;
71
+ if (n > N) break;
72
+ n60 = n % 60;
73
+ if(is_in(n60, s, s_len) == TRUE) {
74
+ toggle(is_prime + n);
75
+ }
76
+ }
77
+ }
78
+ }
79
+
80
+ void eliminate_composites(int is_prime[]) {
81
+ int s[] = {1,7,11,13,17,19,23,29,31,37,41,43,47,49,53,59};
82
+ int s_len = sizeof(s) / sizeof(s[0]);
83
+ int n;
84
+
85
+ for(n = 7; n*n < N; n++) {
86
+ if( is_in(n % 60, s, s_len) == TRUE && is_prime[n] == TRUE) {
87
+ for(int i = 1; i < N/(n*n); i++)
88
+ is_prime[n*n*i] = FALSE;
89
+ }
90
+ }
91
+ }
92
+
93
+
94
+ int main(int argc, char* argv[]) {
95
+ int is_prime[N+1] = {FALSE};
96
+
97
+ step1(is_prime);
98
+ step2(is_prime);
99
+ step3(is_prime);
100
+ eliminate_composites(is_prime);
101
+
102
+ printf("2\n3\n5\n");
103
+ for(int n = 7; n <= N; n++) {
104
+ if(is_prime[n] == TRUE)
105
+ printf("%d\n", n);
106
+ }
107
+
108
+ return 0;
109
+ }
33
110
  ```