Primes whose sum of digits is 25

From Rosetta Code
Revision as of 09:07, 28 March 2021 by rosettacode>Horsth (→‎{{header|Nanoquery}}: append header pascal)
Primes whose sum of digits is 25 is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Show primes which sum of its decimal digits is   25


Find primes     n     such that     0  <  n  <  5000


Stretch goal

Show the total number of all such primes that do not contain any zeroes (997 <= n <= 1,111,111,111,111,111,111,111,111).

ALGOL 68

<lang algol68>BEGIN # find primes whose digits sum to 25 #

   # returns a sieve of primes up to n                                      #
   PROC eratosthenes = ( INT n )[]BOOL:
        BEGIN
            [ 1 : n ]BOOL p;
            p[ 1 ] := FALSE; p[ 2 ] := TRUE;
            FOR i FROM 3 BY 2 TO n DO p[ i ] := TRUE  OD;
            FOR i FROM 4 BY 2 TO n DO p[ i ] := FALSE OD;
            FOR i FROM 3 BY 2 TO ENTIER sqrt( n ) DO
               IF p[ i ] THEN FOR c FROM i * i BY i + i TO n DO p[ c ] := FALSE OD FI
            OD;
            p
        END # eratosthenes # ;
   # show all sum25 primes below 5000                                           #
   INT max show sum25 = 4999;
   []BOOL prime       = eratosthenes( max show sum25 );
   INT    p25 count  := 0;
   FOR n TO max show sum25 DO
       IF prime[ n ] THEN
           # have a prime, check for a sum25 prime                              #
           INT digit sum := 0;
           INT v         := n;
           WHILE v > 0 DO
               INT digit   = v MOD 10;
               digit sum +:= digit;
               v      OVERAB 10
           OD;
           IF digit sum = 25 THEN
               print( ( " ", whole( n, 0 ) ) );
               p25 count +:= 1
           FI
       FI
   OD;
   print( ( newline, "Found ", whole( p25 count, 0 ), " sum25 primes below ", whole( max show sum25 + 1, 0 ), newline ) )

END</lang>

Output:
 997 1699 1789 1879 1987 2689 2797 2887 3499 3697 3769 3877 3967 4597 4759 4957 4993
Found 17 sum25 primes below 5000

Stretch Goal

Uses the candidate generating algorithm used by Phix, Go
Uses the Miller Rabin primality test and the pow mod procedure from prelude/pow_mod

Works with: ALGOL 68G version Any - tested with release 2.8.3.win32

<lang algol68>BEGIN

   PROC pow mod = (LONG LONG INT b,in e, modulus)LONG LONG INT: (
     LONG LONG INT sq := b, e := in e;
     LONG LONG INT out:= IF ODD e THEN b ELSE 1 FI;
     e OVERAB 2;
     WHILE e /= 0 DO
       sq := sq * sq MOD modulus;
       IF ODD e THEN out := out * sq MOD modulus FI ;
       e OVERAB 2
     OD;
     out
   );
   INT p25 count := 0;
   PROC sum25 = ( LONG LONG INT p, INT rem )VOID:
        FOR i TO IF rem > 9 THEN 9 ELSE rem FI DO
           IF   rem > i THEN
               sum25( ( p * 10 ) + i, rem - i )
           ELIF ODD i AND i /= 5 THEN
               LONG LONG INT n = ( p * 10 ) + i;
               IF n MOD 3 /= 0 THEN
                   BOOL          is prime := TRUE;
                   # miller rabin primality test #
                   INT  k    = 10;
                   LONG LONG INT d := n - 1;
                   INT s := 0;
                   WHILE NOT ODD d DO
                       d OVERAB 2;
                       s +:= 1
                   OD;
                   TO k WHILE is prime DO
                       LONG LONG INT a := 2 + ENTIER (random*(n-3));
                       LONG LONG INT x := pow mod(a, d, n);
                       IF x /= 1 THEN
                           BOOL done := FALSE;
                           TO s WHILE NOT done DO
                               IF   x = n-1
                               THEN done := TRUE
                               ELSE x := x * x MOD n
                               FI
                           OD;
                           IF NOT done THEN IF x /= n-1 THEN is prime := FALSE FI FI
                       FI
                   OD;
                   # END miller rabin primality test #
                   IF is prime THEN
                       # IF ( p25 count + 1 ) MOD 100 = 0 THEN print( ( whole( p25 count + 1, -8 ), whole( n, -30 ), newline ) ) FI; #
                       p25 count +:= 1
                   FI
               FI
           FI
        OD;
   sum25( 0, 25 );
   print( ( "There are ", whole( p25 count, 0 ), " sum25 primes that contain no zeroes", newline ) )

