午後のひとときに、プログラミングの問題を考えてみる。
友愛数とは、
ある自然数AのAを除いた約数の和がB、
BのBを除いた約数の和がA
となる(A,B)の組である。
問題
友愛数の組をAを昇順で列挙するプログラムを組め
シンキングタ~イム
前回、婚約数のプログラミングをしましたので、それをちょっと書き換えるだけです。
自分が婚約数でどこまでプログラムを高速化したかというと、ちょっとやりすぎかもしれませんが、かなり大きな配列を作りました。
前回の婚約数の記事のkonyakusu4.cの配列を大きくしたということです。
あまりにも大きすぎて、ブログの文字数制限でアップできませんので、そこをカットします。
どんなデータになるかは、各自考えてみてください。
konyakusu.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
int main(int argc, char *argv[])
{
unsigned long long c, p, q, r, i, j, k, t, s;
int a[42324] = {/* カット */},n;
if ( argc == 3 ) {
c = atoll(argv[1]);
p = atoll(argv[2]);
} else {
c = 0;
p = 2;
}
for (; p<=ULONG_LONG_MAX/10; p++) {
printf("%llu\r",p);
t = p;
s = sqrtl(t);
q = 1;
i = 2;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 3;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 5;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 7;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 11;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 13;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 17;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
for (i=19,n=0; i<=s; i+=a[n],n=(n+1)%42324) {
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
}
if ( t > 1 ) {
q *= 1+t;
}
q -= 1+p;
if ( p >= q ) continue;
t = q;
s = sqrtl(t);
r = 1;
i = 2;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 3;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 5;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 7;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 11;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 13;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 17;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
for (i=19,n=0; i<=s; i+=a[n],n=(n+1)%42324) {
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
}
if ( t > 1 ) {
r *= 1+t;
}
r -= 1+q;
if ( p == r ) {
c++;
printf("%llu: (%llu,%llu)\n",c,p,q);
}
}
return EXIT_SUCCESS;
}※これをコンパイルしても動きませんよ。
配列が42324と膨大すぎですねw
どれくらいの確率で枝刈り出来ているかというと、
自然数全体を100%とすると、
(2*3*5*7*11*13*17-42324)/(2*3*5*7*11*13*17)
=(510510-42324)/510510
=468186/510510
=85085/7054
≒91.709467
の枝刈りが出来ているということです。
yuaisu.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <limits.h>
int main(int argc, char *argv[])
{
unsigned long long c, p, q, r, i, j, k, t, s;
int a[42324] = {/* カット */},n;
if ( argc == 3 ) {
c = atoll(argv[1]);
p = atoll(argv[2]);
} else {
c = 0;
p = 2;
}
for (; p<=ULONG_LONG_MAX/10; p++) {
printf("%llu\r",p);
t = p;
s = sqrtl(t);
q = 1;
i = 2;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 3;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 5;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 7;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 11;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 13;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
i = 17;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
for (i=19,n=0; i<=s; i+=a[n],n=(n+1)%42324) {
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
q *= k;
}
if ( t > 1 ) {
q *= 1+t;
}
q -= p;
if ( p >= q ) continue;
t = q;
s = sqrtl(t);
r = 1;
i = 2;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 3;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 5;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 7;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 11;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 13;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
i = 17;
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
for (i=19,n=0; i<=s; i+=a[n],n=(n+1)%42324) {
j = i;
k = 1;
while ( t%i == 0 ) {
k += j;
t /= i;
j *= i;
}
r *= k;
}
if ( t > 1 ) {
r *= 1+t;
}
r -= q;
if ( p == r ) {
c++;
printf("%llu: (%llu,%llu)\n",c,p,q);
}
}
return EXIT_SUCCESS;
}
変更したのは、赤文字の2行だけです。
さて、婚約数を100組を求めて以降も、プログラムを継続させていますが、まだ200組ちょいしか見つかっていません。
そんな状況下の中、友愛数のプログラミングをして走らせてみたところ、既に500組ちょい見つかっています。
というわけで、出力結果です。
出力結果
1: (220,284)
2: (1184,1210)
3: (2620,2924)
4: (5020,5564)
5: (6232,6368)
6: (10744,10856)
7: (12285,14595)
8: (17296,18416)
9: (63020,76084)
10: (66928,66992)
11: (67095,71145)
12: (69615,87633)
13: (79750,88730)
14: (100485,124155)
15: (122265,139815)
16: (122368,123152)
17: (141664,153176)
18: (142310,168730)
19: (171856,176336)
20: (176272,180848)
21: (185368,203432)
22: (196724,202444)
23: (280540,365084)
24: (308620,389924)
25: (319550,430402)
26: (356408,399592)
27: (437456,455344)
28: (469028,486178)
29: (503056,514736)
30: (522405,525915)
31: (600392,669688)
32: (609928,686072)
33: (624184,691256)
34: (635624,712216)
35: (643336,652664)
36: (667964,783556)
37: (726104,796696)
38: (802725,863835)
39: (879712,901424)
40: (898216,980984)
41: (947835,1125765)
42: (998104,1043096)
43: (1077890,1099390)
44: (1154450,1189150)
45: (1156870,1292570)
46: (1175265,1438983)
47: (1185376,1286744)
48: (1280565,1340235)
49: (1328470,1483850)
50: (1358595,1486845)
51: (1392368,1464592)
52: (1466150,1747930)
53: (1468324,1749212)
54: (1511930,1598470)
55: (1669910,2062570)
56: (1798875,1870245)
57: (2082464,2090656)
58: (2236570,2429030)
59: (2652728,2941672)
60: (2723792,2874064)
61: (2728726,3077354)
62: (2739704,2928136)
63: (2802416,2947216)
64: (2803580,3716164)
65: (3276856,3721544)
66: (3606850,3892670)
67: (3786904,4300136)
68: (3805264,4006736)
69: (4238984,4314616)
70: (4246130,4488910)
71: (4259750,4445050)
72: (4482765,5120595)
73: (4532710,6135962)
74: (4604776,5162744)
75: (5123090,5504110)
76: (5147032,5843048)
77: (5232010,5799542)
78: (5357625,5684679)
79: (5385310,5812130)
80: (5459176,5495264)
81: (5726072,6369928)
82: (5730615,6088905)
83: (5864660,7489324)
84: (6329416,6371384)
85: (6377175,6680025)
86: (6955216,7418864)
87: (6993610,7158710)
88: (7275532,7471508)
89: (7288930,8221598)
90: (7489112,7674088)
91: (7577350,8493050)
92: (7677248,7684672)
93: (7800544,7916696)
94: (7850512,8052488)
95: (8262136,8369864)
96: (8619765,9627915)
97: (8666860,10638356)
98: (8754130,10893230)
99: (8826070,10043690)
100: (9071685,9498555)
101: (9199496,9592504)
102: (9206925,10791795)
103: (9339704,9892936)
104: (9363584,9437056)
105: (9478910,11049730)
106: (9491625,10950615)
107: (9660950,10025290)
108: (9773505,11791935)
109: (10254970,10273670)
110: (10533296,10949704)
111: (10572550,10854650)
112: (10596368,11199112)
113: (10634085,14084763)
114: (10992735,12070305)
115: (11173460,13212076)
116: (11252648,12101272)
117: (11498355,12024045)
118: (11545616,12247504)
119: (11693290,12361622)
120: (11905504,13337336)
121: (12397552,13136528)
122: (12707704,14236136)
123: (13671735,15877065)
124: (13813150,14310050)
125: (13921528,13985672)
126: (14311688,14718712)
127: (14426230,18087818)
128: (14443730,15882670)
129: (14654150,16817050)
130: (15002464,15334304)
131: (15363832,16517768)
132: (15938055,17308665)
133: (16137628,16150628)
134: (16871582,19325698)
135: (17041010,19150222)
136: (17257695,17578785)
137: (17754165,19985355)
138: (17844255,19895265)
139: (17908064,18017056)
140: (18056312,18166888)
141: (18194715,22240485)
142: (18655744,19154336)
143: (20014808,21457192)
144: (20022328,22823432)
145: (20308995,20955645)
146: (21448630,23030090)
147: (22227075,24644925)
148: (22249552,25325528)
149: (22508145,23111055)
150: (22608632,25775368)
151: (23358248,25233112)
152: (23389695,25132545)
153: (23628940,27428276)
154: (24472180,30395276)
155: (25596544,25640096)
156: (25966832,26529808)
157: (26090325,26138475)
158: (28118032,28128368)
159: (28608424,29603576)
160: (30724694,32174506)
161: (30830696,31652704)
162: (31536855,32148585)
163: (31818952,34860248)
164: (32205616,34352624)
165: (32642324,35095276)
166: (32685250,34538270)
167: (33501825,36136575)
168: (34256222,35997346)
169: (34364912,34380688)
170: (34765731,36939357)
171: (35115795,43266285)
172: (35361326,40117714)
173: (35373195,40105845)
174: (35390008,39259592)
175: (35472592,36415664)
176: (37363095,45663849)
177: (37784810,39944086)
178: (37848915,39202605)
179: (38400512,38938288)
180: (38637016,40678184)
181: (38663950,43362050)
182: (38783992,41654408)
183: (38807968,40912232)
184: (43096904,46715896)
185: (44139856,44916944)
186: (45263384,46137016)
187: (46237730,61319902)
188: (46271745,49125375)
189: (46521405,53011395)
190: (46555250,55880590)
191: (46991890,48471470)
192: (48639032,52967368)
193: (48641584,48852176)
194: (49215166,55349570)
195: (50997596,51737764)
196: (52695376,56208368)
197: (56055872,56598208)
198: (56512610,75866014)
199: (56924192,64562488)
200: (58580540,70507972)
201: (59497888,61953512)
202: (63560025,65003175)
203: (63717615,66011985)
204: (66595130,74824390)
205: (66854710,71946890)
206: (67729064,69439576)
207: (67738268,79732132)
208: (68891992,78437288)
209: (71015260,85458596)
210: (71241830,78057370)
211: (72958556,74733604)
212: (73032872,78469528)
213: (74055952,78166448)
214: (74386305,87354495)
215: (74769345,82824255)
216: (75171808,77237792)
217: (75226888,81265112)
218: (78088504,88110536)
219: (78447010,80960990)
220: (79324875,87133365)
221: (80422335,82977345)
222: (82633005,104177619)
223: (83135650,85603550)
224: (84521745,107908335)
225: (84591405,89590995)
226: (86158220,99188788)
227: (87998470,102358010)
228: (88144630,102814490)
229: (89477984,92143456)
230: (90437150,94372450)
231: (91996816,93259184)
232: (93837808,99899792)
233: (95629904,97580944)
234: (95791430,115187002)
235: (96304845,96747315)
236: (97041735,97945785)
237: (102023145,116970399)
238: (102719740,129063812)
239: (103034776,105016424)
240: (104887448,105064552)
241: (108734050,116251550)
242: (109410345,110132055)
243: (110960710,125222330)
244: (114944072,125269528)
245: (115259625,123757335)
246: (115447424,118458976)
247: (115749344,116983744)
248: (116654896,120115664)
249: (118458830,131819506)
250: (120812175,126671985)
251: (121293315,138690045)
252: (127924335,148532625)
253: (131118975,132926625)
254: (131483835,132692805)
255: (133089500,176374564)
256: (133178325,133471275)
257: (133768816,141213584)
258: (134312152,139057448)
259: (134886465,147382335)
260: (136549413,140207067)
261: (136770075,155711205)
262: (137424188,141993412)
263: (138605350,147313850)
264: (139009990,156322490)
265: (140744835,166562685)
266: (140815384,155709416)
267: (144788020,186088988)
268: (145040288,149364256)
269: (146648612,159017308)
270: (147366765,182028483)
271: (148077644,160128436)
272: (153015550,168392450)
273: (154190750,190889986)
274: (155578180,172610492)
275: (155797390,165195890)
276: (156226856,165181144)
277: (157151410,163634510)
278: (161088158,166706530)
279: (162936904,166679096)
280: (164733752,166212808)
281: (165323696,167155024)
282: (165742395,182622405)
283: (166737550,188953970)
284: (168930032,179904784)
285: (169000448,173499952)
286: (169335790,179029010)
287: (169652512,173269088)
288: (169884784,173843216)
289: (170566690,197704670)
290: (172271385,197261415)
291: (175032884,175826716)
292: (176632390,182618810)
293: (177997352,182108128)
294: (180038452,193486028)
295: (181088985,184694055)
296: (182702024,184713976)
297: (183408615,190055385)
298: (186753688,208059752)
299: (186878110,196323170)
300: (189406984,203592056)
301: (190888155,194594085)
302: (195857415,196214265)
303: (196421715,224703405)
304: (199432948,213484172)
305: (200328232,206790368)
306: (200879055,206393265)
307: (201168592,203314448)
308: (203055622,210627578)
309: (203972715,207429525)
310: (204134385,244869135)
311: (204756904,226163096)
312: (205843365,254264283)
313: (208693628,255308932)
314: (209027128,224355272)
315: (209309704,209816696)
316: (211319745,234587199)
317: (214748488,245201912)
318: (216392216,218772184)
319: (221397165,235831635)
320: (223878416,227342704)
321: (224888895,273272769)
322: (226540432,231465968)
323: (227443340,302651764)
324: (231111392,231923488)
325: (238162815,270560385)
326: (238238864,244730224)
327: (242126704,257841296)
328: (242182930,258410030)
329: (245618415,266560785)
330: (248658488,256201912)
331: (250876395,323303445)
332: (251302370,271244830)
333: (252551048,279327352)
334: (252940545,284847615)
335: (253703776,260678624)
336: (256755056,273568144)
337: (256948065,263110815)
338: (258904646,269448634)
339: (260231192,266171608)
340: (264764630,290441770)
341: (265192208,275148208)
342: (267217335,347397705)
343: (270039910,301444250)
344: (270208672,274655648)
345: (271048340,331636372)
346: (271629728,279947872)
347: (273141836,306014644)
348: (274638460,302514116)
349: (274893410,284512030)
350: (275304590,281534770)
351: (275631376,281207984)
352: (276339808,278431136)
353: (278247976,293288024)
354: (281499435,297034965)
355: (285627615,293528865)
356: (286000065,297390015)
357: (287250632,287551288)
358: (287793350,302793850)
359: (291679245,339731955)
360: (291974824,299001176)
361: (295824376,299072024)
362: (300120652,347620148)
363: (300208696,313576904)
364: (301685895,342005985)
365: (302424784,303107888)
366: (302770672,306676928)
367: (304443436,305517524)
368: (305178874,356714246)
369: (305363984,306962896)
370: (305911606,331160522)
371: (308939936,318479584)
372: (311414355,338659245)
373: (311913855,326754945)
374: (312090808,332345192)
375: (316293016,322375784)
376: (318323864,324492136)
377: (318580262,343312858)
378: (319682650,382593830)
379: (319904235,370086165)
380: (320829728,327818272)
381: (323401712,332270608)
382: (324644792,352731208)
383: (330811850,354858550)
384: (332448224,338290096)
385: (332573392,335955248)
386: (334438875,358687845)
387: (339981512,373803448)
388: (343175404,364682516)
389: (346657311,370393569)
390: (347263216,370414064)
391: (347401035,365917365)
392: (348782488,371171432)
393: (356775430,392753210)
394: (357197302,409205258)
395: (359156770,402020318)
396: (360027675,433850085)
397: (360172336,383753264)
398: (360759652,393667868)
399: (362645570,398531518)
400: (362700728,413408872)
401: (364182075,365012325)
402: (370032676,407256284)
403: (371840350,464106146)
404: (373305350,432893050)
405: (375401624,399982216)
406: (377141350,394237850)
407: (382170512,385592848)
408: (385465395,415773645)
409: (388904355,465418845)
410: (391548675,433398525)
411: (393463072,402877088)
412: (394800070,443597882)
413: (395378272,397151648)
414: (395939775,499717185)
415: (397287345,399052815)
416: (400250565,442792251)
417: (404185672,423336248)
418: (405370035,473836365)
419: (406640992,416370848)
420: (407641130,435691990)
421: (414195782,463973818)
422: (419640364,453610196)
423: (425948050,441853550)
424: (426191535,514780497)
425: (426386025,426684375)
426: (427448510,445018690)
427: (427950350,455921650)
428: (429035596,458447924)
429: (430848592,445657808)
430: (436386015,482909985)
431: (437888168,456351832)
432: (438362984,466417816)
433: (438452624,445419376)
434: (439232624,451335376)
435: (442480816,461479184)
436: (447761144,455118856)
437: (460122410,484817110)
438: (465605192,531830968)
439: (466389344,472453792)
440: (467406225,534612975)
441: (471696190,540842690)
442: (474179596,505757684)
443: (475838415,514823985)
444: (487169380,589230476)
445: (491373104,511419856)
446: (492275992,553544168)
447: (494495768,564811432)
448: (504555070,540539330)
449: (506468950,535495610)
450: (509379344,523679536)
451: (512412550,528145850)
452: (514439224,536022776)
453: (519257296,552549104)
454: (520218704,537213616)
455: (522145832,538318048)
456: (525254368,541358816)
457: (526271456,529709344)
458: (526552472,540314728)
459: (529714744,567997256)
460: (536637465,646745463)
461: (537882550,570975050)
462: (540759375,640415025)
463: (541114808,552968392)
464: (545134144,552877376)
465: (551388915,677841165)
466: (553978490,587641990)
467: (557346712,570983288)
468: (558173344,571181792)
469: (558410475,662939925)
470: (559334930,750516718)
471: (573216416,576387424)
472: (577884195,587323485)
473: (579926204,628681924)
474: (579980048,589141552)
475: (585057992,632663608)
476: (586188070,594986330)
477: (586200224,587353696)
478: (595858064,596654896)
479: (596668490,603557110)
480: (600418910,787621282)
481: (601020945,623232495)
482: (601235145,696285495)
483: (602035390,619418690)
484: (606235455,625482945)
485: (613290028,682191572)
486: (621354896,661063024)
487: (625955024,655391536)
488: (626323995,643272165)
489: (630007455,693778785)
490: (637756665,639580935)
491: (640001054,642416866)
492: (640866135,694532265)
493: (643006485,663361515)
494: (647314690,666518270)
495: (651016665,663576615)
496: (653078426,786829414)
497: (658009485,689830515)
498: (659084504,752700136)
499: (659854052,743584348)
500: (660792650,753402550)
今回は100組と言わず、500組を出しておきます。
目標は、どちらも1000組なのですが、友愛数はあと数日もあれば完了しそうですが、婚約数はあと1ヶ月くらいは掛かるのではと予想しております。
というわけで、次は社交数かな。
社交数は厄介だな。
プログラミングの改変はそれほど難しくはないのですが、1000組も求めようとすると、婚約数以上に時間が掛かるかもしれませんね。
ではでは
knifeのmy Pick