Sum of square and cube digits of an integer are primes

Revision as of 22:33, 25 February 2023 by Peak (talk | contribs) (jq)

Find and show here all positive integers n less than 100 where:

  • the sum of the digits of the square of n is prime; and
  • the sum of the digits of the cube of n is also prime.
Sum of square and cube digits of an integer are primes 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


Example

16 satisfies the task descrption because 16 x 16 = 256 has a digit sum of 13 which is prime and 16 x 16 x 16 = 4096 has a digit sum of 19 which is also prime.

ALGOL 68

BEGIN # find numbers where the digit sums of the square and cube are prtime #
    INT max number = 99; # maximum number to consider #
    PR read "primes.incl.a68" PR
    []BOOL prime = PRIMESIEVE ( INT d sum := 9; # calculate the largest possible digit sum #
                                INT n     := max number * max number * max number;
                                WHILE ( n OVERAB 10 ) > 0 DO
                                    d sum +:= 9
                                OD;
                                d sum
                              );
    # returns the sum of the digits of n #
    OP  DIGITSUM = ( INT n )INT:
        BEGIN
            INT v      := ABS n;
            INT result := v MOD 10;
            WHILE ( v OVERAB 10 ) > 0 DO
                result +:= v MOD 10
            OD;
            result
        END # DIGITSUM # ;
    FOR i TO max number DO
        INT i2 = i * i;
        IF prime[ DIGITSUM i2 ] THEN
            IF prime[ DIGITSUM ( i * i2 ) ] THEN
                print( ( " ", whole( i, 0 ) ) )
            FI
        FI
    OD
END
Output:
 16 17 25 28 34 37 47 52 64

APL

((/⍨)/∘((2=0+.=⍳|⊢)(+/¨∘)¨*2 3)¨)100
Output:
16 17 25 28 34 37 47 52 64

Arturo

print select 1..100 'x ->
    and? [prime? sum digits x^2]
         [prime? sum digits x^3]
Output:
16 17 25 28 34 37 47 52 64

AWK

# syntax: GAWK -f SUM_OF_SQUARE_AND_CUBE_DIGITS_OF_AN_INTEGER_ARE_PRIMES.AWK
# converted from FreeBASIC
BEGIN {
    start = 1
    stop = 99
    for (i=start; i<=stop; i++) {
      if (is_prime(digit_sum(i^3,10)) && is_prime(digit_sum(i^2,10))) {
        printf("%5d%1s",i,++count%10?"":"\n")
      }
    }
    printf("\nSum of square and cube digits are prime %d-%d: %d\n",start,stop,count)
    exit(0)
}
function digit_sum(n,b,  s) { # digital sum of n in base b
    while (n) {
      s += n % b
      n = int(n/b)
    }
    return(s)
}
function is_prime(n,  d) {
    d = 5
    if (n < 2) { return(0) }
    if (n % 2 == 0) { return(n == 2) }
    if (n % 3 == 0) { return(n == 3) }
    while (d*d <= n) {
      if (n % d == 0) { return(0) }
      d += 2
      if (n % d == 0) { return(0) }
      d += 4
    }
    return(1)
}
Output:
   16    17    25    28    34    37    47    52    64
Sum of square and cube digits are prime 1-99: 9

BQN

# 'Library' functions from BQNCrate
Digits  10 {𝕗|⌊÷𝕗(1+·𝕗1⌈⊢)}
Prime  2=·+´0=(1+↕)|

(˝((Prime +´Digits)¨23))/↕100
Output:
⟨ 16 17 25 28 34 37 47 52 64 ⟩

C

#include <stdio.h>
#include <stdbool.h>

int digit_sum(int n) {
    int sum;
    for (sum = 0; n; n /= 10) sum += n % 10;
    return sum;
}

/* The numbers involved are tiny */
bool prime(int n) {
    if (n<4) return n>=2;
    for (int d=2; d*d <= n; d++)
        if (n%d == 0) return false;
    return true;
}

int main() {
    for (int i=1; i<100; i++)
        if (prime(digit_sum(i*i)) & prime(digit_sum(i*i*i)))
            printf("%d ", i);
    printf("\n");
    return 0;
}
Output:
16 17 25 28 34 37 47 52 64

CLU

digit_sum = proc (n: int) returns (int)
    sum: int := 0
    while n>0 do
        sum := sum + n // 10
        n := n / 10
    end
    return(sum)