END</lang>

Output:

Note that ALGOL 68G under Windows is fully interpreted so runtime is not of the same order as the Phix and Go samples, under Linux with optimisation and compilation. it may be faster.

There are 1525141 sum25 primes that contain no zeroes

ALGOL W

<lang algolw>begin % find some primes whose digits sum to 25 %

   % 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 MAX_NUMBER;
   MAX_NUMBER := 4999;
   begin
       logical array prime( 1 :: MAX_NUMBER );
       integer       pCount;
       % sieve the primes to MAX_NUMBER %
       Eratosthenes( prime, MAX_NUMBER );
       % find the primes whose digits sum to 25 %
       pCount := 0;
       for i := 1 until MAX_NUMBER do begin
           if prime( i ) then begin
               integer dSum, v;
               v    := i;
               dSum := 0;
               while v > 0 do begin
                   dSum := dSum + ( v rem 10 );
                   v    := v div 10
               end while_v_gt_0 ;
               if dSum = 25 then begin
                   writeon( i_w := 4, s_w := 0, " ", i );
                   pCount := pCount + 1;
                   if pCount rem 20 = 0 then write()
               end if_prime_pReversed
           end if_prime_i
       end for_i ;
       write( i_w := 1, s_w := 0, "Found ", pCount, " sum25 primes below ", MAX_NUMBER + 1 )
   end

end.</lang>

Output:
  997 1699 1789 1879 1987 2689 2797 2887 3499 3697 3769 3877 3967 4597 4759 4957 4993
Found 17 sum25 primes below 5000

C++

Library: GMP

Stretch goal solved the same way as Phix and Go. <lang cpp>#include <algorithm>

  1. include <chrono>
  2. include <iomanip>
  3. include <iostream>
  4. include <string>
  1. include <gmpxx.h>

bool is_probably_prime(const mpz_class& n) {

   return mpz_probab_prime_p(n.get_mpz_t(), 25) != 0;

}

bool is_prime(int n) {

   if (n < 2)
       return false;
   if (n % 2 == 0)
       return n == 2;
   if (n % 3 == 0)
       return n == 3;
   for (int p = 5; p * p <= n; p += 4) {
       if (n % p == 0)
           return false;
       p += 2;
       if (n % p == 0)
           return false;
   }
   return true;

}

int digit_sum(int n) {

   int sum = 0;
   for (; n > 0; n /= 10)
       sum += n % 10;
   return sum;

}

int count_all(const std::string& str, int rem) {

   int count = 0;
   if (rem == 0) {
       switch (str.back()) {
       case '1':
       case '3':
       case '7':
       case '9':
           if (is_probably_prime(mpz_class(str)))
               ++count;
           break;
       default:
           break;
       }
   } else {
       for (int i = 1; i <= std::min(9, rem); ++i)
           count += count_all(str + char('0' + i), rem - i);
   }
   return count;

}

int main() {

   std::cout.imbue(std::locale(""));
   const int limit = 5000;
   std::cout << "Primes < " << limit << " whose digits sum to 25:\n";
   int count = 0;
   for (int p = 1; p < limit; ++p) {
       if (digit_sum(p) == 25 && is_prime(p)) {
           ++count;
           std::cout << std::setw(6) << p << (count % 10 == 0 ? '\n' : ' ');
       }
   }
   std::cout << '\n';
   auto start = std::chrono::steady_clock::now();
   count = count_all("", 25);
   auto end = std::chrono::steady_clock::now();
   std::cout << "\nThere are " << count
             << " primes whose digits sum to 25 and include no zeros.\n";
   std::cout << "Time taken: "
             << std::chrono::duration<double>(end - start).count() << "s\n";
   return 0;

}</lang>

