# No anchor needed, because 2円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(
2円x+? # 2円 = the smallest number larger than the previous value of 2円
# for which the following is true; add 2円 to the running total
# sum of divisors.
|
^x # This must always be the first step. Add 1 to the sum of
# divisors, thus setting 2円 = 1 so the next iteration can keep
# going.
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)
(?^=2円+$) # Assert that 2円 is a divisor of N
)++ # Iterate the above at least once, with a possessive quantifier
# to lock in the match (i.e. prevent any iteration from being
# backtracked into).
$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because
# everything inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?^! # Lookinto – Assert that the following, evaluated right-to-left, is notcannot truematch:
(2円x+) # 3円 = any number greater than 2円
3円+$ # Assert 3円 is a proper divisor of N
)
# No anchor needed, because 1円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(?= # Atomic lookahead:
.*(1円x+$) # 2円 = the smallest number larger than the previous value of 1円
# (which is identical to the previous value of 2円) for which the
# following is true. We can avoid using "x+?" because the ".*"
# before this implicitly forces values to be tested in increasing
# order from the smallest.
(?<=^2円+) # Assert that 2円 is a divisor of N
)
2円 # Add 2円 to the running total sum of divisors
|
^x # This must always be the first step. Add 1 to the sum of divisors,
# thus setting 1円 = 1 so the next iteration can keep going
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)+$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because everything
# inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?<! # Assert that the following, evaluated right-to-left, is notcannot truematch:
^3円+ # [Step 2] is a proper divisor of N
(x+2円) # [Step 1] Any value of 3円 > 2円
)
# No anchor needed, because 2円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(
2円x+? # 2円 = the smallest number larger than the previous value of 2円
# for which the following is true; add 2円 to the running total
# sum of divisors.
|
^x # This must always be the first step. Add 1 to the sum of
# divisors, thus setting 2円 = 1 so the next iteration can keep
# going.
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)
(?^=2円+$) # Assert that 2円 is a divisor of N
)++ # Iterate the above at least once, with a possessive quantifier
# to lock in the match (i.e. prevent any iteration from being
# backtracked into).
$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because
# everything inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?^! # Assert that the following, evaluated right-to-left, is not true:
(2円x+) # 3円 = any number greater than 2円
3円+$ # Assert 3円 is a proper divisor of N
)
# No anchor needed, because 1円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(?= # Atomic lookahead:
.*(1円x+$) # 2円 = the smallest number larger than the previous value of 1円
# (which is identical to the previous value of 2円) for which the
# following is true. We can avoid using "x+?" because the ".*"
# before this implicitly forces values to be tested in increasing
# order from the smallest.
(?<=^2円+) # Assert that 2円 is a divisor of N
)
2円 # Add 2円 to the running total sum of divisors
|
^x # This must always be the first step. Add 1 to the sum of divisors,
# thus setting 1円 = 1 so the next iteration can keep going
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)+$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because everything
# inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?<! # Assert that the following, evaluated right-to-left, is not true:
^3円+ # [Step 2] is a proper divisor of N
(x+2円) # [Step 1] Any value of 3円 > 2円
)
# No anchor needed, because 2円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(
2円x+? # 2円 = the smallest number larger than the previous value of 2円
# for which the following is true; add 2円 to the running total
# sum of divisors.
|
^x # This must always be the first step. Add 1 to the sum of
# divisors, thus setting 2円 = 1 so the next iteration can keep
# going.
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)
(?^=2円+$) # Assert that 2円 is a divisor of N
)++ # Iterate the above at least once, with a possessive quantifier
# to lock in the match (i.e. prevent any iteration from being
# backtracked into).
$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because
# everything inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?^! # Lookinto – Assert that the following cannot match:
(2円x+) # 3円 = any number greater than 2円
3円+$ # Assert 3円 is a proper divisor of N
)
# No anchor needed, because 1円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(?= # Atomic lookahead:
.*(1円x+$) # 2円 = the smallest number larger than the previous value of 1円
# (which is identical to the previous value of 2円) for which the
# following is true. We can avoid using "x+?" because the ".*"
# before this implicitly forces values to be tested in increasing
# order from the smallest.
(?<=^2円+) # Assert that 2円 is a divisor of N
)
2円 # Add 2円 to the running total sum of divisors
|
^x # This must always be the first step. Add 1 to the sum of divisors,
# thus setting 1円 = 1 so the next iteration can keep going
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)+$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because everything
# inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?<! # Assert that the following, evaluated right-to-left, cannot match:
^3円+ # [Step 2] is a proper divisor of N
(x+2円) # [Step 1] Any value of 3円 > 2円
)
- 12.9k
- 2
- 71
- 55
Regex (Perl/PCRE+(?^=)RME ), 44(削除) 44 (削除ここまで) 41 bytes
((?>(1円x+2円x+?|^x\B)(?^=2円+$))|^x\B)+$++$(?^!(2円x+)3円+$)
This iswas a port of my 48 byte .NET regex below, using lookinto instead of variable-length lookbehind. This makes it far faster, and able to scan all numbers from 0 to 9000 in about 7 seconds on my PC. It also enables somes golfs that aren't possible in the .NET version.
# No anchor needed, because 1円2円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(?> # Atomic group – once this finishes matching, lock in the match
# and prevent it from being backtracked into.
2円x+? (1円x+?) # 2円 = the smallest number larger than the previous value of 1円2円
# (which is identical to the previous value of 2円) for which the # following is true; add 2円 to the running total sum of divisors.
(?^=2円+$) # Assert that 2円 is a divisor# sum of Ndivisors.
)
|
^x ^x # This must always be the first step. Add 1 to the sum of divisors,
# divisors, thus setting 1円2円 = 1 so the next iteration can keep # going.
\B \B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)+$
(?^=2円+$) # Assert that 2円 is a divisor of N
)++ # Iterate the above at least once, with a possessive quantifier
# to lock in the match (i.e. prevent any iteration from being
# backtracked into).
$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because everything
# everything inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?^! # Assert that the following, evaluated right-to-left, is not true:
(2円x+) # 3円 = any number greater than 2円
3円+$ # Assert 3円 is a proper divisor of N
)
Regex (PCRE2Perl / PCRE2 v10.35+), (削除) 64 (削除ここまで) 60(削除) 64 (削除ここまで)(削除) 60 (削除ここまで) 57 bytes
This is a port of the 4841 byte .NET regex, emulating variable-length lookbehind using a recursive subroutine call.
(?=((?>(1円x+2円x+?|^x\B)((?<=(?=^2円+$|(?3)).)))|^x\B)+$++$)(?!(1円x+2円x+)4円+$)
Attempt This Online! Try it online! - Perl
Attempt This Online! - PCRE2 v10.40+
# No anchor needed, because 2円 cannot be initially captured if
# matching is started anywhere besides the beginning.
(?=
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(
2円x+?> # 2円 = the smallest number larger than the previous value of 2円
# Atomicfor groupwhich the following is true; add 2円 to the running total
# sum of divisors.
|
^x # This must always be the first step. Add 1 to the sum of
# divisors, thus setting 2円 = 1 so the next iteration can keep
# going.
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (1円x+?as 1 will always be one of them).
)
((?<= # Define subroutine (?3) calls; thislookbehind
(?= # Circumvent the constant-width limitation of lookbehinds
# in PCRE by using a lookahead inside the lookbehind
^2円+$ # This is the payload of the emulated variable-length
# lookbehind,: sameAssert asthat the2円 oneis ina thedivisor .NETof regexN
|
(?3) # Recursive call - this is the only alternative that can
# match until we reach the beginning of the string
)
. # Go back one character at a time, trying the above
# lookahead for a match each time
)) ))++ # Iterate the above at least once, with a possessive quantifier
) # to lock in the match (i.e. prevent any iteration from being
| # backtracked into).
$ ^x # Require that the sum equal N exactly. If this fails, the loop
\B # won't be able to find a match by backtracking, because
)+$ # everything inside the loop is done atomically.
)
# Assert that there are no more proper divisors of N that haven't already been summed:
(?! # Assert that the following cannot match:
(1円x+2円x+) # 4円 = any number greater than 2円
4円+$ # Assert 4円 is a proper divisor of N
)
Regex (Perl/PCRE+(?^=)RME ), 44 bytes
((?>(1円x+?)(?^=2円+$))|^x\B)+$(?^!(2円x+)3円+$)
This is a port of my 48 byte .NET regex below, using lookinto instead of variable-length lookbehind. This makes it far faster, and able to scan all numbers from 0 to 9000 in about 7 seconds on my PC.
# No anchor needed, because 1円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(?> # Atomic group – once this finishes matching, lock in the match
# and prevent it from being backtracked into.
(1円x+?) # 2円 = the smallest number larger than the previous value of 1円
# (which is identical to the previous value of 2円) for which the # following is true; add 2円 to the running total sum of divisors.
(?^=2円+$) # Assert that 2円 is a divisor of N
)
|
^x # This must always be the first step. Add 1 to the sum of divisors,
# thus setting 1円 = 1 so the next iteration can keep going
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)+$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because everything
# inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?^! # Assert that the following, evaluated right-to-left, is not true:
(2円x+) # 3円 = any number greater than 2円
3円+$ # Assert 3円 is a proper divisor of N
)
Regex (PCRE2 v10.35+), (削除) 64 (削除ここまで) 60 bytes
This is a port of the 48 byte .NET regex, emulating variable-length lookbehind using a recursive subroutine call.
(?=((?>(1円x+?)((?<=(?=^2円+$|(?3)).)))|^x\B)+$)(?!(1円x+)4円+$)
(?=
(
(?> # Atomic group
(1円x+?)
((?<= # (?3) calls this
(?= # Circumvent the constant-width limitation of lookbehinds
# in PCRE by using a lookahead inside the lookbehind
^2円+$ # This is the payload of the emulated variable-length
# lookbehind, same as the one in the .NET regex
|
(?3) # Recursive call - this is the only alternative that can
# match until we reach the beginning of the string
)
. # Go back one character at a time, trying the above
# lookahead for a match each time
))
)
|
^x
\B
)+$
)
(?!
(1円x+)
4円+$
)
Regex (Perl/PCRE+(?^=)RME ), (削除) 44 (削除ここまで) 41 bytes
((2円x+?|^x\B)(?^=2円+$))++$(?^!(2円x+)3円+$)
This was a port of my 48 byte .NET regex below, using lookinto instead of variable-length lookbehind. This makes it far faster, and able to scan all numbers from 0 to 9000 in about 7 seconds on my PC. It also enables somes golfs that aren't possible in the .NET version.
# No anchor needed, because 2円 cannot be initially captured if
# matching is started anywhere besides the beginning.
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(
2円x+? # 2円 = the smallest number larger than the previous value of 2円
# for which the following is true; add 2円 to the running total # sum of divisors.
|
^x # This must always be the first step. Add 1 to the sum of
# divisors, thus setting 2円 = 1 so the next iteration can keep # going.
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)
(?^=2円+$) # Assert that 2円 is a divisor of N
)++ # Iterate the above at least once, with a possessive quantifier
# to lock in the match (i.e. prevent any iteration from being
# backtracked into).
$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because
# everything inside the loop is done atomically.
# Assert that there are no more proper divisors of N that haven't already been summed:
(?^! # Assert that the following, evaluated right-to-left, is not true:
(2円x+) # 3円 = any number greater than 2円
3円+$ # Assert 3円 is a proper divisor of N
)
Regex (Perl / PCRE2 v10.35+), (削除) 64 (削除ここまで)(削除) 60 (削除ここまで) 57 bytes
This is a port of the 41 byte regex, emulating variable-length lookbehind using a recursive subroutine call.
(?=((2円x+?|^x\B)((?<=(?=^2円+$|(?3)).)))++$)(?!(2円x+)4円+$)
Try it online! - Perl
Attempt This Online! - PCRE2 v10.40+
# No anchor needed, because 2円 cannot be initially captured if
# matching is started anywhere besides the beginning.
(?=
# Sum as many divisors of N as we can (using the current position as the sum),
# without skipping any of them:
(
(
2円x+? # 2円 = the smallest number larger than the previous value of 2円
# for which the following is true; add 2円 to the running total
# sum of divisors.
|
^x # This must always be the first step. Add 1 to the sum of
# divisors, thus setting 2円 = 1 so the next iteration can keep
# going.
\B # Exclude 1 as a divisor if N == 1. We don't have to do this for
# N > 1, because this loop will never be able to add N to the
# already summed divisors (as 1 will always be one of them).
)
((?<= # Define subroutine (?3); lookbehind
(?= # Circumvent the constant-width limitation of lookbehinds
# in PCRE by using a lookahead inside the lookbehind
^2円+$ # This is the payload of the emulated variable-length
# lookbehind: Assert that 2円 is a divisor of N
|
(?3) # Recursive call - this is the only alternative that can
# match until we reach the beginning of the string
)
. # Go back one character at a time, trying the above
# lookahead for a match each time
)) )++ # Iterate the above at least once, with a possessive quantifier
# to lock in the match (i.e. prevent any iteration from being
# backtracked into).
$ # Require that the sum equal N exactly. If this fails, the loop
# won't be able to find a match by backtracking, because
# everything inside the loop is done atomically.
)
# Assert that there are no more proper divisors of N that haven't already been summed:
(?! # Assert that the following cannot match:
(2円x+) # 4円 = any number greater than 2円
4円+$ # Assert 4円 is a proper divisor of N
)
- 12.9k
- 2
- 71
- 55
Regex (PCRE2v10.35+), 64(削除) 64 (削除ここまで) 60 bytes
This is a direct port of the 48 byte .NET regex, emulating variable-length lookbehind using a recursive subroutine call.
(?=((?=.*>(1円x+$1円x+?)((?<=(?=^2円+$|(?3)).)))2円|^x\B|^x\B)+$)(?!(1円x+)4円+$)
Try it on regex101 Attempt This Online!
(?=
(
(?=> # Atomic group
.*(1円x+$1円x+?)
((?<= # (?3) calls this
(?= # Circumvent the constant-width limitation of lookbehinds
# in PCRE by using a lookahead inside the lookbehind
^2円+$ # This is the payload of the emulated variable-length
# lookbehind, same as the one in the .NET regex
|
(?3) # Recursive call - this is the only alternative that can
# match until we reach the beginning of the string
)
. # Go back one character at a time, trying the above
# lookahead for a match each time
))
)
2円
|
^x
\B
)+$
)
(?!
(1円x+)
4円+$
)
It isn't possiblepractical to directly port the 47 byte regex to PCRE, because it changes the value of a capture group inside the lookbehind, and upon the return of any subroutine in PCRE, all capture groups are reset to the values they had upon entering the subroutine. It is possible, however, and I did this for the corresponding Abundant numbers regex by changing the main loop from iteration into recursion.
Regex (PCRE2), 64 bytes
This is a direct port of the 48 byte .NET regex, emulating variable-length lookbehind using a recursive subroutine call.
(?=((?=.*(1円x+$)((?<=(?=^2円+$|(?3)).)))2円|^x\B)+$)(?!(1円x+)4円+$)
(?=
(
(?=
.*(1円x+$)
((?<= # (?3) calls this
(?= # Circumvent the constant-width limitation of lookbehinds
# in PCRE by using a lookahead inside the lookbehind
^2円+$ # This is the payload of the emulated variable-length
# lookbehind, same as the one in the .NET regex
|
(?3) # Recursive call - this is the only alternative that can
# match until we reach the beginning of the string
)
. # Go back one character at a time, trying the above
# lookahead for a match each time
))
)
2円
|
^x
\B
)+$
)
(?!
(1円x+)
4円+$
)
It isn't possible to directly port the 47 byte regex to PCRE, because it changes the value of a capture group inside the lookbehind, and upon the return of any subroutine in PCRE, all capture groups are reset to the values they had upon entering the subroutine.
Regex (PCRE2v10.35+), (削除) 64 (削除ここまで) 60 bytes
This is a port of the 48 byte .NET regex, emulating variable-length lookbehind using a recursive subroutine call.
(?=((?>(1円x+?)((?<=(?=^2円+$|(?3)).)))|^x\B)+$)(?!(1円x+)4円+$)
(?=
(
(?> # Atomic group
(1円x+?)
((?<= # (?3) calls this
(?= # Circumvent the constant-width limitation of lookbehinds
# in PCRE by using a lookahead inside the lookbehind
^2円+$ # This is the payload of the emulated variable-length
# lookbehind, same as the one in the .NET regex
|
(?3) # Recursive call - this is the only alternative that can
# match until we reach the beginning of the string
)
. # Go back one character at a time, trying the above
# lookahead for a match each time
))
)
|
^x
\B
)+$
)
(?!
(1円x+)
4円+$
)
It isn't practical to directly port the 47 byte regex to PCRE, because it changes the value of a capture group inside the lookbehind, and upon the return of any subroutine in PCRE, all capture groups are reset to the values they had upon entering the subroutine. It is possible, however, and I did this for the corresponding Abundant numbers regex by changing the main loop from iteration into recursion.