Regex 🐇
(PCRE2 v10.35+), 36 bytes
^(?*(\1{10}|^x{9})*x(x*$))(?*\2x+)x+
Attempt This Online!
Attempt This Online! - just the test cases (that are small enough to complete in reasonable time)
Takes its input in unary, as the length of a string of x
s. Returns its output as the number of ways the regex can match. (The rabbit emoji indicates this output method. It can yield outputs bigger than the input, and is really good at multiplying.)
^ # Anchor to start; tail = N = input number
(?* # Non-atomic lookahead - try all possibilities to find ones
# resulting in a later match. This is used to multiply the
# number of possible matches outside by the number of
# possible matches inside.
(\1{10}|^x{9})*x # tail -= {any power of 10}
(x*$) # \2 = tail = N - {the power of 10}
)
(?* # Another non-atomic lookahead
\2 # tail = {the power of 10 chosen above}
x+ # Multiply the number of possible matches by tail. This
# applies for each power of 10 found, and those numbers of
# matches will add together.
)
x+ # Add tail possible matches, where tail==N, with the above
# multiplier being applied.
Regex 🐇
(Perl / PCRE), 108 76 bytes
^(x?)(?=(x*)\2$).*(?=\2((x+)\4{8}(?=\4$))*x{5}$)()?x+.*(?=\2$)(()?x+|\1+$)|x
Try it online! - Perl v5.28.2 / Attempt This Online! - Perl v5.36+
Try it online! - PCRE1
Try it online! - PCRE2 v10.33 / Attempt This Online! - PCRE2 v10.40+
Try it online! - PCRE2 - just the test cases
Without (?*
...)
molecular lookahead, it's much harder to do multiplication. So we reserve half of the number to use as a counter for one operand of the multiplication, letting \$a=\lfloor n/2\rfloor\$ and \$b=n\bmod 2\$, such that \$2a+b=n\$, in order to emulate operations on \$n\$.
We don't actually need to construct the number of the form 111...111 to multiply by. We can pretty much directly sum \$n\$ multiplied by each power of \$10\$, that is to say,
$$\large\left({\sum_{k=1}^{\lfloor log_{10}n\rfloor}2{{10^k}\over 2}(2a+b)}\right)+n = \sum_{k=0}^{\lfloor log_{10}n\rfloor}10^k n$$
using emulated arithmetic on \$2a+b=n\$.
^ # Anchor to start; tail = N = input number
(x?) # \1 = N % 2; tail -= \1
(?=(x*)\2$) # \2 = floor(N / 2)
.* # Find any value of tail ≤ N satisfying the
# following:
(?=
# Assert that 2*(tail-\2) is a power of 10
\2 # tail -= \2
(
(x+)\4{8}(?=\4$) # Assert tail is divisible by 10; tail /= 10
)* # Iterate the above as many times as possible,
# minimum zero.
x{5}$ # Assert tail == 5
)
()? # possibleMatches *= 2, for the following:
x+ # possibleMatches *= tail - \2, for the following:
.*(?=\2$) # tail = \2
(
()? # possibleMatches *= 2, for the following:
x+ # possibleMatches += tail
|
\1+$ # possibleMatches += \1
)
|
# Unanchored
x # possibleMatches += N
Regex (.NET), 129 117 bytes
^(?=(x)*)(x?)(?=(x*)\3$)(((?=\3((x+)\7{8}(?=\7$))*x{5}$)(?=((?=.*(?=\3)(?<1>x)*){4}(?=.*(?=\2)(?<1>x)?){2}x)*\3))?x)*
Try it online!
Try it online! - just the test cases
Returns its output as the capture count of \1
.
This is now a fairly straight port of the Perl/PCRE 🐇
version.
The former 129 byte version actually constructed the number whose digits are all 1
to multiply by – indirectly – by constructing the number \$c\$ whose every digit is a 1
and has one less digit than the input, such that \$10c+1\$ is the actually desired number, then returning \$(10c)(2a+b)+n\$ \$=(10c+1)n\$ as a capture count. That version couldn't return a result for an input of \$0\$, but this version can.
^ # Anchor to start; tail = N = input number
(?=(x)*) # \1.captureCount = tail = N
(x?) # \2 = N % 2; tail = tail-\2 == \3 * 2
(?=(x*)\3$) # \3 = floor(N / 2)
(
(
(?= # Lookahead conditional
# Assert that 2*(tail-\3) is a power of 10
\3 # tail -= \3
(
(x+)\7{8}(?=\7$) # Assert tail is divisible by 10; tail /= 10
)* # Iterate the above as many times as possible,
# minimum zero.
x{5}$ # Assert tail == 5
)
# If the above assertion matches, do the following:
(?=
(
(?=
.*(?=\3) # tail = \3
(?<1>x)* # \1.captureCount += tail
){4} # Iterate the above 4 times
(?=
.*(?=\2) # tail = \2
(?<1>x)? # \1.captureCount += tail
){2} # Iterate the above 2 times
x
)* # Iterate the above as many times as possible,
# which will be a number of iterations equal to
# exactly half the current power of 10.
\3 # Assert tail >= \3
)
)?
x
)* # Iterate the above as many times as possible,
# applying the payload to each power of 10
I think I may have discovered a bug in the .NET regex engine, or at least the version on TIO, while working on this. The following variant of the same length should have worked, but didn't:
^(?=(x)*)(x?)(?=(x*)\3$)((?(?=\3((x+)\6{8}(?=\6$))*x{5}$)(?=((?=.*(?=\3)(?<1>x)*){4}(?=.*(?=\2)(?<1>x)?){2}x)*\3))x)*