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)
21 Answers 21
Jelly, 12 bytes
ŒuO_64μL,SẒP
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)
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
-
1\$\begingroup\$ 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! \$\endgroup\$Sumner18– Sumner182020年09月09日 15:54:20 +00:00Commented Sep 9, 2020 at 15:54
-
2\$\begingroup\$ @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... \$\endgroup\$Dominic van Essen– Dominic van Essen2020年09月09日 21:53:29 +00:00Commented Sep 9, 2020 at 21:53
-
\$\begingroup\$ @DominicvanEssen Thanks! Fixed, at the cost of 3 bytes. \$\endgroup\$Robin Ryder– Robin Ryder2020年09月09日 22:29:43 +00:00Commented Sep 9, 2020 at 22:29
-
\$\begingroup\$ Ah! If you fix it like that, I think you can lose a byte with
5>instead of4==, right? \$\endgroup\$Dominic van Essen– Dominic van Essen2020年09月09日 22:35:20 +00:00Commented Sep 9, 2020 at 22:35 -
1\$\begingroup\$ @DominicvanEssen Yup, it's already there! :-) \$\endgroup\$Robin Ryder– Robin Ryder2020年09月09日 22:36:04 +00:00Commented 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.
-
\$\begingroup\$ This code does not solve this puzzle at all. Your TiO link intentionally left out the two truthy cases it fails: DiningTable, METER \$\endgroup\$DrQuarius– DrQuarius2020年09月13日 05:11:18 +00:00Commented Sep 13, 2020 at 5:11
-
\$\begingroup\$ It was not intentional. I will correct the solution. \$\endgroup\$Razetime– Razetime2020年09月13日 05:46:34 +00:00Commented Sep 13, 2020 at 5:46
-
-
\$\begingroup\$ I don't know if arrays are considered truthy, but nice solution. I just fixed mine. \$\endgroup\$Razetime– Razetime2020年09月13日 06:03:07 +00:00Commented Sep 13, 2020 at 6:03
-
1\$\begingroup\$ prime is part of the ruby standard library, so from what I remember, it doesn't count. \$\endgroup\$Razetime– Razetime2020年09月13日 06:46:01 +00:00Commented 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円$/
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.
05AB1E, 10 bytes
gAIlk>O‚pP
Input as a list of characters.
Try it online or verify all test cases.
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)
-
1\$\begingroup\$
gIÇ5o%O‚pPworks with strings as input at the same length. \$\endgroup\$ovs– ovs2020年09月09日 08:31:23 +00:00Commented Sep 9, 2020 at 8:31
R, 70 bytes
function(s,S=sum,t=S(utf8ToInt(s)%%32))S(!nchar(s)%%1:t)^S(!t%%1:t)==4
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.
-
\$\begingroup\$ Wow! I don't even know what to express here! It seems so detailed, but so methodical! Well done! \$\endgroup\$Sumner18– Sumner182020年09月09日 22:02:52 +00:00Commented Sep 9, 2020 at 22:02
Rockstar, (削除) 327 (削除ここまで) (削除) 321 (削除ここまで) (削除) 319 (削除ここまで) 294 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.
Outputs 0.25 for true and 0 for false.
F takes N
let D be N
let P be N-1
while P and D-2
let D be-1
let M be N/D
turn M up
let P be N/D-M
give P
G takes I
N's 27
while N
cast N+I in C
if C's S at X
give N
let N be-1
give G taking 64
listen to S
X's 0
T's 0
while S at X
let T be+G taking 96
let X be+1
say F taking T*F taking X
Try it here (Code will need to be pasted in)
Retina 0.8.2, 77 bytes
\W|\d|_
$
¶$`
\G.
1
T`L`l
[t-z]
55$&
[j-z]
55$&
T`_l`ddd
.
$*
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.
T`L`l
Convert the remaining letters to lower case.
[t-z]
55$&
[j-z]
55$&
T`_l`ddd
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.
-
1\$\begingroup\$ 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?" \$\endgroup\$2020年09月08日 22:54:12 +00:00Commented Sep 8, 2020 at 22:54
Python 3, (削除) 86 (削除ここまで) (削除) 78 (削除ここまで) 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))
Returns a truthy or falsey value.
-
-
\$\begingroup\$ @ovs Couldn't believe two
lambdas were better than one - thanks! :D \$\endgroup\$Noodle9– Noodle92020年09月09日 08:23:23 +00:00Commented Sep 9, 2020 at 8:23 -
\$\begingroup\$ I think this fails when the string is of length 1 (1 is not a prime number). \$\endgroup\$Robin Ryder– Robin Ryder2020年09月09日 13:22:07 +00:00Commented Sep 9, 2020 at 13:22
-
\$\begingroup\$ @RobinRyder Fixed - thanks! :-) \$\endgroup\$Noodle9– Noodle92020年09月09日 13:38:37 +00:00Commented Sep 9, 2020 at 13:38
Brachylog, 11 bytes
ḷạ-96m+ṗ&lṗ
How it works
ḷạ-96m+ṗ&lṗ (is the implicit input)
ḷ to lowercase
ạ to list of char codes
-96m minus 96 (so 'a' -> 1)
+ summed
ṗ prime?
&l and is the input's length
ṗ prime?
J, 27 22 18 bytes
1*/@p:#,1#.32|3&u:
-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?
-
1
-
\$\begingroup\$ Are there more
*_j_string constants thanAlpha,NumandAlphaNum? Seem really practical, but they don't appear to be documented in the wiki. \$\endgroup\$xash– xash2020年09月10日 09:07:31 +00:00Commented Sep 10, 2020 at 9:07 -
1\$\begingroup\$ @xash you can see all of them by first switching into the J locale with
18!:4 <'j'and then listing all nouns with4!:1]0: Try it online! The ones you listed seem to be the only relevant ones for golf. More here \$\endgroup\$Jonah– Jonah2020年09月10日 16:23:18 +00:00Commented Sep 10, 2020 at 16:23 -
2\$\begingroup\$ 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... \$\endgroup\$Dominic van Essen– Dominic van Essen2020年09月10日 16:40:32 +00:00Commented Sep 10, 2020 at 16:40
-
\$\begingroup\$ @DominicvanEssen Right you are! Thanks. \$\endgroup\$Jonah– Jonah2020年09月10日 16:50:32 +00:00Commented Sep 10, 2020 at 16:50
C - (削除) 119 (削除ここまで) (削除) 108 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);}
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.
-
1\$\begingroup\$ I'm afraid this returns
1(true) for the single-character strings "a", "b" and "c". \$\endgroup\$Dominic van Essen– Dominic van Essen2020年09月09日 22:02:22 +00:00Commented Sep 9, 2020 at 22:02 -
\$\begingroup\$ Fixed (I think) for 108 bytes \$\endgroup\$Dominic van Essen– Dominic van Essen2020年09月09日 22:12:51 +00:00Commented Sep 9, 2020 at 22:12
-
\$\begingroup\$ @DominicvanEssen - ah rats - missed the bits about 1 above.. many thanks for fixing - and saving 10 bytes \$\endgroup\$tom– tom2020年09月10日 03:37:19 +00:00Commented Sep 10, 2020 at 3:37
-
\$\begingroup\$ @ceilingcat- I stare and stare and then you shave off another nearly ten bytes :-) \$\endgroup\$tom– tom2020年09月10日 03:37:58 +00:00Commented Sep 10, 2020 at 3:37
Factor, 78 bytes
: d ( s -- ? ) dup [ length ] dip >lower [ 96 - ] map sum [ prime? ] bi@ and ;
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)
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/
Ruby, (削除) 50 (削除ここまで) (削除) 55 (削除ここまで) 50 bytes
->s{[s.size,s.upcase.sum-64*s.size].all? &:prime?}
+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".
-
1\$\begingroup\$ Everything except false and nil is truthy in Ruby. ruby-for-beginners.rubymonstas.org/conditionals/…. \$\endgroup\$Razetime– Razetime2020年09月13日 06:11:34 +00:00Commented Sep 13, 2020 at 6:11
-
1
-
\$\begingroup\$ Thanks Razetime! That's a neat trick, I don't understand why that works, but it's good to learn! \$\endgroup\$DrQuarius– DrQuarius2020年09月13日 06:52:06 +00:00Commented Sep 13, 2020 at 6:52
Husk, 12 bytes
&ṗL1ṗṁȯ-64ca
Try it online! Outputs a truthy number if the word is a double prime word, and 0 otherwise.
C. This should be falsey, as the length (1) is not prime, even though the sum (3) is prime. \$\endgroup\$