Regex (ECMAScript or better), 33 32 bytes
^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$
Takes its input in unary, as a sequence of x
characters whose length represents the number.
Try it online! - ECMAScript
Try it online! - Perl
Try it online! - Java
Try it online! - Python
Try it online! - Ruby
Try it online! - PCRE
Try it online! - .NET (C#)
Try it online! - .NET (PowerShell)
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
Here is the regex implemented in some of the host languages, where it either beats the other submitted solution(s) or is the only one in its language:
\$Anonymous\ functions\$
PowerShell, 52 bytes
'x'*$args[0]-match'^((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$'
Try it online!
Python, 70 69 bytes
lambda n:re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*n);import re
Try it online!
Python, 73 bytes
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 bytes
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 bytes
pryr::f(sum(grep('^((?=.+?(?=(..+?)\\2*$)\\2$)\\2)*.$',strrep(1,n),0,1)))
Try it online!
pryr::f(sum(grep('^((?=.+?(?!(..+)\\2+$)(..+))\\3)*.$',strrep(1,n),0,1)))
Try it online!
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
\$Full\ programs\$
Python, 79 bytes
import re
print(bool(re.match(r'((?=.+?(?=(xx+?)\2*$)\2$)\2)*x$','x'*input())))
Try it online!
Perl -pl
, 45 bytes
$_=(1x$_)=~/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/
Try it online!
Beaten by Ton Hospel's 41 byte answer which mixes regex and code.
Perl, 46 bytes
$_=1x<>;say-/^((?=.+?(?=(..+?)\2*$)\2$)\2)*.$/
Try it online!
Beaten by 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\$