end digit_sum

% The numbers tested for primality are very small,
% so this simple test suffices.
prime = proc (n: int) returns (bool)
    if n<2 then return(false) end
    d: int := 2
    while d*d <= n do
        if n//d=0 then return(false) end
        d := d+1
    end
    return(true)
end prime

accept = proc (n: int) returns (bool)
    return(prime(digit_sum(n**2)) cand prime(digit_sum(n**3)))
end accept

start_up = proc ()
    po: stream := stream$primary_output()
    for i: int in int$from_to(1, 99) do
        if accept(i) then
            stream$puts(po, int$unparse(i) || " ")
        end
    end
end start_up
Output:
16 17 25 28 34 37 47 52 64

COBOL

       IDENTIFICATION DIVISION.
       PROGRAM-ID. SQUARE-CUBE-DIGITS-PRIME.
       
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01 NUMBER-SEARCH-VARS.
          03 CAND             PIC 9(6).
          03 SQUARE           PIC 9(6).
          03 CUBE             PIC 9(6).
          
       01 SUM-DIGITS-VARS.
          03 SUM-NUM          PIC 9(6).
          03 DIGITS           PIC 9 OCCURS 6 TIMES INDEXED BY D
                              REDEFINES SUM-NUM.
          03 SUM              PIC 99.
       
       01 PRIME-TEST-VARS.
          03 DIVISOR          PIC 99.
          03 DIV-TEST         PIC 99V9999.
          03 FILLER           REDEFINES DIV-TEST.
             05 FILLER        PIC 99.
             05 FILLER        PIC 9999.
                88 DIVISIBLE  VALUE ZERO.
          03 PRIME-FLAG       PIC X.
             88 PRIME         VALUE '*'.
       
       01 OUT-FMT             PIC Z9.
       
       PROCEDURE DIVISION.
       BEGIN.
           PERFORM CHECK-NUMBER VARYING CAND FROM 1 BY 1
           UNTIL CAND IS EQUAL TO 100.
           STOP RUN.
       
       CHECK-NUMBER.
           MULTIPLY CAND BY CAND GIVING SQUARE.
           MULTIPLY CAND BY SQUARE GIVING CUBE.
           MOVE SQUARE TO SUM-NUM.
           PERFORM SUM-DIGITS.
           PERFORM PRIME-TEST.
           IF PRIME,
               MOVE CUBE TO SUM-NUM,
               PERFORM SUM-DIGITS,
               PERFORM PRIME-TEST,
               IF PRIME,
                   MOVE CAND TO OUT-FMT,
                   DISPLAY OUT-FMT.
           
       SUM-DIGITS.
           MOVE ZERO TO SUM.
           PERFORM SUM-DIGIT VARYING D FROM 1 BY 1
           UNTIL D IS GREATER THAN 6.
           
       SUM-DIGIT.
           ADD DIGITS(D) TO SUM.
       
       PRIME-TEST.
           MOVE '*' TO PRIME-FLAG.
           PERFORM CHECK-DIVISOR VARYING DIVISOR FROM 2 BY 1
           UNTIL NOT PRIME, OR DIVISOR IS EQUAL TO SUM.
       
       CHECK-DIVISOR.
           DIVIDE SUM BY DIVISOR GIVING DIV-TEST.
           IF DIVISIBLE, MOVE SPACE TO PRIME-FLAG.
Output:
16
17
25
28
34
37
47
52
64

F#

