Regex (ECMAScript or better), 24 23 bytes
(?=((x(x*))\2+)\1+$)\3^
-1 byte thanks to Grimmy
Try it online! - ECMAScript
Try it online! - Python
Try it online! - Ruby
Takes its input in unary, as a string of x
characters whose length represents the number.
This regex is based on the 18 byte "Is it prime?" regex (?=(x(x*))\1+$)\2^
, which unlike its semiprime version above, is longer than the shortest known, the 16 byte ^(?!(xx+)\1+$)xx
. But like ^(?=(xx+?)\1*$)\1$
(also 18 bytes), it has the interesting attribute of implicitly rejecting 0 and 1 as prime numbers, whereas the 16 byte regex must explicitly reject them (the xx
at the end).
# tail = N = input number; there's no need to anchor here,
# because a start anchor is used at the end of this regex
(?=
( # \1 = largest proper divisor of N that is >=2
(x(x*)) # \2 = largest proper divisor of \1; \3 = \2 - 1
\2+ # Assert that \2 is a proper divisor of \1
)
\1+$ # Assert that \1 is a proper divisor of N
)
\3^ # Assert that \3==0, and thus \2==1, meaning the largest proper
# divisor of the largest proper divisor of N is 1, meaning N is
# semiprime
Regex (Perl / Java / PCRE / Pythonregex
/ .NET), 23 bytes
^(?>((x(x*))\2+)\1+$)\3
Try it online! - Perl
Try it online! - Java
Try it online! - PCRE
Try it online! - Python import regex
Try it online! - .NET
This is a direct port of the "ECMAScript or better" regex above, using an atomic group instead of an atomic lookahead. It is much faster on most regex engines, as the ^
start-anchor test is done first instead of last.
Regex (Perl / Java / PCRE / Pythonregex
), 23 bytes
^((x+)\2*(?=\2$)){2}+x$
Try it online! - Perl
Try it online! - Java
Try it online! - PCRE
Try it online! - Python import regex
This is a port of the now-obsoleted 24 byte "ECMAScript or better" regex, using a possessive quantifier instead of an atomic lookahead to disable backtracking.
^ # tail = input number
(
(x+) # \2 = largest strict divisor of tail
# = tail / {smallest prime factor of tail}
\2*(?=\2$) # Assert that \2 is a strict divisor of tail; tail = \2
){2}+ # Execute the loop exactly 2 times, with backtracking disabled
x$ # assert tail == 1
\$\large\textit{Expressions with interactive input}\$
R, 59 58 54 bytes
grepl('^((.+)\\2*(?=\\2$)){2}+.$',strrep(1,scan()),,1)
Try it online! - test cases only
\$\large\textit{Anonymous functions}\$
R, 63 62 58 53 bytes
\(n)grepl('^((.+)\\2*(?=\\2$)){2}+.$',strrep(1,n),,1)
Attempt This Online!
-1 byte thanks to Giuseppe
-4 bytes by using grepl()
instead of sum(grep())
or any(grep())
-5 bytes by using a new anonymous function syntax introduced in R v4.1.0
The old 58 byte R v3.5.2 function: Try it online!
Ruby, 37 36 bytes
->n{?x*n=~/(?=((x(x*))\2+)\1+$)\3^/}
Try it online!
Try it online! - test cases only
PHP, 62 bytes
fn($n)=>preg_match('/^((.+)\2*(?=\2$)){2}+.$/',str_pad('',$n))
Try it online!
JavaScript (ES6), 46 45 bytes
n=>/(?=((.(.*))\2+)\1+$)\3^/.test(Array(n+1))
Try it online!
Java 8, 61 bytes
n->new String(new char[n]).matches("((.+)\\2*(?=\\2$)){2}+.")
Try it online!
Try it online! - test cases only
Java 11, 51 bytes
n->"x".repeat(n).matches("((x+)\\2*(?=\\2$)){2}+x")
Try it online!
\$\large\textit{Full programs}\$
Retina, 30 29 bytes
.+
$*
^(?>((1(1*))\2+)\1+$)\3
Try it online! - test cases only
PHP, 64 bytes
<?=preg_match('/^((.+)\2*(?=\2$)){2}+.$/',str_pad('',$argv[1]));
Try it online! - tests one number at a time
PHP -F
, 61 bytes
<?=preg_match('/^((.+)\2*(?=\2$)){2}+.$/',str_pad('',$argn));
Try it online! - tests ranges of numbers
Try it online! - tests one number at a time
ÆEḟ0⁼7B¤
to the Jelly answer on this one:ÆfL=2
, you'll notice that there is a significant difference; namely, that one has to check for distinctness. \$\endgroup\$