Magnanimous numbers: Difference between revisions
Thundergnat (talk | contribs) (New draft task and Raku entry) |
m (→{{header|Wren}}: Minor tidy) |
||
(95 intermediate revisions by 35 users not shown) | |||
Line 1:
{{
A magnanimous number is an integer where there is no place in the number where a + (plus sign) could be added between
Line 7:
:* '''6425''' is a magnanimous number. '''6 + 425 == 431''' which is prime; '''64 + 25 == 89''' which is prime; '''642 + 5 == 647''' which is prime.
:* '''3538''' is '''not''' a magnanimous number. '''3 + 538 == 541''' which is prime; '''35 + 38 == 73''' which is prime; but '''353 + 8 == 361''' which is '''not''' prime.
Line 21:
:* Use that function to find and display, here on this page the first '''45''' magnanimous numbers.
:* Use that function to find and display, here on this page the '''
:* Stretch: Use that function to find and display, here on this page the '''391st''' through '''400th''' magnanimous numbers
Line 31:
=={{header|ALGOL 68}}==
<syntaxhighlight lang="algol68">BEGIN # find some magnanimous numbers - numbers where inserting a + between any #
# digits ab=nd evaluatinf the sum results in a prime in all cases #
# returns the first n magnanimous numbers #
# uses global sieve prime which must include 0 and be large enough #
# for all possible sub-sequences of digits #
OP MAGNANIMOUS = ( INT n )[]INT:
BEGIN
[ 1 : n ]INT result;
INT m count := 0;
FOR i FROM 0 WHILE m count < n DO
# split the number into pairs of digit seuences and check the sums of the pairs are all prime #
INT divisor := 1;
BOOL all prime := TRUE;
WHILE divisor *:= 10;
IF INT front = i OVER divisor;
front = 0
THEN FALSE
ELSE all prime := prime[ front + ( i MOD divisor ) ]
FI
DO SKIP OD;
IF all prime THEN result[ m count +:= 1 ] := i FI
OD;
result
END; # MAGNANIMPUS #
# prints part of a seuence of magnanimous numbers #
PROC print magnanimous = ( []INT m, INT first, INT last, STRING legend )VOID:
BEGIN
print( ( legend, ":", newline ) );
FOR i FROM first TO last DO print( ( " ", whole( m[ i ], 0 ) ) ) OD;
print( ( newline ) )
END ; # print magnanimous #
# we assume the first 400 magnanimous numbers will be in 0 .. 1 000 000 #
# so we will need a sieve of 0 up to 99 999 + 9 #
[ 0 : 99 999 + 9 ]BOOL prime;
prime[ 0 ] := prime[ 1 ] := FALSE; prime[ 2 ] := TRUE;
FOR i FROM 3 BY 2 TO UPB prime DO prime[ i ] := TRUE OD;
FOR i FROM 4 BY 2 TO UPB prime DO prime[ i ] := FALSE OD;
FOR i FROM 3 BY 2 TO ENTIER sqrt( UPB prime ) DO
IF prime[ i ] THEN FOR s FROM i * i BY i + i TO UPB prime DO prime[ s ] := FALSE OD FI
OD;
# construct the sequence of magnanimous numbers #
[]INT m = MAGNANIMOUS 400;
print magnanimous( m, 1, 45, "First 45 magnanimous numbers" );
print magnanimous( m, 241, 250, "Magnanimous numbers 241-250" );
print magnanimous( m, 391, 400, "Magnanimous numbers 391-400" )
END</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
Magnanimous numbers 241-250:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
Magnanimous numbers 391-400:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|ALGOL W}}==
<syntaxhighlight lang="algolw">begin
% find some Magnanimous numbers - numbers where inserting a "+" between %
% any two of the digits and evaluating the sum results in a prime number %
% implements the sieve of Eratosthenes %
procedure sieve( logical array s ( * ); integer value n ) ;
begin
% start with everything flagged as prime %
for i := 1 until n do s( i ) := true;
% sieve out the non-primes %
s( 1 ) := false;
for i := 2 until truncate( sqrt( n ) ) do begin
if s( i ) then for p := i * i step i until n do s( p ) := false
end for_i ;
end sieve ;
% construct an array of magnanimous numbers using the isPrime sieve %
procedure findMagnanimous ( logical array magnanimous, isPrime ( * ) ) ;
begin
% 1 digit magnanimous numbers %
for i := 0 until 9 do magnanimous( i ) := true;
% initially, the other magnanimous numbers are unknown %
for i := 10 until MAGNANIMOUS_MAX do magnanimous( i ) := false;
% 2 & 3 digit magnanimous numbers %
for d1 := 1 until 9 do begin
for d2 := 0 until 9 do begin
if isPrime( d1 + d2 ) then magnanimous( ( d1 * 10 ) + d2 ) := true
end for_d2 ;
for d23 := 0 until 99 do begin
if isPrime( d1 + d23 ) then begin
integer d12, d3;
d3 := d23 rem 10;
d12 := ( d1 * 10 ) + ( d23 div 10 );
if isPrime( d12 + d3 ) then magnanimous( ( d12 * 10 ) + d3 ) := true
end if_isPrime_d1_plus_d23
end for_d23
end for_d1 ;
% 4 & 5 digit magnanimous numbers %
for d12 := 10 until 99 do begin
for d34 := 0 until 99 do begin
if isPrime( d12 + d34 ) then begin
integer d123, d4;
d123 := ( d12 * 10 ) + ( d34 div 10 );
d4 := d34 rem 10;
if isPrime( d123 + d4 ) then begin
integer d1, d234;
d1 := d12 div 10;
d234 := ( ( d12 rem 10 ) * 100 ) + d34;
if isPrime( d1 + d234 ) then magnanimous( ( d12 * 100 ) + d34 ) := true
end if_isPrime_d123_plus_d4
end if_isPrime_d12_plus_d34
end for_d34 ;
for d345 := 0 until 999 do begin
if isPrime( d12 + d345 ) then begin
integer d123, d45;
d123 := ( d12 * 10 ) + ( d345 div 100 );
d45 := d345 rem 100;
if isPrime( d123 + d45 ) then begin
integer d1234, d5;
d1234 := ( d123 * 10 ) + ( d45 div 10 );
d5 := d45 rem 10;
if isPrime( d1234 + d5 ) then begin
integer d1, d2345;
d1 := d12 div 10;
d2345 := ( ( d12 rem 10 ) * 1000 ) + d345;
if isPrime( d1 + d2345 ) then magnanimous( ( d12 * 1000 ) + d345 ) := true
end if_isPrime_d1234_plus_d5
end if_isPrime_d123_plus_d45
end if_isPrime_d12_plus_d345
end for_d234
end for_d12 ;
% find 6 digit magnanimous numbers %
for d123 := 100 until 999 do begin
for d456 := 0 until 999 do begin
if isPrime( d123 + d456 ) then begin
integer d1234, d56;
d1234 := ( d123 * 10 ) + ( d456 div 100 );
d56 := d456 rem 100;
if isPrime( d1234 + d56 ) then begin
integer d12345, d6;
d12345 := ( d1234 * 10 ) + ( d56 div 10 );
d6 := d56 rem 10;
if isPrime( d12345 + d6 ) then begin
integer d12, d3456;
d12 := d123 div 10;
d3456 := ( ( d123 rem 10 ) * 1000 ) + d456;
if isPrime( d12 + d3456 ) then begin
integer d1, d23456;
d1 := d12 div 10;
d23456 := ( ( d12 rem 10 ) * 10000 ) + d3456;
if isPrime( d1 + d23456 ) then magnanimous( ( d123 * 1000 ) + d456 ) := true
end if_isPrime_d12_plus_d3456
end if_isPrime_d12345_plus_d6
end if_isPrime_d1234_plus_d56
end if_isPrime_d123_plus_d456
end for_d456
end for_d123
end findMagnanimous ;
% we look for magnanimous numbers with up to 6 digits, so we need to %
% check for primes up to 99999 + 9 = 100008 %
integer PRIME_MAX, MAGNANIMOUS_MAX;
PRIME_MAX := 100008;
MAGNANIMOUS_MAX := 1000000;
begin
logical array magnanimous ( 0 :: MAGNANIMOUS_MAX );
logical array isPrime ( 1 :: PRIME_MAX );
integer mPos;
integer lastM;
sieve( isPrime, PRIME_MAX );
findMagnanimous( magnanimous, isPrime );
% show some of the magnanimous numbers %
lastM := mPos := 0;
i_w := 3; s_w := 1; % output formatting %
for i := 0 until MAGNANIMOUS_MAX do begin
if magnanimous( i ) then begin
mPos := mPos + 1;
lastM := i;
if mPos = 1 then begin
write( "Magnanimous numbers 1-45:" );
write( i )
end
else if mPos < 46 then begin
if mPos rem 15 = 1 then write( i )
else writeon( i )
end
else if mPos = 241 then begin
write( "Magnanimous numbers 241-250:" );
write( i )
end
else if mPos > 241 and mPos <= 250 then writeon( i )
else if mPos = 391 then begin
write( "Magnanimous numbers 391-400:" );
write( i )
end
else if mPos > 391 and mPos <= 400 then writeon( i )
end if_magnanimous_i
end for_i ;
i_w := 1; s_w := 0;
write( "Last magnanimous number found: ", mPos, " = ", lastM )
end
end.</syntaxhighlight>
{{out}}
<pre>
Magnanimous numbers 1-45:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
Magnanimous numbers 241-250:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
Magnanimous numbers 391-400:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Last magnanimous number found: 434 = 999994
</pre>
=={{header|Amazing Hopper}}==
<syntaxhighlight lang="c">
#include <basico.h>
#proto encontrarunMagnanimouspara(_X_)
#synon _encontrarunMagnanimouspara siencontréunMagnanimousen
algoritmo
decimales '0'
res={}, i=0
iterar grupo( ++i, #(length(res)<400), \
i, meter según ( si encontré un Magnanimous en 'i', res ))
#(utf8("Primeros 45 números magnánimos:\n")), #(res[1:45])
#(utf8("\n\nNúmeros magnánimos 241 - 250:\n")), #(res[241:250])
#(utf8("\n\nNúmeros magnánimos 391 - 400:\n")), #(res[391:400]), NL
luego imprime esto
terminar
subrutinas
encontrar un Magnanimous para(n)
tn=n, d=0, i=0, pd=0
iterar
último dígito de 'tn', mover a 'd,tn'
cuando ' tn ' { #( pd += ( d * 10^i ) ) }
mientras ' #( tn && is prime(tn+pd) ); ++i '
retornar ' #(not(tn)) '
</syntaxhighlight>
{{out}}
<pre>
Primeros 45 números magnánimos:
0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110
Números magnánimos 241 - 250:
17992,19972,20209,20261,20861,22061,22201,22801,22885,24407
Números magnánimos 391 - 400:
486685,488489,515116,533176,551558,559952,595592,595598,600881,602081
</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f MAGNANIMOUS_NUMBERS.AWK
# converted from C
BEGIN {
magnanimous(1,45)
magnanimous(241,250)
magnanimous(391,400)
exit(0)
}
function is_magnanimous(n, p,q,r) {
if (n < 10) { return(1) }
for (p=10; ; p*=10) {
q = int(n/p)
r = n % p
if (!is_prime(q+r)) { return(0) }
if (q < 10) { break }
}
return(1)
}
function is_prime(n, d) {
d = 5
if (n < 2) { return(0) }
if (!(n % 2)) { return(n == 2) }
if (!(n % 3)) { return(n == 3) }
while (d*d <= n) {
if (!(n % d)) { return(0) }
d += 2
if (!(n % d)) { return(0) }
d += 4
}
return(1)
}
function magnanimous(start,stop, count,i) {
printf("%d-%d:",start,stop)
for (i=0; count<stop; ++i) {
if (is_magnanimous(i)) {
if (++count >= start) {
printf(" %d",i)
}
}
}
printf("\n")
}
</syntaxhighlight>
{{out}}
<pre>
1-45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241-250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391-400: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|BASIC}}==
<syntaxhighlight lang="gwbasic">10 DEFINT A-Z
20 L = N : R = 0 : S = 1
30 IF L < 10 GOTO 140
40 R = R + (L MOD 10) * S
50 L = L \ 10
60 S = S * 10
70 P = R + L
80 IF P = 1 GOTO 120 ELSE FOR D = 2 TO SQR(P)
90 IF P MOD D = 0 GOTO 120
100 NEXT D
110 GOTO 30
120 N = N + 1
130 GOTO 20
140 I = I + 1
150 IF I = 1 THEN PRINT "1 - 45:" ELSE IF I = 241 THEN PRINT "241 - 250:"
160 IF I <= 45 OR I > 240 THEN PRINT N,
170 N = N + 1
180 IF I < 250 GOTO 20
190 END</syntaxhighlight>
{{out}}
<pre>1 - 45:
0 1 2 3 4
5 6 7 8 9
11 12 14 16 20
21 23 25 29 30
32 34 38 41 43
47 49 50 52 56
58 61 65 67 70
74 76 83 85 89
92 94 98 101 110
241 - 250:
17992 19972 20209 20261 20861
22061 22201 22801 22885 24407</pre>
=={{header|BASIC256}}==
<syntaxhighlight lang="vb">#include "isprime.kbs"
dim magn(400)
n = 10
for i = 0 to 9
magn[i] = i #all single digit ints are magnanimous by definition
next i
while i < 400
n += 1
ns = string(n)
for j = 1 to length(ns)-1
lefty = left(ns, j)
righty = right(ns, length(ns)-j)
if not isPrime(int(lefty) + int(righty)) then continue while
next j
magn[i] = n
i += 1
end while
for i = 0 to 44
print i+1, magn[i]
next i
for i =240 to 249
print i+1, magn[i]
next i
for i = 390 to 399
print i+1, magn[i]
next i
end</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<syntaxhighlight lang="bbcbasic"> DIM Sieve% 1E5
Prime%=2
WHILE Prime%^2 < 1E5
FOR S%=Prime%*2 TO 1E5 STEP Prime% Sieve%?S%=1 NEXT
REPEAT Prime%+=1 UNTIL Sieve%?Prime%=0
ENDWHILE
Sieve%?1=1
PRINT "First 45 magnanimous numbers"
REPEAT
IF M% > 9 THEN
FOR I%=LOGM% TO 1 STEP -1
IF Sieve%?((M% DIV 10^I%) + (M% MOD 10^I%)) EXIT FOR
NEXT
ENDIF
IF I% == 0 THEN
N%+=1
IF N% == 240 OR N% == 390 PRINT '"Magnanimous numbers ";N% + 1 "-";N% + 10
IF N% < 46 OR (N% > 240 AND N% < 251) OR (N% > 390 AND N% < 401) PRINT;M% " ";
ENDIF
M%+=1
UNTIL N% > 400</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
Magnanimous numbers 241-250
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
Magnanimous numbers 391-400
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081</pre>
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
let prime(n) = valof
$( let d = 5
if n<2 resultis false
if n rem 2=0 resultis n=2
if n rem 3=0 resultis n=3
while d*d <= n
$( if n rem d=0 resultis false
d := d+2
if n rem d=0 resultis false
d := d+4
$)
resultis true
$)
let magnanimous(n) = valof
$( let left = n and right = 0 and shift = 1
while left >= 10
$( right := right + (left rem 10) * shift
shift := shift * 10
left := left / 10
unless prime(left + right) resultis false
$)
resultis true
$)
let start() be
$( let n = -1
for i = 1 to 250
$( n := n+1 repeatuntil magnanimous(n)
if i=1 then writes("1 - 45:*N")
if i=241 then writes("241 - 250:*N")
if 0<i<=45 | 240<i<=250
$( writed(n, 7)
if i rem 5=0 then wrch('*N')
$)
$)
$)</syntaxhighlight>
{{out}}
<pre>1 - 45:
0 1 2 3 4
5 6 7 8 9
11 12 14 16 20
21 23 25 29 30
32 34 38 41 43
47 49 50 52 56
58 61 65 67 70
74 76 83 85 89
92 94 98 101 110
241 - 250:
17992 19972 20209 20261 20861
22061 22201 22801 22885 24407</pre>
=={{header|C}}==
{{trans|Go}}
<syntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
typedef int bool;
typedef unsigned long long ull;
#define TRUE 1
#define FALSE 0
/* OK for 'small' numbers. */
bool is_prime(ull n) {
ull d;
if (n < 2) return FALSE;
if (!(n % 2)) return n == 2;
if (!(n % 3)) return n == 3;
d = 5;
while (d * d <= n) {
if (!(n % d)) return FALSE;
d += 2;
if (!(n % d)) return FALSE;
d += 4;
}
return TRUE;
}
void ord(char *res, int n) {
char suffix[3];
int m = n % 100;
if (m >= 4 && m <= 20) {
sprintf(res,"%dth", n);
return;
}
switch(m % 10) {
case 1:
strcpy(suffix, "st");
break;
case 2:
strcpy(suffix, "nd");
break;
case 3:
strcpy(suffix, "rd");
break;
default:
strcpy(suffix, "th");
break;
}
sprintf(res, "%d%s", n, suffix);
}
bool is_magnanimous(ull n) {
ull p, q, r;
if (n < 10) return TRUE;
for (p = 10; ; p *= 10) {
q = n / p;
r = n % p;
if (!is_prime(q + r)) return FALSE;
if (q < 10) break;
}
return TRUE;
}
void list_mags(int from, int thru, int digs, int per_line) {
ull i = 0;
int c = 0;
char res1[13], res2[13];
if (from < 2) {
printf("\nFirst %d magnanimous numbers:\n", thru);
} else {
ord(res1, from);
ord(res2, thru);
printf("\n%s through %s magnanimous numbers:\n", res1, res2);
}
for ( ; c < thru; ++i) {
if (is_magnanimous(i)) {
if (++c >= from) {
printf("%*llu ", digs, i);
if (!(c % per_line)) printf("\n");
}
}
}
}
int main() {
list_mags(1, 45, 3, 15);
list_mags(241, 250, 1, 10);
list_mags(391, 400, 1, 10);
return 0;
}</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|C#|CSharp}}==
<syntaxhighlight lang="csharp">using System; using static System.Console;
class Program {
static bool[] np; // not-prime array
static void ms(long lmt) { // populates array, a not-prime is true
np = new bool[lmt]; np[0] = np[1] = true;
for (long n = 2, j = 1; n < lmt; n += j, j = 2) if (!np[n])
for (long k = n * n; k < lmt; k += n) np[k] = true; }
static bool is_Mag(long n) { long res, rem;
for (long p = 10; n >= p; p *= 10) {
res = Math.DivRem (n, p, out rem);
if (np[res + rem]) return false; } return true; }
static void Main(string[] args) { ms(100_009); string mn;
WriteLine("First 45{0}", mn = " magnanimous numbers:");
for (long l = 0, c = 0; c < 400; l++) if (is_Mag(l)) {
if (c++ < 45 || (c > 240 && c <= 250) || c > 390)
Write(c <= 45 ? "{0,4} " : "{0,8:n0} ", l);
if (c < 45 && c % 15 == 0) WriteLine();
if (c == 240) WriteLine ("\n\n241st through 250th{0}", mn);
if (c == 390) WriteLine ("\n\n391st through 400th{0}", mn); } }
}</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17,992 19,972 20,209 20,261 20,861 22,061 22,201 22,801 22,885 24,407
391st through 400th magnanimous numbers:
486,685 488,489 515,116 533,176 551,558 559,952 595,592 595,598 600,881 602,081</pre>
=={{header|C++}}==
<syntaxhighlight lang="cpp">#include <iomanip>
#include <iostream>
bool is_prime(unsigned int n) {
if (n < 2)
return false;
if (n % 2 == 0)
return n == 2;
if (n % 3 == 0)
return n == 3;
for (unsigned int p = 5; p * p <= n; p += 4) {
if (n % p == 0)
return false;
p += 2;
if (n % p == 0)
return false;
}
return true;
}
bool is_magnanimous(unsigned int n) {
for (unsigned int p = 10; n >= p; p *= 10) {
if (!is_prime(n % p + n / p))
return false;
}
return true;
}
int main() {
unsigned int count = 0, n = 0;
std::cout << "First 45 magnanimous numbers:\n";
for (; count < 45; ++n) {
if (is_magnanimous(n)) {
if (count > 0)
std::cout << (count % 15 == 0 ? "\n" : ", ");
std::cout << std::setw(3) << n;
++count;
}
}
std::cout << "\n\n241st through 250th magnanimous numbers:\n";
for (unsigned int i = 0; count < 250; ++n) {
if (is_magnanimous(n)) {
if (count++ >= 240) {
if (i++ > 0)
std::cout << ", ";
std::cout << n;
}
}
}
std::cout << "\n\n391st through 400th magnanimous numbers:\n";
for (unsigned int i = 0; count < 400; ++n) {
if (is_magnanimous(n)) {
if (count++ >= 390) {
if (i++ > 0)
std::cout << ", ";
std::cout << n;
}
}
}
std::cout << '\n';
return 0;
}</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 16, 20
21, 23, 25, 29, 30, 32, 34, 38, 41, 43, 47, 49, 50, 52, 56
58, 61, 65, 67, 70, 74, 76, 83, 85, 89, 92, 94, 98, 101, 110
241st through 250th magnanimous numbers:
17992, 19972, 20209, 20261, 20861, 22061, 22201, 22801, 22885, 24407
391st through 400th magnanimous numbers:
486685, 488489, 515116, 533176, 551558, 559952, 595592, 595598, 600881, 602081
</pre>
=={{header|CLU}}==
<syntaxhighlight lang="clu">prime = proc (n: int) returns (bool)
if n < 2 then return(false) end
if n//2 = 0 then return(n=2) end
if n//3 = 0 then return(n=3) end
d: int := 5
while d*d <= n do
if n//d = 0 then return(false) end
d := d+2
if n//d = 0 then return(false) end
d := d+4
end
return(true)
end prime
sum_parts = iter (l: int) yields (int)
r: int := 0
s: int := 0
while l >= 10 do
r := r + (l // 10) * 10 ** s
s := s + 1
l := l / 10
yield(l + r)
end
end sum_parts
magnanimous = proc (n: int) returns (bool)
for s: int in sum_parts(n) do
if ~prime(s) then return(false) end
end
return(true)
end magnanimous
start_up = proc ()
po: stream := stream$primary_output()
n: int := 0
i: int := 0
c: int := 0
while i <= 400 do
while ~magnanimous(n) do n := n+1 end
i := i+1
if i=1 then stream$putl(po, "1-45:") c := 0
elseif i=241 then stream$putl(po, "\n241-250:") c := 0
elseif i=391 then stream$putl(po, "391-400:") c := 0
end
if i <= 45 cor (i > 240 cand i <= 250) cor (i > 390 cand i <= 400) then
stream$putright(po, int$unparse(n), 7)
c := c+1
if c = 10 then stream$putl(po, "") c := 0 end
end
n := n+1
end
end start_up</syntaxhighlight>
{{out}}
<pre>1-45:
0 1 2 3 4 5 6 7 8 9
11 12 14 16 20 21 23 25 29 30
32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89
92 94 98 101 110
241-250:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391-400:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081</pre>
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
sub prime(n: uint32): (r: uint32) is
r := 0;
if n <= 4 or n & 1 == 0 or n % 3 == 0 then
if n == 2 or n == 3 then
r := 1;
end if;
return;
end if;
var d: uint32 := 5;
while d*d <= n loop
if n % d == 0 then return; end if;
d := d+2;
if n % d == 0 then return; end if;
d := d+4;
end loop;
r := 1;
end sub;
sub magnanimous(n: uint32): (r: uint32) is
r := 1;
var left: uint32 := n;
var right: uint32 := 0;
var shift: uint32 := 1;
while left >= 10 loop
right := right + (left % 10) * shift;
shift := shift * 10;
left := left / 10;
if prime(left + right) == 0 then
r := 0;
break;
end if;
end loop;
end sub;
var i: uint16 := 0;
var n: uint32 := 0;
while i <= 400 loop
while magnanimous(n) == 0 loop n := n+1; end loop;
i := i + 1;
if i == 1 then print("1 - 45:\n");
elseif i == 241 then print("241 - 250:\n");
elseif i == 391 then print("390 - 400:\n");
end if;
if i<=45 or (i>240 and i<=250) or (i>390 and i<=400) then
print_i32(n);
if i % 5 == 0 then print_nl();
else print_char('\t');
end if;
end if;
n := n + 1;
end loop;</syntaxhighlight>
{{out}}
<pre>1 - 45:
0 1 2 3 4
5 6 7 8 9
11 12 14 16 20
21 23 25 29 30
32 34 38 41 43
47 49 50 52 56
58 61 65 67 70
74 76 83 85 89
92 94 98 101 110
241 - 250:
17992 19972 20209 20261 20861
22061 22201 22801 22885 24407
390 - 400:
486685 488489 515116 533176 551558
559952 595592 595598 600881 602081</pre>
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
Highly modular code breaks the problem down into its basic components, which makes the problem easier to solve conceptually, easier to debug and enhance.
<syntaxhighlight lang="Delphi">
function IsPrime(N: int64): boolean;
{Fast, optimised prime test}
var I,Stop: int64;
begin
if (N = 2) or (N=3) then Result:=true
else if (n <= 1) or ((n mod 2) = 0) or ((n mod 3) = 0) then Result:= false
else
begin
I:=5;
Stop:=Trunc(sqrt(N+0.0));
Result:=False;
while I<=Stop do
begin
if ((N mod I) = 0) or ((N mod (I + 2)) = 0) then exit;
Inc(I,6);
end;
Result:=True;
end;
end;
function IsMagnanimous(N: Integer): boolean;
var S,S1,S2: string;
var I,I1,I2: integer;
begin
Result:=True;
if N<10 then exit;
Result:=False;
S:=IntToStr(N);
for I:=2 to Length(S) do
begin
S1:=Copy(S,1,I-1);
S2:=Copy(S,I,(Length(S)-I)+1);
I1:=StrToInt(S1);
I2:=StrToInt(S2);
if not IsPrime(I1+I2) then exit;
end;
Result:=True;
end;
procedure MagnanimousRange(Memo: TMemo; Start,Stop: integer);
var I,MagCnt,ItemCnt: integer;
var S: string;
begin
S:='';
MagCnt:=0;
ItemCnt:=0;
for I:=0 to High(Integer) do
if IsMagnanimous(I) then
begin
Inc(MagCnt);
if MagCnt>=Start then
begin
if MagCnt>Stop then break;
S:=S+Format('%12d',[I]);
Inc(ItemCnt);
if (ItemCnt mod 5)=0 then S:=S+#$0D#$0A;
end;
end;
Memo.Lines.Add(S);
end;
procedure MagnanimousNumbers(Memo: TMemo);
begin
Memo.Lines.Add('First 45 Magnanimous Numbers');
MagnanimousRange(Memo,0,45);
Memo.Lines.Add('Magnanimous Numbers 241 through 250');
MagnanimousRange(Memo,241,250);
Memo.Lines.Add('Magnanimous Numbers 391 through 400');
MagnanimousRange(Memo,391,400);
end;
</syntaxhighlight>
{{out}}
<pre>
First 45 Magnanimous Numbers
0 1 2 3 4
5 6 7 8 9
11 12 14 16 20
21 23 25 29 30
32 34 38 41 43
47 49 50 52 56
58 61 65 67 70
74 76 83 85 89
92 94 98 101 110
Magnanimous Numbers 241 through 250
17992 19972 20209 20261 20861
22061 22201 22801 22885 24407
Magnanimous Numbers 391 through 400
486685 488489 515116 533176 551558
559952 595592 595598 600881 602081
</pre>
=={{header|Draco}}==
<syntaxhighlight lang="draco">proc isprime(word n) bool:
word d;
bool prime;
if n<2 then false
elif n%2=0 then n=2
elif n%3=0 then n=3
else
prime := true;
d := 5;
while prime and d*d <= n do
if n%d=0 then prime := false fi;
d := d+2;
if n%d=0 then prime := false fi;
d := d+4
od;
prime
fi
corp
proc magnanimous(word n) bool:
word left, right, shift;
bool magn;
left := n;
right := 0;
shift := 1;
magn := true;
while magn and left >= 10 do
right := right + (left % 10) * shift;
shift := shift * 10;
left := left / 10;
magn := magn and isprime(left + right)
od;
magn
corp
proc main() void:
word n, i;
n := 0;
for i from 1 upto 250 do
while not magnanimous(n) do n := n+1 od;
if i=1 then writeln("1 - 45:") fi;
if i=241 then writeln("241 - 250:") fi;
if i<=45 or i>=241 then
write(n:7);
if i%5 = 0 then writeln() fi
fi;
n := n+1
od
corp</syntaxhighlight>
{{out}}
<pre>1 - 45:
0 1 2 3 4
5 6 7 8 9
11 12 14 16 20
21 23 25 29 30
32 34 38 41 43
47 49 50 52 56
58 61 65 67 70
74 76 83 85 89
92 94 98 101 110
241 - 250:
17992 19972 20209 20261 20861
22061 22201 22801 22885 24407</pre>
=={{header|EasyLang}}==
{{trans|AWK}}
<syntaxhighlight>
fastfunc isprim num .
if num < 2
return 0
.
i = 2
while i <= sqrt num
if num mod i = 0
return 0
.
i += 1
.
return 1
.
func ismagnan n .
if n < 10
return 1
.
p = 10
repeat
q = n div p
r = n mod p
if isprim (q + r) = 0
return 0
.
until q < 10
p *= 10
.
return 1
.
proc magnan start stop . .
write start & "-" & stop & ":"
while count < stop
if ismagnan i = 1
count += 1
if count >= start
write " " & i
.
.
i += 1
.
print ""
.
magnan 1 45
magnan 241 250
magnan 391 400
</syntaxhighlight>
=={{header|F_Sharp|F#}}==
===The function===
This task uses [http://www.rosettacode.org/wiki/Extensible_prime_generator#The_function Extensible Prime Generator (F#)]
<syntaxhighlight lang="fsharp">
// Generate Magnanimous numbers. Nigel Galloway: March 20th., 2020
let rec fN n g = match (g/n,g%n) with
(0,_) -> true
|(α,β) when isPrime (α+β) -> fN (n*10) g
|_ -> false
let Magnanimous = let Magnanimous = fN 10 in seq{yield! {0..9}; yield! Seq.initInfinite id |> Seq.skip 10 |> Seq.filter Magnanimous}
</syntaxhighlight>
===The Tasks===
;First 45
<syntaxhighlight lang="fsharp">
Magnanimous |> Seq.take 45 |> Seq.iter (printf "%d "); printfn ""
</syntaxhighlight>
{{out}}
<pre>
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
</pre>
;Magnanimous[241] to Magnanimous[250]
<syntaxhighlight lang="fsharp">
Magnanimous |> Seq.skip 240 |> Seq.take 10 |> Seq.iter (printf "%d "); printfn "";;
</syntaxhighlight>
{{out}}
<pre>
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
</pre>
;Magnanimous[391] to Magnanimous[400]
<syntaxhighlight lang="fsharp">
Magnanimous |> Seq.skip 390 |> Seq.take 10 |> Seq.iter (printf "%d "); printfn "";;
</syntaxhighlight>
{{out}}
<pre>
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|Factor}}==
{{trans|Julia}}
{{works with|Factor|0.99 2020-01-23}}
<syntaxhighlight lang="factor">USING: grouping io kernel lists lists.lazy math math.functions
math.primes math.ranges prettyprint sequences ;
: magnanimous? ( n -- ? )
dup 10 < [ drop t ] [
dup log10 >integer [1,b] [ 10^ /mod + prime? not ] with
find nip >boolean not
] if ;
: magnanimous ( n -- seq )
0 lfrom [ magnanimous? ] lfilter ltake list>array ;
: show ( seq from to -- ) rot subseq 15 group simple-table. nl ;
400 magnanimous
[ "First 45 magnanimous numbers" print 0 45 show ]
[ "241st through 250th magnanimous numbers" print 240 250 show ]
[ "391st through 400th magnanimous numbers" print 390 400 show ]
tri</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">
#include "isprime.bas"
dim as uinteger magn(0 to 399), i, n=10, j
dim as string ns, lefty, righty
for i = 0 to 9
magn(i) = i 'all single digit ints are magnanimous by definition
next i
while i<400
n += 1
ns = str(n)
for j = 1 to len(ns)-1
lefty = left(ns, j)
righty = right(ns, len(ns)-j)
if not isprime( val(lefty) + val(righty) ) then continue while
next j
magn(i) = n
i+=1
wend
for i=0 to 44
print i+1,magn(i)
next i
for i=240 to 249
print i+1,magn(i)
next i
for i=390 to 399
print i+1,magn(i)
next i
</syntaxhighlight>
{{out}}
<pre>1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 9
11 11
12 12
13 14
14 16
15 20
16 21
17 23
18 25
19 29
20 30
21 32
22 34
23 38
24 41
25 43
26 47
27 49
28 50
29 52
30 56
31 58
32 61
33 65
34 67
35 70
36 74
37 76
38 83
39 85
40 89
41 92
42 94
43 98
44 101
45 110
241 17992
242 19972
243 20209
244 20261
245 20861
246 22061
247 22201
248 22801
249 22885
250 24407
391 486685
392 488489
393 515116
394 533176
395 551558
396 559952
397 595592
398 595598
399 600881
400 602081</pre>
=={{header|Go}}==
<syntaxhighlight lang="go">package main
import "fmt"
// OK for 'small' numbers.
func isPrime(n uint64) bool {
switch {
case n < 2:
return false
case n%2 == 0:
return n == 2
case n%3 == 0:
return n == 3
default:
d := uint64(5)
for d*d <= n {
if n%d == 0 {
return false
}
d += 2
if n%d == 0 {
return false
}
d += 4
}
return true
}
}
func ord(n int) string {
m := n % 100
if m >= 4 && m <= 20 {
return fmt.Sprintf("%dth", n)
}
m %= 10
suffix := "th"
if m < 4 {
switch m {
case 1:
suffix = "st"
case 2:
suffix = "nd"
case 3:
suffix = "rd"
}
}
return fmt.Sprintf("%d%s", n, suffix)
}
func isMagnanimous(n uint64) bool {
if n < 10 {
return true
}
for p := uint64(10); ; p *= 10 {
q := n / p
r := n % p
if !isPrime(q + r) {
return false
}
if q < 10 {
break
}
}
return true
}
func listMags(from, thru, digs, perLine int) {
if from < 2 {
fmt.Println("\nFirst", thru, "magnanimous numbers:")
} else {
fmt.Printf("\n%s through %s magnanimous numbers:\n", ord(from), ord(thru))
}
for i, c := uint64(0), 0; c < thru; i++ {
if isMagnanimous(i) {
c++
if c >= from {
fmt.Printf("%*d ", digs, i)
if c%perLine == 0 {
fmt.Println()
}
}
}
}
}
func main() {
listMags(1, 45, 3, 15)
listMags(241, 250, 1, 10)
listMags(391, 400, 1, 10)
}</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|GW-BASIC}}==
{{works with|PC-BASIC|any}}
{{works with|BASICA}}
<syntaxhighlight lang="qbasic">100 DEFINT A-Z
110 CLS
120 LET L = N
130 LET R = 0
140 LET S = 1
150 IF L < 10 THEN GOTO 300
160 LET R = R+(L MOD 10)*S
170 LET L = L\10
180 LET S = S*10
190 LET P = R+L
200 IF P = 1 THEN GOTO 280 ELSE FOR D = 2 TO SQR(P)
210 IF P MOD D = 0 THEN GOTO 280
250 NEXT D
270 GOTO 150
280 LET N = N+1
290 GOTO 120
300 LET I = I+1
310 IF I = 1 THEN PRINT "1 - 45:" ELSE IF I = 241 THEN PRINT : PRINT "241 - 250:"
320 IF I <= 45 OR I > 240 THEN PRINT N,
330 LET N = N+1
340 IF I < 250 THEN GOTO 120
350 PRINT
360 END</syntaxhighlight>
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.List.Split ( chunksOf )
import Data.List ( (!!) )
isPrime :: Int -> Bool
isPrime n
|n == 2 = True
|n == 1 = False
|otherwise = null $ filter (\i -> mod n i == 0 ) [2 .. root]
where
root :: Int
root = floor $ sqrt $ fromIntegral n
isMagnanimous :: Int -> Bool
isMagnanimous n = all isPrime $ map (\p -> fst p + snd p ) numberPairs
where
str:: String
str = show n
splitStrings :: [(String , String)]
splitStrings = map (\i -> splitAt i str) [1 .. length str - 1]
numberPairs :: [(Int , Int)]
numberPairs = map (\p -> ( read $ fst p , read $ snd p )) splitStrings
printInWidth :: Int -> Int -> String
printInWidth number width = replicate ( width - l ) ' ' ++ str
where
str :: String
str = show number
l :: Int
l = length str
solution :: [Int]
solution = take 400 $ filter isMagnanimous [0 , 1 ..]
main :: IO ( )
main = do
let numbers = solution
numberlines = chunksOf 10 $ take 45 numbers
putStrLn "First 45 magnanimous numbers:"
mapM_ (\li -> putStrLn (foldl1 ( ++ ) $ map (\n -> printInWidth n 6 )
li )) numberlines
putStrLn "241'st to 250th magnanimous numbers:"
putStr $ show ( numbers !! 240 )
putStrLn ( foldl1 ( ++ ) $ map(\n -> printInWidth n 8 ) $ take 9 $
drop 241 numbers )
putStrLn "391'st to 400th magnanimous numbers:"
putStr $ show ( numbers !! 390 )
putStrLn ( foldl1 ( ++ ) $ map(\n -> printInWidth n 8 ) $ drop 391 numbers)</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9
11 12 14 16 20 21 23 25 29 30
32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89
92 94 98 101 110
241'st to 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391'st to 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.ArrayList;
import java.util.List;
public class MagnanimousNumbers {
public static void main(String[] args) {
runTask("Find and display the first 45 magnanimous numbers.", 1, 45);
runTask("241st through 250th magnanimous numbers.", 241, 250);
runTask("391st through 400th magnanimous numbers.", 391, 400);
}
private static void runTask(String message, int startN, int endN) {
int count = 0;
List<Integer> nums = new ArrayList<>();
for ( int n = 0 ; count < endN ; n++ ) {
if ( isMagnanimous(n) ) {
nums.add(n);
count++;
}
}
System.out.printf("%s%n", message);
System.out.printf("%s%n%n", nums.subList(startN-1, endN));
}
private static boolean isMagnanimous(long n) {
if ( n >= 0 && n <= 9 ) {
return true;
}
long q = 11;
for ( long div = 10 ; q >= 10 ; div *= 10 ) {
q = n / div;
long r = n % div;
if ( ! isPrime(q+r) ) {
return false;
}
}
return true;
}
private static final int MAX = 100_000;
private static final boolean[] primes = new boolean[MAX];
private static boolean SIEVE_COMPLETE = false;
private static final boolean isPrimeTrivial(long test) {
if ( ! SIEVE_COMPLETE ) {
sieve();
SIEVE_COMPLETE = true;
}
return primes[(int) test];
}
private static final void sieve() {
// primes
for ( int i = 2 ; i < MAX ; i++ ) {
primes[i] = true;
}
for ( int i = 2 ; i < MAX ; i++ ) {
if ( primes[i] ) {
for ( int j = 2*i ; j < MAX ; j += i ) {
primes[j] = false;
}
}
}
}
// See http://primes.utm.edu/glossary/page.php?sort=StrongPRP
public static final boolean isPrime(long testValue) {
if ( testValue == 2 ) return true;
if ( testValue % 2 == 0 ) return false;
if ( testValue <= MAX ) return isPrimeTrivial(testValue);
long d = testValue-1;
int s = 0;
while ( d % 2 == 0 ) {
s += 1;
d /= 2;
}
if ( testValue < 1373565L ) {
if ( ! aSrp(2, s, d, testValue) ) {
return false;
}
if ( ! aSrp(3, s, d, testValue) ) {
return false;
}
return true;
}
if ( testValue < 4759123141L ) {
if ( ! aSrp(2, s, d, testValue) ) {
return false;
}
if ( ! aSrp(7, s, d, testValue) ) {
return false;
}
if ( ! aSrp(61, s, d, testValue) ) {
return false;
}
return true;
}
if ( testValue < 10000000000000000L ) {
if ( ! aSrp(3, s, d, testValue) ) {
return false;
}
if ( ! aSrp(24251, s, d, testValue) ) {
return false;
}
return true;
}
// Try 5 "random" primes
if ( ! aSrp(37, s, d, testValue) ) {
return false;
}
if ( ! aSrp(47, s, d, testValue) ) {
return false;
}
if ( ! aSrp(61, s, d, testValue) ) {
return false;
}
if ( ! aSrp(73, s, d, testValue) ) {
return false;
}
if ( ! aSrp(83, s, d, testValue) ) {
return false;
}
//throw new RuntimeException("ERROR isPrime: Value too large = "+testValue);
return true;
}
private static final boolean aSrp(int a, int s, long d, long n) {
long modPow = modPow(a, d, n);
//System.out.println("a = "+a+", s = "+s+", d = "+d+", n = "+n+", modpow = "+modPow);
if ( modPow == 1 ) {
return true;
}
int twoExpR = 1;
for ( int r = 0 ; r < s ; r++ ) {
if ( modPow(modPow, twoExpR, n) == n-1 ) {
return true;
}
twoExpR *= 2;
}
return false;
}
private static final long SQRT = (long) Math.sqrt(Long.MAX_VALUE);
public static final long modPow(long base, long exponent, long modulus) {
long result = 1;
while ( exponent > 0 ) {
if ( exponent % 2 == 1 ) {
if ( result > SQRT || base > SQRT ) {
result = multiply(result, base, modulus);
}
else {
result = (result * base) % modulus;
}
}
exponent >>= 1;
if ( base > SQRT ) {
base = multiply(base, base, modulus);
}
else {
base = (base * base) % modulus;
}
}
return result;
}
// Result is a*b % mod, without overflow.
public static final long multiply(long a, long b, long modulus) {
long x = 0;
long y = a % modulus;
long t;
while ( b > 0 ) {
if ( b % 2 == 1 ) {
t = x + y;
x = (t > modulus ? t-modulus : t);
}
t = y << 1;
y = (t > modulus ? t-modulus : t);
b >>= 1;
}
return x % modulus;
}
}
</syntaxhighlight>
{{out}}
<pre>
Find and display the first 45 magnanimous numbers.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 16, 20, 21, 23, 25, 29, 30, 32, 34, 38, 41, 43, 47, 49, 50, 52, 56, 58, 61, 65, 67, 70, 74, 76, 83, 85, 89, 92, 94, 98, 101, 110]
241st through 250th magnanimous numbers.
[17992, 19972, 20209, 20261, 20861, 22061, 22201, 22801, 22885, 24407]
391st through 400th magnanimous numbers.
[486685, 488489, 515116, 533176, 551558, 559952, 595592, 595598, 600881, 602081]
</pre>
=={{header|J}}==
<pre>
write_sum_expressions=: ([: }: ]\) ,"1 '+' ,"1 ([: }. ]\.) NB. combine prefixes with suffixes
interstitial_sums=: ".@write_sum_expressions@":
primeQ=: 1&p:
magnanimousQ=: 1:`([: *./ [: primeQ interstitial_sums)@.(>&9)
A=: (#~ magnanimousQ&>) i.1000000 NB. filter 1000000 integers
#A
434
strange=: ({. + [: i. -~/)@:(_1 0&+) NB. produce index ranges for output
I=: _2 <@strange\ 1 45 241 250 391 400
I (":@:{~ >)~"0 _ A
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|jq}}==
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
For a suitable definition of `is_prime`, see [[Erd%C5%91s-primes#jq]].
'''Preliminaries'''
<syntaxhighlight lang="jq"># To take advantage of gojq's arbitrary-precision integer arithmetic:
def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);
def divrem($x; $y):
[$x/$y|floor, $x % $y];
</syntaxhighlight>
'''The Task'''
<syntaxhighlight lang="jq">
def ismagnanimous:
. as $n
| if $n < 10 then true
else first(range( 1; tostring|length) as $i
| divrem($n; (10|power($i))) as [$q, $r]
| if ($q + $r) | is_prime == false then 0 else empty end)
// true
| . == true
end;
# An unbounded stream ...
def magnanimous:
range(0; infinite)
| select(ismagnanimous);
[limit(400; magnanimous)]
| "First 45 magnanimous numbers:", .[:45],
"\n241st through 250th magnanimous numbers:", .[241:251],
"\n391st through 400th magnanimous numbers:", .[391:]</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
[0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110]
241st through 250th magnanimous numbers:
[19972,20209,20261,20861,22061,22201,22801,22885,24407,26201]
391st through 400th magnanimous numbers:
[488489,515116,533176,551558,559952,595592,595598,600881,602081]
</pre>
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Primes
function ismagnanimous(n)
n < 10 && return true
for i in 1:ndigits(n)-1
q, r = divrem(n, 10^i)
!isprime(q + r) && return false
end
return true
end
function magnanimous(N)
mvec, i = Int[], 0
while length(mvec) < N
if ismagnanimous(i)
push!(mvec, i)
end
i += 1
end
return mvec
end
const mag400 = magnanimous(400)
println("First 45 magnanimous numbers:\n", mag400[1:24], "\n", mag400[25:45])
println("\n241st through 250th magnanimous numbers:\n", mag400[241:250])
println("\n391st through 400th magnanimous numbers:\n", mag400[391:400])
</syntaxhighlight>{{out}}
<pre>
First 45 magnanimous numbers:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 16, 20, 21, 23, 25, 29, 30, 32, 34, 38, 41]
[43, 47, 49, 50, 52, 56, 58, 61, 65, 67, 70, 74, 76, 83, 85, 89, 92, 94, 98, 101, 110]
241st through 250th magnanimous numbers:
[17992, 19972, 20209, 20261, 20861, 22061, 22201, 22801, 22885, 24407]
391st through 400th magnanimous numbers:
[486685, 488489, 515116, 533176, 551558, 559952, 595592, 595598, 600881, 602081]
</pre>
=={{header|Lambdatalk}}==
{{trans|Phix}}
<syntaxhighlight lang="scheme">
{def isprime
{def isprime.loop
{lambda {:n :m :i}
{if {> :i :m}
then true
else {if {= {% :n :i} 0}
then false
else {isprime.loop :n :m {+ :i 2}}
}}}}
{lambda {:n}
{if {= :n 1}
then false
else {if {or {= :n 2} {= :n 3} {= :n 5} {= :n 7}}
then true
else {if {or {< : n 2} {= {% :n 2} 0}}
then false
else {isprime.loop :n {sqrt :n} 3}
}}}}}
-> isprime
{def magnanimous
{def magnanimous.loop
{lambda {:n :p :r}
{if {>= :n 10}
then {let { {:n {floor {/ :n 10}}}
{:p :p}
{:r {+ :r {* {% :n 10} :p}}}
} {if {not {isprime {+ :n :r}}}
then false
else {magnanimous.loop :n {* :p 10} :r} }
}
else true }}}
{lambda {:n}
{magnanimous.loop :n 1 0} }}
-> magnanimous
{def mags
{lambda {:n}
{S.last
{S.map {{lambda {:a :i}
{if {magnanimous :i} then {A.addlast! :i :a} else}}
{A.new}}
{S.serie 0 :n}}}}}
-> mags
{A.slice 0 45 {mags 110}}
-> [0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110]
{A.slice 240 250 {mags 30000}}
->
[17992,19972,20209,20261,20861,22061,22201,22801,22885,24407]
{A.slice 390 400 {mags 700000}}
->
[486685,488489,515116,533176,551558,559952,595592,595598,600881,602081]
time of CPU in milliseconds
iPadPro MacBookAir MacBookPro
[0,45] 30 15 12
[240,250] 2430 5770 3650
[390,400] 117390 284230 213210
</syntaxhighlight>
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">Clear[MagnanimousNumberQ]
MagnanimousNumberQ[Alternatives @@ Range[0, 9]] = True;
MagnanimousNumberQ[n_Integer] := AllTrue[Range[IntegerLength[n] - 1], PrimeQ[Total[FromDigits /@ TakeDrop[IntegerDigits[n], #]]] &]
sel = Select[Range[0, 1000000], MagnanimousNumberQ];
sel[[;; 45]]
sel[[241 ;; 250]]
sel[[391 ;; 400]]</syntaxhighlight>
{{out}}
<pre>{0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110}
{17992,19972,20209,20261,20861,22061,22201,22801,22885,24407}
{486685,488489,515116,533176,551558,559952,595592,595598,600881,602081}</pre>
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE MagnanimousNumbers;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
VAR n, i: CARDINAL;
PROCEDURE prime(n: CARDINAL): BOOLEAN;
VAR d: CARDINAL;
BEGIN
IF n<2 THEN RETURN FALSE END;
IF n MOD 2 = 0 THEN RETURN n = 2 END;
IF n MOD 3 = 0 THEN RETURN n = 3 END;
d := 5;
WHILE d*d <= n DO
IF n MOD d = 0 THEN RETURN FALSE END;
INC(d, 2);
IF n MOD d = 0 THEN RETURN FALSE END;
INC(d, 4)
END;
RETURN TRUE
END prime;
PROCEDURE magnanimous(n: CARDINAL): BOOLEAN;
VAR left, right, shift: CARDINAL;
BEGIN
left := n;
right := 0;
shift := 1;
WHILE left >= 10 DO
INC(right, (left MOD 10) * shift);
shift := shift * 10;
left := left DIV 10;
IF NOT prime(left + right) THEN RETURN FALSE END
END;
RETURN TRUE
END magnanimous;
BEGIN
n := 0;
FOR i := 1 TO 250 DO
WHILE NOT magnanimous(n) DO INC(n) END;
IF i=1 THEN WriteString("1 - 45:"); WriteLn
ELSIF i=240 THEN WriteString("241 - 250:"); WriteLn
END;
IF (i <= 45) OR (i > 240) THEN
WriteCard(n, 7);
IF i MOD 5 = 0 THEN WriteLn END
END;
INC(n)
END
END MagnanimousNumbers.</syntaxhighlight>
{{out}}
<pre>1 - 45:
0 1 2 3 4
5 6 7 8 9
11 12 14 16 20
21 23 25 29 30
32 34 38 41 43
47 49 50 52 56
58 61 65 67 70
74 76 83 85 89
92 94 98 101 110
241 - 250:
17992 19972 20209 20261 20861
22061 22201 22801 22885 24407</pre>
=={{header|Nim}}==
<syntaxhighlight lang="nim">func isPrime(n: Natural): bool =
if n < 2: return
if n mod 2 == 0: return n == 2
if n mod 3 == 0: return n == 3
var d = 5
while d * d <= n:
if n mod d == 0: return false
inc d, 2
if n mod d == 0: return false
inc d, 4
return true
func isMagnanimous(n: Natural): bool =
var p = 10
while true:
let a = n div p
let b = n mod p
if a == 0: break
if not isPrime(a + b): return false
p *= 10
return true
iterator magnanimous(): (int, int) =
var n, count = 0
while true:
if n.isMagnanimous:
inc count
yield (count, n)
inc n
for (i, n) in magnanimous():
if i in 1..45:
if i == 1: stdout.write "First 45 magnanimous numbers:\n "
stdout.write n, if i == 45: '\n' else: ' '
elif i in 241..250:
if i == 241: stdout.write "\n241st through 250th magnanimous numbers:\n "
stdout.write n, if i == 250: "\n" else: " "
elif i in 391..400:
if i == 391: stdout.write "\n391st through 400th magnanimous numbers:\n "
stdout.write n, if i == 400: "\n" else: " "
elif i > 400:
break</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081</pre>
=={{header|Pascal}}==
{{works with|Free Pascal}}
Version nearly like on Talk.<br>
Eliminating all numbers, which would sum to 5 in the last digit.<br>
On TIO.RUN found all til 569 84448000009 0.715 s
<syntaxhighlight lang="pascal">program Magnanimous;
//Magnanimous Numbers
//algorithm find only numbers where all digits are even except the last
//or where all digits are odd except the last
//so 1,11,20,101,1001 will not be found
//starting at 100001 "1>"+x"0"+"1" is not prime because of 1001 not prime
{$IFDEF FPC}
{$MODE DELPHI}
{$Optimization ON}
{$CODEALIGN proc=16}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
{$DEFINE USE_GMP}
uses
//strUtils, // commatize Numb2USA
{$IFDEF USE_GMP}gmp,{$ENDIF}
SysUtils;
const
MaxLimit = 10*1000*1000 +10;
MAXHIGHIDX = 10;
type
tprimes = array of byte;
tBaseType = Byte;
tpBaseType = pByte;
tBase =array[0..15] of tBaseType;
tNumType = NativeUint;
tSplitNum = array[0..15] of tNumType;
tMagList = array[0..1023] of Uint64;
var
{$ALIGN 32}
MagList : tMagList;
dgtBase5, // count in Base 5
dgtORMask, //Mark of used digit (or (1 shl Digit ))
dgtEvenBase10,
dgtOddBase10: tbase;
primes : tprimes;
{$IFDEF USE_GMP} z : mpz_t;gmp_count :NativeUint;{$ENDIF}
pPrimes0 : pByte;
T0: int64;
HighIdx,num,MagIdx,count,cnt: NativeUint;
procedure InitPrimes;
const
smallprimes :array[0..5] of byte = (2,3,5,7,11,13);
var
pPrimes : pByte;
p,i,j,l : NativeUint;
begin
l := 1;
for j := 0 to High(smallprimes) do
l*= smallprimes[j];
//scale primelimit to be multiple of l
i :=((MaxLimit-1) DIV l+1)*l+1;//+1 should suffice
setlength(primes,i);
pPrimes := @primes[0];
for j := 0 to High(smallprimes) do
begin
p := smallprimes[j];
i := p;
if j <> 0 then
p +=p;
while i <= l do
begin
pPrimes[i] := 1;
inc(i,p)
end;
end;
//turn the prime wheel
for p := length(primes) div l -1 downto 1 do
move(pPrimes[1],pPrimes[p*l+1],l);
l := High(primes);
//reinsert smallprimes
for j := 0 to High(smallprimes) do
pPrimes[smallprimes[j]] := 0;
pPrimes[1]:=1;
pPrimes[0]:=1;
p := smallprimes[High(smallprimes)];
repeat
repeat
inc(p)
until pPrimes[p] = 0;
j := l div p;
while (pPrimes[j]<> 0) AND (j>=p) do
dec(j);
if j<p then
BREAK;
//delta going downwards no factor 2,3 :-2 -4 -2 -4
i := (j+1) mod 6;
if i = 0 then
i :=4;
repeat
while (pPrimes[j]<> 0) AND (j>=p) do
begin
dec(j,i);
i := 6-i;
end;
if j<p then
BREAK;
pPrimes[j*p] := 1;
dec(j,i);
i := 6-i;
until j<p;
until false;
pPrimes0 := pPrimes;
end;
procedure InsertSort(pMag:pUint64; Left, Right : NativeInt );
var
I, J: NativeInt;
Pivot : Uint64;
begin
for i:= 1 + Left to Right do
begin
Pivot:= pMag[i];
j:= i - 1;
while (j >= Left) and (pMag[j] > Pivot) do
begin
pMag[j+1]:=pMag[j];
Dec(j);
end;
pMag[j+1]:= pivot;
end;
end;
procedure OutBase5;
var
pb: tpBaseType;
i : NativeUint;
begin
write(count :10);
pb:= @dgtBase5[0];
for i := HighIdx downto 0 do
write(pb[i]:3);
write(' : ' );
pb:= @dgtORMask[0];
for i := HighIdx downto 0 do
write(pb[i]:3);
end;
function Base10toNum(var dgtBase10: tBase):NativeUint;
var
i : NativeInt;
begin
Result := 0;
for i := HighIdx downto 0 do
Result := Result * 10 + dgtBase10[i];
end;
procedure OutSol(cnt:Uint64);
begin
writeln(MagIdx:4,cnt:13,Base10toNum(dgtOddBase10):20,
(Gettickcount64-T0) / 1000: 10: 3, ' s');
end;
procedure CnvEvenBase10(lastIdx:NativeInt);
var
pdgt : tpBaseType;
idx: nativeint;
begin
pDgt := @dgtEvenBase10[0];
for idx := lastIdx downto 1 do
pDgt[idx] := 2 * dgtBase5[idx];
pDgt[0] := 2 * dgtBase5[0]+1;
end;
procedure CnvOddBase10(lastIdx:NativeInt);
var
pdgt : tpBaseType;
idx: nativeint;
begin
pDgt := @dgtOddBase10[0];
//make all odd
for idx := lastIdx downto 1 do
pDgt[idx] := 2 * dgtBase5[idx] + 1;
//but the lowest even
pDgt[0] := 2 * dgtBase5[0];
end;
function IncDgtBase5:NativeUint;
// increment n base 5 until resulting sum of split number
// can't end in 5
var
pb: tpBaseType;
n,i: nativeint;
begin
result := 0;
repeat
repeat
//increment Base5
pb:= @dgtBase5[0];
i := 0;
repeat
n := pb[i] + 1;
if n < 5 then
begin
pb[i] := n;
break;
end;
pb[i] := 0;
Inc(i);
until False;
if HighIdx < i then
begin
HighIdx := i;
pb[i] := 0;
end;
if result < i then
result := i;
n := dgtORMask[i+1];
while i >= 0 do
begin
n := n OR (1 shl pb[i]);
dgtORMask[i]:= n;
if n = 31 then
break;
dec(i);
end;
if HighIdx<4 then
break;
if (n <> 31) OR (i=0) then
break;
//Now there are all digits are used at digit i ( not in last pos)
//this will always lead to a number ending in 5-> not prime
//so going on with a number that will change the used below i to highest digit
//to create an overflow of the next number, to change the digits
dec(i);
repeat
pb[i] := 4;
dgtORMask[i]:= 31;
dec(i);
until i < 0;
until false;
if HighIdx<4 then
break;
n := dgtORMask[1];
//ending in 5. base10(base5) for odd 1+4(0,2),3+2(1,1),5+0(2,0)
i := pb[0];
if i <= 2 then
begin
i := 1 shl (2-i);
end
else
Begin
//ending in 5 7+8(3,4),9+6(4,3)
i := 1 shl (4-i);
n := n shr 3;
end;
if (i AND n) = 0 then
BREAK;
until false;
end;
procedure CheckMagn(var dgtBase10: tBase);
//split number into sum of all "partitions" of digits
//check if sum is always prime
//1234 -> 1+234,12+34 ;123+4
var
LowSplitNum : tSplitNum;
i,fac,n: NativeInt;
isMagn : boolean;
Begin
n := 0;
fac := 1;
For i := 0 to HighIdx-1 do
begin
n := fac*dgtBase10[i]+n;
fac *=10;
LowSplitNum[HighIdx-1-i] := n;
end;
n := 0;
fac := HighIdx;
isMagn := true;
For i := 0 to fac-1 do
begin
//n = HighSplitNum[i]
n := n*10+dgtBase10[fac-i];
LowSplitNum[i] += n;
if LowSplitNum[i]<=MAXLIMIT then
begin
isMagn := isMagn AND (pPrimes0[LowSplitNum[i]] = 0);
if NOT(isMagn) then
EXIT;
end;
end;
{$IFDEF USE_GMP}
For i := 0 to fac-1 do
begin
n := LowSplitNum[i];
if n >MAXLIMIT then
Begin
// IF NOT((n mod 30) in [1,7,11,13,17,19,23,29]) then EXIT;
mpz_set_ui(z,n);
gmp_count +=1;
isMagn := isMagn AND (mpz_probab_prime_p(z,1) >0);
if NOT(isMagn) then
EXIT;
end;
end;
{$ENDIF}
//insert magnanimous numbers
num := Base10toNum(dgtBase10);
MagList[MagIdx] := num;
inc(MagIdx);
end;
function Run(StartDgtCount:byte):Uint64;
var
lastIdx: NativeInt;
begin
result := 0;
HighIdx := StartDgtCount;// 7 start with 7 digits
LastIdx := HighIdx;
repeat
if dgtBase5[HighIdx] <> 0 then
Begin
CnvEvenBase10(LastIdx);
CheckMagn(dgtEvenBase10);
end;
CnvOddBase10(LastIdx);
CheckMagn(dgtOddBase10);
inc(result);
//output for still running every 16.22 Mio
IF result AND (1 shl 22-1) = 0 then
OutSol(result);
lastIdx := IncDgtBase5;
until HighIdx > MAXHIGHIDX;
end;
BEGIN
{$IFDEF USE_GMP}mpz_init_set_ui(z,0);{$ENDIF}
T0 := Gettickcount64;
InitPrimes;
T0 -= Gettickcount64;
writeln('getting primes ',-T0 / 1000: 0: 3, ' s');
T0 := Gettickcount64;
fillchar(dgtBase5,SizeOf(dgtBase5),#0);
fillchar(dgtEvenBase10,SizeOf(dgtEvenBase10),#0);
fillchar(dgtOddBase10,SizeOf(dgtOddBase10),#0);
//Magnanimous Numbers that can not be found by this algorithm
MagIdx := 0;
MagList[MagIdx] := 1;inc(MagIdx);
MagList[MagIdx] := 11;inc(MagIdx);
MagList[MagIdx] := 20;inc(MagIdx);
MagList[MagIdx] := 101;inc(MagIdx);
MagList[MagIdx] := 1001;inc(MagIdx);
//cant be checked easy for ending in 5
MagList[MagIdx] := 40001;inc(MagIdx);
{$IFDEF USE_GMP} mpz_init_set_ui(z,0);{$ENDIF}
count := Run(0);
writeln;
CnvOddBase10(highIdx);
writeln(MagIdx:5,count:12,Base10toNum(dgtOddBase10):18,
(Gettickcount64-T0) / 1000: 10: 3, ' s');
InsertSort(@MagList[0],0,MagIdx-1);
{$IFDEF USE_GMP} mpz_clear(z);writeln('Count of gmp tests ',gmp_count);{$ENDIF}
For cnt := 0 to MagIdx-1 do
writeln(cnt+1:3,' ',MagList[cnt]);
{$IFDEF WINDOWS}
readln;
{$ENDIF}
end.</syntaxhighlight>
{{out}}
<pre style="height:180px">
TIO.RUN
Real time: 0.924 s User time: 0.864 s Sys. time: 0.053 s CPU share: 99.29 %
getting primes 0.023 s
567 4194304 53771777176 0.400 s
569 6990860 111111111110 0.715 s
Count of gmp tests 45755
1 0
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 9
11 11
12 12
13 14
14 16
15 20
16 21
17 23
18 25
19 29
20 30
21 32
22 34
23 38
24 41
25 43
26 47
27 49
28 50
29 52
30 56
31 58
32 61
33 65
34 67
35 70
36 74
37 76
38 83
39 85
40 89
41 92
42 94
43 98
44 101
45 110
46 112
47 116
48 118
49 130
50 136
51 152
52 158
53 170
54 172
55 203
56 209
57 221
58 227
59 229
60 245
61 265
62 281
63 310
64 316
65 334
66 338
67 356
68 358
69 370
70 376
71 394
72 398
73 401
74 403
75 407
76 425
77 443
78 449
79 467
80 485
81 512
82 518
83 536
84 538
85 554
86 556
87 574
88 592
89 598
90 601
91 607
92 625
93 647
94 661
95 665
96 667
97 683
98 710
99 712
100 730
101 736
102 754
103 772
104 776
105 790
106 794
107 803
108 809
109 821
110 845
111 863
112 881
113 889
114 934
115 938
116 952
117 958
118 970
119 974
120 992
121 994
122 998
123 1001
124 1112
125 1130
126 1198
127 1310
128 1316
129 1598
130 1756
131 1772
132 1910
133 1918
134 1952
135 1970
136 1990
137 2209
138 2221
139 2225
140 2249
141 2261
142 2267
143 2281
144 2429
145 2447
146 2465
147 2489
148 2645
149 2681
150 2885
151 3110
152 3170
153 3310
154 3334
155 3370
156 3398
157 3518
158 3554
159 3730
160 3736
161 3794
162 3934
163 3974
164 4001
165 4027
166 4063
167 4229
168 4247
169 4265
170 4267
171 4427
172 4445
173 4463
174 4643
175 4825
176 4883
177 5158
178 5176
179 5374
180 5516
181 5552
182 5558
183 5594
184 5752
185 5972
186 5992
187 6001
188 6007
189 6067
190 6265
191 6403
192 6425
193 6443
194 6485
195 6601
196 6685
197 6803
198 6821
199 7330
200 7376
201 7390
202 7394
203 7534
204 7556
205 7592
206 7712
207 7934
208 7970
209 8009
210 8029
211 8221
212 8225
213 8801
214 8821
215 9118
216 9172
217 9190
218 9338
219 9370
220 9374
221 9512
222 9598
223 9710
224 9734
225 9752
226 9910
227 11116
228 11152
229 11170
230 11558
231 11930
232 13118
233 13136
234 13556
235 15572
236 15736
237 15938
238 15952
239 17716
240 17752
241 17992
242 19972
243 20209
244 20261
245 20861
246 22061
247 22201
248 22801
249 22885
250 24407
251 26201
252 26285
253 26881
254 28285
255 28429
256 31370
257 31756
258 33118
259 33538
260 33554
261 35116
262 35776
263 37190
264 37556
265 37790
266 37930
267 39158
268 39394
269 40001
270 40043
271 40049
272 40067
273 40427
274 40463
275 40483
276 42209
277 42265
278 44009
279 44443
280 44447
281 46445
282 48089
283 48265
284 51112
285 53176
286 53756
287 53918
288 55516
289 55552
290 55558
291 55576
292 55774
293 57116
294 57754
295 60007
296 60047
297 60403
298 60443
299 60667
300 62021
301 62665
302 64645
303 66667
304 66685
305 68003
306 68683
307 71536
308 71572
309 71716
310 71752
311 73156
312 75374
313 75556
314 77152
315 77554
316 79330
317 79370
318 80009
319 80029
320 80801
321 80849
322 82265
323 82285
324 82825
325 82829
326 84265
327 86081
328 86221
329 88061
330 88229
331 88265
332 88621
333 91792
334 93338
335 93958
336 93994
337 99712
338 99998
339 111112
340 111118
341 111170
342 111310
343 113170
344 115136
345 115198
346 115772
347 117116
348 119792
349 135158
350 139138
351 151156
352 151592
353 159118
354 177556
355 193910
356 199190
357 200209
358 200809
359 220021
360 220661
361 222245
362 224027
363 226447
364 226681
365 228601
366 282809
367 282881
368 282889
369 311156
370 319910
371 331118
372 333770
373 333994
374 335156
375 339370
376 351938
377 359794
378 371116
379 373130
380 393554
381 399710
382 400049
383 404249
384 408049
385 408889
386 424607
387 440843
388 464447
389 484063
390 484445
391 486685
392 488489
393 515116
394 533176
395 551558
396 559952
397 595592
398 595598
399 600881
400 602081
401 626261
402 628601
403 644485
404 684425
405 686285
406 711512
407 719710
408 753316
409 755156
410 773554
411 777712
412 777776
413 799394
414 799712
415 800483
416 802061
417 802081
418 804863
419 806021
420 806483
421 806681
422 822265
423 864883
424 888485
425 888601
426 888643
427 911390
428 911518
429 915752
430 931130
431 975772
432 979592
433 991118
434 999994
435 1115756
436 1137770
437 1191518
438 1197370
439 1353136
440 1379930
441 1533736
442 1593538
443 1711576
444 1791110
445 1795912
446 1915972
447 1951958
448 2000221
449 2008829
450 2442485
451 2604067
452 2606647
453 2664425
454 2666021
455 2828809
456 2862445
457 3155116
458 3171710
459 3193198
460 3195338
461 3195398
462 3315358
463 3373336
464 3573716
465 3737534
466 3751576
467 3939118
468 4000483
469 4408603
470 4468865
471 4488245
472 4644407
473 5115736
474 5357776
475 5551376
476 5579774
477 5731136
478 5759594
479 5959774
480 6462667
481 6600227
482 6600443
483 6608081
484 6640063
485 6640643
486 6824665
487 6864485
488 6866683
489 7113710
490 7133110
491 7139390
492 7153336
493 7159172
494 7311170
495 7351376
496 7719370
497 7959934
498 7979534
499 8044009
500 8068201
501 8608081
502 8844449
503 9171170
504 9777910
505 9959374
506 11771992
507 13913170
508 15177112
509 17115116
510 19337170
511 19713130
512 20266681
513 22086821
514 22600601
515 22862885
516 26428645
517 28862465
518 33939518
519 37959994
520 40866083
521 44866043
522 48606043
523 48804809
524 51137776
525 51513118
526 53151376
527 53775934
528 59593574
529 60402247
530 60860603
531 62202281
532 64622665
533 66864625
534 66886483
535 71553536
536 77917592
537 82486825
538 86842265
539 91959398
540 95559998
541 117711170
542 222866845
543 228440489
544 244064027
545 280422829
546 331111958
547 400044049
548 460040803
549 511151552
550 593559374
551 606202627
552 608844043
553 622622801
554 622888465
555 773719910
556 844460063
557 882428665
558 995955112
559 1777137770
560 2240064227
561 2444402809
562 5753779594
563 6464886245
564 9151995592
565 22226226625
566 31993717930
567 39393115598
568 46884486265
569 84448000009
</pre>
=={{header|Perl}}==
{{trans|Raku}}
{{libheader|ntheory}}
<syntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
use ntheory 'is_prime';
sub magnanimous {
my($n) = @_;
my $last;
for my $c (1 .. length($n) - 1) {
++$last and last unless is_prime substr($n,0,$c) + substr($n,$c)
}
not $last;
}
my @M;
for ( my $i = 0, my $count = 0; $count < 400; $i++ ) {
++$count and push @M, $i if magnanimous($i);
}
say "First 45 magnanimous numbers\n".
(sprintf "@{['%4d' x 45]}", @M[0..45-1]) =~ s/(.{60})/$1\n/gr;
say "241st through 250th magnanimous numbers\n" .
join ' ', @M[240..249];
say "\n391st through 400th magnanimous numbers\n".
join ' ', @M[390..399];</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081</pre>
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">magnanimous</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">p</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">is_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">+</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">p</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">10</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">mag</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mag</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">400</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">magnanimous</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">mag</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"First 45 magnanimous numbers: "</span><span style="color: #0000FF;">)</span> <span style="color: #7060A8;">pp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mag</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">45</span><span style="color: #0000FF;">],{</span><span style="color: #004600;">pp_Indent</span><span style="color: #0000FF;">,</span><span style="color: #000000;">30</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_IntCh</span><span style="color: #0000FF;">,</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #004600;">pp_Maxlen</span><span style="color: #0000FF;">,</span><span style="color: #000000;">100</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"magnanimous numbers[241..250]: %v\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">mag</span><span style="color: #0000FF;">[</span><span style="color: #000000;">241</span><span style="color: #0000FF;">..</span><span style="color: #000000;">250</span><span style="color: #0000FF;">]})</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"magnanimous numbers[391..400]: %v\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">mag</span><span style="color: #0000FF;">[</span><span style="color: #000000;">391</span><span style="color: #0000FF;">..</span><span style="color: #000000;">400</span><span style="color: #0000FF;">]})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
First 45 magnanimous numbers: {0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,
47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110}
magnanimous numbers[241..250]: {17992,19972,20209,20261,20861,22061,22201,22801,22885,24407}
magnanimous numbers[391..400]: {486685,488489,515116,533176,551558,559952,595592,595598,600881,602081}
</pre>
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(de **Mod (X Y N)
(let M 1
(loop
(when (bit? 1 Y)
(setq M (% (* M X) N)) )
(T (=0 (setq Y (>> 1 Y)))
M )
(setq X (% (* X X) N)) ) ) )
(de isprime (N)
(cache '(NIL) N
(if (== N 2)
T
(and
(> N 1)
(bit? 1 N)
(let (Q (dec N) N1 (dec N) K 0 X)
(until (bit? 1 Q)
(setq
Q (>> 1 Q)
K (inc K) ) )
(catch 'composite
(do 16
(loop
(setq X
(**Mod
(rand 2 (min (dec N) 1000000000000))
Q
N ) )
(T (or (=1 X) (= X N1)))
(T
(do K
(setq X (**Mod X 2 N))
(when (=1 X) (throw 'composite))
(T (= X N1) T) ) )
(throw 'composite) ) )
(throw 'composite T) ) ) ) ) ) )
(de numbers (N)
(let (P 10 Q N)
(make
(until (> 10 Q)
(link
(+
(setq Q (/ N P))
(% N P) ) )
(setq P (* P 10)) ) ) ) )
(de ismagna (N)
(or
(> 10 N)
(fully isprime (numbers N)) ) )
(let (C 0 N 0 Lst)
(setq Lst
(make
(until (== C 401)
(when (ismagna N)
(link N)
(inc 'C) )
(inc 'N) ) ) )
(println (head 45 Lst))
(println (head 10 (nth Lst 241)))
(println (head 10 (nth Lst 391))) )</syntaxhighlight>
{{out}}
<pre>
(0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110)
(17992 19972 20209 20261 20861 22061 22201 22801 22885 24407)
(486685 488489 515116 533176 551558 559952 595592 595598 600881 602081)
</pre>
=={{header|PL/M}}==
This sample can be compiled with the original 8080 PL/M compiler and run under CP/M (or a clone/emulator).
<br>THe original 8080 PL/M only supports 8 and 16 bit quantities, so this only shows magnanimous numbers up to the 250th.
<syntaxhighlight lang="plm">100H: /* FIND SOME MAGNANIMOUS NUMBERS - THOSE WHERE INSERTING '+' BETWEEN */
/* ANY TWO OF THE DIGITS AND EVALUATING THE SUM RESULTS IN A PRIME */
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
DECLARE FN BYTE, ARG ADDRESS;
GOTO 5;
END BDOS;
PRINT$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PRINT$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
PRINT$NL: PROCEDURE; CALL PRINT$STRING( .( 0DH, 0AH, '$' ) ); END;
PRINT$NUMBER: PROCEDURE( N );
DECLARE N ADDRESS;
DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
V = N;
W = LAST( N$STR );
N$STR( W ) = '$';
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
END;
IF N < 100 THEN DO;
IF N < 10 THEN CALL PRINT$CHAR( ' ' );
CALL PRINT$CHAR( ' ' );
END;
CALL PRINT$STRING( .N$STR( W ) );
END PRINT$NUMBER;
/* INTEGER SQUARE ROOT: BASED ON THE ONE IN THE PL/M FROBENIUS NUMBERS */
SQRT: PROCEDURE( N )ADDRESS;
DECLARE ( N, X0, X1 ) ADDRESS;
IF N <= 3 THEN DO;
IF N = 0 THEN X0 = 0; ELSE X0 = 1;
END;
ELSE DO;
X0 = SHR( N, 1 );
DO WHILE( ( X1 := SHR( X0 + ( N / X0 ), 1 ) ) < X0 );
X0 = X1;
END;
END;
RETURN X0;
END SQRT;
DECLARE MAGNANIMOUS (251)ADDRESS; /* MAGNANIMOUS NUMBERS */
DECLARE FALSE LITERALLY '0';
DECLARE TRUE LITERALLY '0FFH';
/* TO FIND MAGNANIMOUS NUMBERS UP TO 30$000, WE NEED TO FIND PRIMES */
/* UP TO 9$999 + 9 = 10$008 */
DECLARE MAX$PRIME LITERALLY '10$008';
DECLARE DCL$PRIME LITERALLY '10$009';
/* SIEVE THE PRIMES TO MAX$PRIME */
DECLARE ( I, S ) ADDRESS;
DECLARE PRIME ( DCL$PRIME )BYTE;
PRIME( 1 ) = FALSE; PRIME( 2 ) = TRUE;
DO I = 3 TO LAST( PRIME ) BY 2; PRIME( I ) = TRUE; END;
DO I = 4 TO LAST( PRIME ) BY 2; PRIME( I ) = FALSE; END;
DO I = 3 TO SQRT( MAX$PRIME );
IF PRIME( I ) THEN DO;
DO S = I * I TO LAST( PRIME ) BY I + I;PRIME( S ) = FALSE; END;
END;
END;
/* FIND THE MAGNANIMOUS NUMBERS */
FIND$MAGNANIMOUS: PROCEDURE;
DECLARE ( D1, D2, D3, D4, D5
, D12, D123, D1234
, D23, D234, D2345
, D34, D345, D45
) ADDRESS;
DECLARE M$COUNT ADDRESS; /* COUNT OF MAGNANIMOUS NUMBERS FOUND */
STORE$MAGNANIMOUS: PROCEDURE( N )BYTE;
DECLARE N ADDRESS;
M$COUNT = M$COUNT + 1;
IF M$COUNT <= LAST( MAGNANIMOUS ) THEN MAGNANIMOUS( M$COUNT ) = N;
RETURN M$COUNT <= LAST( MAGNANIMOUS );
END STORE$MAGNANIMOUS;
M$COUNT = 0;
/* 1 DIGIT MAGNANIMOUS NUMBERS */
DO D1 = 0 TO 9; IF NOT STORE$MAGNANIMOUS( D1 ) THEN RETURN; END;
/* 2 DIGIT MAGNANIMOUS NUMBERS */
DO D1 = 1 TO 9;
DO D2 = 0 TO 9;
IF PRIME( D1 + D2 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D1 * 10 ) + D2 ) THEN RETURN;
END;
END;
END;
/* 3 DIGIT MAGNANIMOUS NUMBERS */
DO D1 = 1 TO 9;
DO D23 = 0 TO 99;
IF PRIME( D1 + D23 ) THEN DO;
D3 = D23 MOD 10;
D12 = ( D1 * 10 ) + ( D23 / 10 );
IF PRIME( D12 + D3 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D12 * 10 ) + D3 ) THEN RETURN;
END;
END;
END;
END;
/* 4 DIGIT MAGNANIMOUS NUMBERS */
DO D12 = 10 TO 99;
DO D34 = 0 TO 99;
IF PRIME( D12 + D34 ) THEN DO;
D123 = ( D12 * 10 ) + ( D34 / 10 );
D4 = D34 MOD 10;
IF PRIME( D123 + D4 ) THEN DO;
D1 = D12 / 10;
D234 = ( ( D12 MOD 10 ) * 100 ) + D34;
IF PRIME( D1 + D234 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D12 * 100 ) + D34 )
THEN RETURN;
END;
END;
END;
END;
END;
/* 5 DIGIT MAGNANIMOUS NUMBERS UP TO 30$000 */
DO D12 = 10 TO 30;
DO D345 = 0 TO 999;
IF PRIME( D12 + D345 ) THEN DO;
D123 = ( D12 * 10 ) + ( D345 / 100 );
D45 = D345 MOD 100;
IF PRIME( D123 + D45 ) THEN DO;
D1234 = ( D123 * 10 ) + ( D45 / 10 );
D5 = D45 MOD 10;
IF PRIME( D1234 + D5 ) THEN DO;
D1 = D12 / 10;
D2345 = ( ( D12 MOD 10 ) * 1000 ) + D345;
IF PRIME( D1 + D2345 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D12 * 1000 ) + D345 )
THEN RETURN;
END;
END;
END;
END;
END;
END;
END FIND$MAGNANIMOUS ;
CALL FIND$MAGNANIMOUS;
DO I = 1 TO LAST( MAGNANIMOUS );
IF I = 1 THEN DO;
CALL PRINT$STRING( .'MAGNANIMOUS NUMBERS 1-45:$' ); CALL PRINT$NL;
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
ELSE IF I < 46 THEN DO;
IF I MOD 15 = 1 THEN CALL PRINT$NL; ELSE CALL PRINT$CHAR( ' ' );
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
ELSE IF I = 241 THEN DO;
CALL PRINT$NL;
CALL PRINT$STRING( .'MAGANIMOUS NUMBERS 241-250:$' ); CALL PRINT$NL;
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
ELSE IF I > 241 AND I <= 250 THEN DO;
CALL PRINT$CHAR( ' ' );
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
END;
CALL PRINT$NL;
EOF</syntaxhighlight>
{{out}}
<pre>
MAGNANIMOUS NUMBERS 1-45:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
MAGANIMOUS NUMBERS 241-250:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
</pre>
=={{header|Python}}==
<syntaxhighlight lang="python">""" rosettacode.orgwiki/Magnanimous_numbers """
from sympy import isprime
def is_magnanimous(num):
""" True is num is a magnanimous number """
if num < 10:
return True
for i in range(1, len(str(num))):
quo, rem = divmod(num, 10**i)
if not isprime(quo + rem):
return False
return True
if __name__ == '__main__':
K, MCOUNT = 0, 0
print('First 45 magnanimous numbers:')
while MCOUNT < 400:
if is_magnanimous(K):
if MCOUNT < 45:
print(f'{K:4d}', end='\n' if (MCOUNT + 1) % 15 == 0 else '')
elif MCOUNT == 239:
print('\n241st through 250th magnanimous numbers:')
elif 239 < MCOUNT < 250:
print(f'{K:6d}', end='')
elif MCOUNT == 389:
print('\n\n391st through 400th magnanimous numbers:')
elif 389 < MCOUNT < 400:
print(f'{K:7d}', end='')
MCOUNT += 1
K += 1
</syntaxhighlight>{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|Quackery}}==
<code>isprime</code> is defined at [[Primality by trial division#Quackery]].
<syntaxhighlight lang="Quackery"> [ 10
[ 2dup /mod
over 0 = iff
[ 2drop true ]
done
+ isprime not iff
false done
10 * again ]
unrot 2drop ] is magnanimous ( n --> b )
[] 0
[ dup magnanimous
if [ tuck join swap ]
1+
over size 250 =
until ]
drop
say "First 45 magnanimous numbers:" cr
45 split swap echo cr cr
say "Magnanimous numbers 241-250:" cr
-10 split echo cr cr
drop</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers:
[ 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 ]
Magnanimous numbers 241-250:
[ 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 ]
</pre>
=={{header|Raku}}==
{{works with|Rakudo|2020.02}}
<syntaxhighlight lang="raku"
my int $last;
(1 ..^ .chars
next if $last;
$_
} ),
(1002 .. ∞)
# optimization for numbers > 1001; First and last digit can not both be even or both be odd
next if (.substr(0,1)
my int $last;
(1 ..^ .chars
next if $last;
$_
Line 54 ⟶ 3,358:
put @magnanimous[^45]».fmt('%3d').batch(15).join: "\n";
put "\
put @magnanimous[240..249];
put "\n391st through 400th magnanimous numbers";
put @magnanimous[390..399];</
{{out}}
<pre>First 45 magnanimous numbers
Line 65 ⟶ 3,369:
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081</pre>
=={{header|REXX}}==
The majority of the time consumed was in generating a list (sparse array) of suitable primes.
<br>The '''magna''' function (magnanimous) was quite simple to code and pretty fast, it includes the 1<sup>st</sup> and last digit parity test.
<br>By far, the most CPU time was in the generation of primes.
<syntaxhighlight lang="rexx">/*REXX pgm finds/displays magnanimous #s (#s with a inserted + sign to sum to a prime).*/
parse arg bet.1 bet.2 bet.3 highP . /*obtain optional arguments from the CL*/
if bet.1=='' | bet.1=="," then bet.1= 1..45 /* " " " " " " */
if bet.2=='' | bet.2=="," then bet.2= 241..250 /* " " " " " " */
if bet.3=='' | bet.3=="," then bet.3= 391..400 /* " " " " " " */
if highP=='' | highP=="," then highP= 1000000 /* " " " " " " */
call genP /*gen primes up to highP (1 million).*/
do j=1 for 3 /*process three magnanimous "ranges". */
parse var bet.j LO '..' HI /*obtain the first range (if any). */
if HI=='' then HI= LO /*Just a single number? Then use LO. */
if HI==0 then iterate /*Is HI a zero? Then skip this range.*/
finds= 0; $= /*#: magnanimous # cnt; $: is a list*/
do k=0 until finds==HI /* [↓] traipse through the number(s). */
if \magna(k) then iterate /*Not magnanimous? Then skip this num.*/
finds= finds + 1 /*bump the magnanimous number count. */
if finds>=LO then $= $ k /*In range► Then add number ──► $ list*/
end /*k*/
say
say center(' 'LO "──►" HI 'magnanimous numbers ', 126, "─")
say strip($)
end /*j*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
magna: procedure expose @. !.; parse arg x 1 L 2 '' -1 R /*obtain #, 1st & last digit.*/
len= length(x); if len==1 then return 1 /*one digit #s are magnanimous*/
if x>1001 then if L//2 == R//2 then return 0 /*Has parity? Not magnanimous*/
do s= 1 for len-1 /*traipse thru #, inserting + */
parse var x y +(s) z; sum= y + z /*parse 2 parts of #, sum 'em.*/
if !.sum then iterate /*Is sum prime? So far so good*/
else return 0 /*Nope? Then not magnanimous.*/
end /*s*/
return 1 /*Pass all the tests, it's magnanimous.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13 /*assign low primes; # primes.*/
!.= 0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1 /* " semaphores to " */
#= 6; sq.#= @.# ** 2 /*# primes so far; P squared.*/
do j=@.#+4 by 2 to highP; parse var j '' -1 _; if _==5 then iterate /*÷ by 5?*/
if j// 3==0 then iterate; if j// 7==0 then iterate /*÷ by 3?; ÷ by 7?*/
if j//11==0 then iterate /*" " 11? " " 13?*/
do k=6 while sq.k<=j /*divide by some generated odd primes. */
if j//@.k==0 then iterate j /*Is J divisible by P? Then not prime*/
end /*k*/ /* [↓] a prime (J) has been found. */
#= #+1; @.#= j; sq.#= j*j; !.j= 1 /*bump #Ps; P──►@.assign P; P^2; P flag*/
end /*j*/; return</syntaxhighlight>
{{out|output|text= when using the default inputs:}}
<pre>
──────────────────────────────────────────────── 1 ──► 45 magnanimous numbers ────────────────────────────────────────────────
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
and took 0.00 seconds.
────────────────────────────────────────────── 241 ──► 250 magnanimous numbers ───────────────────────────────────────────────
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
and took 0.31 seconds.
────────────────────────────────────────────── 391 ──► 400 magnanimous numbers ───────────────────────────────────────────────
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|Ring}}==
<syntaxhighlight lang="ring">
load "stdlib.ring"
n = -1
sum = 0
magn = []
while sum < 45
n = n + 1
if n < 10
add(magn,n)
sum = sum + 1
else
nStr = string(n)
check = 0
for m = 1 to len(nStr)-1
nr1 = number(left(nStr,m))
nr2 = number(right(nStr,len(nStr)-m))
nr3 = nr1 + nr2
if not isprime(nr3)
check = 1
ok
next
if check = 0
add(magn,n)
sum = sum + 1
ok
ok
end
see "Magnanimous numbers 1-45:" + nl
showArray(magn)
n = -1
sum = 0
magn = []
while sum < 250
n = n + 1
if n < 10
sum = sum + 1
else
nStr = string(n)
check = 0
for m = 1 to len(nStr)-1
nr1 = number(left(nStr,m))
nr2 = number(right(nStr,len(nStr)-m))
nr3 = nr1 + nr2
if not isprime(nr3)
check = 1
ok
next
if check = 0
sum = sum + 1
ok
if check = 0 and sum > 240 and sum < 251
add(magn,n)
ok
ok
end
see nl
see "Magnanimous numbers 241-250:" + nl
showArray(magn)
func showArray array
txt = ""
see "["
for n = 1 to len(array)
txt = txt + array[n] + ","
next
txt = left(txt,len(txt)-1)
txt = txt + "]"
see txt
</syntaxhighlight>
<pre>
Magnanimous numbers 1-45:
[0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110]
Magnanimous numbers 241-250:
[17992,19972,20209,20261,20861,22061,22201,22801,22885,24407]
</pre>
=={{header|RPL}}==
{{works with|Halcyon Calc|4.2.7}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪
DUP2 1 SWAP SUB "+" + ROT ROT
1 + OVER SIZE SUB + STR→ EVAL
≫ ‘'''InsertPlus'''’ STO
≪
"'" SWAP →STR OVER + + DUP SIZE → str len
≪ 2 SF 2 len 2 - FOR j
str j '''InsertPlus'''
IF '''PRIM?''' NOT THEN 2 CF len 'j' STO END
NEXT
2 FS?
≫ ≫ ‘'''MAGN?'''’ STO
≪ → n
≪ { 0 1 2 3 4 5 6 7 8 9 } 10
WHILE OVER SIZE n < REPEAT
IF DUP '''MAGN?''' THEN SWAP OVER + SWAP END
1 +
END DROP
≫ ≫ ‘'''MAGLST'''’ STO
≪
DO 1 + UNTIL DUP '''MAGN?''' END
≫ ‘'''NXMAGN'''’ STO
|
'''InsertPlus''' ''( "'####'" pos -- sum )''
insert a plus sign in the string
evaluate the expression
'''MAGN?''' ''( "'####'" pos -- sum )''
turn ### into "'###'"
for each possibility
add digits
if not a prime, clear flag 2 and exit the loop
'''MAGLST''' ''( n -- { M(1)..M(n) } )''
'''NXMAGN''' ''( x -- next_M(n) )''
|}
{{in}}
<pre>
45 MAGLST
17752 NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN
</pre>
{{out}}
<pre>
11: { 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 }
10: 17992
9: 19972
8: 20209
7: 20261
6: 20861
5: 22061
4: 22201
3: 22801
2: 22885
1: 24407
</pre>
=={{header|Ruby}}==
{{trans|Sidef}}
<syntaxhighlight lang="ruby">require "prime"
magnanimouses = Enumerator.new do |y|
(0..).each {|n| y << n if (1..n.digits.size-1).all? {|k| n.divmod(10**k).sum.prime?} }
end
puts "First 45 magnanimous numbers:"
puts magnanimouses.first(45).join(' ')
puts "\n241st through 250th magnanimous numbers:"
puts magnanimouses.first(250).last(10).join(' ')
puts "\n391st through 400th magnanimous numbers:"
puts magnanimouses.first(400).last(10).join(' ')
</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn is_prime(n: u32) -> bool {
if n < 2 {
return false;
}
if n % 2 == 0 {
return n == 2;
}
if n % 3 == 0 {
return n == 3;
}
let mut p = 5;
while p * p <= n {
if n % p == 0 {
return false;
}
p += 2;
if n % p == 0 {
return false;
}
p += 4;
}
true
}
fn is_magnanimous(n: u32) -> bool {
let mut p: u32 = 10;
while n >= p {
if !is_prime(n % p + n / p) {
return false;
}
p *= 10;
}
true
}
fn main() {
let mut m = (0..).filter(|x| is_magnanimous(*x)).take(400);
println!("First 45 magnanimous numbers:");
for (i, n) in m.by_ref().take(45).enumerate() {
if i > 0 && i % 15 == 0 {
println!();
}
print!("{:3} ", n);
}
println!("\n\n241st through 250th magnanimous numbers:");
for n in m.by_ref().skip(195).take(10) {
print!("{} ", n);
}
println!("\n\n391st through 400th magnanimous numbers:");
for n in m.by_ref().skip(140) {
print!("{} ", n);
}
println!();
}</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|SETL}}==
<syntaxhighlight lang="setl">program magnanimous;
n := -1;
loop for i in [1..400] do
loop until magnanimous(n) do n +:= 1; end loop;
case i of
(1): print("1 - 45:");
(241): print; print("241 - 250:");
(391): print; print("391 - 400:");
end case;
if i in [1..45] or i in [241..250] or i in [391..400] then
putchar(lpad(str n, 7));
if i mod 5 = 0 then print; end if;
end if;
end loop;
proc magnanimous(n);
return forall k in splitsums(n) | prime(k);
end proc;
proc splitsums(n);
s := str n;
return [val s(..i) + val s(i+1..) : i in [1..#s-1]];
end proc;
proc prime(n);
if n<2 then return false;
elseif even n then return(n = 2);
elseif n mod 3=0 then return(n = 3);
else
d := 5;
loop while d*d <= n do
if n mod d=0 then return false; end if;
d +:= 2;
if n mod d=0 then return false; end if;
d +:= 4;
end loop;
return true;
end if;
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>1 - 45:
0 1 2 3 4
5 6 7 8 9
11 12 14 16 20
21 23 25 29 30
32 34 38 41 43
47 49 50 52 56
58 61 65 67 70
74 76 83 85 89
92 94 98 101 110
241 - 250:
17992 19972 20209 20261 20861
22061 22201 22801 22885 24407
391 - 400:
486685 488489 515116 533176 551558
559952 595592 595598 600881 602081</pre>
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func is_magnanimous(n) {
1..n.ilog10 -> all {|k|
sum(divmod(n, k.ipow10)).is_prime
}
}
say "First 45 magnanimous numbers:"
say is_magnanimous.first(45).join(' ')
say "\n241st through 250th magnanimous numbers:"
say is_magnanimous.first(250).last(10).join(' ')
say "\n391st through 400th magnanimous numbers:"
say is_magnanimous.first(400).last(10).join(' ')</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|Swift}}==
{{trans|Rust}}
<syntaxhighlight lang="swift">import Foundation
func isPrime(_ n: Int) -> Bool {
if n < 2 {
return false
}
if n % 2 == 0 {
return n == 2
}
if n % 3 == 0 {
return n == 3
}
var p = 5
while p * p <= n {
if n % p == 0 {
return false
}
p += 2
if n % p == 0 {
return false
}
p += 4
}
return true
}
func isMagnanimous(_ n: Int) -> Bool {
var p = 10;
while n >= p {
if !isPrime(n % p + n / p) {
return false
}
p *= 10
}
return true
}
let m = (0...).lazy.filter{isMagnanimous($0)}.prefix(400);
print("First 45 magnanimous numbers:");
for (i, n) in m.prefix(45).enumerated() {
if i > 0 && i % 15 == 0 {
print()
}
print(String(format: "%3d", n), terminator: " ")
}
print("\n\n241st through 250th magnanimous numbers:");
for n in m.dropFirst(240).prefix(10) {
print(n, terminator: " ")
}
print("\n\n391st through 400th magnanimous numbers:");
for n in m.dropFirst(390) {
print(n, terminator: " ")
}
print()</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<syntaxhighlight lang="vbnet">Imports System, System.Console
Module Module1
Dim np As Boolean()
Sub ms(ByVal lmt As Long)
np = New Boolean(CInt(lmt)) {} : np(0) = True : np(1) = True
Dim n As Integer = 2, j As Integer = 1 : While n < lmt
If Not np(n) Then
Dim k As Long = CLng(n) * n
While k < lmt : np(CInt(k)) = True : k += n : End While
End If : n += j : j = 2 : End While
End Sub
Function is_Mag(ByVal n As Integer) As Boolean
Dim res, rm As Integer, p As Integer = 10
While n >= p
res = Math.DivRem(n, p, rm)
If np(res + rm) Then Return False
p = p * 10 : End While : Return True
End Function
Sub Main(ByVal args As String())
ms(100_009) : Dim mn As String = " magnanimous numbers:"
WriteLine("First 45{0}", mn) : Dim l As Integer = 0, c As Integer = 0
While c < 400 : If is_Mag(l) Then
c += 1 : If c <= 45 OrElse (c > 240 AndAlso c <= 250) OrElse c > 390 Then Write(If(c <= 45, "{0,4} ", "{0,8:n0} "), l)
If c < 45 AndAlso c Mod 15 = 0 Then WriteLine()
If c = 240 Then WriteLine(vbLf & vbLf & "241st through 250th{0}", mn)
If c = 390 Then WriteLine(vbLf & vbLf & "391st through 400th{0}", mn)
End If : l += 1 : End While
End Sub
End Module</syntaxhighlight>
{{out}}
<pre>First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17,992 19,972 20,209 20,261 20,861 22,061 22,201 22,801 22,885 24,407
391st through 400th magnanimous numbers:
486,685 488,489 515,116 533,176 551,558 559,952 595,592 595,598 600,881 602,081 </pre>
=={{header|Wren}}==
{{libheader|Wren-fmt}}
{{libheader|Wren-math}}
{{trans|Go}}
<syntaxhighlight lang="wren">import "./fmt" for Conv, Fmt
import "./math" for Int
var isMagnanimous = Fn.new { |n|
if (n < 10) return true
var p = 10
while (true) {
var q = (n/p).floor
var r = n % p
if (!Int.isPrime(q + r)) return false
if (q < 10) break
p = p * 10
}
return true
}
var listMags = Fn.new { |from, thru, digs, perLine|
if (from < 2) {
System.print("\nFirst %(thru) magnanimous numbers:")
} else {
System.print("\n%(Conv.ord(from)) through %(Conv.ord(thru)) magnanimous numbers:")
}
var i = 0
var c = 0
while (c < thru) {
if (isMagnanimous.call(i)) {
c = c + 1
if (c >= from) {
System.write(Fmt.d(digs, i) + " ")
if (c % perLine == 0) System.print()
}
}
i = i + 1
}
}
listMags.call(1, 45, 3, 15)
listMags.call(241, 250, 1, 10)
listMags.call(391, 400, 1, 10)</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
</pre>
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">func IsPrime(N); \Return 'true' if N is prime
int N, I;
[if N <= 2 then return N = 2;
if (N&1) = 0 then \even >2\ return false;
for I:= 3 to sqrt(N) do
[if rem(N/I) = 0 then return false;
I:= I+1;
];
return true;
];
func Magnan(N); \Return 'true' if N is a magnanimous number
int N, M, P;
[M:= 0; P:= 1;
loop [N:= N/10;
if N = 0 then return true;
M:= P*rem(0) + M;
P:= P*10;
if not IsPrime(N+M) then return false;
];
];
int Cnt, N;
[Cnt:= 0; N:= 0;
Text(0, "First 45 magnanimous numbers:^m^j");
loop [if N < 10 or Magnan(N) then
[Cnt:= Cnt+1;
if Cnt <= 45 then
[Format(4, 0);
RlOut(0, float(N));
if rem(Cnt/15) = 0 then CrLf(0);
];
if Cnt = 241 then
Text(0, "^m^j241st through 250th magnanimous numbers:^m^j");
if Cnt >= 241 and Cnt <= 250 then
[IntOut(0, N); ChOut(0, ^ )];
if Cnt = 391 then
Text(0, "^m^j^j391st through 400th magnanimous numbers:^m^j");
if Cnt >= 391 and Cnt <= 400 then
[IntOut(0, N); ChOut(0, ^ )];
if Cnt >= 400 then quit;
];
N:= N+1;
];
]</syntaxhighlight>
{{out}}
<pre>
First 45 magnanimous numbers:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20
21 23 25 29 30 32 34 38 41 43 47 49 50 52 56
58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
241st through 250th magnanimous numbers:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
391st through 400th magnanimous numbers:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081 </pre>
|
Latest revision as of 16:09, 30 December 2023
You are encouraged to solve this task according to the task description, using any language you may know.
A magnanimous number is an integer where there is no place in the number where a + (plus sign) could be added between any two digits to give a non-prime sum.
- E.G.
- 6425 is a magnanimous number. 6 + 425 == 431 which is prime; 64 + 25 == 89 which is prime; 642 + 5 == 647 which is prime.
- 3538 is not a magnanimous number. 3 + 538 == 541 which is prime; 35 + 38 == 73 which is prime; but 353 + 8 == 361 which is not prime.
Traditionally the single digit numbers 0 through 9 are included as magnanimous numbers as there is no place in the number where you can add a plus between two digits at all. (Kind of weaselly but there you are...) Except for the actual value 0, leading zeros are not permitted. Internal zeros are fine though, 1001 -> 1 + 001 (prime), 10 + 01 (prime) 100 + 1 (prime).
There are only 571 known magnanimous numbers. It is strongly suspected, though not rigorously proved, that there are no magnanimous numbers above 97393713331910, the largest one known.
- Task
- Write a routine (procedure, function, whatever) to find magnanimous numbers.
- Use that function to find and display, here on this page the first 45 magnanimous numbers.
- Use that function to find and display, here on this page the 241st through 250th magnanimous numbers.
- Stretch: Use that function to find and display, here on this page the 391st through 400th magnanimous numbers
- See also
ALGOL 68
BEGIN # find some magnanimous numbers - numbers where inserting a + between any #
# digits ab=nd evaluatinf the sum results in a prime in all cases #
# returns the first n magnanimous numbers #
# uses global sieve prime which must include 0 and be large enough #
# for all possible sub-sequences of digits #
OP MAGNANIMOUS = ( INT n )[]INT:
BEGIN
[ 1 : n ]INT result;
INT m count := 0;
FOR i FROM 0 WHILE m count < n DO
# split the number into pairs of digit seuences and check the sums of the pairs are all prime #
INT divisor := 1;
BOOL all prime := TRUE;
WHILE divisor *:= 10;
IF INT front = i OVER divisor;
front = 0
THEN FALSE
ELSE all prime := prime[ front + ( i MOD divisor ) ]
FI
DO SKIP OD;
IF all prime THEN result[ m count +:= 1 ] := i FI
OD;
result
END; # MAGNANIMPUS #
# prints part of a seuence of magnanimous numbers #
PROC print magnanimous = ( []INT m, INT first, INT last, STRING legend )VOID:
BEGIN
print( ( legend, ":", newline ) );
FOR i FROM first TO last DO print( ( " ", whole( m[ i ], 0 ) ) ) OD;
print( ( newline ) )
END ; # print magnanimous #
# we assume the first 400 magnanimous numbers will be in 0 .. 1 000 000 #
# so we will need a sieve of 0 up to 99 999 + 9 #
[ 0 : 99 999 + 9 ]BOOL prime;
prime[ 0 ] := prime[ 1 ] := FALSE; prime[ 2 ] := TRUE;
FOR i FROM 3 BY 2 TO UPB prime DO prime[ i ] := TRUE OD;
FOR i FROM 4 BY 2 TO UPB prime DO prime[ i ] := FALSE OD;
FOR i FROM 3 BY 2 TO ENTIER sqrt( UPB prime ) DO
IF prime[ i ] THEN FOR s FROM i * i BY i + i TO UPB prime DO prime[ s ] := FALSE OD FI
OD;
# construct the sequence of magnanimous numbers #
[]INT m = MAGNANIMOUS 400;
print magnanimous( m, 1, 45, "First 45 magnanimous numbers" );
print magnanimous( m, 241, 250, "Magnanimous numbers 241-250" );
print magnanimous( m, 391, 400, "Magnanimous numbers 391-400" )
END
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 Magnanimous numbers 241-250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 Magnanimous numbers 391-400: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
ALGOL W
begin
% find some Magnanimous numbers - numbers where inserting a "+" between %
% any two of the digits and evaluating the sum results in a prime number %
% implements the sieve of Eratosthenes %
procedure sieve( logical array s ( * ); integer value n ) ;
begin
% start with everything flagged as prime %
for i := 1 until n do s( i ) := true;
% sieve out the non-primes %
s( 1 ) := false;
for i := 2 until truncate( sqrt( n ) ) do begin
if s( i ) then for p := i * i step i until n do s( p ) := false
end for_i ;
end sieve ;
% construct an array of magnanimous numbers using the isPrime sieve %
procedure findMagnanimous ( logical array magnanimous, isPrime ( * ) ) ;
begin
% 1 digit magnanimous numbers %
for i := 0 until 9 do magnanimous( i ) := true;
% initially, the other magnanimous numbers are unknown %
for i := 10 until MAGNANIMOUS_MAX do magnanimous( i ) := false;
% 2 & 3 digit magnanimous numbers %
for d1 := 1 until 9 do begin
for d2 := 0 until 9 do begin
if isPrime( d1 + d2 ) then magnanimous( ( d1 * 10 ) + d2 ) := true
end for_d2 ;
for d23 := 0 until 99 do begin
if isPrime( d1 + d23 ) then begin
integer d12, d3;
d3 := d23 rem 10;
d12 := ( d1 * 10 ) + ( d23 div 10 );
if isPrime( d12 + d3 ) then magnanimous( ( d12 * 10 ) + d3 ) := true
end if_isPrime_d1_plus_d23
end for_d23
end for_d1 ;
% 4 & 5 digit magnanimous numbers %
for d12 := 10 until 99 do begin
for d34 := 0 until 99 do begin
if isPrime( d12 + d34 ) then begin
integer d123, d4;
d123 := ( d12 * 10 ) + ( d34 div 10 );
d4 := d34 rem 10;
if isPrime( d123 + d4 ) then begin
integer d1, d234;
d1 := d12 div 10;
d234 := ( ( d12 rem 10 ) * 100 ) + d34;
if isPrime( d1 + d234 ) then magnanimous( ( d12 * 100 ) + d34 ) := true
end if_isPrime_d123_plus_d4
end if_isPrime_d12_plus_d34
end for_d34 ;
for d345 := 0 until 999 do begin
if isPrime( d12 + d345 ) then begin
integer d123, d45;
d123 := ( d12 * 10 ) + ( d345 div 100 );
d45 := d345 rem 100;
if isPrime( d123 + d45 ) then begin
integer d1234, d5;
d1234 := ( d123 * 10 ) + ( d45 div 10 );
d5 := d45 rem 10;
if isPrime( d1234 + d5 ) then begin
integer d1, d2345;
d1 := d12 div 10;
d2345 := ( ( d12 rem 10 ) * 1000 ) + d345;
if isPrime( d1 + d2345 ) then magnanimous( ( d12 * 1000 ) + d345 ) := true
end if_isPrime_d1234_plus_d5
end if_isPrime_d123_plus_d45
end if_isPrime_d12_plus_d345
end for_d234
end for_d12 ;
% find 6 digit magnanimous numbers %
for d123 := 100 until 999 do begin
for d456 := 0 until 999 do begin
if isPrime( d123 + d456 ) then begin
integer d1234, d56;
d1234 := ( d123 * 10 ) + ( d456 div 100 );
d56 := d456 rem 100;
if isPrime( d1234 + d56 ) then begin
integer d12345, d6;
d12345 := ( d1234 * 10 ) + ( d56 div 10 );
d6 := d56 rem 10;
if isPrime( d12345 + d6 ) then begin
integer d12, d3456;
d12 := d123 div 10;
d3456 := ( ( d123 rem 10 ) * 1000 ) + d456;
if isPrime( d12 + d3456 ) then begin
integer d1, d23456;
d1 := d12 div 10;
d23456 := ( ( d12 rem 10 ) * 10000 ) + d3456;
if isPrime( d1 + d23456 ) then magnanimous( ( d123 * 1000 ) + d456 ) := true
end if_isPrime_d12_plus_d3456
end if_isPrime_d12345_plus_d6
end if_isPrime_d1234_plus_d56
end if_isPrime_d123_plus_d456
end for_d456
end for_d123
end findMagnanimous ;
% we look for magnanimous numbers with up to 6 digits, so we need to %
% check for primes up to 99999 + 9 = 100008 %
integer PRIME_MAX, MAGNANIMOUS_MAX;
PRIME_MAX := 100008;
MAGNANIMOUS_MAX := 1000000;
begin
logical array magnanimous ( 0 :: MAGNANIMOUS_MAX );
logical array isPrime ( 1 :: PRIME_MAX );
integer mPos;
integer lastM;
sieve( isPrime, PRIME_MAX );
findMagnanimous( magnanimous, isPrime );
% show some of the magnanimous numbers %
lastM := mPos := 0;
i_w := 3; s_w := 1; % output formatting %
for i := 0 until MAGNANIMOUS_MAX do begin
if magnanimous( i ) then begin
mPos := mPos + 1;
lastM := i;
if mPos = 1 then begin
write( "Magnanimous numbers 1-45:" );
write( i )
end
else if mPos < 46 then begin
if mPos rem 15 = 1 then write( i )
else writeon( i )
end
else if mPos = 241 then begin
write( "Magnanimous numbers 241-250:" );
write( i )
end
else if mPos > 241 and mPos <= 250 then writeon( i )
else if mPos = 391 then begin
write( "Magnanimous numbers 391-400:" );
write( i )
end
else if mPos > 391 and mPos <= 400 then writeon( i )
end if_magnanimous_i
end for_i ;
i_w := 1; s_w := 0;
write( "Last magnanimous number found: ", mPos, " = ", lastM )
end
end.
- Output:
Magnanimous numbers 1-45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 Magnanimous numbers 241-250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 Magnanimous numbers 391-400: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081 Last magnanimous number found: 434 = 999994
Amazing Hopper
#include <basico.h>
#proto encontrarunMagnanimouspara(_X_)
#synon _encontrarunMagnanimouspara siencontréunMagnanimousen
algoritmo
decimales '0'
res={}, i=0
iterar grupo( ++i, #(length(res)<400), \
i, meter según ( si encontré un Magnanimous en 'i', res ))
#(utf8("Primeros 45 números magnánimos:\n")), #(res[1:45])
#(utf8("\n\nNúmeros magnánimos 241 - 250:\n")), #(res[241:250])
#(utf8("\n\nNúmeros magnánimos 391 - 400:\n")), #(res[391:400]), NL
luego imprime esto
terminar
subrutinas
encontrar un Magnanimous para(n)
tn=n, d=0, i=0, pd=0
iterar
último dígito de 'tn', mover a 'd,tn'
cuando ' tn ' { #( pd += ( d * 10^i ) ) }
mientras ' #( tn && is prime(tn+pd) ); ++i '
retornar ' #(not(tn)) '
- Output:
Primeros 45 números magnánimos: 0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110 Números magnánimos 241 - 250: 17992,19972,20209,20261,20861,22061,22201,22801,22885,24407 Números magnánimos 391 - 400: 486685,488489,515116,533176,551558,559952,595592,595598,600881,602081
AWK
# syntax: GAWK -f MAGNANIMOUS_NUMBERS.AWK
# converted from C
BEGIN {
magnanimous(1,45)
magnanimous(241,250)
magnanimous(391,400)
exit(0)
}
function is_magnanimous(n, p,q,r) {
if (n < 10) { return(1) }
for (p=10; ; p*=10) {
q = int(n/p)
r = n % p
if (!is_prime(q+r)) { return(0) }
if (q < 10) { break }
}
return(1)
}
function is_prime(n, d) {
d = 5
if (n < 2) { return(0) }
if (!(n % 2)) { return(n == 2) }
if (!(n % 3)) { return(n == 3) }
while (d*d <= n) {
if (!(n % d)) { return(0) }
d += 2
if (!(n % d)) { return(0) }
d += 4
}
return(1)
}
function magnanimous(start,stop, count,i) {
printf("%d-%d:",start,stop)
for (i=0; count<stop; ++i) {
if (is_magnanimous(i)) {
if (++count >= start) {
printf(" %d",i)
}
}
}
printf("\n")
}
- Output:
1-45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241-250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391-400: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
BASIC
10 DEFINT A-Z
20 L = N : R = 0 : S = 1
30 IF L < 10 GOTO 140
40 R = R + (L MOD 10) * S
50 L = L \ 10
60 S = S * 10
70 P = R + L
80 IF P = 1 GOTO 120 ELSE FOR D = 2 TO SQR(P)
90 IF P MOD D = 0 GOTO 120
100 NEXT D
110 GOTO 30
120 N = N + 1
130 GOTO 20
140 I = I + 1
150 IF I = 1 THEN PRINT "1 - 45:" ELSE IF I = 241 THEN PRINT "241 - 250:"
160 IF I <= 45 OR I > 240 THEN PRINT N,
170 N = N + 1
180 IF I < 250 GOTO 20
190 END
- Output:
1 - 45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241 - 250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
BASIC256
#include "isprime.kbs"
dim magn(400)
n = 10
for i = 0 to 9
magn[i] = i #all single digit ints are magnanimous by definition
next i
while i < 400
n += 1
ns = string(n)
for j = 1 to length(ns)-1
lefty = left(ns, j)
righty = right(ns, length(ns)-j)
if not isPrime(int(lefty) + int(righty)) then continue while
next j
magn[i] = n
i += 1
end while
for i = 0 to 44
print i+1, magn[i]
next i
for i =240 to 249
print i+1, magn[i]
next i
for i = 390 to 399
print i+1, magn[i]
next i
end
- Output:
Same as FreeBASIC entry.
BBC BASIC
DIM Sieve% 1E5
Prime%=2
WHILE Prime%^2 < 1E5
FOR S%=Prime%*2 TO 1E5 STEP Prime% Sieve%?S%=1 NEXT
REPEAT Prime%+=1 UNTIL Sieve%?Prime%=0
ENDWHILE
Sieve%?1=1
PRINT "First 45 magnanimous numbers"
REPEAT
IF M% > 9 THEN
FOR I%=LOGM% TO 1 STEP -1
IF Sieve%?((M% DIV 10^I%) + (M% MOD 10^I%)) EXIT FOR
NEXT
ENDIF
IF I% == 0 THEN
N%+=1
IF N% == 240 OR N% == 390 PRINT '"Magnanimous numbers ";N% + 1 "-";N% + 10
IF N% < 46 OR (N% > 240 AND N% < 251) OR (N% > 390 AND N% < 401) PRINT;M% " ";
ENDIF
M%+=1
UNTIL N% > 400
- Output:
First 45 magnanimous numbers 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 Magnanimous numbers 241-250 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 Magnanimous numbers 391-400 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
BCPL
get "libhdr"
let prime(n) = valof
$( let d = 5
if n<2 resultis false
if n rem 2=0 resultis n=2
if n rem 3=0 resultis n=3
while d*d <= n
$( if n rem d=0 resultis false
d := d+2
if n rem d=0 resultis false
d := d+4
$)
resultis true
$)
let magnanimous(n) = valof
$( let left = n and right = 0 and shift = 1
while left >= 10
$( right := right + (left rem 10) * shift
shift := shift * 10
left := left / 10
unless prime(left + right) resultis false
$)
resultis true
$)
let start() be
$( let n = -1
for i = 1 to 250
$( n := n+1 repeatuntil magnanimous(n)
if i=1 then writes("1 - 45:*N")
if i=241 then writes("241 - 250:*N")
if 0<i<=45 | 240<i<=250
$( writed(n, 7)
if i rem 5=0 then wrch('*N')
$)
$)
$)
- Output:
1 - 45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241 - 250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
C
#include <stdio.h>
#include <string.h>
typedef int bool;
typedef unsigned long long ull;
#define TRUE 1
#define FALSE 0
/* OK for 'small' numbers. */
bool is_prime(ull n) {
ull d;
if (n < 2) return FALSE;
if (!(n % 2)) return n == 2;
if (!(n % 3)) return n == 3;
d = 5;
while (d * d <= n) {
if (!(n % d)) return FALSE;
d += 2;
if (!(n % d)) return FALSE;
d += 4;
}
return TRUE;
}
void ord(char *res, int n) {
char suffix[3];
int m = n % 100;
if (m >= 4 && m <= 20) {
sprintf(res,"%dth", n);
return;
}
switch(m % 10) {
case 1:
strcpy(suffix, "st");
break;
case 2:
strcpy(suffix, "nd");
break;
case 3:
strcpy(suffix, "rd");
break;
default:
strcpy(suffix, "th");
break;
}
sprintf(res, "%d%s", n, suffix);
}
bool is_magnanimous(ull n) {
ull p, q, r;
if (n < 10) return TRUE;
for (p = 10; ; p *= 10) {
q = n / p;
r = n % p;
if (!is_prime(q + r)) return FALSE;
if (q < 10) break;
}
return TRUE;
}
void list_mags(int from, int thru, int digs, int per_line) {
ull i = 0;
int c = 0;
char res1[13], res2[13];
if (from < 2) {
printf("\nFirst %d magnanimous numbers:\n", thru);
} else {
ord(res1, from);
ord(res2, thru);
printf("\n%s through %s magnanimous numbers:\n", res1, res2);
}
for ( ; c < thru; ++i) {
if (is_magnanimous(i)) {
if (++c >= from) {
printf("%*llu ", digs, i);
if (!(c % per_line)) printf("\n");
}
}
}
}
int main() {
list_mags(1, 45, 3, 15);
list_mags(241, 250, 1, 10);
list_mags(391, 400, 1, 10);
return 0;
}
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
C#
using System; using static System.Console;
class Program {
static bool[] np; // not-prime array
static void ms(long lmt) { // populates array, a not-prime is true
np = new bool[lmt]; np[0] = np[1] = true;
for (long n = 2, j = 1; n < lmt; n += j, j = 2) if (!np[n])
for (long k = n * n; k < lmt; k += n) np[k] = true; }
static bool is_Mag(long n) { long res, rem;
for (long p = 10; n >= p; p *= 10) {
res = Math.DivRem (n, p, out rem);
if (np[res + rem]) return false; } return true; }
static void Main(string[] args) { ms(100_009); string mn;
WriteLine("First 45{0}", mn = " magnanimous numbers:");
for (long l = 0, c = 0; c < 400; l++) if (is_Mag(l)) {
if (c++ < 45 || (c > 240 && c <= 250) || c > 390)
Write(c <= 45 ? "{0,4} " : "{0,8:n0} ", l);
if (c < 45 && c % 15 == 0) WriteLine();
if (c == 240) WriteLine ("\n\n241st through 250th{0}", mn);
if (c == 390) WriteLine ("\n\n391st through 400th{0}", mn); } }
}
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17,992 19,972 20,209 20,261 20,861 22,061 22,201 22,801 22,885 24,407 391st through 400th magnanimous numbers: 486,685 488,489 515,116 533,176 551,558 559,952 595,592 595,598 600,881 602,081
C++
#include <iomanip>
#include <iostream>
bool is_prime(unsigned int n) {
if (n < 2)
return false;
if (n % 2 == 0)
return n == 2;
if (n % 3 == 0)
return n == 3;
for (unsigned int p = 5; p * p <= n; p += 4) {
if (n % p == 0)
return false;
p += 2;
if (n % p == 0)
return false;
}
return true;
}
bool is_magnanimous(unsigned int n) {
for (unsigned int p = 10; n >= p; p *= 10) {
if (!is_prime(n % p + n / p))
return false;
}
return true;
}
int main() {
unsigned int count = 0, n = 0;
std::cout << "First 45 magnanimous numbers:\n";
for (; count < 45; ++n) {
if (is_magnanimous(n)) {
if (count > 0)
std::cout << (count % 15 == 0 ? "\n" : ", ");
std::cout << std::setw(3) << n;
++count;
}
}
std::cout << "\n\n241st through 250th magnanimous numbers:\n";
for (unsigned int i = 0; count < 250; ++n) {
if (is_magnanimous(n)) {
if (count++ >= 240) {
if (i++ > 0)
std::cout << ", ";
std::cout << n;
}
}
}
std::cout << "\n\n391st through 400th magnanimous numbers:\n";
for (unsigned int i = 0; count < 400; ++n) {
if (is_magnanimous(n)) {
if (count++ >= 390) {
if (i++ > 0)
std::cout << ", ";
std::cout << n;
}
}
}
std::cout << '\n';
return 0;
}
- Output:
First 45 magnanimous numbers: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 16, 20 21, 23, 25, 29, 30, 32, 34, 38, 41, 43, 47, 49, 50, 52, 56 58, 61, 65, 67, 70, 74, 76, 83, 85, 89, 92, 94, 98, 101, 110 241st through 250th magnanimous numbers: 17992, 19972, 20209, 20261, 20861, 22061, 22201, 22801, 22885, 24407 391st through 400th magnanimous numbers: 486685, 488489, 515116, 533176, 551558, 559952, 595592, 595598, 600881, 602081
CLU
prime = proc (n: int) returns (bool)
if n < 2 then return(false) end
if n//2 = 0 then return(n=2) end
if n//3 = 0 then return(n=3) end
d: int := 5
while d*d <= n do
if n//d = 0 then return(false) end
d := d+2
if n//d = 0 then return(false) end
d := d+4
end
return(true)
end prime
sum_parts = iter (l: int) yields (int)
r: int := 0
s: int := 0
while l >= 10 do
r := r + (l // 10) * 10 ** s
s := s + 1
l := l / 10
yield(l + r)
end
end sum_parts
magnanimous = proc (n: int) returns (bool)
for s: int in sum_parts(n) do
if ~prime(s) then return(false) end
end
return(true)
end magnanimous
start_up = proc ()
po: stream := stream$primary_output()
n: int := 0
i: int := 0
c: int := 0
while i <= 400 do
while ~magnanimous(n) do n := n+1 end
i := i+1
if i=1 then stream$putl(po, "1-45:") c := 0
elseif i=241 then stream$putl(po, "\n241-250:") c := 0
elseif i=391 then stream$putl(po, "391-400:") c := 0
end
if i <= 45 cor (i > 240 cand i <= 250) cor (i > 390 cand i <= 400) then
stream$putright(po, int$unparse(n), 7)
c := c+1
if c = 10 then stream$putl(po, "") c := 0 end
end
n := n+1
end
end start_up
- Output:
1-45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241-250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391-400: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Cowgol
include "cowgol.coh";
sub prime(n: uint32): (r: uint32) is
r := 0;
if n <= 4 or n & 1 == 0 or n % 3 == 0 then
if n == 2 or n == 3 then
r := 1;
end if;
return;
end if;
var d: uint32 := 5;
while d*d <= n loop
if n % d == 0 then return; end if;
d := d+2;
if n % d == 0 then return; end if;
d := d+4;
end loop;
r := 1;
end sub;
sub magnanimous(n: uint32): (r: uint32) is
r := 1;
var left: uint32 := n;
var right: uint32 := 0;
var shift: uint32 := 1;
while left >= 10 loop
right := right + (left % 10) * shift;
shift := shift * 10;
left := left / 10;
if prime(left + right) == 0 then
r := 0;
break;
end if;
end loop;
end sub;
var i: uint16 := 0;
var n: uint32 := 0;
while i <= 400 loop
while magnanimous(n) == 0 loop n := n+1; end loop;
i := i + 1;
if i == 1 then print("1 - 45:\n");
elseif i == 241 then print("241 - 250:\n");
elseif i == 391 then print("390 - 400:\n");
end if;
if i<=45 or (i>240 and i<=250) or (i>390 and i<=400) then
print_i32(n);
if i % 5 == 0 then print_nl();
else print_char('\t');
end if;
end if;
n := n + 1;
end loop;
- Output:
1 - 45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241 - 250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 390 - 400: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Delphi
Highly modular code breaks the problem down into its basic components, which makes the problem easier to solve conceptually, easier to debug and enhance.
function IsPrime(N: int64): boolean;
{Fast, optimised prime test}
var I,Stop: int64;
begin
if (N = 2) or (N=3) then Result:=true
else if (n <= 1) or ((n mod 2) = 0) or ((n mod 3) = 0) then Result:= false
else
begin
I:=5;
Stop:=Trunc(sqrt(N+0.0));
Result:=False;
while I<=Stop do
begin
if ((N mod I) = 0) or ((N mod (I + 2)) = 0) then exit;
Inc(I,6);
end;
Result:=True;
end;
end;
function IsMagnanimous(N: Integer): boolean;
var S,S1,S2: string;
var I,I1,I2: integer;
begin
Result:=True;
if N<10 then exit;
Result:=False;
S:=IntToStr(N);
for I:=2 to Length(S) do
begin
S1:=Copy(S,1,I-1);
S2:=Copy(S,I,(Length(S)-I)+1);
I1:=StrToInt(S1);
I2:=StrToInt(S2);
if not IsPrime(I1+I2) then exit;
end;
Result:=True;
end;
procedure MagnanimousRange(Memo: TMemo; Start,Stop: integer);
var I,MagCnt,ItemCnt: integer;
var S: string;
begin
S:='';
MagCnt:=0;
ItemCnt:=0;
for I:=0 to High(Integer) do
if IsMagnanimous(I) then
begin
Inc(MagCnt);
if MagCnt>=Start then
begin
if MagCnt>Stop then break;
S:=S+Format('%12d',[I]);
Inc(ItemCnt);
if (ItemCnt mod 5)=0 then S:=S+#$0D#$0A;
end;
end;
Memo.Lines.Add(S);
end;
procedure MagnanimousNumbers(Memo: TMemo);
begin
Memo.Lines.Add('First 45 Magnanimous Numbers');
MagnanimousRange(Memo,0,45);
Memo.Lines.Add('Magnanimous Numbers 241 through 250');
MagnanimousRange(Memo,241,250);
Memo.Lines.Add('Magnanimous Numbers 391 through 400');
MagnanimousRange(Memo,391,400);
end;
- Output:
First 45 Magnanimous Numbers 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 Magnanimous Numbers 241 through 250 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 Magnanimous Numbers 391 through 400 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Draco
proc isprime(word n) bool:
word d;
bool prime;
if n<2 then false
elif n%2=0 then n=2
elif n%3=0 then n=3
else
prime := true;
d := 5;
while prime and d*d <= n do
if n%d=0 then prime := false fi;
d := d+2;
if n%d=0 then prime := false fi;
d := d+4
od;
prime
fi
corp
proc magnanimous(word n) bool:
word left, right, shift;
bool magn;
left := n;
right := 0;
shift := 1;
magn := true;
while magn and left >= 10 do
right := right + (left % 10) * shift;
shift := shift * 10;
left := left / 10;
magn := magn and isprime(left + right)
od;
magn
corp
proc main() void:
word n, i;
n := 0;
for i from 1 upto 250 do
while not magnanimous(n) do n := n+1 od;
if i=1 then writeln("1 - 45:") fi;
if i=241 then writeln("241 - 250:") fi;
if i<=45 or i>=241 then
write(n:7);
if i%5 = 0 then writeln() fi
fi;
n := n+1
od
corp
- Output:
1 - 45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241 - 250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
EasyLang
fastfunc isprim num .
if num < 2
return 0
.
i = 2
while i <= sqrt num
if num mod i = 0
return 0
.
i += 1
.
return 1
.
func ismagnan n .
if n < 10
return 1
.
p = 10
repeat
q = n div p
r = n mod p
if isprim (q + r) = 0
return 0
.
until q < 10
p *= 10
.
return 1
.
proc magnan start stop . .
write start & "-" & stop & ":"
while count < stop
if ismagnan i = 1
count += 1
if count >= start
write " " & i
.
.
i += 1
.
print ""
.
magnan 1 45
magnan 241 250
magnan 391 400
F#
The function
This task uses Extensible Prime Generator (F#)
// Generate Magnanimous numbers. Nigel Galloway: March 20th., 2020
let rec fN n g = match (g/n,g%n) with
(0,_) -> true
|(α,β) when isPrime (α+β) -> fN (n*10) g
|_ -> false
let Magnanimous = let Magnanimous = fN 10 in seq{yield! {0..9}; yield! Seq.initInfinite id |> Seq.skip 10 |> Seq.filter Magnanimous}
The Tasks
- First 45
Magnanimous |> Seq.take 45 |> Seq.iter (printf "%d "); printfn ""
- Output:
0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110
- Magnanimous[241] to Magnanimous[250]
Magnanimous |> Seq.skip 240 |> Seq.take 10 |> Seq.iter (printf "%d "); printfn "";;
- Output:
17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
- Magnanimous[391] to Magnanimous[400]
Magnanimous |> Seq.skip 390 |> Seq.take 10 |> Seq.iter (printf "%d "); printfn "";;
- Output:
486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Factor
USING: grouping io kernel lists lists.lazy math math.functions
math.primes math.ranges prettyprint sequences ;
: magnanimous? ( n -- ? )
dup 10 < [ drop t ] [
dup log10 >integer [1,b] [ 10^ /mod + prime? not ] with
find nip >boolean not
] if ;
: magnanimous ( n -- seq )
0 lfrom [ magnanimous? ] lfilter ltake list>array ;
: show ( seq from to -- ) rot subseq 15 group simple-table. nl ;
400 magnanimous
[ "First 45 magnanimous numbers" print 0 45 show ]
[ "241st through 250th magnanimous numbers" print 240 250 show ]
[ "391st through 400th magnanimous numbers" print 390 400 show ]
tri
- Output:
First 45 magnanimous numbers 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
FreeBASIC
#include "isprime.bas"
dim as uinteger magn(0 to 399), i, n=10, j
dim as string ns, lefty, righty
for i = 0 to 9
magn(i) = i 'all single digit ints are magnanimous by definition
next i
while i<400
n += 1
ns = str(n)
for j = 1 to len(ns)-1
lefty = left(ns, j)
righty = right(ns, len(ns)-j)
if not isprime( val(lefty) + val(righty) ) then continue while
next j
magn(i) = n
i+=1
wend
for i=0 to 44
print i+1,magn(i)
next i
for i=240 to 249
print i+1,magn(i)
next i
for i=390 to 399
print i+1,magn(i)
next i
- Output:
1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 11 11 12 12 13 14 14 16 15 20 16 21 17 23 18 25 19 29 20 30 21 32 22 34 23 38 24 41 25 43 26 47 27 49 28 50 29 52 30 56 31 58 32 61 33 65 34 67 35 70 36 74 37 76 38 83 39 85 40 89 41 92 42 94 43 98 44 101 45 110 241 17992 242 19972 243 20209 244 20261 245 20861 246 22061 247 22201 248 22801 249 22885 250 24407 391 486685 392 488489 393 515116 394 533176 395 551558 396 559952 397 595592 398 595598 399 600881 400 602081
Go
package main
import "fmt"
// OK for 'small' numbers.
func isPrime(n uint64) bool {
switch {
case n < 2:
return false
case n%2 == 0:
return n == 2
case n%3 == 0:
return n == 3
default:
d := uint64(5)
for d*d <= n {
if n%d == 0 {
return false
}
d += 2
if n%d == 0 {
return false
}
d += 4
}
return true
}
}
func ord(n int) string {
m := n % 100
if m >= 4 && m <= 20 {
return fmt.Sprintf("%dth", n)
}
m %= 10
suffix := "th"
if m < 4 {
switch m {
case 1:
suffix = "st"
case 2:
suffix = "nd"
case 3:
suffix = "rd"
}
}
return fmt.Sprintf("%d%s", n, suffix)
}
func isMagnanimous(n uint64) bool {
if n < 10 {
return true
}
for p := uint64(10); ; p *= 10 {
q := n / p
r := n % p
if !isPrime(q + r) {
return false
}
if q < 10 {
break
}
}
return true
}
func listMags(from, thru, digs, perLine int) {
if from < 2 {
fmt.Println("\nFirst", thru, "magnanimous numbers:")
} else {
fmt.Printf("\n%s through %s magnanimous numbers:\n", ord(from), ord(thru))
}
for i, c := uint64(0), 0; c < thru; i++ {
if isMagnanimous(i) {
c++
if c >= from {
fmt.Printf("%*d ", digs, i)
if c%perLine == 0 {
fmt.Println()
}
}
}
}
}
func main() {
listMags(1, 45, 3, 15)
listMags(241, 250, 1, 10)
listMags(391, 400, 1, 10)
}
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
GW-BASIC
100 DEFINT A-Z
110 CLS
120 LET L = N
130 LET R = 0
140 LET S = 1
150 IF L < 10 THEN GOTO 300
160 LET R = R+(L MOD 10)*S
170 LET L = L\10
180 LET S = S*10
190 LET P = R+L
200 IF P = 1 THEN GOTO 280 ELSE FOR D = 2 TO SQR(P)
210 IF P MOD D = 0 THEN GOTO 280
250 NEXT D
270 GOTO 150
280 LET N = N+1
290 GOTO 120
300 LET I = I+1
310 IF I = 1 THEN PRINT "1 - 45:" ELSE IF I = 241 THEN PRINT : PRINT "241 - 250:"
320 IF I <= 45 OR I > 240 THEN PRINT N,
330 LET N = N+1
340 IF I < 250 THEN GOTO 120
350 PRINT
360 END
Haskell
import Data.List.Split ( chunksOf )
import Data.List ( (!!) )
isPrime :: Int -> Bool
isPrime n
|n == 2 = True
|n == 1 = False
|otherwise = null $ filter (\i -> mod n i == 0 ) [2 .. root]
where
root :: Int
root = floor $ sqrt $ fromIntegral n
isMagnanimous :: Int -> Bool
isMagnanimous n = all isPrime $ map (\p -> fst p + snd p ) numberPairs
where
str:: String
str = show n
splitStrings :: [(String , String)]
splitStrings = map (\i -> splitAt i str) [1 .. length str - 1]
numberPairs :: [(Int , Int)]
numberPairs = map (\p -> ( read $ fst p , read $ snd p )) splitStrings
printInWidth :: Int -> Int -> String
printInWidth number width = replicate ( width - l ) ' ' ++ str
where
str :: String
str = show number
l :: Int
l = length str
solution :: [Int]
solution = take 400 $ filter isMagnanimous [0 , 1 ..]
main :: IO ( )
main = do
let numbers = solution
numberlines = chunksOf 10 $ take 45 numbers
putStrLn "First 45 magnanimous numbers:"
mapM_ (\li -> putStrLn (foldl1 ( ++ ) $ map (\n -> printInWidth n 6 )
li )) numberlines
putStrLn "241'st to 250th magnanimous numbers:"
putStr $ show ( numbers !! 240 )
putStrLn ( foldl1 ( ++ ) $ map(\n -> printInWidth n 8 ) $ take 9 $
drop 241 numbers )
putStrLn "391'st to 400th magnanimous numbers:"
putStr $ show ( numbers !! 390 )
putStrLn ( foldl1 ( ++ ) $ map(\n -> printInWidth n 8 ) $ drop 391 numbers)
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241'st to 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391'st to 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Java
import java.util.ArrayList;
import java.util.List;
public class MagnanimousNumbers {
public static void main(String[] args) {
runTask("Find and display the first 45 magnanimous numbers.", 1, 45);
runTask("241st through 250th magnanimous numbers.", 241, 250);
runTask("391st through 400th magnanimous numbers.", 391, 400);
}
private static void runTask(String message, int startN, int endN) {
int count = 0;
List<Integer> nums = new ArrayList<>();
for ( int n = 0 ; count < endN ; n++ ) {
if ( isMagnanimous(n) ) {
nums.add(n);
count++;
}
}
System.out.printf("%s%n", message);
System.out.printf("%s%n%n", nums.subList(startN-1, endN));
}
private static boolean isMagnanimous(long n) {
if ( n >= 0 && n <= 9 ) {
return true;
}
long q = 11;
for ( long div = 10 ; q >= 10 ; div *= 10 ) {
q = n / div;
long r = n % div;
if ( ! isPrime(q+r) ) {
return false;
}
}
return true;
}
private static final int MAX = 100_000;
private static final boolean[] primes = new boolean[MAX];
private static boolean SIEVE_COMPLETE = false;
private static final boolean isPrimeTrivial(long test) {
if ( ! SIEVE_COMPLETE ) {
sieve();
SIEVE_COMPLETE = true;
}
return primes[(int) test];
}
private static final void sieve() {
// primes
for ( int i = 2 ; i < MAX ; i++ ) {
primes[i] = true;
}
for ( int i = 2 ; i < MAX ; i++ ) {
if ( primes[i] ) {
for ( int j = 2*i ; j < MAX ; j += i ) {
primes[j] = false;
}
}
}
}
// See http://primes.utm.edu/glossary/page.php?sort=StrongPRP
public static final boolean isPrime(long testValue) {
if ( testValue == 2 ) return true;
if ( testValue % 2 == 0 ) return false;
if ( testValue <= MAX ) return isPrimeTrivial(testValue);
long d = testValue-1;
int s = 0;
while ( d % 2 == 0 ) {
s += 1;
d /= 2;
}
if ( testValue < 1373565L ) {
if ( ! aSrp(2, s, d, testValue) ) {
return false;
}
if ( ! aSrp(3, s, d, testValue) ) {
return false;
}
return true;
}
if ( testValue < 4759123141L ) {
if ( ! aSrp(2, s, d, testValue) ) {
return false;
}
if ( ! aSrp(7, s, d, testValue) ) {
return false;
}
if ( ! aSrp(61, s, d, testValue) ) {
return false;
}
return true;
}
if ( testValue < 10000000000000000L ) {
if ( ! aSrp(3, s, d, testValue) ) {
return false;
}
if ( ! aSrp(24251, s, d, testValue) ) {
return false;
}
return true;
}
// Try 5 "random" primes
if ( ! aSrp(37, s, d, testValue) ) {
return false;
}
if ( ! aSrp(47, s, d, testValue) ) {
return false;
}
if ( ! aSrp(61, s, d, testValue) ) {
return false;
}
if ( ! aSrp(73, s, d, testValue) ) {
return false;
}
if ( ! aSrp(83, s, d, testValue) ) {
return false;
}
//throw new RuntimeException("ERROR isPrime: Value too large = "+testValue);
return true;
}
private static final boolean aSrp(int a, int s, long d, long n) {
long modPow = modPow(a, d, n);
//System.out.println("a = "+a+", s = "+s+", d = "+d+", n = "+n+", modpow = "+modPow);
if ( modPow == 1 ) {
return true;
}
int twoExpR = 1;
for ( int r = 0 ; r < s ; r++ ) {
if ( modPow(modPow, twoExpR, n) == n-1 ) {
return true;
}
twoExpR *= 2;
}
return false;
}
private static final long SQRT = (long) Math.sqrt(Long.MAX_VALUE);
public static final long modPow(long base, long exponent, long modulus) {
long result = 1;
while ( exponent > 0 ) {
if ( exponent % 2 == 1 ) {
if ( result > SQRT || base > SQRT ) {
result = multiply(result, base, modulus);
}
else {
result = (result * base) % modulus;
}
}
exponent >>= 1;
if ( base > SQRT ) {
base = multiply(base, base, modulus);
}
else {
base = (base * base) % modulus;
}
}
return result;
}
// Result is a*b % mod, without overflow.
public static final long multiply(long a, long b, long modulus) {
long x = 0;
long y = a % modulus;
long t;
while ( b > 0 ) {
if ( b % 2 == 1 ) {
t = x + y;
x = (t > modulus ? t-modulus : t);
}
t = y << 1;
y = (t > modulus ? t-modulus : t);
b >>= 1;
}
return x % modulus;
}
}
- Output:
Find and display the first 45 magnanimous numbers. [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 16, 20, 21, 23, 25, 29, 30, 32, 34, 38, 41, 43, 47, 49, 50, 52, 56, 58, 61, 65, 67, 70, 74, 76, 83, 85, 89, 92, 94, 98, 101, 110] 241st through 250th magnanimous numbers. [17992, 19972, 20209, 20261, 20861, 22061, 22201, 22801, 22885, 24407] 391st through 400th magnanimous numbers. [486685, 488489, 515116, 533176, 551558, 559952, 595592, 595598, 600881, 602081]
J
write_sum_expressions=: ([: }: ]\) ,"1 '+' ,"1 ([: }. ]\.) NB. combine prefixes with suffixes interstitial_sums=: ".@write_sum_expressions@": primeQ=: 1&p: magnanimousQ=: 1:`([: *./ [: primeQ interstitial_sums)@.(>&9) A=: (#~ magnanimousQ&>) i.1000000 NB. filter 1000000 integers #A 434 strange=: ({. + [: i. -~/)@:(_1 0&+) NB. produce index ranges for output I=: _2 <@strange\ 1 45 241 250 391 400 I (":@:{~ >)~"0 _ A 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
jq
Works with gojq, the Go implementation of jq
For a suitable definition of `is_prime`, see Erdős-primes#jq.
Preliminaries
# To take advantage of gojq's arbitrary-precision integer arithmetic:
def power($b): . as $in | reduce range(0;$b) as $i (1; . * $in);
def divrem($x; $y):
[$x/$y|floor, $x % $y];
The Task
def ismagnanimous:
. as $n
| if $n < 10 then true
else first(range( 1; tostring|length) as $i
| divrem($n; (10|power($i))) as [$q, $r]
| if ($q + $r) | is_prime == false then 0 else empty end)
// true
| . == true
end;
# An unbounded stream ...
def magnanimous:
range(0; infinite)
| select(ismagnanimous);
[limit(400; magnanimous)]
| "First 45 magnanimous numbers:", .[:45],
"\n241st through 250th magnanimous numbers:", .[241:251],
"\n391st through 400th magnanimous numbers:", .[391:]
- Output:
First 45 magnanimous numbers: [0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110] 241st through 250th magnanimous numbers: [19972,20209,20261,20861,22061,22201,22801,22885,24407,26201] 391st through 400th magnanimous numbers: [488489,515116,533176,551558,559952,595592,595598,600881,602081]
Julia
using Primes
function ismagnanimous(n)
n < 10 && return true
for i in 1:ndigits(n)-1
q, r = divrem(n, 10^i)
!isprime(q + r) && return false
end
return true
end
function magnanimous(N)
mvec, i = Int[], 0
while length(mvec) < N
if ismagnanimous(i)
push!(mvec, i)
end
i += 1
end
return mvec
end
const mag400 = magnanimous(400)
println("First 45 magnanimous numbers:\n", mag400[1:24], "\n", mag400[25:45])
println("\n241st through 250th magnanimous numbers:\n", mag400[241:250])
println("\n391st through 400th magnanimous numbers:\n", mag400[391:400])
- Output:
First 45 magnanimous numbers: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 14, 16, 20, 21, 23, 25, 29, 30, 32, 34, 38, 41] [43, 47, 49, 50, 52, 56, 58, 61, 65, 67, 70, 74, 76, 83, 85, 89, 92, 94, 98, 101, 110] 241st through 250th magnanimous numbers: [17992, 19972, 20209, 20261, 20861, 22061, 22201, 22801, 22885, 24407] 391st through 400th magnanimous numbers: [486685, 488489, 515116, 533176, 551558, 559952, 595592, 595598, 600881, 602081]
Lambdatalk
{def isprime
{def isprime.loop
{lambda {:n :m :i}
{if {> :i :m}
then true
else {if {= {% :n :i} 0}
then false
else {isprime.loop :n :m {+ :i 2}}
}}}}
{lambda {:n}
{if {= :n 1}
then false
else {if {or {= :n 2} {= :n 3} {= :n 5} {= :n 7}}
then true
else {if {or {< : n 2} {= {% :n 2} 0}}
then false
else {isprime.loop :n {sqrt :n} 3}
}}}}}
-> isprime
{def magnanimous
{def magnanimous.loop
{lambda {:n :p :r}
{if {>= :n 10}
then {let { {:n {floor {/ :n 10}}}
{:p :p}
{:r {+ :r {* {% :n 10} :p}}}
} {if {not {isprime {+ :n :r}}}
then false
else {magnanimous.loop :n {* :p 10} :r} }
}
else true }}}
{lambda {:n}
{magnanimous.loop :n 1 0} }}
-> magnanimous
{def mags
{lambda {:n}
{S.last
{S.map {{lambda {:a :i}
{if {magnanimous :i} then {A.addlast! :i :a} else}}
{A.new}}
{S.serie 0 :n}}}}}
-> mags
{A.slice 0 45 {mags 110}}
-> [0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110]
{A.slice 240 250 {mags 30000}}
->
[17992,19972,20209,20261,20861,22061,22201,22801,22885,24407]
{A.slice 390 400 {mags 700000}}
->
[486685,488489,515116,533176,551558,559952,595592,595598,600881,602081]
time of CPU in milliseconds
iPadPro MacBookAir MacBookPro
[0,45] 30 15 12
[240,250] 2430 5770 3650
[390,400] 117390 284230 213210
Mathematica/Wolfram Language
Clear[MagnanimousNumberQ]
MagnanimousNumberQ[Alternatives @@ Range[0, 9]] = True;
MagnanimousNumberQ[n_Integer] := AllTrue[Range[IntegerLength[n] - 1], PrimeQ[Total[FromDigits /@ TakeDrop[IntegerDigits[n], #]]] &]
sel = Select[Range[0, 1000000], MagnanimousNumberQ];
sel[[;; 45]]
sel[[241 ;; 250]]
sel[[391 ;; 400]]
- Output:
{0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110} {17992,19972,20209,20261,20861,22061,22201,22801,22885,24407} {486685,488489,515116,533176,551558,559952,595592,595598,600881,602081}
Modula-2
MODULE MagnanimousNumbers;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
VAR n, i: CARDINAL;
PROCEDURE prime(n: CARDINAL): BOOLEAN;
VAR d: CARDINAL;
BEGIN
IF n<2 THEN RETURN FALSE END;
IF n MOD 2 = 0 THEN RETURN n = 2 END;
IF n MOD 3 = 0 THEN RETURN n = 3 END;
d := 5;
WHILE d*d <= n DO
IF n MOD d = 0 THEN RETURN FALSE END;
INC(d, 2);
IF n MOD d = 0 THEN RETURN FALSE END;
INC(d, 4)
END;
RETURN TRUE
END prime;
PROCEDURE magnanimous(n: CARDINAL): BOOLEAN;
VAR left, right, shift: CARDINAL;
BEGIN
left := n;
right := 0;
shift := 1;
WHILE left >= 10 DO
INC(right, (left MOD 10) * shift);
shift := shift * 10;
left := left DIV 10;
IF NOT prime(left + right) THEN RETURN FALSE END
END;
RETURN TRUE
END magnanimous;
BEGIN
n := 0;
FOR i := 1 TO 250 DO
WHILE NOT magnanimous(n) DO INC(n) END;
IF i=1 THEN WriteString("1 - 45:"); WriteLn
ELSIF i=240 THEN WriteString("241 - 250:"); WriteLn
END;
IF (i <= 45) OR (i > 240) THEN
WriteCard(n, 7);
IF i MOD 5 = 0 THEN WriteLn END
END;
INC(n)
END
END MagnanimousNumbers.
- Output:
1 - 45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241 - 250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
Nim
func isPrime(n: Natural): bool =
if n < 2: return
if n mod 2 == 0: return n == 2
if n mod 3 == 0: return n == 3
var d = 5
while d * d <= n:
if n mod d == 0: return false
inc d, 2
if n mod d == 0: return false
inc d, 4
return true
func isMagnanimous(n: Natural): bool =
var p = 10
while true:
let a = n div p
let b = n mod p
if a == 0: break
if not isPrime(a + b): return false
p *= 10
return true
iterator magnanimous(): (int, int) =
var n, count = 0
while true:
if n.isMagnanimous:
inc count
yield (count, n)
inc n
for (i, n) in magnanimous():
if i in 1..45:
if i == 1: stdout.write "First 45 magnanimous numbers:\n "
stdout.write n, if i == 45: '\n' else: ' '
elif i in 241..250:
if i == 241: stdout.write "\n241st through 250th magnanimous numbers:\n "
stdout.write n, if i == 250: "\n" else: " "
elif i in 391..400:
if i == 391: stdout.write "\n391st through 400th magnanimous numbers:\n "
stdout.write n, if i == 400: "\n" else: " "
elif i > 400:
break
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Pascal
Version nearly like on Talk.
Eliminating all numbers, which would sum to 5 in the last digit.
On TIO.RUN found all til 569 84448000009 0.715 s
program Magnanimous;
//Magnanimous Numbers
//algorithm find only numbers where all digits are even except the last
//or where all digits are odd except the last
//so 1,11,20,101,1001 will not be found
//starting at 100001 "1>"+x"0"+"1" is not prime because of 1001 not prime
{$IFDEF FPC}
{$MODE DELPHI}
{$Optimization ON}
{$CODEALIGN proc=16}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
{$DEFINE USE_GMP}
uses
//strUtils, // commatize Numb2USA
{$IFDEF USE_GMP}gmp,{$ENDIF}
SysUtils;
const
MaxLimit = 10*1000*1000 +10;
MAXHIGHIDX = 10;
type
tprimes = array of byte;
tBaseType = Byte;
tpBaseType = pByte;
tBase =array[0..15] of tBaseType;
tNumType = NativeUint;
tSplitNum = array[0..15] of tNumType;
tMagList = array[0..1023] of Uint64;
var
{$ALIGN 32}
MagList : tMagList;
dgtBase5, // count in Base 5
dgtORMask, //Mark of used digit (or (1 shl Digit ))
dgtEvenBase10,
dgtOddBase10: tbase;
primes : tprimes;
{$IFDEF USE_GMP} z : mpz_t;gmp_count :NativeUint;{$ENDIF}
pPrimes0 : pByte;
T0: int64;
HighIdx,num,MagIdx,count,cnt: NativeUint;
procedure InitPrimes;
const
smallprimes :array[0..5] of byte = (2,3,5,7,11,13);
var
pPrimes : pByte;
p,i,j,l : NativeUint;
begin
l := 1;
for j := 0 to High(smallprimes) do
l*= smallprimes[j];
//scale primelimit to be multiple of l
i :=((MaxLimit-1) DIV l+1)*l+1;//+1 should suffice
setlength(primes,i);
pPrimes := @primes[0];
for j := 0 to High(smallprimes) do
begin
p := smallprimes[j];
i := p;
if j <> 0 then
p +=p;
while i <= l do
begin
pPrimes[i] := 1;
inc(i,p)
end;
end;
//turn the prime wheel
for p := length(primes) div l -1 downto 1 do
move(pPrimes[1],pPrimes[p*l+1],l);
l := High(primes);
//reinsert smallprimes
for j := 0 to High(smallprimes) do
pPrimes[smallprimes[j]] := 0;
pPrimes[1]:=1;
pPrimes[0]:=1;
p := smallprimes[High(smallprimes)];
repeat
repeat
inc(p)
until pPrimes[p] = 0;
j := l div p;
while (pPrimes[j]<> 0) AND (j>=p) do
dec(j);
if j<p then
BREAK;
//delta going downwards no factor 2,3 :-2 -4 -2 -4
i := (j+1) mod 6;
if i = 0 then
i :=4;
repeat
while (pPrimes[j]<> 0) AND (j>=p) do
begin
dec(j,i);
i := 6-i;
end;
if j<p then
BREAK;
pPrimes[j*p] := 1;
dec(j,i);
i := 6-i;
until j<p;
until false;
pPrimes0 := pPrimes;
end;
procedure InsertSort(pMag:pUint64; Left, Right : NativeInt );
var
I, J: NativeInt;
Pivot : Uint64;
begin
for i:= 1 + Left to Right do
begin
Pivot:= pMag[i];
j:= i - 1;
while (j >= Left) and (pMag[j] > Pivot) do
begin
pMag[j+1]:=pMag[j];
Dec(j);
end;
pMag[j+1]:= pivot;
end;
end;
procedure OutBase5;
var
pb: tpBaseType;
i : NativeUint;
begin
write(count :10);
pb:= @dgtBase5[0];
for i := HighIdx downto 0 do
write(pb[i]:3);
write(' : ' );
pb:= @dgtORMask[0];
for i := HighIdx downto 0 do
write(pb[i]:3);
end;
function Base10toNum(var dgtBase10: tBase):NativeUint;
var
i : NativeInt;
begin
Result := 0;
for i := HighIdx downto 0 do
Result := Result * 10 + dgtBase10[i];
end;
procedure OutSol(cnt:Uint64);
begin
writeln(MagIdx:4,cnt:13,Base10toNum(dgtOddBase10):20,
(Gettickcount64-T0) / 1000: 10: 3, ' s');
end;
procedure CnvEvenBase10(lastIdx:NativeInt);
var
pdgt : tpBaseType;
idx: nativeint;
begin
pDgt := @dgtEvenBase10[0];
for idx := lastIdx downto 1 do
pDgt[idx] := 2 * dgtBase5[idx];
pDgt[0] := 2 * dgtBase5[0]+1;
end;
procedure CnvOddBase10(lastIdx:NativeInt);
var
pdgt : tpBaseType;
idx: nativeint;
begin
pDgt := @dgtOddBase10[0];
//make all odd
for idx := lastIdx downto 1 do
pDgt[idx] := 2 * dgtBase5[idx] + 1;
//but the lowest even
pDgt[0] := 2 * dgtBase5[0];
end;
function IncDgtBase5:NativeUint;
// increment n base 5 until resulting sum of split number
// can't end in 5
var
pb: tpBaseType;
n,i: nativeint;
begin
result := 0;
repeat
repeat
//increment Base5
pb:= @dgtBase5[0];
i := 0;
repeat
n := pb[i] + 1;
if n < 5 then
begin
pb[i] := n;
break;
end;
pb[i] := 0;
Inc(i);
until False;
if HighIdx < i then
begin
HighIdx := i;
pb[i] := 0;
end;
if result < i then
result := i;
n := dgtORMask[i+1];
while i >= 0 do
begin
n := n OR (1 shl pb[i]);
dgtORMask[i]:= n;
if n = 31 then
break;
dec(i);
end;
if HighIdx<4 then
break;
if (n <> 31) OR (i=0) then
break;
//Now there are all digits are used at digit i ( not in last pos)
//this will always lead to a number ending in 5-> not prime
//so going on with a number that will change the used below i to highest digit
//to create an overflow of the next number, to change the digits
dec(i);
repeat
pb[i] := 4;
dgtORMask[i]:= 31;
dec(i);
until i < 0;
until false;
if HighIdx<4 then
break;
n := dgtORMask[1];
//ending in 5. base10(base5) for odd 1+4(0,2),3+2(1,1),5+0(2,0)
i := pb[0];
if i <= 2 then
begin
i := 1 shl (2-i);
end
else
Begin
//ending in 5 7+8(3,4),9+6(4,3)
i := 1 shl (4-i);
n := n shr 3;
end;
if (i AND n) = 0 then
BREAK;
until false;
end;
procedure CheckMagn(var dgtBase10: tBase);
//split number into sum of all "partitions" of digits
//check if sum is always prime
//1234 -> 1+234,12+34 ;123+4
var
LowSplitNum : tSplitNum;
i,fac,n: NativeInt;
isMagn : boolean;
Begin
n := 0;
fac := 1;
For i := 0 to HighIdx-1 do
begin
n := fac*dgtBase10[i]+n;
fac *=10;
LowSplitNum[HighIdx-1-i] := n;
end;
n := 0;
fac := HighIdx;
isMagn := true;
For i := 0 to fac-1 do
begin
//n = HighSplitNum[i]
n := n*10+dgtBase10[fac-i];
LowSplitNum[i] += n;
if LowSplitNum[i]<=MAXLIMIT then
begin
isMagn := isMagn AND (pPrimes0[LowSplitNum[i]] = 0);
if NOT(isMagn) then
EXIT;
end;
end;
{$IFDEF USE_GMP}
For i := 0 to fac-1 do
begin
n := LowSplitNum[i];
if n >MAXLIMIT then
Begin
// IF NOT((n mod 30) in [1,7,11,13,17,19,23,29]) then EXIT;
mpz_set_ui(z,n);
gmp_count +=1;
isMagn := isMagn AND (mpz_probab_prime_p(z,1) >0);
if NOT(isMagn) then
EXIT;
end;
end;
{$ENDIF}
//insert magnanimous numbers
num := Base10toNum(dgtBase10);
MagList[MagIdx] := num;
inc(MagIdx);
end;
function Run(StartDgtCount:byte):Uint64;
var
lastIdx: NativeInt;
begin
result := 0;
HighIdx := StartDgtCount;// 7 start with 7 digits
LastIdx := HighIdx;
repeat
if dgtBase5[HighIdx] <> 0 then
Begin
CnvEvenBase10(LastIdx);
CheckMagn(dgtEvenBase10);
end;
CnvOddBase10(LastIdx);
CheckMagn(dgtOddBase10);
inc(result);
//output for still running every 16.22 Mio
IF result AND (1 shl 22-1) = 0 then
OutSol(result);
lastIdx := IncDgtBase5;
until HighIdx > MAXHIGHIDX;
end;
BEGIN
{$IFDEF USE_GMP}mpz_init_set_ui(z,0);{$ENDIF}
T0 := Gettickcount64;
InitPrimes;
T0 -= Gettickcount64;
writeln('getting primes ',-T0 / 1000: 0: 3, ' s');
T0 := Gettickcount64;
fillchar(dgtBase5,SizeOf(dgtBase5),#0);
fillchar(dgtEvenBase10,SizeOf(dgtEvenBase10),#0);
fillchar(dgtOddBase10,SizeOf(dgtOddBase10),#0);
//Magnanimous Numbers that can not be found by this algorithm
MagIdx := 0;
MagList[MagIdx] := 1;inc(MagIdx);
MagList[MagIdx] := 11;inc(MagIdx);
MagList[MagIdx] := 20;inc(MagIdx);
MagList[MagIdx] := 101;inc(MagIdx);
MagList[MagIdx] := 1001;inc(MagIdx);
//cant be checked easy for ending in 5
MagList[MagIdx] := 40001;inc(MagIdx);
{$IFDEF USE_GMP} mpz_init_set_ui(z,0);{$ENDIF}
count := Run(0);
writeln;
CnvOddBase10(highIdx);
writeln(MagIdx:5,count:12,Base10toNum(dgtOddBase10):18,
(Gettickcount64-T0) / 1000: 10: 3, ' s');
InsertSort(@MagList[0],0,MagIdx-1);
{$IFDEF USE_GMP} mpz_clear(z);writeln('Count of gmp tests ',gmp_count);{$ENDIF}
For cnt := 0 to MagIdx-1 do
writeln(cnt+1:3,' ',MagList[cnt]);
{$IFDEF WINDOWS}
readln;
{$ENDIF}
end.
- Output:
TIO.RUN Real time: 0.924 s User time: 0.864 s Sys. time: 0.053 s CPU share: 99.29 % getting primes 0.023 s 567 4194304 53771777176 0.400 s 569 6990860 111111111110 0.715 s Count of gmp tests 45755 1 0 2 1 3 2 4 3 5 4 6 5 7 6 8 7 9 8 10 9 11 11 12 12 13 14 14 16 15 20 16 21 17 23 18 25 19 29 20 30 21 32 22 34 23 38 24 41 25 43 26 47 27 49 28 50 29 52 30 56 31 58 32 61 33 65 34 67 35 70 36 74 37 76 38 83 39 85 40 89 41 92 42 94 43 98 44 101 45 110 46 112 47 116 48 118 49 130 50 136 51 152 52 158 53 170 54 172 55 203 56 209 57 221 58 227 59 229 60 245 61 265 62 281 63 310 64 316 65 334 66 338 67 356 68 358 69 370 70 376 71 394 72 398 73 401 74 403 75 407 76 425 77 443 78 449 79 467 80 485 81 512 82 518 83 536 84 538 85 554 86 556 87 574 88 592 89 598 90 601 91 607 92 625 93 647 94 661 95 665 96 667 97 683 98 710 99 712 100 730 101 736 102 754 103 772 104 776 105 790 106 794 107 803 108 809 109 821 110 845 111 863 112 881 113 889 114 934 115 938 116 952 117 958 118 970 119 974 120 992 121 994 122 998 123 1001 124 1112 125 1130 126 1198 127 1310 128 1316 129 1598 130 1756 131 1772 132 1910 133 1918 134 1952 135 1970 136 1990 137 2209 138 2221 139 2225 140 2249 141 2261 142 2267 143 2281 144 2429 145 2447 146 2465 147 2489 148 2645 149 2681 150 2885 151 3110 152 3170 153 3310 154 3334 155 3370 156 3398 157 3518 158 3554 159 3730 160 3736 161 3794 162 3934 163 3974 164 4001 165 4027 166 4063 167 4229 168 4247 169 4265 170 4267 171 4427 172 4445 173 4463 174 4643 175 4825 176 4883 177 5158 178 5176 179 5374 180 5516 181 5552 182 5558 183 5594 184 5752 185 5972 186 5992 187 6001 188 6007 189 6067 190 6265 191 6403 192 6425 193 6443 194 6485 195 6601 196 6685 197 6803 198 6821 199 7330 200 7376 201 7390 202 7394 203 7534 204 7556 205 7592 206 7712 207 7934 208 7970 209 8009 210 8029 211 8221 212 8225 213 8801 214 8821 215 9118 216 9172 217 9190 218 9338 219 9370 220 9374 221 9512 222 9598 223 9710 224 9734 225 9752 226 9910 227 11116 228 11152 229 11170 230 11558 231 11930 232 13118 233 13136 234 13556 235 15572 236 15736 237 15938 238 15952 239 17716 240 17752 241 17992 242 19972 243 20209 244 20261 245 20861 246 22061 247 22201 248 22801 249 22885 250 24407 251 26201 252 26285 253 26881 254 28285 255 28429 256 31370 257 31756 258 33118 259 33538 260 33554 261 35116 262 35776 263 37190 264 37556 265 37790 266 37930 267 39158 268 39394 269 40001 270 40043 271 40049 272 40067 273 40427 274 40463 275 40483 276 42209 277 42265 278 44009 279 44443 280 44447 281 46445 282 48089 283 48265 284 51112 285 53176 286 53756 287 53918 288 55516 289 55552 290 55558 291 55576 292 55774 293 57116 294 57754 295 60007 296 60047 297 60403 298 60443 299 60667 300 62021 301 62665 302 64645 303 66667 304 66685 305 68003 306 68683 307 71536 308 71572 309 71716 310 71752 311 73156 312 75374 313 75556 314 77152 315 77554 316 79330 317 79370 318 80009 319 80029 320 80801 321 80849 322 82265 323 82285 324 82825 325 82829 326 84265 327 86081 328 86221 329 88061 330 88229 331 88265 332 88621 333 91792 334 93338 335 93958 336 93994 337 99712 338 99998 339 111112 340 111118 341 111170 342 111310 343 113170 344 115136 345 115198 346 115772 347 117116 348 119792 349 135158 350 139138 351 151156 352 151592 353 159118 354 177556 355 193910 356 199190 357 200209 358 200809 359 220021 360 220661 361 222245 362 224027 363 226447 364 226681 365 228601 366 282809 367 282881 368 282889 369 311156 370 319910 371 331118 372 333770 373 333994 374 335156 375 339370 376 351938 377 359794 378 371116 379 373130 380 393554 381 399710 382 400049 383 404249 384 408049 385 408889 386 424607 387 440843 388 464447 389 484063 390 484445 391 486685 392 488489 393 515116 394 533176 395 551558 396 559952 397 595592 398 595598 399 600881 400 602081 401 626261 402 628601 403 644485 404 684425 405 686285 406 711512 407 719710 408 753316 409 755156 410 773554 411 777712 412 777776 413 799394 414 799712 415 800483 416 802061 417 802081 418 804863 419 806021 420 806483 421 806681 422 822265 423 864883 424 888485 425 888601 426 888643 427 911390 428 911518 429 915752 430 931130 431 975772 432 979592 433 991118 434 999994 435 1115756 436 1137770 437 1191518 438 1197370 439 1353136 440 1379930 441 1533736 442 1593538 443 1711576 444 1791110 445 1795912 446 1915972 447 1951958 448 2000221 449 2008829 450 2442485 451 2604067 452 2606647 453 2664425 454 2666021 455 2828809 456 2862445 457 3155116 458 3171710 459 3193198 460 3195338 461 3195398 462 3315358 463 3373336 464 3573716 465 3737534 466 3751576 467 3939118 468 4000483 469 4408603 470 4468865 471 4488245 472 4644407 473 5115736 474 5357776 475 5551376 476 5579774 477 5731136 478 5759594 479 5959774 480 6462667 481 6600227 482 6600443 483 6608081 484 6640063 485 6640643 486 6824665 487 6864485 488 6866683 489 7113710 490 7133110 491 7139390 492 7153336 493 7159172 494 7311170 495 7351376 496 7719370 497 7959934 498 7979534 499 8044009 500 8068201 501 8608081 502 8844449 503 9171170 504 9777910 505 9959374 506 11771992 507 13913170 508 15177112 509 17115116 510 19337170 511 19713130 512 20266681 513 22086821 514 22600601 515 22862885 516 26428645 517 28862465 518 33939518 519 37959994 520 40866083 521 44866043 522 48606043 523 48804809 524 51137776 525 51513118 526 53151376 527 53775934 528 59593574 529 60402247 530 60860603 531 62202281 532 64622665 533 66864625 534 66886483 535 71553536 536 77917592 537 82486825 538 86842265 539 91959398 540 95559998 541 117711170 542 222866845 543 228440489 544 244064027 545 280422829 546 331111958 547 400044049 548 460040803 549 511151552 550 593559374 551 606202627 552 608844043 553 622622801 554 622888465 555 773719910 556 844460063 557 882428665 558 995955112 559 1777137770 560 2240064227 561 2444402809 562 5753779594 563 6464886245 564 9151995592 565 22226226625 566 31993717930 567 39393115598 568 46884486265 569 84448000009
Perl
use strict;
use warnings;
use feature 'say';
use ntheory 'is_prime';
sub magnanimous {
my($n) = @_;
my $last;
for my $c (1 .. length($n) - 1) {
++$last and last unless is_prime substr($n,0,$c) + substr($n,$c)
}
not $last;
}
my @M;
for ( my $i = 0, my $count = 0; $count < 400; $i++ ) {
++$count and push @M, $i if magnanimous($i);
}
say "First 45 magnanimous numbers\n".
(sprintf "@{['%4d' x 45]}", @M[0..45-1]) =~ s/(.{60})/$1\n/gr;
say "241st through 250th magnanimous numbers\n" .
join ' ', @M[240..249];
say "\n391st through 400th magnanimous numbers\n".
join ' ', @M[390..399];
- Output:
First 45 magnanimous numbers 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Phix
with javascript_semantics function magnanimous(integer n) integer p = 1, r = 0 while n>=10 do r += remainder(n,10)*p n = floor(n/10) if not is_prime(n+r) then return false end if p *= 10 end while return true end function sequence mag = {} integer n = 0 while length(mag)<400 do if magnanimous(n) then mag &= n end if n += 1 end while puts(1,"First 45 magnanimous numbers: ") pp(mag[1..45],{pp_Indent,30,pp_IntCh,false,pp_Maxlen,100}) printf(1,"magnanimous numbers[241..250]: %v\n", {mag[241..250]}) printf(1,"magnanimous numbers[391..400]: %v\n", {mag[391..400]})
- Output:
First 45 magnanimous numbers: {0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43, 47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110} magnanimous numbers[241..250]: {17992,19972,20209,20261,20861,22061,22201,22801,22885,24407} magnanimous numbers[391..400]: {486685,488489,515116,533176,551558,559952,595592,595598,600881,602081}
PicoLisp
(de **Mod (X Y N)
(let M 1
(loop
(when (bit? 1 Y)
(setq M (% (* M X) N)) )
(T (=0 (setq Y (>> 1 Y)))
M )
(setq X (% (* X X) N)) ) ) )
(de isprime (N)
(cache '(NIL) N
(if (== N 2)
T
(and
(> N 1)
(bit? 1 N)
(let (Q (dec N) N1 (dec N) K 0 X)
(until (bit? 1 Q)
(setq
Q (>> 1 Q)
K (inc K) ) )
(catch 'composite
(do 16
(loop
(setq X
(**Mod
(rand 2 (min (dec N) 1000000000000))
Q
N ) )
(T (or (=1 X) (= X N1)))
(T
(do K
(setq X (**Mod X 2 N))
(when (=1 X) (throw 'composite))
(T (= X N1) T) ) )
(throw 'composite) ) )
(throw 'composite T) ) ) ) ) ) )
(de numbers (N)
(let (P 10 Q N)
(make
(until (> 10 Q)
(link
(+
(setq Q (/ N P))
(% N P) ) )
(setq P (* P 10)) ) ) ) )
(de ismagna (N)
(or
(> 10 N)
(fully isprime (numbers N)) ) )
(let (C 0 N 0 Lst)
(setq Lst
(make
(until (== C 401)
(when (ismagna N)
(link N)
(inc 'C) )
(inc 'N) ) ) )
(println (head 45 Lst))
(println (head 10 (nth Lst 241)))
(println (head 10 (nth Lst 391))) )
- Output:
(0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110) (17992 19972 20209 20261 20861 22061 22201 22801 22885 24407) (486685 488489 515116 533176 551558 559952 595592 595598 600881 602081)
PL/M
This sample can be compiled with the original 8080 PL/M compiler and run under CP/M (or a clone/emulator).
THe original 8080 PL/M only supports 8 and 16 bit quantities, so this only shows magnanimous numbers up to the 250th.
100H: /* FIND SOME MAGNANIMOUS NUMBERS - THOSE WHERE INSERTING '+' BETWEEN */
/* ANY TWO OF THE DIGITS AND EVALUATING THE SUM RESULTS IN A PRIME */
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
DECLARE FN BYTE, ARG ADDRESS;
GOTO 5;
END BDOS;
PRINT$CHAR: PROCEDURE( C ); DECLARE C BYTE; CALL BDOS( 2, C ); END;
PRINT$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S ); END;
PRINT$NL: PROCEDURE; CALL PRINT$STRING( .( 0DH, 0AH, '$' ) ); END;
PRINT$NUMBER: PROCEDURE( N );
DECLARE N ADDRESS;
DECLARE V ADDRESS, N$STR( 6 ) BYTE, W BYTE;
V = N;
W = LAST( N$STR );
N$STR( W ) = '$';
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
DO WHILE( ( V := V / 10 ) > 0 );
N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
END;
IF N < 100 THEN DO;
IF N < 10 THEN CALL PRINT$CHAR( ' ' );
CALL PRINT$CHAR( ' ' );
END;
CALL PRINT$STRING( .N$STR( W ) );
END PRINT$NUMBER;
/* INTEGER SQUARE ROOT: BASED ON THE ONE IN THE PL/M FROBENIUS NUMBERS */
SQRT: PROCEDURE( N )ADDRESS;
DECLARE ( N, X0, X1 ) ADDRESS;
IF N <= 3 THEN DO;
IF N = 0 THEN X0 = 0; ELSE X0 = 1;
END;
ELSE DO;
X0 = SHR( N, 1 );
DO WHILE( ( X1 := SHR( X0 + ( N / X0 ), 1 ) ) < X0 );
X0 = X1;
END;
END;
RETURN X0;
END SQRT;
DECLARE MAGNANIMOUS (251)ADDRESS; /* MAGNANIMOUS NUMBERS */
DECLARE FALSE LITERALLY '0';
DECLARE TRUE LITERALLY '0FFH';
/* TO FIND MAGNANIMOUS NUMBERS UP TO 30$000, WE NEED TO FIND PRIMES */
/* UP TO 9$999 + 9 = 10$008 */
DECLARE MAX$PRIME LITERALLY '10$008';
DECLARE DCL$PRIME LITERALLY '10$009';
/* SIEVE THE PRIMES TO MAX$PRIME */
DECLARE ( I, S ) ADDRESS;
DECLARE PRIME ( DCL$PRIME )BYTE;
PRIME( 1 ) = FALSE; PRIME( 2 ) = TRUE;
DO I = 3 TO LAST( PRIME ) BY 2; PRIME( I ) = TRUE; END;
DO I = 4 TO LAST( PRIME ) BY 2; PRIME( I ) = FALSE; END;
DO I = 3 TO SQRT( MAX$PRIME );
IF PRIME( I ) THEN DO;
DO S = I * I TO LAST( PRIME ) BY I + I;PRIME( S ) = FALSE; END;
END;
END;
/* FIND THE MAGNANIMOUS NUMBERS */
FIND$MAGNANIMOUS: PROCEDURE;
DECLARE ( D1, D2, D3, D4, D5
, D12, D123, D1234
, D23, D234, D2345
, D34, D345, D45
) ADDRESS;
DECLARE M$COUNT ADDRESS; /* COUNT OF MAGNANIMOUS NUMBERS FOUND */
STORE$MAGNANIMOUS: PROCEDURE( N )BYTE;
DECLARE N ADDRESS;
M$COUNT = M$COUNT + 1;
IF M$COUNT <= LAST( MAGNANIMOUS ) THEN MAGNANIMOUS( M$COUNT ) = N;
RETURN M$COUNT <= LAST( MAGNANIMOUS );
END STORE$MAGNANIMOUS;
M$COUNT = 0;
/* 1 DIGIT MAGNANIMOUS NUMBERS */
DO D1 = 0 TO 9; IF NOT STORE$MAGNANIMOUS( D1 ) THEN RETURN; END;
/* 2 DIGIT MAGNANIMOUS NUMBERS */
DO D1 = 1 TO 9;
DO D2 = 0 TO 9;
IF PRIME( D1 + D2 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D1 * 10 ) + D2 ) THEN RETURN;
END;
END;
END;
/* 3 DIGIT MAGNANIMOUS NUMBERS */
DO D1 = 1 TO 9;
DO D23 = 0 TO 99;
IF PRIME( D1 + D23 ) THEN DO;
D3 = D23 MOD 10;
D12 = ( D1 * 10 ) + ( D23 / 10 );
IF PRIME( D12 + D3 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D12 * 10 ) + D3 ) THEN RETURN;
END;
END;
END;
END;
/* 4 DIGIT MAGNANIMOUS NUMBERS */
DO D12 = 10 TO 99;
DO D34 = 0 TO 99;
IF PRIME( D12 + D34 ) THEN DO;
D123 = ( D12 * 10 ) + ( D34 / 10 );
D4 = D34 MOD 10;
IF PRIME( D123 + D4 ) THEN DO;
D1 = D12 / 10;
D234 = ( ( D12 MOD 10 ) * 100 ) + D34;
IF PRIME( D1 + D234 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D12 * 100 ) + D34 )
THEN RETURN;
END;
END;
END;
END;
END;
/* 5 DIGIT MAGNANIMOUS NUMBERS UP TO 30$000 */
DO D12 = 10 TO 30;
DO D345 = 0 TO 999;
IF PRIME( D12 + D345 ) THEN DO;
D123 = ( D12 * 10 ) + ( D345 / 100 );
D45 = D345 MOD 100;
IF PRIME( D123 + D45 ) THEN DO;
D1234 = ( D123 * 10 ) + ( D45 / 10 );
D5 = D45 MOD 10;
IF PRIME( D1234 + D5 ) THEN DO;
D1 = D12 / 10;
D2345 = ( ( D12 MOD 10 ) * 1000 ) + D345;
IF PRIME( D1 + D2345 ) THEN DO;
IF NOT STORE$MAGNANIMOUS( ( D12 * 1000 ) + D345 )
THEN RETURN;
END;
END;
END;
END;
END;
END;
END FIND$MAGNANIMOUS ;
CALL FIND$MAGNANIMOUS;
DO I = 1 TO LAST( MAGNANIMOUS );
IF I = 1 THEN DO;
CALL PRINT$STRING( .'MAGNANIMOUS NUMBERS 1-45:$' ); CALL PRINT$NL;
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
ELSE IF I < 46 THEN DO;
IF I MOD 15 = 1 THEN CALL PRINT$NL; ELSE CALL PRINT$CHAR( ' ' );
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
ELSE IF I = 241 THEN DO;
CALL PRINT$NL;
CALL PRINT$STRING( .'MAGANIMOUS NUMBERS 241-250:$' ); CALL PRINT$NL;
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
ELSE IF I > 241 AND I <= 250 THEN DO;
CALL PRINT$CHAR( ' ' );
CALL PRINT$NUMBER( MAGNANIMOUS( I ) );
END;
END;
CALL PRINT$NL;
EOF
- Output:
MAGNANIMOUS NUMBERS 1-45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 MAGANIMOUS NUMBERS 241-250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407
Python
""" rosettacode.orgwiki/Magnanimous_numbers """
from sympy import isprime
def is_magnanimous(num):
""" True is num is a magnanimous number """
if num < 10:
return True
for i in range(1, len(str(num))):
quo, rem = divmod(num, 10**i)
if not isprime(quo + rem):
return False
return True
if __name__ == '__main__':
K, MCOUNT = 0, 0
print('First 45 magnanimous numbers:')
while MCOUNT < 400:
if is_magnanimous(K):
if MCOUNT < 45:
print(f'{K:4d}', end='\n' if (MCOUNT + 1) % 15 == 0 else '')
elif MCOUNT == 239:
print('\n241st through 250th magnanimous numbers:')
elif 239 < MCOUNT < 250:
print(f'{K:6d}', end='')
elif MCOUNT == 389:
print('\n\n391st through 400th magnanimous numbers:')
elif 389 < MCOUNT < 400:
print(f'{K:7d}', end='')
MCOUNT += 1
K += 1
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Quackery
isprime
is defined at Primality by trial division#Quackery.
[ 10
[ 2dup /mod
over 0 = iff
[ 2drop true ]
done
+ isprime not iff
false done
10 * again ]
unrot 2drop ] is magnanimous ( n --> b )
[] 0
[ dup magnanimous
if [ tuck join swap ]
1+
over size 250 =
until ]
drop
say "First 45 magnanimous numbers:" cr
45 split swap echo cr cr
say "Magnanimous numbers 241-250:" cr
-10 split echo cr cr
drop
- Output:
First 45 magnanimous numbers: [ 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 ] Magnanimous numbers 241-250: [ 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 ]
Raku
my @magnanimous = lazy flat ^10, (10 .. 1001).map( {
my int $last;
(1 ..^ .chars).map: -> \c { $last = 1 and last unless (.substr(0,c) + .substr(c)).is-prime }
next if $last;
$_
} ),
(1002 .. ∞).map: {
# optimization for numbers > 1001; First and last digit can not both be even or both be odd
next if (.substr(0,1) + .substr(*-1)) %% 2;
my int $last;
(1 ..^ .chars).map: -> \c { $last = 1 and last unless (.substr(0,c) + .substr(c)).is-prime }
next if $last;
$_
}
put 'First 45 magnanimous numbers';
put @magnanimous[^45]».fmt('%3d').batch(15).join: "\n";
put "\n241st through 250th magnanimous numbers";
put @magnanimous[240..249];
put "\n391st through 400th magnanimous numbers";
put @magnanimous[390..399];
- Output:
First 45 magnanimous numbers 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
REXX
The majority of the time consumed was in generating a list (sparse array) of suitable primes.
The magna function (magnanimous) was quite simple to code and pretty fast, it includes the 1st and last digit parity test.
By far, the most CPU time was in the generation of primes.
/*REXX pgm finds/displays magnanimous #s (#s with a inserted + sign to sum to a prime).*/
parse arg bet.1 bet.2 bet.3 highP . /*obtain optional arguments from the CL*/
if bet.1=='' | bet.1=="," then bet.1= 1..45 /* " " " " " " */
if bet.2=='' | bet.2=="," then bet.2= 241..250 /* " " " " " " */
if bet.3=='' | bet.3=="," then bet.3= 391..400 /* " " " " " " */
if highP=='' | highP=="," then highP= 1000000 /* " " " " " " */
call genP /*gen primes up to highP (1 million).*/
do j=1 for 3 /*process three magnanimous "ranges". */
parse var bet.j LO '..' HI /*obtain the first range (if any). */
if HI=='' then HI= LO /*Just a single number? Then use LO. */
if HI==0 then iterate /*Is HI a zero? Then skip this range.*/
finds= 0; $= /*#: magnanimous # cnt; $: is a list*/
do k=0 until finds==HI /* [↓] traipse through the number(s). */
if \magna(k) then iterate /*Not magnanimous? Then skip this num.*/
finds= finds + 1 /*bump the magnanimous number count. */
if finds>=LO then $= $ k /*In range► Then add number ──► $ list*/
end /*k*/
say
say center(' 'LO "──►" HI 'magnanimous numbers ', 126, "─")
say strip($)
end /*j*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
magna: procedure expose @. !.; parse arg x 1 L 2 '' -1 R /*obtain #, 1st & last digit.*/
len= length(x); if len==1 then return 1 /*one digit #s are magnanimous*/
if x>1001 then if L//2 == R//2 then return 0 /*Has parity? Not magnanimous*/
do s= 1 for len-1 /*traipse thru #, inserting + */
parse var x y +(s) z; sum= y + z /*parse 2 parts of #, sum 'em.*/
if !.sum then iterate /*Is sum prime? So far so good*/
else return 0 /*Nope? Then not magnanimous.*/
end /*s*/
return 1 /*Pass all the tests, it's magnanimous.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13 /*assign low primes; # primes.*/
!.= 0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; !.13=1 /* " semaphores to " */
#= 6; sq.#= @.# ** 2 /*# primes so far; P squared.*/
do j=@.#+4 by 2 to highP; parse var j '' -1 _; if _==5 then iterate /*÷ by 5?*/
if j// 3==0 then iterate; if j// 7==0 then iterate /*÷ by 3?; ÷ by 7?*/
if j//11==0 then iterate /*" " 11? " " 13?*/
do k=6 while sq.k<=j /*divide by some generated odd primes. */
if j//@.k==0 then iterate j /*Is J divisible by P? Then not prime*/
end /*k*/ /* [↓] a prime (J) has been found. */
#= #+1; @.#= j; sq.#= j*j; !.j= 1 /*bump #Ps; P──►@.assign P; P^2; P flag*/
end /*j*/; return
- output when using the default inputs:
──────────────────────────────────────────────── 1 ──► 45 magnanimous numbers ──────────────────────────────────────────────── 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 and took 0.00 seconds. ────────────────────────────────────────────── 241 ──► 250 magnanimous numbers ─────────────────────────────────────────────── 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 and took 0.31 seconds. ────────────────────────────────────────────── 391 ──► 400 magnanimous numbers ─────────────────────────────────────────────── 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Ring
load "stdlib.ring"
n = -1
sum = 0
magn = []
while sum < 45
n = n + 1
if n < 10
add(magn,n)
sum = sum + 1
else
nStr = string(n)
check = 0
for m = 1 to len(nStr)-1
nr1 = number(left(nStr,m))
nr2 = number(right(nStr,len(nStr)-m))
nr3 = nr1 + nr2
if not isprime(nr3)
check = 1
ok
next
if check = 0
add(magn,n)
sum = sum + 1
ok
ok
end
see "Magnanimous numbers 1-45:" + nl
showArray(magn)
n = -1
sum = 0
magn = []
while sum < 250
n = n + 1
if n < 10
sum = sum + 1
else
nStr = string(n)
check = 0
for m = 1 to len(nStr)-1
nr1 = number(left(nStr,m))
nr2 = number(right(nStr,len(nStr)-m))
nr3 = nr1 + nr2
if not isprime(nr3)
check = 1
ok
next
if check = 0
sum = sum + 1
ok
if check = 0 and sum > 240 and sum < 251
add(magn,n)
ok
ok
end
see nl
see "Magnanimous numbers 241-250:" + nl
showArray(magn)
func showArray array
txt = ""
see "["
for n = 1 to len(array)
txt = txt + array[n] + ","
next
txt = left(txt,len(txt)-1)
txt = txt + "]"
see txt
Magnanimous numbers 1-45: [0,1,2,3,4,5,6,7,8,9,11,12,14,16,20,21,23,25,29,30,32,34,38,41,43,47,49,50,52,56,58,61,65,67,70,74,76,83,85,89,92,94,98,101,110] Magnanimous numbers 241-250: [17992,19972,20209,20261,20861,22061,22201,22801,22885,24407]
RPL
RPL code | Comment |
---|---|
≪ DUP2 1 SWAP SUB "+" + ROT ROT 1 + OVER SIZE SUB + STR→ EVAL ≫ ‘InsertPlus’ STO ≪ "'" SWAP →STR OVER + + DUP SIZE → str len ≪ 2 SF 2 len 2 - FOR j str j InsertPlus IF PRIM? NOT THEN 2 CF len 'j' STO END NEXT 2 FS? ≫ ≫ ‘MAGN?’ STO ≪ → n ≪ { 0 1 2 3 4 5 6 7 8 9 } 10 WHILE OVER SIZE n < REPEAT IF DUP MAGN? THEN SWAP OVER + SWAP END 1 + END DROP ≫ ≫ ‘MAGLST’ STO ≪ DO 1 + UNTIL DUP MAGN? END ≫ ‘NXMAGN’ STO |
InsertPlus ( "'####'" pos -- sum ) insert a plus sign in the string evaluate the expression MAGN? ( "'####'" pos -- sum ) turn ### into "'###'" for each possibility add digits if not a prime, clear flag 2 and exit the loop MAGLST ( n -- { M(1)..M(n) } ) NXMAGN ( x -- next_M(n) ) |
- Input:
45 MAGLST 17752 NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN NXMAGN
- Output:
11: { 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 } 10: 17992 9: 19972 8: 20209 7: 20261 6: 20861 5: 22061 4: 22201 3: 22801 2: 22885 1: 24407
Ruby
require "prime"
magnanimouses = Enumerator.new do |y|
(0..).each {|n| y << n if (1..n.digits.size-1).all? {|k| n.divmod(10**k).sum.prime?} }
end
puts "First 45 magnanimous numbers:"
puts magnanimouses.first(45).join(' ')
puts "\n241st through 250th magnanimous numbers:"
puts magnanimouses.first(250).last(10).join(' ')
puts "\n391st through 400th magnanimous numbers:"
puts magnanimouses.first(400).last(10).join(' ')
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Rust
fn is_prime(n: u32) -> bool {
if n < 2 {
return false;
}
if n % 2 == 0 {
return n == 2;
}
if n % 3 == 0 {
return n == 3;
}
let mut p = 5;
while p * p <= n {
if n % p == 0 {
return false;
}
p += 2;
if n % p == 0 {
return false;
}
p += 4;
}
true
}
fn is_magnanimous(n: u32) -> bool {
let mut p: u32 = 10;
while n >= p {
if !is_prime(n % p + n / p) {
return false;
}
p *= 10;
}
true
}
fn main() {
let mut m = (0..).filter(|x| is_magnanimous(*x)).take(400);
println!("First 45 magnanimous numbers:");
for (i, n) in m.by_ref().take(45).enumerate() {
if i > 0 && i % 15 == 0 {
println!();
}
print!("{:3} ", n);
}
println!("\n\n241st through 250th magnanimous numbers:");
for n in m.by_ref().skip(195).take(10) {
print!("{} ", n);
}
println!("\n\n391st through 400th magnanimous numbers:");
for n in m.by_ref().skip(140) {
print!("{} ", n);
}
println!();
}
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
SETL
program magnanimous;
n := -1;
loop for i in [1..400] do
loop until magnanimous(n) do n +:= 1; end loop;
case i of
(1): print("1 - 45:");
(241): print; print("241 - 250:");
(391): print; print("391 - 400:");
end case;
if i in [1..45] or i in [241..250] or i in [391..400] then
putchar(lpad(str n, 7));
if i mod 5 = 0 then print; end if;
end if;
end loop;
proc magnanimous(n);
return forall k in splitsums(n) | prime(k);
end proc;
proc splitsums(n);
s := str n;
return [val s(..i) + val s(i+1..) : i in [1..#s-1]];
end proc;
proc prime(n);
if n<2 then return false;
elseif even n then return(n = 2);
elseif n mod 3=0 then return(n = 3);
else
d := 5;
loop while d*d <= n do
if n mod d=0 then return false; end if;
d +:= 2;
if n mod d=0 then return false; end if;
d +:= 4;
end loop;
return true;
end if;
end proc;
end program;
- Output:
1 - 45: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241 - 250: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391 - 400: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Sidef
func is_magnanimous(n) {
1..n.ilog10 -> all {|k|
sum(divmod(n, k.ipow10)).is_prime
}
}
say "First 45 magnanimous numbers:"
say is_magnanimous.first(45).join(' ')
say "\n241st through 250th magnanimous numbers:"
say is_magnanimous.first(250).last(10).join(' ')
say "\n391st through 400th magnanimous numbers:"
say is_magnanimous.first(400).last(10).join(' ')
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Swift
import Foundation
func isPrime(_ n: Int) -> Bool {
if n < 2 {
return false
}
if n % 2 == 0 {
return n == 2
}
if n % 3 == 0 {
return n == 3
}
var p = 5
while p * p <= n {
if n % p == 0 {
return false
}
p += 2
if n % p == 0 {
return false
}
p += 4
}
return true
}
func isMagnanimous(_ n: Int) -> Bool {
var p = 10;
while n >= p {
if !isPrime(n % p + n / p) {
return false
}
p *= 10
}
return true
}
let m = (0...).lazy.filter{isMagnanimous($0)}.prefix(400);
print("First 45 magnanimous numbers:");
for (i, n) in m.prefix(45).enumerated() {
if i > 0 && i % 15 == 0 {
print()
}
print(String(format: "%3d", n), terminator: " ")
}
print("\n\n241st through 250th magnanimous numbers:");
for n in m.dropFirst(240).prefix(10) {
print(n, terminator: " ")
}
print("\n\n391st through 400th magnanimous numbers:");
for n in m.dropFirst(390) {
print(n, terminator: " ")
}
print()
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
Visual Basic .NET
Imports System, System.Console
Module Module1
Dim np As Boolean()
Sub ms(ByVal lmt As Long)
np = New Boolean(CInt(lmt)) {} : np(0) = True : np(1) = True
Dim n As Integer = 2, j As Integer = 1 : While n < lmt
If Not np(n) Then
Dim k As Long = CLng(n) * n
While k < lmt : np(CInt(k)) = True : k += n : End While
End If : n += j : j = 2 : End While
End Sub
Function is_Mag(ByVal n As Integer) As Boolean
Dim res, rm As Integer, p As Integer = 10
While n >= p
res = Math.DivRem(n, p, rm)
If np(res + rm) Then Return False
p = p * 10 : End While : Return True
End Function
Sub Main(ByVal args As String())
ms(100_009) : Dim mn As String = " magnanimous numbers:"
WriteLine("First 45{0}", mn) : Dim l As Integer = 0, c As Integer = 0
While c < 400 : If is_Mag(l) Then
c += 1 : If c <= 45 OrElse (c > 240 AndAlso c <= 250) OrElse c > 390 Then Write(If(c <= 45, "{0,4} ", "{0,8:n0} "), l)
If c < 45 AndAlso c Mod 15 = 0 Then WriteLine()
If c = 240 Then WriteLine(vbLf & vbLf & "241st through 250th{0}", mn)
If c = 390 Then WriteLine(vbLf & vbLf & "391st through 400th{0}", mn)
End If : l += 1 : End While
End Sub
End Module
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17,992 19,972 20,209 20,261 20,861 22,061 22,201 22,801 22,885 24,407 391st through 400th magnanimous numbers: 486,685 488,489 515,116 533,176 551,558 559,952 595,592 595,598 600,881 602,081
Wren
import "./fmt" for Conv, Fmt
import "./math" for Int
var isMagnanimous = Fn.new { |n|
if (n < 10) return true
var p = 10
while (true) {
var q = (n/p).floor
var r = n % p
if (!Int.isPrime(q + r)) return false
if (q < 10) break
p = p * 10
}
return true
}
var listMags = Fn.new { |from, thru, digs, perLine|
if (from < 2) {
System.print("\nFirst %(thru) magnanimous numbers:")
} else {
System.print("\n%(Conv.ord(from)) through %(Conv.ord(thru)) magnanimous numbers:")
}
var i = 0
var c = 0
while (c < thru) {
if (isMagnanimous.call(i)) {
c = c + 1
if (c >= from) {
System.write(Fmt.d(digs, i) + " ")
if (c % perLine == 0) System.print()
}
}
i = i + 1
}
}
listMags.call(1, 45, 3, 15)
listMags.call(241, 250, 1, 10)
listMags.call(391, 400, 1, 10)
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
XPL0
func IsPrime(N); \Return 'true' if N is prime
int N, I;
[if N <= 2 then return N = 2;
if (N&1) = 0 then \even >2\ return false;
for I:= 3 to sqrt(N) do
[if rem(N/I) = 0 then return false;
I:= I+1;
];
return true;
];
func Magnan(N); \Return 'true' if N is a magnanimous number
int N, M, P;
[M:= 0; P:= 1;
loop [N:= N/10;
if N = 0 then return true;
M:= P*rem(0) + M;
P:= P*10;
if not IsPrime(N+M) then return false;
];
];
int Cnt, N;
[Cnt:= 0; N:= 0;
Text(0, "First 45 magnanimous numbers:^m^j");
loop [if N < 10 or Magnan(N) then
[Cnt:= Cnt+1;
if Cnt <= 45 then
[Format(4, 0);
RlOut(0, float(N));
if rem(Cnt/15) = 0 then CrLf(0);
];
if Cnt = 241 then
Text(0, "^m^j241st through 250th magnanimous numbers:^m^j");
if Cnt >= 241 and Cnt <= 250 then
[IntOut(0, N); ChOut(0, ^ )];
if Cnt = 391 then
Text(0, "^m^j^j391st through 400th magnanimous numbers:^m^j");
if Cnt >= 391 and Cnt <= 400 then
[IntOut(0, N); ChOut(0, ^ )];
if Cnt >= 400 then quit;
];
N:= N+1;
];
]
- Output:
First 45 magnanimous numbers: 0 1 2 3 4 5 6 7 8 9 11 12 14 16 20 21 23 25 29 30 32 34 38 41 43 47 49 50 52 56 58 61 65 67 70 74 76 83 85 89 92 94 98 101 110 241st through 250th magnanimous numbers: 17992 19972 20209 20261 20861 22061 22201 22801 22885 24407 391st through 400th magnanimous numbers: 486685 488489 515116 533176 551558 559952 595592 595598 600881 602081
- Programming Tasks
- Prime Numbers
- ALGOL 68
- ALGOL W
- Amazing Hopper
- AWK
- BASIC
- BASIC256
- BBC BASIC
- BCPL
- C
- C sharp
- C++
- CLU
- Cowgol
- Delphi
- SysUtils,StdCtrls
- Draco
- EasyLang
- F Sharp
- Factor
- FreeBASIC
- Go
- GW-BASIC
- Haskell
- Java
- J
- Jq
- Julia
- Lambdatalk
- Mathematica
- Wolfram Language
- Modula-2
- Nim
- Pascal
- Perl
- Ntheory
- Phix
- PicoLisp
- PL/M
- Python
- Quackery
- Raku
- REXX
- Ring
- RPL
- Ruby
- Rust
- SETL
- Sidef
- Swift
- Visual Basic .NET
- Wren
- Wren-fmt
- Wren-math
- XPL0