Verifying output to "Find the numbers between 1 and 1000 whose prime factors' sum is itself a prime" from Allain's Jumping into C++ (ch7 #3)

StackOverflow https://stackoverflow.com/questions/22255147

Question

The question:

Design a program that finds all numbers from 1 to 1000 whose prime factors, when added together, sum up to a prime number (for example, 12 has prime factors of 2, 2, and 3, which sum to 7, which is prime). Implement the code for that algorithm.

I modified the problem to only sum unique factors, because I don't see why you'd count a factor twice, as in his example using 12.

My solution. Is there any good (read: automated) way to verify the output of my program?

Sample output for 1 to 1000:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
17
19
20
22
23
24
25
26
28
29
30
31
34
37
40
41
43
44
46
47
48
49
52
53
58
59
60
61
63
67
68
70
71
73
76
79
80
82
83
88
89
92
94
96
97
99
101
103
107
109
113
116
117
118
120
121
124
127
131
136
137
139
140
142
147
148
149
151
153
157
160
163
164
167
169
171
172
173
176
179
181
184
188
189
191
192
193
197
198
199
202
207
210
211
212
214
223
227
229
232
233
239
240
241
244
251
252
257
261
263
268
269
271
272
273
274
275
277
279
280
281
283
286
289
292
293
294
297
298
306
307
311
313
317
320
325
331
332
333
334
337
347
349
351
352
353
358
359
361
367
368
369
373
376
379
382
383
384
388
389
394
396
397
399
401
404
409
412
414
419
421
423
424
425
428
431
433
439
443
449
454
457
459
461
462
463
464
467
468
472
475
478
479
480
487
491
495
499
503
509
513
521
522
523
524
529
531
538
539
541
544
546
547
548
549
550
557
560
561
562
563
567
569
571
572
575
577
587
588
593
594
599
601
603
604
605
607
612
613
617
619
621
622
628
631
639
640
641
643
646
647
651
652
653
659
661
664
668
673
677
683
684
691
692
694
701
704
709
712
714
718
719
725
726
727
733
736
738
739
741
743
751
752
756
757
759
761
764
765
768
769
772
773
775
777
783
787
792
797
798
801
809
811
821
823
825
827
828
829
833
837
838
839
841
846
847
848
850
853
856
857
859
862
863
873
877
881
883
887
891
892
903
904
907
908
909
911
918
919
922
925
928
929
932
937
941
944
947
953
954
957
960
961
966
967
971
975
977
981
983
991
997
999

Update: I have solved my problem and verified the output of my program using an OEIS given series, as suggested by @MVW (shown in the source given by my new github solution). In the future, I will aim to test my programs by doing zero or more of the following (depending on the scope/importance of the problem):

  • google keywords for an existing solution to the problem, comparing it against my solution if I find it
  • unit test components for correctness as they're built and integrated, comparing these tests with known correct outputs
Was it helpful?

Solution

Some suggestions:

You need to check the properties of your calculated numbers. Here that means

  1. calculating the prime factors and
  2. calculating their sum and
  3. testing if that sum is a prime number.

Which is what your program should do in the first place, by the way.

So one nice option for checking is comparing your output with a known solution or the output of a another program which is known to work. The tricky bit is to have such a solution or program available. And I neglect that your comparison could be plagued by errors as well :-)

If you just compare it with other implementations, e.g. programs from other folks here, it would turn out more of a voting, it would not be a proof. It would just give increased probability that your program is correct, if several independent implementations come up with the same result. Of course all implementations could err :-) The more agree the better. And the more diverse the implementations are, the better. E.g. you could use different programming languages, algebraic systems or a friend with time and paper and pencil and Wikipedia. :-)

Another means is to add checks to your intermediate steps, to get more confidence in your result. Kind of building a chain of trust.

  • You could output the prime factors you determined and compare it with the output of a prime factorization program which is known to work.

  • Then you check if your summing works.

  • Finally you could check if the primality test you apply to the candidate sums is working correctly by feeding it with known prime numbers and non prime numbers and so on.

That is kind of what folks do with unit testing for example. Trying to cover most parts of the code as working, hoping if the parts work, that the whole will work.

Or you could formally prove your program step by step, using Hoare Calculus for example or another formal method. But that is tricky, and you might end up shifting program errors to errors in the proof.

And today, in the era of internet, of course, you could internet search for the solution:

Try searching for sum of prime factors is prime in the online encyclopedia of integer sequences, which should give you series A100118. :-) It is the problem with multiplicity, but shows you what the number theory pros do, with Mathematica and program fragments to calculate the series, the argument for the case of 1 and literature. Quite impressive.

OTHER TIPS

Here's the answer I get. I exclude 1 as it has no prime divisors so their sum is 0, not a prime.

Haskell> filter (isPrime . sum . map fst . primePowers) [2..1000]
[2,3,4,5,6,7,8,9,10,11,12,13,16,17,18,19,20,22,23,24,25,27,29,31,32,34,36,37,40,
41,43,44,47,48,49,50,53,54,58,59,61,64,67,68,71,72,73,79,80,81,82,83,88,89,96,97
,100,101,103,107,108,109,113,116,118,121,125,127,128,131,136,137,139,142,144,149
,151,157,160,162,163,164,165,167,169,173,176,179,181,191,192,193,197,199,200,202
,210,211,214,216,223,227,229,232,233,236,239,241,242,243,250,251,256,257,263,269
,271,272,273,274,277,281,283,284,288,289,293,298,307,311,313,317,320,324,328,331
,337,343,345,347,349,352,353,358,359,361,367,373,379,382,383,384,385,389,390,394
,397,399,400,401,404,409,419,420,421,428,431,432,433,435,439,443,449,454,457,461
,462,463,464,467,472,478,479,484,486,487,491,495,499,500,503,509,512,521,523,529
,538,541,544,547,548,557,561,562,563,568,569,570,571,576,577,578,587,593,595,596
,599,601,607,613,617,619,622,625,630,631,640,641,643,647,648,651,653,656,659,661
,665,673,677,683,691,694,701,704,709,714,715,716,719,727,729,733,739,743,751,757
,759,761,764,768,769,773,777,780,787,788,795,797,798,800,808,809,811,819,821,823
,825,827,829,838,839,840,841,853,856,857,858,859,862,863,864,877,881,883,885,887
,903,907,908,911,919,922,924,928,929,930,937,941,944,947,953,956,957,961,967,968
,971,972,977,983,991,997,1000]

Haskell> primePowers 12
[(2,2),(3,1)]

Haskell> primePowers 14
[(2,1),(7,1)]

You could hard-code this list in and test against it. I'm pretty confident these results are without error.

(read . is "of").

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top