Regex (Perl/PCRE+(?^=)RME), 4444 41 bytes
((?>(\1x+\2x+?|^x\B)(?^=\2+$))|^x\B)+$++$(?^!(\2x+)\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. \2x+? (\1x+?) # \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: (\2x+) # \3 = any number greater than \2 \3+$ # Assert \3 is a proper divisor of N )
Regex (PCRE2Perl / PCRE2 v10.35+), 64 6064 60 57 bytes
This is a port of the 4841 byte .NET regex, emulating variable-length lookbehind using a recursive subroutine call.
(?=((?>(\1x+\2x+?|^x\B)((?<=(?=^\2+$|(?3)).)))|^x\B)+$++$)(?!(\1x+\2x+)\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: ( ( \2x+?> # \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 (\1x+?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 the\2 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: (\1x+\2x+) # \4 = any number greater than \2 \4+$ # Assert \4 is a proper divisor of N )