# Double Prime Words

Consider a word/string of length $$\n\$$, only including the letters A-Z, a-z. A word/string is a double prime word if and only if n is prime and the sum of the letters, s, is also prime, using their numeric position in the alphabet (a=1, B=2, c=3, etc.).

Input can be any combination of upper or lower case alphabetic characters, as there is no numeric difference between a or A.

Output is any appropriate logical format related to your language. i.e. True or False, T or F, 1 or 0, etc. Specifying what format your output will appear is highly appreciated, but not required. (Output need not include n, s, but I include them below as demonstration and example)

Winning condition is shortest code in bytes able to detect if a string is a double prime, fitting both conditions for n and s to be prime. (I've now included cases from all 4 possible situations of n, s.)

## Examples

Input -> Output (n, s)

Prime -> True (5, 61)
han -> True (3, 23)
ASK -> True (3, 31)
pOpCoRn -> True (7, 97)
DiningTable -> True (11, 97)
METER -> True (5, 61)

Hello -> False (5, 52)
SMILE -> False (5, 58)
frown -> False (5, 76)

HelpMe -> False (6, 59)
John -> False (4, 47)
TwEnTy -> False (6, 107)

HelloWorld -> False (10, 124)
Donald -> False (6, 50)
telePHONES -> False (10, 119)

A -> False (1, 1)
C -> False (1, 3) {1 is not prime}
d -> False (1, 4)

• The main point of the Sandbox is to get feedback, and because of this we usually leave a challenge in for around 3 days. 1 hour is far too short, and because of that, this challenge is still, unfortunately, still unclear IMO. For example, you say "Consider a word/string of length n, only including the letters A-Z, a-z" but then go on to say "If input is a phrase or sentence, strip any numbers, punctuation, special characters, and spaces". This is an interesting challenge, but I think you didn't leave it in the Sandbox long enough Sep 8, 2020 at 21:04
• Things to avoid when writing challenges: The prime numbers
– xnor
Sep 8, 2020 at 21:16
• Testing the primality of n is enough to give the correct answer for all test cases. You may want to add one for which it doesn't hold. Sep 8, 2020 at 21:16
• @Sumner18 Don't worry too much about it. As long as you're paying attention to a challenge, it's usually possible to rescue even the worst challenges (and this is a long way from that). I'd just recommend editing in any clarifications you make in the comments into the questions, and being available to answer people's questions. From that, other users will help find and close the edge cases/confusing language that you may have overlooked. Sep 8, 2020 at 22:51
• Suggested test case: C. This should be falsey, as the length (1) is not prime, even though the sum (3) is prime. Sep 9, 2020 at 13:19

# Jelly, 12 bytes

ŒuO_64µL,SẒP


Try it online!

## How it works

ŒuO_64µL,SẒP - Main link, takes string s as argument e.g. s = "Prime"
Œu           - Convert to upper case                          "PRIME"
O          - Convert to ordinals                            [80, 82, 73, 77, 69]
_64       - Subtract 65 (call this L)                      [16, 18, 9, 13, 5]
µ      - Start a new link with L as the left argument
L     - Take the length                                5
S   - Take the sum                                   61
,    - Pair the two values                            [5, 61]
Ẓ  - Take primality of each                         [1, 1]
P - Take product                                   1


# R, 68 71 bytes

+3 bytes to correct a bug pointed out by Dominic van Essen

?=sum;s=?b<-utf8ToInt(scan(,""))%%32;l=?b^0;l-1&5>?c(!s%%1:s,!l%%1:l)


Try it online!

Notice that to convert both upper and lower case letters to the integers 1...26, we can take the ASCII codepoint modulo 32. sum(!x%%1:x) is a golfy way of counting the number of divisors of x, which will be equal to 2 iff x is prime.

Ungolfed:

? = sum                       # shorthand for sum
b = utf8ToInt(scan(, "")) %% 32 # take input and convert to ASCII, then take mod 32
s = sum(b)
l = sum(b^0)                    # l = length(b)
5 > sum(c(!s%%1:s,!l%%1:l))    # sum the number of divisors of s and l, and check whether you get <5.
& l!=1                   # and that l is not 1

• The ingenuity is palpable! The shorthand, the modulus, the method for getting length! It's beautiful! True Art from the Language of the Month and my language of choice! Have an upvote! Sep 9, 2020 at 15:54
• @Robin - I think that checking the sum of the sums of divisors fails for "D". I fell into the same trap, and only realized while I was writing it up... Sep 9, 2020 at 21:53
• @DominicvanEssen Thanks! Fixed, at the cost of 3 bytes. Sep 9, 2020 at 22:29
• Ah! If you fix it like that, I think you can lose a byte with 5> instead of 4==, right? Sep 9, 2020 at 22:35
• @DominicvanEssen Yup, it's already there! :-) Sep 9, 2020 at 22:36

# Ruby, 27 59 bytes

->a{[a.size,a.upcase.bytes.map{|i|i-64}.sum].all? &:prime?}


+33 bytes after correcting the solution, thanks to DrQuarius.

• This code does not solve this puzzle at all. Your TiO link intentionally left out the two truthy cases it fails: DiningTable, METER Sep 13, 2020 at 5:11
• It was not intentional. I will correct the solution. Sep 13, 2020 at 5:46
• Sorry to imply it was, the two examples it failed being removed seemed suss. I posted a solution in Ruby that solves it in 50 bytes (TiO) Sep 13, 2020 at 6:00
• I don't know if arrays are considered truthy, but nice solution. I just fixed mine. Sep 13, 2020 at 6:03
• prime is part of the ruby standard library, so from what I remember, it doesn't count. Sep 13, 2020 at 6:46

# perl -Mfeature=say -MList::Util=sum -pl, 95 bytes

s/[^a-z]//gi;$m=sum map-64+ord,split//,uc;$_=(1 x y===c)!~/^(11+)\1+$|^1$/&&(1x$m)!~/^(11+)\1$/


Try it online!

## How does it work?

s/[^a-z]//gi;   # Clean the input, remove anything which isn't an ASCII letter.

uc;     # Upper case the string
split//,        # Split it into individual characters
-64+ord                 # Calculate its value:
#           subtract 64 from its ASCII value
map                        # Do this for each character, return a list
$m=sum # Sum the values, and store it in$m

y===c                        # Returns the length of the input string
(1 x y===c)                       # Length of the input string in unary

/^(11+)\1+$|^1$/                  # Match a string consisting of a composite
# number of 1's, or a single 1
!~                                # Negates the match, so
(1 x y===c)1~/^(11+)\1+$|^1$/     # this is true of the input string (after
# cleaning) has prime length

(1x$m)!~/^(11+)\1+$/              # Similar for the sum of the values --
# note that the value is at least 2, so
# no check for 1.


Combining this, and the program will print 1 on lines which match the conditions, and an empty line for lines which do not match.

• 62 bytes, essentially using your logic. Eliminates the command line module inclusion. Sep 11, 2020 at 0:03
• Oops, make that 63 bytes. I forgot a /e on the substitution. Sep 11, 2020 at 0:15

# 05AB1E, 10 bytes

gAIlk>O‚pP


Input as a list of characters.

Explanation:

g           # Get the length of the (implicit) input-list
A          # Push the lowercase alphabet
I         # Push the input-list of characters
l        # Convert the input to lowercase
k       # Get the (0-based) index of each character in the alphabet-string
>      # Increase each by 1 to make them 1-based indices
O     # Take the sum of that
‚    # Pair the length together with this sum
p   # Check for both whether they're a prime (1 if it's a prime; 0 if not)
P  # And check if both are truthy by taking the product of the pair
# (after which the result is output implicitly)


# R, 70 bytes

function(s,S=sum,t=S(utf8ToInt(s)%%32))S(!nchar(s)%%1:t)^S(!t%%1:t)==4


Try it online!

I forced myself not to peek at Robin Ryder's answer before having a shot at this, and (satisfyingly) it turns out that we've used some rather different golfing tricks.

t is the total of all letter indices. This is certain to be greater-than-or-equal-to nchar(s) (it's only equal if the string s is "A" or "a"). So we can use modulo 1:t to test for primality of the string length instead of modulo 1:nchar(s), and there's no need waste characters on a variable declaration to store nchar(s).

Both primality tests sum(!t%%1:t) and sum(!nchar(s)%%1:t) must be equal to 2 if both the sum-of-letter-indices and the string length are prime.
We could check if they're both 2, but this requires ==2 twice (plus a & or equivalent), which seems wasteful. Is it ok to check that the total is 4? The edge-case we need to worry about is if one of them equals 1 and the other 3: this happens for the string "D" (length=1 and character-index=4 with divisors 1,2 and 4). So it's not Ok. Can we multiply them? Also no, because 1 and 4 will again give 4 (think about the string "F").
But - since we know that the string length must be less-than-or-equal to the sum-of-character-indices, we can use exponentiation: the only way to get 4 is 4^1 or 2^2, and since the sum-of-character-indices can't be 1 if the string-length is 4, 2^2 is the only possibility.

So the final, combined check for double-primality is sum(!nchar(s)%%1:t)^sum(!t%%1:t)==4, saving 3 characters compared to testing them separately.

• Wow! I don't even know what to express here! It seems so detailed, but so methodical! Well done! Sep 9, 2020 at 22:02

# Rockstar, 327321 319 bytes

No built-in for testing primes!
No case conversion!
No way to get the codepoint of a character!

Why do I do these things to myself?! Spent so long just getting the damn thing to work, I'm sure it's far from optimally golfed but it'll do for now.

F takes N
let D be N
let P be N aint 1
while P and D-2
let D be-1
let M be N/D
turn up M
let P be N/D aint M

return P

G takes I
Y's0
N's27
while N
cast N+I into C
if C is S at X
return N

let N be-1

return G taking 64

listen to S
X's0
T's0
while S at X
let T be+G taking 96
let X be+1

say F taking T and F taking X


Try it here (Code will need to be pasted in)

# Retina 0.8.2, 77 bytes

\W|\d|_

$¶$
\G.
1
TLl
[t-z]
55$& [j-z] 55$&
T_lddd
.
$* A^(..+)\1+$
¶


Try it online! Link includes test cases. Explanation:

\W|\d|_



Delete anything that isn't a letter.

$¶$


Duplicate the letters.

\G.
1


Replace the letters on the first line with 1s, thus taking the length in unary.

TLl


Convert the remaining letters to lower case.

[t-z]
55$& [j-z] 55$&
T_lddd


Convert them to digits that will sum to their numeric position.

.
$*  Convert the digits to unary, thus taking their sum. A^(..+)\1+$


Delete any composite values.

¶


Check that both values are still present.

• I have to say, I'm consistently surprised at just how powerful Retina can be, given the basic idea of "what if regex was a language?" Sep 8, 2020 at 22:54

# Python 3, 8678 87 bytes

Saved 8 bytes thanks to ovs!!!
Added 9 bytes to fix a bug kindly pointed out by Robin Ryder.

lambda s:~-len(s)*all(n%i for n in(len(s),sum(ord(c)&31for c in s))for i in range(2,n))


Try it online!

Returns a truthy or falsey value.

• 78 bytes as a single function.
– ovs
Sep 9, 2020 at 6:10
• @ovs Couldn't believe two lambdas were better than one - thanks! :D Sep 9, 2020 at 8:23
• I think this fails when the string is of length 1 (1 is not a prime number). Sep 9, 2020 at 13:22
• @RobinRyder Fixed - thanks! :-) Sep 9, 2020 at 13:38

# Brachylog, 11 bytes

ḷạ-₉₆ᵐ+ṗ&lṗ


Try it online!

### How it works

ḷạ-₉₆ᵐ+ṗ&lṗ (is the implicit input)
ḷ           to lowercase
ạ          to list of char codes
-₉₆ᵐ      minus 96 (so 'a' -> 1)
+     summed
ṗ    prime?
&l  and is the input's length
ṗ prime?


# Wolfram Language (Mathematica), 34 bytes

PrimeQ@*Tr/@(LetterNumber@#&&1^#)&


Try it online!

-22 bytes from @att

• 52 bytes
– att
Sep 8, 2020 at 22:34
• 38 bytes while still working with the original input specification. (34 bytes taking a list of characters with the new restriction that input is wholly alphabetic)
– att
Sep 13, 2020 at 19:25

# Japt, 16 bytes

Êj ©Uu ¬mc xaI j


Try it

# J, 2722 18 bytes

1*/@p:#,1#.32|3&u:


Try it online!

-5 bytes thanks to xash

-4 bytes thanks to Dominic van Essen

• 32|3&u: Turn each letter into its index by first converting to its ascii number, the modding by 32.
• 1#. Sum.
• #, Prepend list length.
• 1...p: Are each of those two numbers prime?
• */@ Multiply them together -- are they all prime?
• 22 bytes
– xash
Sep 10, 2020 at 8:50
• Are there more *_j_ string constants than Alpha, Num and AlphaNum? Seem really practical, but they don't appear to be documented in the wiki.
– xash
Sep 10, 2020 at 9:07
• @xash you can see all of them by first switching into the J locale with 18!:4 <'j' and then listing all nouns with 4!:1]0: Try it online! The ones you listed seem to be the only relevant ones for golf. More here Sep 10, 2020 at 16:23
• I have no idea at all how to write 'J', so possibly this is a useless comment, but I don't think you need to subtract 64 before performing MOD 32, since 64 is itself a multiple of 32... Sep 10, 2020 at 16:40
• @DominicvanEssen Right you are! Thanks. Sep 10, 2020 at 16:50

# C - 119108 99 98 bytes (gcc)

@ceilingcat saved another byte!

b,t,e;p(c){for(;--e&&c%e;);c=e==1;}a(char*a){t=0;for(e=b=strlen(a);b;)t+=a[--b]%32;t=p(e)*p(e=t);}


try it online

previously

Many thanks to @DominicvanEssen and @ceilingcat for saving 20 bytes! - and particularly to Dominic for fixing error on n=1 (non-prime)

b,t,e;p(c){for(b=c;--b&&c%b;);c=b==1;}a(char*a){t=0;for(e=b=strlen(a);b;)t+=a[--b]%32;t=p(e)*p(t);}


first attempt below 119 bytes

a(char*a){int t=0,d=strlen(a),e=d;while(d)t+=a[--d]%32;return p(e)*p(t);}
p(int c){int b=c;while(--b&&c%b);return b<2;}


In fact can save 3 bytes by using while(c%--b) in the second routine, but this fails for the case of p(1) e.g. 'a'. or other single characters.

try it online

• I'm afraid this returns 1 (true) for the single-character strings "a", "b" and "c". Sep 9, 2020 at 22:02
• Fixed (I think) for 108 bytes Sep 9, 2020 at 22:12
• @DominicvanEssen - ah rats - missed the bits about 1 above.. many thanks for fixing - and saving 10 bytes
– tom
Sep 10, 2020 at 3:37
• @ceilingcat- I stare and stare and then you shave off another nearly ten bytes :-)
– tom
Sep 10, 2020 at 3:37

