Regex (ECMAScript or better), 33 32 bytes
^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$
Takes its input in unary, as a string of x
characters whose length represents the number.
Try it online! - ECMAScript
Try it online! - Java
Try it online! - Perl
Try it online! - PCRE
Try it online! - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
I finally found a use for the positive lookahead primality test I came up with on 2018-12-07! This is 2 bytes longer than the "standard" negative lookahead primality test, but it allows the full regex to be 1 byte shorter:
^ # tail = input number
( # Loop the following:
(?= # Atomic lookahead - finds the first match, and once
# finished, its result won't be changed by backtracking
.+? # tail = largest number that is less than the current tail,
# for which the following matches:
(?=(xx+?)\2*$)\2$ # Assert tail is prime; \2 = tail
)
\2 # tail -= \2
)* # Iterate the above loop zero or more times
x$ # Assert tail==1
A neat thing about this regex is that it can be logically negated for all inputs other than zero simply by adding one byte, because after the repeated subtraction, all \$n>0\$ end up at either \$1\$ or \$2\$:
^((?=.+?(?=(xx+?)\2*$)\2$)\2)*xx$
Try it online! - ECMAScript
Try it online! - Java
Try it online! - Perl
Try it online! - PCRE
Try it online! - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
Here is the regex implemented in some languages that have golf-efficient regex calls, where it either beats the other submitted solution(s) or is the only one in that language:
\$\large\textit{Anonymous functions}\$
Julia v0.4+, 58 bytes
n->split("x"^n,r"^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$")[1]==""
Try it online!
The above returns truthy for an input of 0
. If returning falsey for 0
were needed, it'd be 60 bytes:
n->match(r"^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$","x"^n)!=nothing
Try it online!
or 59 bytes in Julia v0.7 and earlier with !=Void()
: Try it online!
Of course as far as Julia v0.4 goes, Glen O's answer outgolfs this at 32 bytes, but for v0.5 and later, this and the below may be optimal golf.
Julia v0.7+, 54 bytes
n->occursin(r"^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$",'x'^n)
Try it online!
Julia v1.2+, 53 bytes
n->endswith('x'^n,r"^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x")
Attempt This Online!
PowerShell, 52 51 bytes
'x'*"$args"-match'^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$'
Try it online!
-1 bytes thanks to Julian
Python, 70 69 bytes
lambda n:re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*n);import re
Try it online!
lambda n:__import__('re').match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*n)
Try it online!
(If it must be a pure lambda.)
JavaScript (ES6), 58 54 bytes
n=>/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/.test(Array(n+1))
Try it online!
-4 bytes thanks to a technique used by RK. and CubeyTheCube
Perl, 49 47 bytes
-2 bytes thanks to dingledooper
sub{1x pop~~/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/}
Try it online!
This beats a port of Ton Hospel's 41 byte answer (57 bytes):
sub{my$x=1x pop;$x=$`while$x=~/\B(?!(11+)\1+$|$)|11$/;$x}
Try it online!
Even if it's allowed to modified the global variable $_
(51 bytes):
sub{$_=1x pop;$_=$`while/\B(?!(11+)\1+$|$)|11$/;$_}
Try it online!
Ruby, 48 45 bytes
->n{?x*n=~/^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$/}
Try it online!
-2 bytes by switching the truthy value from "string of x
characters whose length is the input number" to "the integer value 0
", while keeping the same falsey value of nil
-1 byte by using ?x
instead of "x"
PHP, 89 75 71 bytes
fn($n)=>preg_match('/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/',str_pad('',$n))
Try it online!
-4 bytes by switching from x
to
as the repeated character
R, 73 72 68 63 bytes
\(n)grepl('^((?=.+?(?=(..+?)\\2*$)\\2$)\\2)*.$',strrep(1,n),,1)
Attempt This Online! / Try it online!
\(n)grepl('^((?=.+?(?!(..+)\\2+$)(..+))\\3)*.$',strrep(1,n),,1)
Attempt This Online! / Try it 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
Since TIO uses R v3.5.2, the TIO links have the old 68 byte versions of the function.
Java 8, 92 89 88 71 bytes
n->new String(new char[n]).matches("((?=.+?(?=(..+?)\\2*$)\\2$)\\2)*.")
Try it online!
n->new String(new char[n]).matches("((?=.+?(?!(..+)\\2+$)(..+))\\3)*.")
Try it online!
-17 bytes by just matching the regex straight against a string of NUL characters instead of replacing the NULs with x
Java 11, 61 bytes
n->"x".repeat(n).matches("((?=.+?(?=(xx+?)\\2*$)\\2$)\\2)*x")
Try it online!
-10 bytes relative to Java <11, thanks to Kevin Cruijssen
\$\large\textit{Full programs}\$
import re
re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*input()).re
Outputs via its exit code, value 0
for truthy (by exiting normally), and 1
for falsey (by triggering an AttributeError
).
Try it online!
import re
re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*xx$','x'*input()).re
Outputs via its exit code, value 1
for truthy and 0
for falsey, using the truth-inverted regex.
Try it online!
Alternative method using the uninverted regex, outputting exit code 1
for truthy (by triggering a NameError
), and 0
for falsey (by exiting normally), at 71 bytes:
import re
if re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*input()):z
Try it online!
import re
print re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*input())>0
Outputs True
or False
via stdout.
Try it online!
import re
print(not re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*xx$','x'*int(input())))
Try it online!
The above uses the truth-inverted regex. Without it is 84 bytes:
import re
print(bool(re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*int(input()))))
Try it online!
PHP -F
, 70 bytes
<?=preg_match('/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/',str_pad('',$argn));
Try it online!
Perl -p
, 45 43 bytes
-2 bytes thanks to dingledooper
$_=1x$_~~/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/
Try it online!
Beaten by Ton Hospel's 41 byte answer which mixes regex and code: Try it online!
Perl, 46 44 bytes
say 1x<>~~/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/
Try it online!
Now beats a port of Ton Hospel's answer (45 bytes):
$_=1x<>;$_=$`while/\B(?!(11+)\1+$|$)|11$/;say
Try it online!
9/10
as2^(-1) 3^2 5^(-1)
is thinking in terms of the latter) \$\endgroup\$