Output:
Primes < 5,000 whose digits sum to 25:
   997  1,699  1,789  1,879  1,987  2,689  2,797  2,887  3,499  3,697
 3,769  3,877  3,967  4,597  4,759  4,957  4,993 

There are 1,525,141 primes whose digits sum to 25 and include no zeros.
Time taken: 13.7191s

Delphi

Library: PrimTrial
Translation of: Ring

<lang Delphi> program Primes_which_sum_of_digits_is_25;

{$APPTYPE CONSOLE}

uses

 System.SysUtils,
 PrimTrial;

var

 row: Integer = 0;
 limit1: Integer = 25;
 limit2: Integer = 5000;

function Sum25(n: Integer): boolean; var

 sum: Integer;
 str: string;
 c: char;

begin

 sum := 0;
 str := n.ToString;
 for c in str do
   inc(sum, strToInt(c));
 Result := sum = limit1;

end;

begin

 for var n := 1 to limit2-1 do
 begin
   if isPrime(n) and sum25(n) then
   begin
     inc(row);
     write(n: 4, ' ');
     if (row mod 5) = 0 then
       writeln;
   end;
 end;
 readln;

end.</lang>

Output:
 997 1699 1789 1879 1987
2689 2797 2887 3499 3697
3769 3877 3967 4597 4759
4957 4993

Factor

Works with: Factor version 0.99 2021-02-05

<lang factor>USING: kernel lists lists.lazy math math.primes.lists prettyprint ;

digit-sum ( n -- sum )
   0 swap [ 10 /mod rot + swap ] until-zero ;
lprimes25 ( -- list ) lprimes [ digit-sum 25 = ] lfilter ;

lprimes25 [ 5,000 < ] lwhile [ . ] leach</lang>

Output:
997
1699
1789
1879
1987
2689
2797
2887
3499
3697
3769
3877
3967
4597
4759
4957
4993

Forth

Works with: Gforth

<lang forth>: prime? ( n -- ? ) here + c@ 0= ;

notprime! ( n -- ) here + 1 swap c! ;
prime_sieve { n -- }
 here n erase
 0 notprime!
 1 notprime!
 n 4 > if
   n 4 do i notprime! 2 +loop
 then
 3
 begin
   dup dup * n <
 while
   dup prime? if
     n over dup * do
       i notprime!
     dup 2* +loop
   then
   2 +
 repeat
 drop ;
digit_sum ( u -- u )
 dup 10 < if exit then
 10 /mod recurse + ;
prime25? { p -- ? }
 p prime? if
   p digit_sum 25 =
 else
   false
 then ;  
.prime25 { n -- }
 ." Primes < " n . ." whose digits sum to 25:" cr
 n prime_sieve
 0
 n 0 do
   i prime25? if
     i 5 .r
     1+ dup 10 mod 0= if cr then
   then
 loop
 cr ." Count: " . cr ;

5000 .prime25 bye</lang>

Output:
Primes < 5000 whose digits sum to 25:
  997 1699 1789 1879 1987 2689 2797 2887 3499 3697
 3769 3877 3967 4597 4759 4957 4993
Count: 17 

Go

This uses the Phix routine for the stretch goal though I've had to plug in a GMP wrapper to better the Phix time. Using Go's native big.Int, the time was slightly slower than Phix at 1 minute 28 seconds. <lang go>package main

import (

   "fmt"
   big "github.com/ncw/gmp"
   "time"

)

// for small numbers func sieve(limit int) []bool {

   limit++
   // True denotes composite, false denotes prime.
   c := make([]bool, limit) // all false by default
   c[0] = true
   c[1] = true
   // no need to bother with even numbers over 2 for this task
   p := 3 // Start from 3.
   for {
       p2 := p * p
       if p2 >= limit {
           break
       }
       for i := p2; i < limit; i += 2 * p {
           c[i] = true
       }
       for {
           p += 2
           if !c[p] {
               break
           }
       }
   }
   return c

}

func sumDigits(n int) int {

   sum := 0
   for n > 0 {
       sum += n % 10
       n /= 10
   }
   return sum

}

func min(a, b int) int {

   if a < b {
       return a
   }
   return b

}