This task uses Extensible Prime Generator (F#)

// Sum of square and cube digits of an integer are primes. Nigel Galloway: December 22nd., 2021
let rec fN g=function 0->g |n->fN(g+n%10)(n/10)
[1..99]|>List.filter(fun g->isPrime(fN 0 (g*g)) && isPrime(fN 0 (g*g*g)))|>List.iter(printf "%d "); printfn ""
Output:
16 17 25 28 34 37 47 52 64

Factor

Works with: Factor version 0.99 2021-06-02
USING: kernel math math.functions math.primes math.text.utils prettyprint sequences ;

100 <iota> [ [ sq ] [ 3 ^ ] bi [ 1 digit-groups sum prime? ] both? ] filter .
Output:
V{ 16 17 25 28 34 37 47 52 64 }

FOCAL

01.10 F I=1,100;D 2
01.20 Q

02.10 F P=2,3;S N=I^P;D 3;D 4;I (C)2.3
02.20 T %2,I,!
02.30 R

03.10 S S=0
03.20 S M=FITR(N/10)
03.30 S S=S+(N-M*10)
03.40 S N=M
03.50 I (-N)3.2

04.10 S C=0
04.20 I (1-S)4.3;S C=-1;R
04.30 I (2-S)4.4;S C=0;R
04.40 F D=2,FSQT(S)+1;D 5;I (C)4.5
04.50 R

05.10 S Z=S/D
05.20 I (FITR(Z)-Z)5.3;S C=-1
05.30 R
Output:
= 16
= 17
= 25
= 28
= 34
= 37
= 47
= 52
= 64

FreeBASIC

function digsum(byval n as uinteger, b as const uinteger) as uinteger
    'digital sum of n in base b
    dim as integer s
    while n
        s+=n mod b
        n\=b
    wend
    return s
end function

function isprime(n as const uinteger) as boolean
    if n<2 then return false
    if n<4 then return true
    if n mod 2 = 0 then return false
    dim as uinteger i = 3
    while i*i<=n
        if n mod i = 0 then return false
        i+=2
    wend
    return true
end function

for n as uinteger = 1 to 99
    if isprime(digsum(n^3,10)) andalso isprime(digsum(n^2,10)) then print n;"   ";
next n
Output:
16   17   25   28   34   37   47   52   64

Go

Library: Go-rcu
package main

import (
    "fmt"
    "rcu"
)

func main() {
    for i := 1; i < 100; i++ {
        if !rcu.IsPrime(rcu.DigitSum(i*i, 10)) {
            continue
        }
        if rcu.IsPrime(rcu.DigitSum(i*i*i, 10)) {
            fmt.Printf("%d ", i)
        }
    }
    fmt.Println()
}
Output:
16 17 25 28 34 37 47 52 64 

Haskell

import Data.Bifunctor (first)
import Data.Numbers.Primes (isPrime)

---- SQUARE AND CUBE BOTH HAVE PRIME DECIMAL DIGIT SUMS --

p :: Int -> Bool
p =
  ((&&) . primeDigitSum . (^ 2))
    <*> (primeDigitSum . (^ 3))

--------------------------- TEST -------------------------
main :: IO ()
main = print $ filter p [2 .. 99]

------------------------- GENERIC ------------------------
primeDigitSum :: Int -> Bool
primeDigitSum = isPrime . digitSum 10

digitSum :: Int -> Int -> Int
digitSum base = go
  where
    go 0 = 0
    go n = uncurry (+) . first go $ quotRem n base
Output:
[16,17,25,28,34,37,47,52,64]

J

((1*./@p:[:+/@|:10#.^:_1^&2 3)"0#]) i.100
Output:
16 17 25 28 34 37 47 52 64

jq

Works with: jq

Also works with gojq and fq

Preliminaries

def is_prime:
  . as $n
  | if ($n < 2)         then false
    elif ($n % 2 == 0)  then $n == 2
    elif ($n % 3 == 0)  then $n == 3
    elif ($n % 5 == 0)  then $n == 5
    elif ($n % 7 == 0)  then $n == 7
    elif ($n % 11 == 0) then $n == 11
    elif ($n % 13 == 0) then $n == 13
    elif ($n % 17 == 0) then $n == 17
    elif ($n % 19 == 0) then $n == 19
    else 23
         | until( (. * .) > $n or ($n % . == 0); .+2)
	 | . * . > $n
    end;

def digitSum: tostring | explode | map([.] | implode | tonumber) | add;

The Task

range(1;100)
| (.*.) as $sq
|  select( ($sq | digitSum | is_prime) and ($sq * . | digitSum | is_prime ) )
Output:
16
17
25
28
34
37
47
52
64

Julia

using Primes

is_sqcubsumprime(n) = isprime(sum(digits(n*n))) && isprime(sum(digits(n*n*n)))
println(filter(is_sqcubsumprime, 1:100)) # [16, 17, 25, 28, 34, 37, 47, 52, 64]

MAD

            NORMAL MODE IS INTEGER
            
            BOOLEAN PRIME
            DIMENSION PRIME(100)
            PRIME(0)=0B
            PRIME(1)=0B
            THROUGH SET, FOR P=2, 1, P.G.100
SET         PRIME(P)=1B
            THROUGH SIEVE, FOR P=2, 1, P*P.G.100
            THROUGH SIEVE, FOR C=P*P, P, C.G.100
SIEVE       PRIME(C)=0B
            
            THROUGH CHECK, FOR I=1, 1, I.GE.100
            WHENEVER .NOT.PRIME(DIGSUM.(I*I)), TRANSFER TO CHECK
            WHENEVER .NOT.PRIME(DIGSUM.(I*I*I)), TRANSFER TO CHECK
            PRINT FORMAT FMT, I
CHECK       CONTINUE
            
            INTERNAL FUNCTION(N)
            ENTRY TO DIGSUM.
            SUM=0
            NN=N
LOOP        WHENEVER NN.G.0
                NXT=NN/10
                SUM=SUM+NN-NXT*10
                NN=NXT
                TRANSFER TO LOOP
            END OF CONDITIONAL
            FUNCTION RETURN SUM
            END OF FUNCTION
            
            VECTOR VALUES FMT = $I2*$
            END OF PROGRAM
Output:
16
17
25
28
34
37
47
52
64

OCaml

let is_prime n =
  let rec test x =
    let q = n / x in x > q || x * q <> n && n mod (x + 2) <> 0 && test (x + 6)
  in if n < 5 then n lor 1 = 3 else n land 1 <> 0 && n mod 3 <> 0 && test 5

let rec digit_sum n =
  if n < 10 then n else n mod 10 + digit_sum (n / 10)

let is_square_and_cube_digit_sum_prime n =
  is_prime (digit_sum (n * n)) && is_prime (digit_sum (n * n * n))

let () =
  Seq.ints 1 |> Seq.take_while ((>) 100)
  |> Seq.filter is_square_and_cube_digit_sum_prime
  |> Seq.iter (Printf.printf " %u") |> print_newline
Output:
 16 17 25 28 34 37 47 52 64

Perl

Library: ntheory
#!/usr/bin/perl

use strict; # https://rosettacode.org/wiki/Sum_of_square_and_cube_digits_of_an_integer_are_primes
use warnings;
use ntheory qw( is_prime vecsum );

my @results = grep
  is_prime( vecsum( split //, $_ ** 2 ) ) &&
  is_prime( vecsum( split //, $_ ** 3 ) ), 1 .. 100;
print "@results\n";
Output:
16 17 25 28 34 37 47 52 64

Phix

with javascript_semantics
function ipsd(integer n) return is_prime(sum(sq_sub(sprintf("%d",n),'0'))) end function
function scdp(integer n) return ipsd(n*n) and ipsd(n*n*n) end function
pp(filter(tagset(99),scdp))
Output:
{16,17,25,28,34,37,47,52,64}


Python

Procedural

#!/usr/bin/python

def isPrime(n):
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False        
    return True

def digSum(n, b):
    s = 0
    while n:
        s += (n % b)
        n = n // b
    return s

if __name__ == '__main__':
    for n in range(11, 99):
        if isPrime(digSum(n**3, 10)) and isPrime(digSum(n**2, 10)):
            print(n, end = "  ")
Output:
16  17  25  28  34  37  47  52  64

Functional

'''Square and cube both have prime decimal digit sums'''

# p :: Int -> Bool
def p(n):
    '''True if the square and the cube of N both have
       decimal digit sums which are prime.
    '''
    return primeDigitSum(n ** 2) and primeDigitSum(n ** 3)


# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''Matches in the range [1..99]'''
    print([
        x for x in range(2, 100)
        if p(x)
    ])


# ----------------------- GENERIC ------------------------

# primeDigitSum :: Int -> Bool
def primeDigitSum(n):
    '''True if the sum of the decimal digits of n is prime.
    '''
    return isPrime(digitSum(10)(n))


# digitSum :: Int -> Int
def digitSum(base):
    '''The sum of the digits of n in a given base.
    '''
    def go(n):
        q, r = divmod(n, base)
        return go(q) + r if n else 0
    return go


# isPrime :: Int -> Bool
def isPrime(n):
    '''True if n is prime.'''
    if n in (2, 3):
        return True
    if 2 > n or 0 == n % 2:
        return False
    if 9 > n:
        return True
    if 0 == n % 3:
        return False

    def q(x):
        return 0 == n % x or 0 == n % (2 + x)

    return not any(map(q, range(5, 1 + int(n ** 0.5), 6)))


# MAIN ---
if __name__ == '__main__':
    main()
Output:
[16, 17, 25, 28, 34, 37, 47, 52, 64]

Quackery

isprime is defined at Primality by trial division#Quackery.

  [ 0 swap
    [ dup while
      10 /mod
      rot + swap
      again ]
   drop ]        is digitsum ( n --> n )

  98 times
   [ i^ 1+ 2 **
     digitsum isprime if
       [  i^ 1+ 3 **
          digitsum isprime if
            [ i^ 1+ echo sp ] ] ]
Output:
16 17 25 28 34 37 47 52 64

Raku

say ^100 .grep: { .².comb.sum.is-prime && .³.comb.sum.is-prime }
Output:
(16 17 25 28 34 37 47 52 64)

Ring

load "stdlib.ring"
see "working..." +nl

limit = 100

for n = 1 to limit
    sums = 0
    sumc = 0
    sps = string(pow(n,2))
    spc = string(pow(n,3))
    for m = 1 to len(sps)
        sums = sums + sps[m]
    next
    for p = 1 to len(spc)
        sumc = sumc + spc[p]
    next
    if isprime(sums) and isprime(sumc)
       see "" + n + " "
    ok
next
  
see nl + "done..." + nl
Output:
working...
16 17 25 28 34 37 47 52 64 
done...

Sidef

1..99 -> grep { .square.digits_sum.is_prime && .cube.digits_sum.is_prime }.say
Output:
[16, 17, 25, 28, 34, 37, 47, 52, 64]

TinyBASIC

This can only go up to 31 because 32^3 is too big to fit in a signed 16-bit int.

REM      N, the number to be tested
REM      D, the digital sum of its square or cube
REM      T, temporary variable
REM      Z, did D test as prime or not

    LET N = 1
 10 LET T = N*N*N
    GOSUB 20
    GOSUB 30
    IF Z = 0 THEN GOTO 11
    LET T = N*N
    GOSUB 20
    GOSUB 30
    IF Z = 0 THEN GOTO 11
    PRINT N
 11 IF N = 31 THEN END
    LET N = N + 1
    GOTO 10
 20 LET D = 0
 21 IF T = 0 THEN RETURN
    LET D = D + (T-(T/10)*10)
    LET T = T/10
    GOTO 21
 30 LET Z = 0
    IF D < 2 THEN RETURN
    LET Z = 1
    IF D < 4 THEN RETURN
    LET Z = 0
    IF (D/2)*2 = D THEN RETURN
    LET T = 1
 31 LET T = T + 2
    IF T*T>D THEN GOTO 32
    IF (D/T)*T=D THEN RETURN
    GOTO 31
 32 LET Z = 1
    RETURN
Output:

16 17 25

28

Wren

Library: Wren-math
import "./math" for Int

for (i in 1..99) {
    if (Int.isPrime(Int.digitSum(i*i)) && Int.isPrime(Int.digitSum(i*i*i))) System.write("%(i) ")
}
System.print()
Output:
16 17 25 28 34 37 47 52 64 

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 SumDigits(N);      \Return the sum of digits in N
int  N, Sum;
[Sum:= 0;
while N do
    [N:= N/10;
    Sum:= Sum + rem(0);
    ];
return Sum;
];

int N;
[for N:= 0 to 100-1 do
    if IsPrime(SumDigits(N*N)) & IsPrime(SumDigits(N*N*N)) then
        [IntOut(0, N);  ChOut(0, ^ )];
]
Output:
16 17 25 28 34 37 47 52 64 

Yabasic

Translation of: Ring
// Rosetta Code problem: http://rosettacode.org/wiki/Sum_of_square_and_cube_digits_of_an_integer_are_primes
// by Galileo, 04/2022

sub isPrime(n)
	local i
	
	if n < 4 return n >= 2
	for i = 2 to sqrt(n)
		if not mod(n, i) return false
	next
    return true
end sub
 
limit = 100
 
for n = 1 to limit
    sums = 0
    sumc = 0
    sps$ = str$(n^2)
    spc$ = str$(n^3)
    for m = 1 to len(sps$)
        sums = sums + val(mid$(sps$, m, 1))
    next
    for p = 1 to len(spc$)
        sumc = sumc + val(mid$(spc$, p, 1))
    next
    if isPrime(sums) and isPrime(sumc) then
       print n, " ";
    endif
next
print
Output:
16 17 25 28 34 37 47 52 64
---Program done, press RETURN---