Nice primes: Difference between revisions
m (Added a ;Task: section header to give the (draft) task some "body" and structure).) |
(Added Fōrmulæ solution) |
||
Line 733: | Line 733: | ||
</pre> |
</pre> |
||
=={{header|Fōrmulæ}}== |
|||
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition. |
|||
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used. |
|||
In '''[https://formulae.org/?example=Nice_primes this]''' page you can see the program(s) related to this task and their results. |
|||
=={{header|Go}}== |
=={{header|Go}}== |
Revision as of 22:23, 28 July 2021
- Task
-
- Take an positive integer n
- sumn is the sum of the decimal digits of n
- If sumn's length is greater than 1 (unity), repeat step 2 for n = sumn
- Stop when sumn's length is equal to 1 (unity)
If n and sumn are prime, then n is a Nice prime
Let 500 < n < 1000
- Example
853 (prime) 8 + 5 + 3 = 16 1 + 6 = 7 (prime)
- Also see
-
- The OEIS article: A78403 Primes such that digital root is prime.
ALGOL 68
<lang algol68>BEGIN # find nice primes - primes whose digital root is also prime #
INT min prime = 501; INT max prime = 999; # sieve the primes to max prime # [ 1 : max prime ]BOOL prime; 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( max prime ) DO IF prime[ i ] THEN FOR s FROM i * i BY i + i TO UPB prime DO prime[ s ] := FALSE OD FI OD; # find the nice primes # INT nice count := 0; FOR n FROM min prime TO max prime DO IF prime[ n ] THEN # have a prime # INT digit sum := 0; INT v := n; WHILE digit sum := 0; WHILE v > 0 DO digit sum +:= v MOD 10; v OVERAB 10 OD; digit sum > 9 DO v := digit sum OD; IF prime( digit sum ) THEN # the digital root is prime # nice count +:= 1; print( ( " ", whole( n, -3 ), "(", whole( digit sum, 0 ), ")" ) ); IF nice count MOD 12 = 0 THEN print( ( newline ) ) FI FI FI OD
END</lang>
- Output:
509(5) 547(7) 563(5) 569(2) 587(2) 599(5) 601(7) 617(5) 619(7) 641(2) 653(5) 659(2) 673(7) 677(2) 691(7) 709(7) 727(7) 743(5) 761(5) 797(5) 821(2) 839(2) 853(7) 857(2) 887(5) 907(7) 911(2) 929(2) 941(5) 947(2) 977(5) 983(2) 997(7)
ALGOL W
<lang algolw>begin % find some nice primes - primes whose digital root is prime %
% returns the digital root of n in base 10 % integer procedure digitalRoot( integer value n ) ; if n = 0 then 0 else begin integer root; root := ( abs n ) rem 9; if root = 0 then 9 else root end digitalRoot ; % sets p( 1 :: n ) to a sieve of primes up to n % procedure Eratosthenes ( logical array p( * ) ; integer value n ) ; begin p( 1 ) := false; p( 2 ) := true; for i := 3 step 2 until n do p( i ) := true; for i := 4 step 2 until n do p( i ) := false; for i := 3 step 2 until truncate( sqrt( n ) ) do begin integer ii; ii := i + i; if p( i ) then for pr := i * i step ii until n do p( pr ) := false end for_i ; end Eratosthenes ; integer MIN_PRIME, MAX_PRIME; MIN_PRIME := 501; MAX_PRIME := 999; % find the nice primes in the exclusive range 500 < prime < 1000 % begin logical array p ( 1 :: MAX_PRIME ); integer nCount; % construct a sieve of primes up to the maximum required % Eratosthenes( p, MAX_PRIME ); % show the primes that are nice % write( i_w := 1, s_w := 0, "Nice primes from ", MIN_PRIME, " to ", MAX_PRIME ); for i := MIN_PRIME until MAX_PRIME do begin if p( i ) then begin integer dr; dr := digitalRoot( i ); if p( dr ) then begin nCount := nCount + 1; write( i_w := 3, s_w := 0, nCount, ":", i, " dr(", i_w := 1, dr, ")" ) end if_dr_p end if_p_i end for_i end
end. </lang>
- Output:
Nice primes from 501 to 999 1:509 dr(5) 2:547 dr(7) 3:563 dr(5) 4:569 dr(2) 5:587 dr(2) 6:599 dr(5) 7:601 dr(7) 8:617 dr(5) 9:619 dr(7) 10:641 dr(2) 11:653 dr(5) 12:659 dr(2) 13:673 dr(7) 14:677 dr(2) 15:691 dr(7) 16:709 dr(7) 17:727 dr(7) 18:743 dr(5) 19:761 dr(5) 20:797 dr(5) 21:821 dr(2) 22:839 dr(2) 23:853 dr(7) 24:857 dr(2) 25:887 dr(5) 26:907 dr(7) 27:911 dr(2) 28:929 dr(2) 29:941 dr(5) 30:947 dr(2) 31:977 dr(5) 32:983 dr(2) 33:997 dr(7)
APL
<lang APL>(⊢(/⍨)(∧/(2=(0+.=⍳|⊢))¨∘(⊢,(+/10⊥⍣¯1⊢)⍣(9≥⊣)))¨) 500+⍳500</lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
AppleScript
sumn formula borrowed from the Factor solution. <lang applescript>on sieveOfEratosthenes(limit)
script o property numberList : {missing value} end script repeat with n from 2 to limit set end of o's numberList to n end repeat repeat with n from 2 to (limit ^ 0.5 div 1) if (item n of o's numberList is n) then repeat with multiple from (n * n) to limit by n set item multiple of o's numberList to missing value end repeat end if end repeat return o's numberList's numbers
end sieveOfEratosthenes
on nicePrimes(a, b)
script o property primes : reverse of sieveOfEratosthenes(b) property niceOnes : {} end script repeat with n in o's primes set n to n's contents if (n < a) then exit repeat set sumn to (n - 1) mod 9 + 1 -- n being a prime, sumn can obviously never be 0 here. Tests suggest that it's never 6 or 9 -- either and that it's only ever 3 when n is 3. Occurrences of the other single-digit -- possibilities are fairly evenly distributed. Testing for a prime result — 2, 5, 7, or the -- very unlikely 3 — requires one to four tests, depending on which test eventually decides -- the matter. An alternative is to eliminate 8, 4, and 1 instead, which can be done with -- only one or two tests. The test eliminating both 8 and 4 should be tried first. if ((sumn mod 4 > 0) and (sumn > 1)) then set end of o's niceOnes to n end repeat return reverse of o's niceOnes
end nicePrimes
return nicePrimes(501, 999)</lang>
- Output:
<lang applescript>{509, 547, 563, 569, 587, 599, 601, 617, 619, 641, 653, 659, 673, 677, 691, 709, 727, 743, 761, 797, 821, 839, 853, 857, 887, 907, 911, 929, 941, 947, 977, 983, 997}</lang>
Arturo
<lang rebol>sumd: function [n][
s: sum digits n (1 = size digits s)? -> return s -> return sumd s
]
nice?: function [x] -> and? prime? x
prime? sumd x
loop split.every:10 select 500..1000 => nice? 'a ->
print map a => [pad to :string & 4]</lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
AWK
<lang AWK>
- syntax: GAWK -f NICE_PRIMES.AWK
BEGIN {
start = 500 stop = 1000 for (i=start; i<=stop; i++) { if (is_prime(i)) { s = i while (s >= 10) { s = sum_digits(s) } if (s ~ /^[2357]$/) { count++ printf("%d %d\n",i,s) } } } printf("Nice primes %d-%d: %d\n",start,stop,count) exit(0)
} function is_prime(x, i) {
if (x <= 1) { return(0) } for (i=2; i<=int(sqrt(x)); i++) { if (x % i == 0) { return(0) } } return(1)
} function sum_digits(x, sum,y) {
while (x) { y = x % 10 sum += y x = int(x/10) } return(sum)
} </lang>
- Output:
509 5 547 7 563 5 569 2 587 2 599 5 601 7 617 5 619 7 641 2 653 5 659 2 673 7 677 2 691 7 709 7 727 7 743 5 761 5 797 5 821 2 839 2 853 7 857 2 887 5 907 7 911 2 929 2 941 5 947 2 977 5 983 2 997 7 Nice primes 500-1000: 33
BASIC
<lang basic>10 DEFINT A-Z: B=500: E=1000 20 DIM P(E): P(0)=-1: P(1)=-1 30 FOR I=2 TO SQR(E) 40 IF NOT P(I) THEN FOR J=I*2 TO E STEP I: P(J)=-1: NEXT 50 NEXT 60 FOR I=B TO E: IF P(I) GOTO 110 70 J=I 80 S=0 90 IF J>0 THEN S=S+J MOD 10: J=J\10: GOTO 90 100 IF S>9 THEN J=S: GOTO 80 ELSE IF NOT P(S) THEN PRINT I, 110 NEXT</lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
BCPL
<lang bcpl>get "libhdr" manifest $(
begin = 500 end = 1000
$)
let sieve(prime, top) be $( 0!prime := false
1!prime := false for i=2 to top do i!prime := true for i=2 to top/2 if i!prime $( let j = i*2 while j <= top $( j!prime := false j := j + i $) $)
$)
let digroot(n) =
n<10 -> n, digroot(digsum(n))
and digsum(n) =
n<10 -> n, n rem 10 + digsum(n/10)
let nice(prime, n) = n!prime & digroot(n)!prime
let start() be $( let prime = getvec(end)
sieve(prime, end) for i = begin to end if nice(prime, i) do writef("%N*N", i) freevec(prime)
$)</lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
C
<lang c>#include <stdbool.h>
- include <stdio.h>
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;
}
unsigned int digital_root(unsigned int n) {
return n == 0 ? 0 : 1 + (n - 1) % 9;
}
int main() {
const unsigned int from = 500, to = 1000; unsigned int count = 0; unsigned int n;
printf("Nice primes between %d and %d:\n", from, to); for (n = from; n < to; ++n) { if (is_prime(digital_root(n)) && is_prime(n)) { ++count; //std::cout << n << (count % 10 == 0 ? '\n' : ' '); printf("%d", n); if (count % 10 == 0) { putc('\n', stdout); } else { putc(' ', stdout); } } } printf("\n%d nice primes found.\n", count);
return 0;
}</lang>
- Output:
Nice primes between 500 and 1000: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 nice primes found.
C++
<lang cpp>#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;
}
unsigned int digital_root(unsigned int n) {
return n == 0 ? 0 : 1 + (n - 1) % 9;
}
int main() {
const unsigned int from = 500, to = 1000; std::cout << "Nice primes between " << from << " and " << to << ":\n"; unsigned int count = 0; for (unsigned int n = from; n < to; ++n) { if (is_prime(digital_root(n)) && is_prime(n)) { ++count; std::cout << n << (count % 10 == 0 ? '\n' : ' '); } } std::cout << '\n' << count << " nice primes found.\n";
}</lang>
- Output:
Nice primes between 500 and 1000: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 nice primes found.
D
<lang d>import std.stdio;
bool isPrime(uint n) {
if (n < 2) { return false; } if (n % 2 == 0) { return n == 2; } if (n % 3 == 0) { return n == 3; } for (uint p = 5; p * p <= n; p += 4) { if (n % p == 0) { return false; } p += 2; if (n % p == 0) { return false; } } return true;
}
uint digitalRoot(uint n) {
return n == 0 ? 0 : 1 + (n - 1) % 9;
}
void main() {
immutable from = 500; immutable to = 1000; writeln("Nice primes between ", from, " and ", to, ':'); uint count; foreach (n; from .. to) { if (isPrime(digitalRoot(n)) && isPrime(n)) { count++; write(n); if (count % 10 == 0) { writeln; } else { write(' '); } } } writeln; writeln(count, " nice primes found.");
}</lang>
- Output:
Nice primes between 500 and 1000: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 nice primes found.
F#
This task uses Extensible Prime Generator (F#) <lang fsharp> // Nice primes. Nigel Galloway: March 22nd., 2021 let fN g=1+((g-1)%9) in primes32()|>Seq.skipWhile((>)500)|>Seq.takeWhile((>)1000)|>Seq.filter(fN>>isPrime)|>Seq.iter(printf "%d "); printfn "" </lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
Factor
Using the following formula to find the digital root of a base 10 number:
- dr10(n) = 0 if n = 0,
- dr10(n) = 1 + ((n - 1) mod 9) if n ≠ 0.
(n = 0 may not need to be special-cased depending on the behavior of your language's modulo operator.)
<lang factor>USING: math math.primes prettyprint sequences ;
- digital-root ( m -- n ) 1 - 9 mod 1 + ;
500 1000 primes-between [ digital-root prime? ] filter .</lang>
- Output:
V{ 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 }
Forth
<lang forth>: prime? ( n -- ? ) here + c@ 0= ;
- notprime! ( n -- ) here + 1 swap c! ;
- prime_sieve ( n -- )
here over erase 0 notprime! 1 notprime! 2 begin 2dup dup * > while dup prime? if 2dup dup * do i notprime! dup +loop then 1+ repeat 2drop ;
- digital_root ( m -- n ) 1 - 9 mod 1 + ;
- print_nice_primes ( m n -- )
." Nice primes between " dup . ." and " over 1 .r ." :" cr over prime_sieve 0 -rot do i prime? if i digital_root prime? if i 3 .r 1+ dup 10 mod 0= if cr else space then then then loop cr . ." nice primes found." cr ;
1000 500 print_nice_primes bye</lang>
- Output:
Nice primes between 500 and 1000: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 nice primes found.
FreeBASIC
<lang freebasic> Function isPrime(Byval ValorEval As Integer) As Boolean
If ValorEval <= 1 Then Return False For i As Integer = 2 To Int(Sqr(ValorEval)) If ValorEval Mod i = 0 Then Return False Next i Return True
End Function
Dim As Integer column = 0, limit1 = 500, limit2 = 1000, sumn
Print !"Buenos n£meros entre"; limit1; " y"; limit2; !": \n"
For n As Integer = limit1 To limit2
Dim As String strn = Str(n) Do sumn = 0 For m As Integer = 1 To Len(strn) sumn += Val(Mid(strn,m,1)) Next m strn = Str(sumn) Loop Until Len(strn) = 1 If isPrime(n) And isPrime(sumn) Then column += 1 Print Using " ###"; n; If column Mod 8 = 0 Then Print : End If End If
Next n
Print !"\n\n"; column; " buenos n£meros encontrados." Sleep </lang>
- Output:
Buenos números entre 500 y 1000: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 buenos números encontrados.
Fōrmulæ
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in its website, However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
In this page you can see the program(s) related to this task and their results.
Go
<lang go>package main
import "fmt"
func isPrime(n int) bool {
switch { case n < 2: return false case n%2 == 0: return n == 2 case n%3 == 0: return n == 3 default: d := 5 for d*d <= n { if n%d == 0 { return false } d += 2 if n%d == 0 { return false } d += 4 } return true }
}
func sumDigits(n int) int {
sum := 0 for n > 0 { sum += n % 10 n /= 10 } return sum
}
func main() {
fmt.Println("Nice primes in the interval (500, 900) are:") c := 0 for i := 501; i <= 999; i += 2 { if isPrime(i) { s := i for s >= 10 { s = sumDigits(s) } if s == 2 || s == 3 || s == 5 || s == 7 { c++ fmt.Printf("%2d: %d -> Σ = %d\n", c, i, s) } } }
}</lang>
- Output:
Same as Wren example.
J
primeQ=: 1&p: digital_root=: +/@:(10&#.inv)^:_ NB. sum the digits to convergence niceQ=: [: *./ [: primeQ (, digital_root) (#~niceQ&>)(+i.)500 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 NB. testing only the primes on the range p:inv 500 1000 NB. index of the next largest prime in an ordered list of primes 95 168 (#~ (2 3 5 7 e.~ digital_root&>)) p: 95 + i. 168 - 95 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
Java
<lang java>public class NicePrimes {
private static boolean isPrime(long n) { if (n < 2) { return false; } if (n % 2 == 0L) { return n == 2L; } if (n % 3 == 0L) { return n == 3L; }
var p = 5L; while (p * p <= n) { if (n % p == 0L) { return false; } p += 2; if (n % p == 0L) { return false; } p += 4; } return true; }
private static long digitalRoot(long n) { if (n == 0) { return 0; } return 1 + (n - 1) % 9; }
public static void main(String[] args) { final long from = 500; final long to = 1000; int count = 0;
System.out.printf("Nice primes between %d and %d%n", from, to); long n = from; while (n < to) { if (isPrime(digitalRoot(n)) && isPrime(n)) { count++; System.out.print(n); if (count % 10 == 0) { System.out.println(); } else { System.out.print(' '); } }
n++; } System.out.println(); System.out.printf("%d nice primes found.%n", count); }
}</lang>
- Output:
Nice primes between 500 and 1000 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 nice primes found.
Julia
See Strange_numbers#Julia for the filter_open_interval function. <lang julia>using Primes
isnice(n, base=10) = isprime(n) && (mod1(n - 1, base - 1) + 1) in [2, 3, 5, 7, 11, 13, 17, 19]
filter_open_interval(500, 1000, isnice)
</lang>
- Output:
Finding numbers matching isnice for open interval (500, 1000): 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 The total found was 33
Kotlin
<lang scala>fun isPrime(n: Long): Boolean {
if (n < 2) { return false } if (n % 2 == 0L) { return n == 2L } if (n % 3 == 0L) { return n == 3L }
var p = 5 while (p * p <= n) { if (n % p == 0L) { return false } p += 2 if (n % p == 0L) { return false } p += 4 } return true
}
fun digitalRoot(n: Long): Long {
if (n == 0L) { return 0 } return 1 + (n - 1) % 9
}
fun main() {
val from = 500L val to = 1000L var count = 0
println("Nice primes between $from and $to:") var n = from while (n < to) { if (isPrime(digitalRoot(n)) && isPrime(n)) { count += 1 print(n) if (count % 10 == 0) { println() } else { print(' ') } }
n += 1 } println() println("$count nice primes found.")
}</lang>
- Output:
Nice primes between 500 and 1000: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 nice primes found.
Lua
<lang lua>function isPrime(n)
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
local p = 5 while p * p <= n do if n % p == 0 then return false end p = p + 2 if n % p == 0 then return false end p = p + 4 end return true
end
function digitalRoot(n)
if n == 0 then return 0 else return 1 + (n - 1) % 9 end
end
from = 500 to = 1000 count = 0 print("Nice primes between " .. from .. " and " .. to) n = from while n < to do
if isPrime(digitalRoot(n)) and isPrime(n) then count = count + 1 io.write(n) if count % 10 == 0 then print() else io.write(' ') end end n = n + 1
end print(count .. " nice primes found.")</lang>
- Output:
Nice primes between 500 and 1000 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997 33 nice primes found.
Nim
<lang Nim>import strutils, sugar
func isPrime(n: Positive): bool =
if (n and 1) == 0: return n == 2 var m = 3 while m * m <= n: if n mod m == 0: return false inc m, 2 result = true
func sumn(n: Positive): int =
var n = n.int while n != 0: result += n mod 10 n = n div 10
func isNicePrime(n: Positive): bool =
if not n.isPrime: return false var n = n while n notin 1..9: n = sumn(n) result = n in [2, 3, 5, 7]
let list = collect(newSeq):
for n in 501..999: if n.isNicePrime: n
echo "Found $1 nice primes between 501 and 999:".format(list.len) for i, n in list:
stdout.write n, if (i + 1) mod 10 == 0: '\n' else: ' '
echo()</lang>
- Output:
Found 33 nice primes between 501 and 999: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
Perl
<lang perl>use strict; use warnings;
use ntheory 'is_prime'; use List::Util qw(sum);
sub digital_root {
my ($n) = @_; do { $n = sum split , $n } until 1 == length $n; $n
}
my($low, $high, $cnt, @nice_primes) = (500,1000); is_prime($_) and is_prime(digital_root($_)) and push @nice_primes, $_ for $low+1 .. $high-1;
$cnt = @nice_primes; print "Nice primes between $low and $high (total of $cnt):\n" . (sprintf "@{['%5d' x $cnt]}", @nice_primes[0..$cnt-1]) =~ s/(.{55})/$1\n/gr;</lang>
- Output:
Nice primes between 500 and 1000 (total of 33): 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
Phix
function pdr(integer n) return is_prime(n) and is_prime(1+remainder(n-1,9)) end function sequence res = filter(tagset(1000,500),pdr) printf(1,"%d nice primes found:\n %s\n",{length(res),join_by(apply(res,sprint),1,11," ","\n ")})
- Output:
33 nice primes found: 509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
PL/M
<lang plm>100H: /* FIND NICE PRIMES - PRIMES WHOSE DIGITAL ROOT IS ALSO 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$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; CALL PRINT$STRING( .N$STR( W ) ); END PRINT$NUMBER; /* INTEGER SUARE ROOT: BASED ON THE ONE IN THE PL/M FOR 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 MIN$PRIME LITERALLY '501'; DECLARE MAX$PRIME LITERALLY '999'; DECLARE DCL$PRIME LITERALLY '1000'; DECLARE FALSE LITERALLY '0'; DECLARE TRUE LITERALLY '1'; /* 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 NICE PRIMES */ DECLARE NICE$COUNT ADDRESS; NICE$COUNT = 0; DO I = MIN$PRIME TO MAX$PRIME; IF PRIME( I ) THEN DO; /* HAVE A PRIME */ DECLARE DIGIT$SUM BYTE, V ADDRESS; DIGIT$SUM = LOW( V := I ); DO WHILE( V > 9 ); DIGIT$SUM = 0; DO WHILE( V > 0 ); DIGIT$SUM = DIGIT$SUM + ( V MOD 10 ); V = V / 10; END; V = DIGIT$SUM; END; IF PRIME( DIGIT$SUM ) THEN DO; /* THE DIGITAL ROOT IS PRIME */ NICE$COUNT = NICE$COUNT + 1; CALL PRINT$CHAR( ' ' ); CALL PRINT$NUMBER( I ); CALL PRINT$CHAR( '(' ); CALL PRINTCHAR( DIGIT$SUM + '0' ); CALL PRINT$CHAR( ')' ); IF NICE$COUNT MOD 12 = 0 THEN DO; CALL PRINT$STRING( .( 0DH, 0AH, '$' ) ); END; END; END; END;
EOF</lang>
- Output:
509(5) 547(7) 563(5) 569(2) 587(2) 599(5) 601(7) 617(5) 619(7) 641(2) 653(5) 659(2) 673(7) 677(2) 691(7) 709(7) 727(7) 743(5) 761(5) 797(5) 821(2) 839(2) 853(7) 857(2) 887(5) 907(7) 911(2) 929(2) 941(5) 947(2) 977(5) 983(2) 997(7)
Raku
<lang perl6>sub digroot ($r) { .tail given $r, { [+] .comb } ... { .chars == 1 } } my @is-nice = lazy (0..*).map: { .&is-prime && .&digroot.&is-prime ?? $_ !! False }; say @is-nice[500 ^..^ 1000].grep(*.so).batch(11)».fmt("%4d").join: "\n";</lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
Alternately, with somewhat better separation of concerns. <lang perl6>sub digroot ($r) { ($r, { .comb.sum } … { .chars == 1 }).tail } sub is-nice ($_) { .is-prime && .&digroot.is-prime } say (500 ^..^ 1000).grep( *.&is-nice ).batch(11)».fmt("%4d").join: "\n";</lang> Same output.
REXX
<lang rexx>/*REXX program finds and displays nice primes, primes whose digital root is also prime.*/ parse arg lo hi cols . /*obtain optional argument from the CL.*/ if lo== | lo=="," then lo= 500 /*Not specified? Then use the default.*/ if hi== | hi=="," then hi= 1000 /* " " " " " " */ if cols== | cols=="," then cols= 10 /* " " " " " " */ call genP /*build array of semaphores for primes.*/ w= 10 /*width of a number in any column. */
title= ' nice primes that are between ' commas(lo) " and " commas(hi)
if cols>0 then say ' index │'center(title ' (not inclusive)', 1 + cols*(w+1) ) if cols>0 then say '───────┼'center("" , 1 + cols*(w+1), '─') found= 0; idx= 1 /*initialize # of nice primes and index*/ $= /*a list of nice primes (so far). */
do j=lo+1 to hi-1; if \!.j then iterate /*search for nice primes within range*/ digRoot= 1 + (j - 1) // 9 /*obtain the digital root of J. */ if \!.digRoot then iterate /*Is digRoot prime? No, then skip it.*/ found= found + 1 /*bump the number of nice primes. */ if cols<0 then iterate /*Build the list (to be shown later)? */ c= commas(j) /*maybe add commas to the number. */ $= $ right(c, max(w, length(c) ) ) /*add a nice prime ──► list, allow big#*/ if found//cols\==0 then iterate /*have we populated a line of output? */ say center(idx, 7)'│' substr($, 2); $= /*display what we have so far (cols). */ idx= idx + cols /*bump the index count for the output*/ end /*j*/
if $\== then say center(idx, 7)"│" substr($, 2) /*possible display residual output.*/ if cols>0 then say '───────┴'center("" , 1 + cols*(w+1), '─') say say 'Found ' commas(found) title ' (not inclusive).' exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ? /*──────────────────────────────────────────────────────────────────────────────────────*/ genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11 /*define some low primes. */
!.=0; !.2=1; !.3=1; !.5=1; !.7=1; !.11=1 /* " " " " semaphores. */ #=5; s.#= @.# **2 /*number of primes so far; prime². */ do j=@.#+2 by 2 to hi /*find odd primes from here on. */ parse var j -1 _; if _==5 then iterate /*J divisible by 5? (right dig)*/ if j// 3==0 then iterate /*" " " 3? */ if j// 7==0 then iterate /*" " " 7? */ /* [↑] the above five lines saves time*/ do k=5 while s.k<=j /* [↓] divide by the known odd primes.*/ if j // @.k == 0 then iterate j /*Is J ÷ X? Then not prime. ___ */ end /*k*/ /* [↑] only process numbers ≤ √ J */ #= #+1; @.#= j; s.#= j*j; !.j= 1 /*bump # of Ps; assign next P; P²; P# */ end /*j*/; return</lang>
- output when using the default inputs:
index │ nice primes that are between 500 and 1,000 (not inclusive) ───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────── 1 │ 509 547 563 569 587 599 601 617 619 641 11 │ 653 659 673 677 691 709 727 743 761 797 21 │ 821 839 853 857 887 907 911 929 941 947 31 │ 977 983 997 ───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────── Found 33 nice primes that are between 500 and 1,000 (not inclusive).
Ring
<lang ring> load "stdlib.ring"
num = 0 limit1 = 500 limit2 = 1000
see "working..." + nl see "Nice numbers are:" + nl
for n = limit1 to limit2
strn = string(n) while true sumn = 0 for m = 1 to len(strn) sumn = sumn + number(strn[m]) next if len(string(sumn)) = 1 exit ok strn = string(sumn) end if isprime(n) and isprime(sumn) num = num + 1 see "" + num + ": " + n + " > Σ = " + sumn + nl ok
next
see "done..." + nl </lang>
- Output:
working... Nice numbers are: 1: 509 > Σ = 5 2: 547 > Σ = 7 3: 563 > Σ = 5 4: 569 > Σ = 2 5: 587 > Σ = 2 6: 599 > Σ = 5 7: 601 > Σ = 7 8: 617 > Σ = 5 9: 619 > Σ = 7 10: 641 > Σ = 2 11: 653 > Σ = 5 12: 659 > Σ = 2 13: 673 > Σ = 7 14: 677 > Σ = 2 15: 691 > Σ = 7 16: 709 > Σ = 7 17: 727 > Σ = 7 18: 743 > Σ = 5 19: 761 > Σ = 5 20: 797 > Σ = 5 21: 821 > Σ = 2 22: 839 > Σ = 2 23: 853 > Σ = 7 24: 857 > Σ = 2 25: 887 > Σ = 5 26: 907 > Σ = 7 27: 911 > Σ = 2 28: 929 > Σ = 2 29: 941 > Σ = 5 30: 947 > Σ = 2 31: 977 > Σ = 5 32: 983 > Σ = 2 33: 997 > Σ = 7 done...
Rust
<lang rust>// [dependencies] // primal = "0.3"
fn digital_root(n: u64) -> u64 {
if n == 0 { 0 } else { 1 + (n - 1) % 9 }
}
fn nice_primes(from: usize, to: usize) {
primal::Sieve::new(to) .primes_from(from) .take_while(|x| *x < to) .filter(|x| primal::is_prime(digital_root(*x as u64))) .for_each(|x| println!("{}", x));
}
fn main() {
nice_primes(500, 1000);
}</lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
Seed7
<lang seed7>$ include "seed7_05.s7i";
const func boolean: isPrime (in integer: number) is func
result var boolean: prime is FALSE; local var integer: upTo is 0; var integer: testNum is 3; begin if number = 2 then prime := TRUE; elsif odd(number) and number > 2 then upTo := sqrt(number); while number rem testNum <> 0 and testNum <= upTo do testNum +:= 2; end while; prime := testNum > upTo; end if; end func;
const proc: main is func
local var integer: n is 0; begin for n range 501 to 999 step 2 do if isPrime(n) and 1 + ((n - 1) rem 9) in {2, 3, 5, 7} then write(n <& " "); end if; end for; end func;</lang>
- Output:
509 547 563 569 587 599 601 617 619 641 653 659 673 677 691 709 727 743 761 797 821 839 853 857 887 907 911 929 941 947 977 983 997
Sidef
<lang ruby>func digital_root(n, base=10) {
while (n.len(base) > 1) { n = n.sumdigits(base) } return n
}
say primes(500, 1000).grep { digital_root(_).is_prime }</lang>
- Output:
[509, 547, 563, 569, 587, 599, 601, 617, 619, 641, 653, 659, 673, 677, 691, 709, 727, 743, 761, 797, 821, 839, 853, 857, 887, 907, 911, 929, 941, 947, 977, 983, 997]
Wren
<lang ecmascript>import "/math" for Int import "/trait" for Stepped import "/fmt" for Fmt
var sumDigits = Fn.new { |n|
var sum = 0 while (n > 0) { sum = sum + (n % 10) n = (n/10).floor } return sum
}
System.print("Nice primes in the interval (500, 900) are:") var c = 0 for (i in Stepped.new(501..999, 2)) {
if (Int.isPrime(i)) { var s = i while (s >= 10) s = sumDigits.call(s) if (Int.isPrime(s)) { c = c + 1 Fmt.print("$2d: $d -> Σ = $d", c, i, s) } }
}</lang>
- Output:
Nice primes in the interval (500, 900) are: 1: 509 -> Σ = 5 2: 547 -> Σ = 7 3: 563 -> Σ = 5 4: 569 -> Σ = 2 5: 587 -> Σ = 2 6: 599 -> Σ = 5 7: 601 -> Σ = 7 8: 617 -> Σ = 5 9: 619 -> Σ = 7 10: 641 -> Σ = 2 11: 653 -> Σ = 5 12: 659 -> Σ = 2 13: 673 -> Σ = 7 14: 677 -> Σ = 2 15: 691 -> Σ = 7 16: 709 -> Σ = 7 17: 727 -> Σ = 7 18: 743 -> Σ = 5 19: 761 -> Σ = 5 20: 797 -> Σ = 5 21: 821 -> Σ = 2 22: 839 -> Σ = 2 23: 853 -> Σ = 7 24: 857 -> Σ = 2 25: 887 -> Σ = 5 26: 907 -> Σ = 7 27: 911 -> Σ = 2 28: 929 -> Σ = 2 29: 941 -> Σ = 5 30: 947 -> Σ = 2 31: 977 -> Σ = 5 32: 983 -> Σ = 2 33: 997 -> Σ = 7