// for big numbers func countAll(p string, rem, res int) int {

   if rem == 0 {
       b := p[len(p)-1]
       if b == '1' || b == '3' || b == '7' || b == '9' {
           z := new(big.Int)
           z.SetString(p, 10)
           if z.ProbablyPrime(1) {
               res++
           }
       }
   } else {
       for i := 1; i <= min(9, rem); i++ {
           res = countAll(p+fmt.Sprintf("%d", i), rem-i, res)
       }
   }
   return res

}

func commatize(n int) string {

   s := fmt.Sprintf("%d", n)
   if n < 0 {
       s = s[1:]
   }
   le := len(s)
   for i := le - 3; i >= 1; i -= 3 {
       s = s[0:i] + "," + s[i:]
   }
   if n >= 0 {
       return s
   }
   return "-" + s

}

func main() {

   start := time.Now()
   c := sieve(4999)
   var primes25 []int
   for i := 997; i < 5000; i += 2 {
       if !c[i] && sumDigits(i) == 25 {
           primes25 = append(primes25, i)
       }
   }
   fmt.Println("The", len(primes25), "primes under 5,000 whose digits sum to 25 are:")
   fmt.Println(primes25)
   n := countAll("", 25, 0)
   fmt.Println("\nThere are", commatize(n), "primes whose digits sum to 25 and include no zeros.")
   fmt.Printf("\nTook %s\n", time.Since(start))

}</lang>

Output:
The 17 primes under 5,000 whose digits sum to 25 are:
[997 1699 1789 1879 1987 2689 2797 2887 3499 3697 3769 3877 3967 4597 4759 4957 4993]

There are 1,525,141 primes whose digits sum to 25 and include no zeros.

Took 25.300758564s

Haskell

<lang haskell>import Data.Bifunctor (second) import Data.List (replicate) import Data.List.Split (chunksOf) import Data.Numbers.Primes (primes)


PRIMES WITH DECIMAL DIGITS SUMMING TO 25 -------

matchingPrimes :: [Int] matchingPrimes =

 takeWhile
   (< 5000)
   [n | n <- primes, 25 == decimalDigitSum n]

decimalDigitSum :: Int -> Int decimalDigitSum n =

 snd $
   until
     ((0 ==) . fst)
     (\(n, x) -> second (+ x) $ quotRem n 10)
     (n, 0)

TEST -------------------------

main :: IO () main = do

 let w = length (show (last matchingPrimes))
 mapM_ putStrLn $
   ( show (length matchingPrimes)
       <> " primes (< 5000) with decimal digits totalling 25:\n"
   ) :
   ( unwords
       <$> chunksOf
         4
         (justifyRight w ' ' . show <$> matchingPrimes)
   )

justifyRight :: Int -> Char -> String -> String justifyRight n c = (drop . length) <*> (replicate n c <>)</lang>

Output:
17 primes (< 5000) with decimal digits totalling 25:

 997 1699 1789 1879
1987 2689 2797 2887
3499 3697 3769 3877
3967 4597 4759 4957
4993

Julia

<lang julia>using Primes

let

   pmask, pcount = primesmask(1, 5000), 0
   issum25prime(n) = pmask[n] && sum(digits(n)) == 25
   println("Primes with digits summing to 25 between 0 and 5000:")
   for n in 1:4999
       if issum25prime(n)
           pcount += 1
           print(rpad(n, 5))
       end
   end
   println("\nTotal found: $pcount")

end

</lang>

Output:
Primes with digits summing to 25 between 0 and 5000:
997  1699 1789 1879 1987 2689 2797 2887 3499 3697 3769 3877 3967 4597 4759 4957 4993 
Total found: 17

Stretch goal

Translation of: Phix

<lang julia>using Primes, Formatting

function sum25(p::String, rm, res)

   if rm == 0
       if p[end] in "1379" && isprime(parse(Int128, p))
           res += 1
       end
   else
       for i in 1:min(rm, 9)
           res = sum25(p * string(i), rm - i, res)
       end
   end
   return res

end

@time println("There are ", format(sum25("", 25, 0), commas=true),

   " primes whose digits sum to 25 without any zero digits.")

</lang>

Output:
There are 1,525,141 primes whose digits sum to 25 without any zero digits.
 29.377893 seconds (100.61 M allocations: 4.052 GiB, 0.55% gc time)