# Scala, 7574 69 bytes

| =>p(|size)&p(|map(_&95-64)sum)
def p(n:Int)=(2 to n/2)forall(n%_>0)


Try it online!

# Factor, 78 bytes

: d ( s -- ? ) dup [ length ] dip >lower [ 96 - ] map sum [ prime? ] bi@ and ;


Try it online!

# 05AB1E, 11 bytes

uÇ64-Op¹gp&


Try it online!

Bytes removed due to lack of input restrictions

# JavaScript (Node.js), 88 bytes

Returns 0 or 1.

s=>(g=k=>n%--k?g(k):k==1)(Buffer(s).map(c=>x+=n<(n+=c>64&(c&=31)<27&&c),x=n=0)|n)&g(n=x)


Try it online!

### Commented

Helper function

g = k =>                   // g is a helper function testing if n is prime
n % --k ?                //   decrement k; if it does not divide n:
g(k)                   //     do recursive calls until it does
:                        //   else:
k == 1                 //     test whether k = 1


Main function

s =>                       // s = input string
g(                       // test if the 'sum of the letters' is prime
Buffer(s).map(c =>     //   for each ASCII code c in s:
x +=                 //     increment x if ...
n < (              //       ... n is less than ...
n +=             //         ... the new value of n:
c > 64 &       //           if c is greater than 64
(c &= 31) < 27 //           and c mod 32 is less than 27:
&& c           //             add c mod 32 to n
),                 //
x = n = 0            //     start with x = n = 0
) | n                  //   end of map(); yield n
)                        // end of the first call to g
& g(n = x)               // 2nd call to g with the 'length' x


# Perl 5-pl, 52 bytes

Uses the prime identification regex from @Abigail's answer

$_.=$".1x s/./1x(31&ord$&)/ge;$_=!/\b((11+)\2+|1)\b/


Try it online!

# Ruby, 5055 50 bytes

->s{[s.size,s.upcase.sum-64*s.size].all? &:prime?}


Try it online!

+5 bytes due to a misunderstanding of whether arrays could be considered truthy.

-5 bytes thanks to Razetime, using the nice trick of putting the " &:prime?" at the end instead of doing a ".map(&:prime?)" before the ".all?".

Posted separately because Razetime's solution actually didn't sum the alphabet index but simply the ascii ordinals. It fails for the double prime words "DiningTable" and "METER".

• Everything except false and nil is truthy in Ruby. ruby-for-beginners.rubymonstas.org/conditionals/…. Sep 13, 2020 at 6:11
• 50 bytes Sep 13, 2020 at 6:42
• Thanks Razetime! That's a neat trick, I don't understand why that works, but it's good to learn! Sep 13, 2020 at 6:52

# Husk, 12 bytes

&ṗL¹ṗṁȯ-64ca


Try it online! Outputs a truthy number if the word is a double prime word, and 0 otherwise.