Regex (ECMAScript / Java), 38 37 34 33 bytes
\b(?=(^|x))((x*)\3\3(?=\3$))*x\1$
Try it online! - ECMAScript
Try it online! - Java
Takes its input in unary, as an optional -
sign followed by a string of x
characters, the count of which represents the absolute value of the number. (As such, it is not bijective unary, as zero can be represented in two ways. The regex works with both.)
Sets a flag for whether a negative sign is present. Operating on the absolute value, repeatedly divides by 4 (requiring that there is no remainder), and then asserts that the remaining number is 1 if there was no negative sign, or 2 if there was.
\b # Anchor on the border between {start or "-"} and "x"; in the
# domain of this problem, it is actually equivalent to
# (?<=^(?=x)|-|x$) - so it can anchor on the end instead of the
# beginning, but that would result in a non-match.
(?=(^|x)) # \1 = 1 if negative sign is present, 0 if not
( # loop the following:
(x*)\3\3(?=\3$) # assert tail is divisible by 4; tail = tail / 4
)* # iterate as many times as possible (minimum 0)
x # tail -= 1
\1 # tail -= \1
$ # assert tail==0
Regex (ECMAScript), 36 bytes
^(-(x*)(?=\2$))?((x*)\4\4(?=\4$))*x$
Try it online!
This was the original version I posted; I'm keeping it here, as it's sufficiently different, yet close enough in length, to be interesting.
If it sees a negative sign, it strips it and divides the number by 2 (requiring that there is no remainder). It then asserts that the remaining number is a power of 4.
^
(
- # eat a leading negative sign
(x*)(?=\2$) # assert tail is even; tail = tail / 2
)? # do the above optionally
# Assert that tail is a power of 4
( # loop the following:
(x*)\4\4(?=\4$) # assert tail is divisible by 4; tail = tail / 4
)* # iterate as many times as possible (minimum 0)
x$ # assert tail == 1; if this fails to match, the regex engine will
# try backtracking the loops, but that cannot result in a match
Regex (Perl / PCRE / Boost / Python / Ruby / .NET), 32 bytes
^(-)?((x*)\3\3(?=\3$))*x(?(1)x)$
Try it online! - Perl
Try it online! - PCRE2
Try it online! - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
Uses essentially the same algorithm as the 33 byte ECMAScript version, but in a more straightforward way, which never matches strings outside the problem's domain.
^
(-)? # \1 = negative sign if it is present; unset otherwise
( # loop the following:
(x*)\3\3(?=\3$) # assert tail is divisible by 4; tail = tail / 4
)* # iterate as many times as possible (minimum 0)
x # tail = tail - 1
(?(1)x) # if \1 is set, then tail = tail - 1, else do nothing
$ # assert tail == 0
Regex (ECMAScript or better), 26 bytes
^((.*)\2\2(?=\2$))*(x|oo)$
Try it online! - ECMAScript
Try it online! - Perl
Try it online! - Java
Try it online! - Boost
Try it online! - Python
Try it online! - Ruby
Try it online! - PCRE2
Try it online! - .NET
Takes its input in bijective signed unary. A nonnegative number is a string of x
characters, and a nonpositive number is a string of o
characters. The the length of the string is the absolute value of the number.
^ # tail = N = input number
( # Loop the following:
(.*)\2\2(?=\2$) # Assert tail is divisible by 4; tail = tail / 4;
# use "." so that either "x" or "o" can be matched, as
# long as all characters are identical.
)* # Iterate as many times as possible (minimum 0).
(x|oo)$ # Assert tail == 1 or tail == -2
i
such that(-2)^i = 2
\$\endgroup\$-0.5
should be valid since it's 2^(-1). \$\endgroup\$