Nanoquery

<lang Nanoquery>// find primes using the sieve of eratosthenes // https://en.wikipedia.org/wiki/Sieve_of_Eratosthenes#Pseudocode def find_primes(upper_bound)

   a = {true} * (upper_bound + 1)
   for i in range(2, int(sqrt(upper_bound)))
       if a[i]
           for j in range(i ^ 2, upper_bound, i)
               a[j] = false
           end for
       end if
   end for
   primes = {}
   for i in range(2, len(a) - 1)
       if a[i]
           primes.append(i)
       end if
   end for
   return primes

end find_primes

def sum_digits(num)

   digits = str(num)
   digit_sum = 0
   for i in range(0, len(digits) - 1)
       digit_sum += int(digits[i])
   end for
   return digit_sum

end sum_digits

primes_to_check = find_primes(5000) for prime in primes_to_check

   if sum_digits(prime) = 25
       print prime + " "
   end if

end for println</lang>

Output:
997 1699 1789 1879 1987 2689 2797 2887 3499 3697 3769 3877 3967 4597 4759 4957 4993 

Pascal

added only strechted goal.Generating the numbers by permutation.Same result as go.runtime reduced from 5.8s to 0.4s
I don't know why the gmp test is so much faster and why there is one more probably prime. <lang pascal> program Perm5aus8; {$IFDEF FPC}

 {$mode Delphi}
 {$Optimization ON,All}

{$ELSE}

 {$APPTYPE CONSOLE}

{$ENDIF} uses

 sysutils,
 gmp;

const

 cTotalSum = 25;
 cMaxCardsOnDeck = cTotalSum;
 CMaxCardsUsed   = cTotalSum;

type

 tDeckIndex     = 0..cMaxCardsOnDeck-1;
 tSequenceIndex = 0..CMaxCardsUsed-1;
 tDiffCardCount = 0..9;
 tMengenElem     = record
                     Elemcount : tDeckIndex;
                     Elem  : tDiffCardCount;
                   end;
 tMenge          = record
                     RestMenge : array [low(tDiffCardCount)..High(tDiffCardCount)] of tMengenElem;
                     MaxUsedIdx,
                     TotElemCnt   : word;
                   end;
 tRestmengen     = array [low(tSequenceIndex)..High(tSequenceIndex)+1] of tMenge;
 tCardSequence   = array [low(tSequenceIndex)..High(tSequenceIndex)] of tDiffCardCount;
 tPermRec        = packed record
                     permTiefe : byte;// Stelle der Änderung gegenüber Vorgängerpermutation
                     permCardSequence :tCardSequence ;
                   end;

var

// globale Variable, um Stelle der Änderung gegenüber der
// Vorgänger permutation festzuhalten
 Restmengen    : tRestmengen;
 TotalUsedDigits : array[tDeckIndex] of Int32;
 ManifoldOfDigit : array[tDiffCardCount] of Int32;
 CardSequence  : tCardSequence;
 CardString    : string[cMaxCardsOnDeck+3];
 Count: NativeInt;
 PermCount  : integer;
 mindepth   : integer;

//***************************************************************************** procedure MengeInit(var ioMenge:tMenge); var

 i : integer;

begin

 with ioMenge do
   begin
   MaxUsedIdx := 0;
   For i := Low(tDiffCardCount) to High(tDiffCardCount) do
     with RestMenge[i] do
       begin
       ElemCount := 0;
       Elem      := 0;
       end;
   end;

end;

procedure CheckPrime(LastDigit:NativeInt); var

 z : mpz_t;

begin

 if Lastdigit in [1,3,7,9] then
 Begin
   mpz_init_set_str(z,pChar(@CardString[1]),10);
   if mpz_probab_prime_p(z,1)>0 then
     inc(count);
   mpz_clear(z);
 end;

end;

procedure Permute(depth,MaxCardsUsed:integer); var

 i : NativeInt;
 pMengeElem : ^tMengenElem;

begin

 i := 0;
 pMengeElem := @RestMengen[depth].RestMenge[i];
 repeat
   if  pMengeElem^.Elemcount <> 0 then begin
       //take element
       dec(pMengeElem^.ElemCount);
       //insert in result here string too
       CardSequence[depth] := pMengeElem^.Elem;
       CardString[depth+1] := chr(pMengeElem^.Elem+Ord('0'));
       //done one permutation
       IF depth = MaxCardsUsed then begin
         inc(permCount);

// ###########

           setlength(CardString,depth+1);
           CardString[ depth+2] := #0;
           CheckPrime(CardSequence[depth]);

// ###########

         mindepth := depth;
         end
       else begin
         RestMengen[depth+1]:= RestMengen[depth];
         Permute(depth+1,MaxCardsUsed);
         //insert element
         inc(pMengeElem^.ElemCount);
         dec(minDepth);
         end;
       end;
   inc(pMengeElem);
   inc(i);
 until i >=RestMengen[depth].MaxUsedIdx;

end;

procedure Check(n:nativeInt); var

 i,dgtCnt,cnt,dgtIdx : NativeInt;

Begin

 MengeInit(Restmengen[0]);
 dgtCnt := 0;
 dgtIdx := 0;
 with Restmengen[0] do
 Begin
   For i in tDiffCardCount do
   Begin
     cnt := ManifoldOfDigit[i];
     if cnt > 0 then
     Begin
       with RestMenge[dgtIdx] do
       Begin
         Elemcount := cnt;
         Elem  := i;
       end;
       inc(dgtCnt,cnt);
       inc(dgtIdx);
     end;
   end;
   MaxUsedIdx := dgtIdx;
 end;
 permute(0,dgtCnt-1);

end;

procedure AppendToSum(n,dgt,remsum:NativeInt); var

 i: NativeInt;

begin

 inc(ManifoldOfDigit[dgt]);
 IF remsum > 0 then
   For i := dgt to 9 do
     AppendToSum(n+1,i,remsum-i)
 else
 Begin
   if remsum = 0 then
   Begin
     Check(n);
     inc(TotalUsedDigits[n]);
   end;
 end;
 dec(ManifoldOfDigit[dgt]);

end;

var

 i :NativeInt;

BEGIN

 permcount:=0;
 fillchar(ManifoldOfDigit[0],SizeOf(ManifoldOfDigit),#0);
 count := 0;
 For i := 1 to 9 do
   AppendToSum(0,i,cTotalSum-i);
 writeln('Count of generated numbers with digits sum of ',cTotalSum,' are ',permcount);
 Writeln('Propably primes ',count);

//For i := 0 to cTotalSum-1 do writeln(i+1:3,TotalUsedDigits[i]:10); writeln; END.</lang>

Output:
Count of generated numbers with digits sum of 25 are 16499120
Propably primes 1525142<pre>

real	0m6,875s

=={{header|Perl}}==
{{libheader|ntheory}}
<lang perl>use strict;
use warnings;
use feature 'say';
use List::Util 'sum';
use ntheory 'is_prime';

my($limit, @p25) = 5000;
is_prime($_) and 25 == sum(split '', $_) and push @p25, $_ for 1..$limit;
say @p25 . " primes < $limit with digital sum 25:\n" . join ' ', @p25;
</lang>
{{out}}
<pre>17 primes < 5000 with digital sum 25:
997 1699 1789 1879 1987 2689 2797 2887 3499 3697 3769 3877 3967 4597 4759 4957 4993

Phix

<lang Phix>function sum25(integer p) return sum(sq_sub(sprint(p),'0'))=25 end function sequence res = filter(get_primes_le(5000),sum25) string r = join(shorten(apply(res,sprint),"",4)) printf(1,"%d sum25 primes less than 5000 found: %s\n",{length(res),r})</lang>

Output:
17 sum25 primes less than 5000 found: 997 1699 1789 1879 ... 4597 4759 4957 4993

Stretch goal

Library: Phix/mpfr

<lang Phix>include mpfr.e atom t0 = time(), t1 = time()+1 mpz pz = mpz_init(0)

function sum25(string p, integer rem, res=0)

   if rem=0 then
       if find(p[$],"1379") then -- (saves 13s)
           mpz_set_str(pz,p)
           if mpz_prime(pz) then
               res += 1
               if time()>t1 then
                   progress("%d, %s...",{res,p})
                   t1 = time()+1
               end if
           end if
       end if
   else
       for i=1 to min(rem,9) do
           res = sum25(p&'0'+i,rem-i,res)
       end for
   end if
   return res

end function

printf(1,"There are %,d sum25 primes that contain no zeroes\n",sum25("",25)) ?elapsed(time()-t0)</lang>

Output:
There are 1,525,141 sum25 primes that contain no zeroes
"1 minute and 27s"

Python

<lang python>Primes with a decimal digit sum of 25

from itertools import takewhile


  1. primesWithGivenDigitSum :: Int -> Int -> [Int]

def primesWithGivenDigitSum(below, n):

   Primes below a given value with
      decimal digits sums equal to n.
   
   return list(
       takewhile(
           lambda x: below > x,
           (
               x for x in primes()
               if n == sum(int(c) for c in str(x))
           )
       )
   )


  1. ------------------------- TEST -------------------------
  2. main :: IO ()

def main():

   Test
   matches = primesWithGivenDigitSum(5000, 25)
   print(
       str(len(matches)) + (
           ' primes below 5000 with a decimal digit sum of 25:\n'
       )
   )
   print(
       '\n'.join([
           ' '.join([str(x).rjust(4, ' ') for x in xs])
           for xs in chunksOf(4)(matches)
       ])
   )


  1. ----------------------- GENERIC ------------------------
  1. chunksOf :: Int -> [a] -> a

def chunksOf(n):

   A series of lists of length n, subdividing the
      contents of xs. Where the length of xs is not evenly
      divible, the final list will be shorter than n.
   
   def go(xs):
       return (
           xs[i:n + i] for i in range(0, len(xs), n)
       ) if 0 < n else None
   return go


  1. primes :: [Int]

def primes():

    Non-finite sequence of prime numbers.
   
   n = 2
   dct = {}
   while True:
       if n in dct:
           for p in dct[n]:
               dct.setdefault(n + p, []).append(p)
           del dct[n]
       else:
           yield n
           dct[n * n] = [n]
       n = 1 + n


  1. MAIN ---

if __name__ == '__main__':

   main()</lang>
Output:
17 primes below 5000 with a decimal digit sum of 25:

 997 1699 1789 1879
1987 2689 2797 2887
3499 3697 3769 3877
3967 4597 4759 4957
4993

Raku

<lang perl6>unit sub MAIN ($limit = 5000); say "{+$_} primes < $limit with digital sum 25:\n{$_».fmt("%" ~ $limit.chars ~ "d").batch(10).join("\n")}",

   with ^$limit .grep: { .is-prime and .comb.sum == 25 }</lang>
Output:
17 primes < 5000 with digital sum 25:
 997 1699 1789 1879 1987 2689 2797 2887 3499 3697
3769 3877 3967 4597 4759 4957 4993

REXX

This REXX version allows the following to be specified on the command line:

  •   the high number   (HI)
  •   the number of columns shown per line   (COLS)
  •   the target sum   (TARGET)

<lang rexx>/*REXX pgm finds and displays primes less than HI whose decimal digits sum to TARGET.*/ parse arg hi cols target . /*obtain optional argument from the CL.*/ if hi== | hi=="," then hi= 5000 /*Not specified? Then use the default.*/ if cols== | cols=="," then cols= 10 /* " " " " " " */ if target== | target=="," then target= 25 /* " " " " " " */ call genP /*build array of semaphores for primes.*/ w= 10 /*width of a number in any column. */

         @primes= ' primes that are  < '  commas(hi)  " and whose decimal digits sum to "

if cols>0 then say ' index │'center(@primes commas(target), 1 + cols*(w+1) ) if cols>0 then say '───────┼'center("" , 1 + cols*(w+1), '─') primesT= 0; idx= 1 /*define # target primes found & index.*/ $= /*list of target primes found (so far).*/

    do j=1  for #;     y= @.j                   /*examine all the primes generated.    */
    if sumDigs(y)\==target  then iterate        /*Is sum≡target sum?  No, then skip it.*/
    primesT= primesT + 1                        /*bump the number of target primes.    */
    if cols==0              then iterate        /*Build the list  (to be shown later)? */
    c= commas(y)                                /*maybe add commas to the number.      */
    $= $ right(c, max(w, length(c) ) )          /*add a prime ──► list,  allow big #'s.*/
    if primesT//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.*/ say say 'Found ' commas(primesT) @primes commas(target) 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: !.= 0 /*placeholders for primes' semaphores. */

     @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13 /*define some  low primes.             */
     !.2=1; !.3=1; !.5=1; !.7=1; !.11=1; @.13=1 /*   "     "   "   primes' semaphores. */
                          #= 6;    s.#= @.# **2 /*number of primes so far;     prime². */
                                                /* [↓]  generate more  primes  ≤  high.*/
       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?            */
                            if j//11==0  then iterate  /*"     "      " 11?            */
              do k=6  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

/*──────────────────────────────────────────────────────────────────────────────────────*/ sumDigs: parse arg x 1 s 2 -1 z; L= length(x); if L==1 then return s; s= s + z

                  do m=2  for L-2;   s= s + substr(x, m, 1);  end;  return s</lang>
output   when using the default inputs:
 index │                         primes that are  <  5,000  and whose decimal digits sum to  25
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   │        997      1,699      1,789      1,879      1,987      2,689      2,797      2,887      3,499      3,697
  11   │      3,769      3,877      3,967      4,597      4,759      4,957      4,993

Found  17  primes that are  <  5,000  and whose decimal digits sum to  25
output   when using the input of:     1000000   0
Found  6,198  primes that are  <  1,000,000  and whose decimal digits sum to  25

Ring

<lang ring> load "stdlib.ring"

see "working..." + nl decimals(0) row = 0 num = 0 nr = 0 numsum25 = 0 limit1 = 25 limit2 = 5000

for n = 1 to limit2

   if isprime(n)
      bool = sum25(n)
      if bool = 1
         row = row + 1
         see "" + n + " "
         if (row%5) = 0
             see nl
         ok
      ok
   ok

next

see nl + "Found " + row + " sum25 primes below 5000" + nl

time1 = clock() see nl row = 0

while true

     num = num + 1
     str = string(num)
     for m = 1 to len(str)
         if str[m] = 0
            loop
         ok
     next
     if isprime(num)
        bool = sum25(num)
        if bool = 1
           nr = num
           numsum25 = numsum25 + 1
         ok
     ok
     time2 = clock()
     time3 = (time2-time1)/1000/60
     if time3 > 30
        exit
     ok

end

see "There are " + numsum25 + " sum25 primes that contain no zeroes (during 30 mins)" + nl see "The last sum25 prime found during 30 mins is: " + nr + nl see "time = " + time3 + " mins" + nl see "done..." + nl

func sum25(n)

    sum = 0
    str = string(n)
    for n = 1 to len(str)
        sum = sum + number(str[n])
    next
    if sum = limit1
       return 1
    ok

</lang>

Output:
working...
997 1699 1789 1879 1987 
2689 2797 2887 3499 3697 
3769 3877 3967 4597 4759 
4957 4993 
Found 17 sum25 primes below 5000

There are 1753 sum25 primes that contain no zeroes (during 30 mins)
The last sum25 prime found during 30 mins is: 230929
time = 30 mins
done...

Wren

Library: Wren-math
Library: Wren-fmt
Library: Wren-seq

Although do-able, the stretch goal would take too long in Wren so I haven't bothered. <lang ecmascript>import "/math" for Int import "/fmt" for Fmt import "/seq" for Lst

var sumDigits = Fn.new { |n|

   var sum = 0
   while (n > 0) {
       sum = sum + (n % 10)
       n = (n/10).floor
   }
   return sum

}

var primes = Int.primeSieve(4999).where { |p| p >= 997 } var primes25 = [] for (p in primes) {

   if (sumDigits.call(p) == 25) primes25.add(p)

} System.print("The %(primes25.count) primes under 5,000 whose digits sum to 25 are:") for (chunk in Lst.chunks(primes25, 6)) Fmt.print("$,6d", chunk)</lang>

Output:
The 17 primes under 5,000 whose digits sum to 25 are:
   997  1,699  1,789  1,879  1,987  2,689
 2,797  2,887  3,499  3,697  3,769  3,877
 3,967  4,597  4,759  4,957  4,993