大量的整数!


40

一个丰富的数字是任何数,其中其应有的除数的总和比原来的数量。例如,12的适当除数是:

1, 2, 3, 4, 6

并将这些结果相加为16。由于16大于12,因此12丰富。请注意,这并没有包括“完美号”,例如数字是等于其适当除数的总和,如6和28。

今天的任务是编写确定数字是否丰富的程序或函数。您的程序应采用单个整数作为输入,并根据其是否丰富输出真/假值。您可以假设输入将始终有效且大于0,因此对于错误的输入,可以使用未定义的行为。

您可以采用任何合理的格式输入和输出,例如STDIN / STDOUT,文件或参数/返回值都可以接受。

作为参考,以下是多达100个的大量数字:

12,
18,
20,
24,
30,
36,
40,
42,
48,
54,
56,
60,
66,
70,
72,
78,
80,
84,
88,
90,
96,
100

A005101上可以找到更多信息

由于这是,因此会拒绝标准漏洞,并尝试使用碰巧选择的任何一种语言编写尽可能短的代码!


11
“第一个奇数是945 = 3 ^ 3 * 5 * 7,第232个奇数!”
mbomb007 '17

大量的渐近密度在区间[0.24761748,0.24764422]内。使用本文中包含的源代码进行计算。
Deadcode

1
我正在尝试在Geometry Dash中执行此操作。这是一场噩梦
MilkyWay90

Answers:


41

ECMAScript正则表达式,1085 855 597 536 511 508 504字节

在ECMAScript正则表达式中匹配大量数字与在几乎任何其他正则表达式中进行匹配完全不同。缺少前向/嵌套的反向引用或递归意味着不可能直接计算或保持任何事物的连续总数。缺乏后顾之忧使得即使有足够的工作空间也常常是一个挑战。

必须从完全不同的角度解决许多问题,并且您会怀疑它们是否完全可以解决。它迫使您建立一个更广泛的网络,以发现正在使用的数字的哪些数学属性可以用来解决特定问题。

早在2014年3月至4月,我就在ECMAScript正则表达式中构造了此问题的解决方案。最初,我有充分的理由怀疑这个问题是完全不可能的,但是数学家teukon提出了一个想法,使它最终看起来可以解决,这是一个令人鼓舞的案例–但他明确表示,他无意构造正则表达式(曾与我竞争/合作构建/推广以前的正则表达式,但在这一点上已经达到了极限,并满足于限制他对理论的进一步贡献。

就像几天前发布的正则表达式一样,我会警告:我强烈建议学习如何在ECMAScript正则表达式中解决一元数学问题。对于我来说,这是一段引人入胜的旅程,对于那些可能想要自己尝试的人,尤其是对数字理论感兴趣的人,我都不想破坏它。请参阅该帖子,以获取逐个解决问题的建议问题列表,以一一解决。

因此,如果您不希望为您破坏一元深的一元正则表达式魔术,请不要继续阅读。我以前的帖子只是一个小味道。如果您确实想自己弄清楚该魔术,我强烈建议您先解决ECMAScript regex中的一些问题,如上面链接的那部分所述。

发布我的ECMAScript的正则表达式之前,我认为这将是有趣的分析马丁安德的.NET纯正则表达式的解决方案^(?!(1(?<=(?=(?(\3+$)((?>\2?)\3)))^(1+)))*1$)。事实证明,了解正则表达式非常简单,并且它的简洁性非常好。为了展示我们的解决方案之间的对比,这是他的正则表达式的注释版和漂亮印刷版(但未经修改):

# For the purpose of these comments, the input number will be referred to as N.

^(?!                  # Attempt to add up all the divisors. Since this is a regex and we
                      # can only work within the available space of the input, that means
                      # if the sum of the divisors is greater than N, the attempt to add
                      # all the divisors will fail at some point, causing this negative
                      # lookahead to succeed, showing that N is an abundant number.

  (1                  # Cycle through all values of tail that are less than N, testing
                      # each one to see if it is a divisor of N.

    (?<=              # Temporarily go back to the start so we can directly operate both
                      # on N and the potential divisor. This requires variable-length
                      # lookbehind, a .NET feature – even though this special case of
                      # going back to the start, if done left-to-right, would actually be
                      # very easy to implement even in a regex flavour that has no
                      # lookbehind to begin with. But .NET evaluates lookbehinds right
                      # to left, so please read these comments in the order indicated,
                      # from [Step 1] to [Step 7]. The comment applying to entering the
                      # lookahead group, [Step 2], is shown on its closing parenthesis.
      (?=             # [Step 3] Since we're now in a lookahead, evaluation is left to
                      #          right.
        (?(\3+$)      # [Step 4] If \3 is a divisor of N, then...
          (           # [Step 5] Add it to \2, the running total sum of divisors:
                      #          \2 = \2 + \3         
            (?>\2?)   # [Step 6] Since \2 is a nested backref, it will fail to match on
                      #          the first iteration. The "?" accounts for this, making
                      #          it add zero to itself on the first iteration. This must
                      #          be done before adding \3, to ensure there is enough room
                      #          for the "?" not to cause the match to become zero-length
                      #          even if \2 has a value.
            \3        # [Step 7] Iff we run out of space here, i.e. iff the sum would
                      #          exceed N at this point, the match will fail, making the
                      #          negative lookahead succeed, showing that we have an
                      #          abundant number.
          )

        )
      )               # [Step 2] Enter a lookahead that is anchored to the start due to
                      #          having a "^" immediately to its right. The regex would
                      #          still work if the "^" were moved to the left of the
                      #          lookahead, but would be slightly slower, because the
                      #          engine would do some spurious matching before hitting
                      #          the "^" and backtracking.
      ^(1+)           # [Step 1] \3 = number to test for being a potential divisor – its
                      #               right-side-end is at the point where the lookbehind
                      #               started, and thus \3 cycles through all values from
                      #               1 to N-1.
    )
  )*1$                # Exclude N itself from being considered as a potential divisor,
                      # because if we included it, the test for proper abundance would be
                      # the sum of divisors exceeding 2*N. We don't have enough space for
                      # that, so instead what would happen if we did not exclude N as a
                      # divisor would be testing for "half-abundance", i.e. the sum of
                      # all divisors other than N exceeding N/2. By excluding N as a
                      # divisor we can let our threshold for abundance be the sum of
                      # divisors exceeding N.
)

在线尝试.NET正则表达式

现在,回到我的ECMAScript正则表达式。首先,这里是原始,无空格和无注释的格式:

^(?=(((?=(xx+?)\3+$)(x+)\4*(?=\4$))+(?!\3+$)(?=(xx(x*?))\5*$)x)(x+))(?=\1(x(x*))(?=\8*$)\6\9+$)(?=(.*)((?=\8*$)\5\9+$))(?=(x*?)(?=(x\11)+$)(?=\12\10|(x))(x(x*))(?=\15*$)(?=\11+$)\11\16+$)(?=(x(x*))(?=\17*$)\7\18+$)((?=(x*?(?=\17+$)(?=\17+?(?=((xx(x*))(?=\18+$)\22*$))(x+).*(?=\17$)\24*(?=\24$)(?!(xx+)\25*(?!\22+$)\25$)\22+$)((?=(x\7)+$)\15{2}\14|)))(?=.*(?=\24)x(x(x*))(?=\28*$)\23\29*$)(?=.*(x((?=\28*$)\22\29+$)))(.*(?!\30)\20|(?=.*?(?!x\20)(?=\30*$)(x(x*))(?=\33*$)(?=\31+$)\31\34+$).*(?=\33\21$)))+$

(其他城市\14\14?这不是ECMAScript中与PCRE,.NET的兼容性,以及几乎所有其他正则表达式的味道)

在线尝试!
在线尝试!(更快,正则表达式的537字节版本)

现在,简要介绍其背后的故事。

起初,至少对于我来说,不是很明显,甚至可以在一般情况下匹配素数。在解决了这一问题之后,同样适用于2的幂。然后是复数的幂。然后是完美的正方形。甚至在解决了这一问题之后,一开始也不可能进行广义乘法。

在ECMAScript循环中,您只能跟踪一个变化的数字。该数字不能超过输入,并且必须在每一步都减少。我的第一个用于匹配正确的乘法语句A * B = C的正则表达式为913字节,并且通过将A,B和C分解为它们的素幂进行工作–对于每个素因数,将A和C的一对素幂因数重复除直到他们的素数达到1为止;然后,将与C对应的一个功率与B的质数功率因数进行比较。相同质数的这两个质数通过加在一起而被“复用”为一个数;出于位置数字系统起作用的相同原因,在循环的每个后续迭代中,这始终是毫无区别的。

我们使用完全不同的算法将乘法减到了50个字节(teukon和我能够独立到达,尽管他只花了几个小时就直奔它,而即使是这样,我也花了几天的时间)引起我注意,存在一个简短的方法):对于A≥B,只有在C是满足C≡0mod A和C≡Bmod A-1的最小数时,A * B = C才是。(为方便起见,A = 1的例外不需要在正则表达式中进行特殊处理,其中0%0 = 0会产生匹配项。)我只是无法克服这样一个优雅的乘法方法存在多么整洁的问题极少的正则表达式味道。(并且A≥B的要求可以用A和B是相同幂的质数幂的要求来代替。对于A≥B的情况,这可以用中国余数定理证明。)

如果事实证明没有简单的乘法算法,则正则表达式的数量可能约为一万字节左右(即使考虑到我将913字节算法压缩为651字节)。它执行很多乘法和除法运算,并且ECMAScript regex没有子例程。

我于2014年3月23日切线开始研究大量数字问题,方法是针对当时似乎是该问题的一个子问题构建一个解决方案:确定最高多重性的素因,以便将其除以N首先,留出空间来进行一些必要的计算。当时,这似乎是一个有前途的途径。(我最初的解决方案最终非常大,只有326个字节,后来下降到185个字节。)但是teukon概述的其余方法将非常复杂,因此事实证明,我采取了另一种不同的方法。事实证明,将N的最大素数功率因数除以N上的最大素数因子就足够了;这样做是为了获得最高的多重性,这会增加正则表达式不必要的复杂性和长度。

剩下的就是将除数之和视为和的乘积,而不是直接的和。正如teukon在2014年3月14日所解释的

给定一个数字n = p 0 a 0 p 1 a 1 ... p k-1 a k-1。我们要处理n的因子之和,即(1 + p 0 + p 0 2 + ... + p 0 a 0)(1 + p 1 + p 1 2 + ... + p 1 a 1)...(1 + p k-1 + p k-1 2 + ... + p k-1 a k-1)。

看到这一点,我大吃一惊。我从来没有想过要用这种方式来计算等分和,而正是这个公式比其他任何事情更使ECMAScript regex中大量匹配的可解性显得合理。

最后,我没有测试除法结果是否超过N,也没有测试过被M除以的结果超过了N / M,而是进行了除法结果是否小于1的测试。 2014年4月7日发布第一个工作版本。

我对该正则表达式进行高尔夫优化的完整历史记录在github上。在某个时候,一个优化最终使正则表达式变慢了,所以从那时起,我维护了两个版本。他们是:

匹配大量数字的正则表达式.txt 匹配大量数字的正则表达式-shortest.txt

这些正则表达式与ECMAScript和PCRE完全兼容,但是最近的优化涉及使用可能不参与的捕获组\14,因此,通过删除PCRE兼容性并将其更改\14?\14它们,都可以减少1个字节。

这是最小的版本,已应用优化(使其仅适用于ECMAScript),重新格式化为适合于StackExchange代码块,(几乎)不需要水平滚动:

# Match abundant numbers in the domain ^x*$ using only the ECMAScript subset of regex
# functionality. For the purposes of these comments, the input number = N.
^
# Capture the largest prime factor of N, and the largest power of that factor that is
# also a factor of N. Note that the algorithm used will fail if N itself is a prime
# power, but that's fine, because prime powers are never abundant.
(?=
  (                      # \1 = tool to make tail = Z-1
    (                    # Repeatedly divide current number by its smallest factor
      (?=(xx+?)\3+$)
      (x+)\4*(?=\4$)
    )+                   # A "+" is intentionally used instead of a "*", to fail if N
                         #  is prime. This saves the rest of the regex from having to
                         #  do needless work, because prime numbers are never abundant.
    (?!\3+$)             # Require that the last factor divided out is a different prime.
    (?=(xx(x*?))\5*$)    # \5 = the largest prime factor of N; \6 = \5-2
    x                    # An extra 1 so that the tool \1 can make tail = Z-1 instead of just Z
  )
  (x+)                   # Z = the largest power of \5 that is a factor of N; \7 = Z-1
)
# We want to capture Z + Z/\5 + Z/\5^2 + ... + \5^2 + \5 + 1 = (Z * \5 - 1) / (\5 - 1),
# but in case Z * \5 > N we need to calculate it as (Z - 1) / (\5 - 1) * \5 + 1.
# The following division will fail if Z == N, but that's fine, because no prime power is
# abundant.
(?=
  \1                     # tail = (Z - 1)
  (x(x*))                # \8   = (Z - 1) / (\5 - 1); \9 = \8-1
  # It is guaranteed that either \8 > \5-1 or \8 == 1, which allows the following
  # division-by-multiplication to work.
  (?=\8*$)
  \6\9+$
)
(?=
  (.*)                   # \10 = tool to compare against \11
  (                      # \11 = \8 * \5  =  (Z - 1) / (\5 - 1) * \5; later, \13 = \11+1
    (?=\8*$)
    \5\9+$
  )
)
# Calculate Q = \15{2} + Q_R = floor(2 * N / \13). Since we don't have space for 2*N, we
# need to calculate N / \13 first, including the fractional part (i.e. the remainder),
# and then multiply the result, including the fractional part, by 2.
(?=
  (x*?)(?=(x\11)+$)      # \12 = N % \13; \13 = \11 + 1
  (?=\12\10|(x))         # \14 = Q_R = floor(\12 * 2 / \13)
                         #     = +1 carry if \12 * 2 > \11, or NPCG otherwise
  (x(x*))                # \15 = N / \13; \16 = \15-1
  (?=\15*$)
  (?=\11+$)              # must match if \15 <  \13; otherwise doesn't matter
  \11\16+$               # must match if \15 >= \13; otherwise doesn't matter
)
# Calculate \17 = N / Z. The division by Z can be done quite simply, because the divisor
# is a prime power.
(?=
  (x(x*))                # \17 = N / Z; \18 = \17-1
  (?=\17*$)
  \7\18+$
)
# Seed a loop which will start with Q and divide it by (P^(K+1)-1)/(P-1) for every P^K
# that is a factor of \17. The state is encoded as \17 * P + R, where the initial value
# of R is Q, and P is the last prime factor of N to have been already processed.
#
# However, since the initial R would be larger than \17 (and for that matter there would
# be no room for any nonzero R since with the initial value of P, it is possible for
# \17 * P to equal N), treat it as a special case, and let the initial value of R be 0,
# signalling the first iteration to pretend R=Q. This way we can avoid having to divide Q
# and \17 again outside the loop.
#
# While we're at it, there's really no reason to do anything to seed this loop. To seed
# it with an initial value of P=\5, we'd have to do some multiplication. If we don't do
# anything to seed it, it will decode P=Z. That is wrong, but harmless, since the next
# lower prime that \17 is divisible by will still be the same, as \5 cannot be a factor
# of \17.

# Start the loop.
(
  (?=
    (                    # \20 = actual value of R
      x*?(?=\17+$)       # move forward by directly decoded value of R, which can be zero
      # The division by \17 can be done quite simply, because it is known that
      # the quotient is prime.
      (?=
        \17+?            # tail = \17 * (a prime which divides into \17)
        (?=
          (              # \21 = encoded value for next loop iteration
            (xx(x*))     # \22 = decoded value of next smaller P; \23 = (\22-1)-1
            (?=\18+$)    # iff \22 > \17, this can have a false positive, but never a false negative
            \22*$        # iff \22 < \17, this can have a false positive, but never a false negative
          )
        )
        # Find the largest power of \22 that is a factor of \17, while also asserting
        # that \22 is prime.
        (x+)             # \24 = the largest power of \22 that is a factor of \17
        .*(?=\17$)
        \24*(?=\24$)
        (?!
          (xx+)\25*
          (?!\22+$)
          \25$
        )
        \22+$
      )
      (
        (?=(x\7)+$)      # True iff this is the first iteration of the loop.
        \15{2}\14        # Potentially unset capture, and thus dependent on ECMAScript
                         # behavior. Change "\14" to "\14?" for compatibility with non-
                         # ECMAScript engines, so that it will act as an empty capture
                         # with engines in which unset backrefs always fail to match.
      |
      )
    )
  )
  # Calculate \30 = (\24 - 1) / (\22 - 1) * \22 + 1
  (?=
    .*(?=\24)x           # tail = \24 - 1
    (x(x*))              # \28 = (\24 - 1) / (\22 - 1); \29 = \28-1
    (?=\28*$)
    \23\29*$
  )
  (?=
    .*(x(                # \30 = 1 + \28 * \22 = (\28 - 1) / (\22 - 1) * \22 + 1; \31 = \30-1
      (?=\28*$)
      \22\29+$
    ))
  )
  # Calculate \33 = floor(\20 / \30)
  (
    .*(?!\30)\20         # if dividing \20 / \30 would result in a number less than 1,
                         # then N is abundant and we can exit the loop successfully
  |
    (?=
      .*?(?!x\20)(?=\30*$)
      (x(x*))            # \33 = \20 / \30; \34 = \33-1
      (?=\33*$)
      (?=\31+$)          # must match if \33 <  \30; otherwise doesn't matter
      \31\34+$           # must match if \33 >= \30; otherwise doesn't matter
    )
    # Encode the state for the next iteration of the loop, as \17 * \22 + \33
    .*(?=\33\21$)
  )
)+$

评论不作进一步讨论;此对话已转移至聊天
DJMcMayhem


27

Python 2中41 40个字节

n=k=j=input()
while~k<0:j-=1;k-=j>>n%j*n

输出是通过退出代码进行的,因此0为真实,1为虚假。

在线尝试!

这个怎么运作

将所有nkj都设置为来自STDIN的输入后,我们进入while循环。一旦-k-1 =〜k≥0,即k≤-1 / k <0,所述环路就会中断。

在每次迭代中,我们首先递减j以仅考虑n的适当除数。如果jn的除数,则n%j得出0,并且j >> n%j * n = j / 2 0 = jk中减去。然而,如果Ĵ没有划分Ñn%j是正的,所以n%j*n是至少N>日志2 ĴĴ>> N引用%j * N = j的/ 2 N%Ĵ* N = 0是从减去ķ

对于大量的数字,由于n的适当除数之和严格大于n,因此kj变为1之前或之时将达到负值。在这种情况下,我们退出了while循环,程序正常完成。

但是,如果ñ不是丰富,Ĵ最终达到0。在这种情况下,n%j抛出ZeroDivisionError,程序退出并出现错误。


4
~k<0是花哨的,但我认为-1<k也能做到;)
Martin Ender


10

果冻,3个字节

Æṣ>

在线尝试!

这个怎么运作

Æṣ>  Main link. Argument: n

Æs   Get the proper divisor sum of n.
  >  Test if the result is greater than n.


10

Mathematica,17个字节

Tr@Divisors@#>2#&

说明

Tr@                 The sum of the main diagonal of
   Divisors@         the list of divisors of
            #         the first argument
             >      is greater than
              2#      twice the first argument.
                &   End of function.

1
我很惊讶数学没有内置在这个..
MrPaulch

1
@MrPaulch考虑到程序的长度,内建函数的名称可能会更长>。>
Conor O'Brien

1
@ ConorO'Brien如果存在,则可能是这样AbundantNumberQ,因此它将节省几个字节:)
ngenisis


7

视网膜50 45字节

^(?!(1(?<=(?=(?(\3+$)((?>\2?)\3)))^(1+)))*1$)

一元输入10否则输出大量。

此解决方案没有特定于Retina的内容。上面是纯.NET正则表达式,仅匹配大量数字。

在线尝试!(测试套件使用上述正则表达式过滤十进制输入。)


6

视网膜,34字节

字节数假定为ISO 8859-1编码。

M!&`(1+)$(?<=^\1+)
1>`¶

^(1+)¶1\1

一元输入10否则输出大量。

在线尝试!

说明

M!&`(1+)$(?<=^\1+)

我们首先获取输入的所有除数。为此,我们返回(!)正则表达式的所有重叠&)匹配项(M(1+)$(?<=^\1+)。如果整个输入是该后缀的倍数,则正则表达式与输入的后缀匹配(我们通过仅使用后缀的副本来尝试到达字符串的开头来确保此后缀)。由于正则表达式引擎查找匹配项的方式,这将导致除数列表以降序排列(由换行分隔)。

1>`¶

舞台本身仅匹配换行符()并将其删除。但是,1>是一个限制,它会跳过第一个匹配项。因此,这有效地将除输入本身之外的所有除数加在一起。我们最后在第一行输入,在第二行将所有适当除数的总和。

^(1+)¶1\1

最后,我们尝试1比第二行多匹配至少第二行。在这种情况下,适当的除数之和超过了输入。Retina会计算此正则表达式的匹配次数,这将1用于大量的正则表达式0


1
我总是惊讶于如何在视网膜中进行数学运算。我希望看到一个解释!:)
DJMcMayhem

1
@DJMcMayhem对不起,忘了早点添加。做完了
Martin Ender

6

8086组装, 23 28 25 24字节

8bc8 d1e9 33db 33d2 50f7 f158 85d2 7502 03d9 7204 e2f0 3bc3

未组装:

; calculate if N (1 < N <= 65535) is abundant
; input: N (mem16/r16)
; output: CF=1 -> abundant, CF=0 -> not abundant
ABUND   MACRO   N 
        LOCAL DIV_LOOP, CONT_LOOP, END_ABUND
        IFDIFI <N>,<AX> ; skip if N is already AX
    MOV  AX, N          ; AX is dividend
        ENDIF
    MOV  CX, AX         ; counter starts at N / 2
    SHR  CX, 1          ; divide by 2
    XOR  BX, BX         ; clear BX (running sum of factors)
DIV_LOOP:
    XOR  DX, DX         ; clear DX (high word for dividend)
    PUSH AX             ; save original dividend
    DIV  CX             ; DX = DX:AX MOD CX, AX = DX:AX / CX
    POP  AX             ; restore dividend (AX was changed by DIV)
    TEST DX, DX         ; if remainder (DX) = 0, it divides evenly so CX is a divisor
    JNZ  CONT_LOOP      ; if not, continue loop to next
    ADD  BX, CX         ; add number to sum
    JC   END_ABUND      ; if CF=1, BX has unsigned overflow it is abundant (when CX < 65536)
CONT_LOOP:
    LOOP DIV_LOOP
    CMP  AX, BX         ; BX<=AX -> CF=0 (non-abund), BX>AX -> CF=1 (abund)
END_ABUND:
        ENDM

示例测试程序,测试N = [12..1000]:

    MOV  AX, 12         ; start tests at 12
LOOP_START:
    ABUND AX            ; call ABUND MACRO for N (in AX)
    JNC  LOOP_END       ; if not abundant, display nothing
    CALL OUTDECCSV      ; display AX as decimal (generic decimal output routine)
LOOP_END:
    INC  AX             ; increment loop counter
    CMP  AX, 1000       ; if less than 1000...
    JBE  LOOP_START     ; continue loop
    RET                 ; return to DOS

输出[2..1000]

12, 18, 20, 24, 30, 36, 40, 42, 48, 54, 56, 60, 66, 70, 72, 78, 80, 84, 88, 90, 96, 100, 102, 104, 108, 112, 114, 120, 126, 132, 138, 140, 144, 150, 156, 160, 162, 168, 174, 176, 180, 186, 192, 196, 198, 200, 204, 208, 210, 216, 220, 222, 224, 228, 234, 240, 246, 252, 258, 260, 264, 270, 272, 276, 280, 282, 288, 294, 300, 304, 306, 308, 312, 318, 320, 324, 330, 336, 340, 342, 348, 350, 352, 354, 360, 364, 366, 368, 372, 378, 380, 384, 390, 392, 396, 400, 402, 408, 414, 416, 420, 426, 432, 438, 440, 444, 448, 450, 456, 460, 462, 464, 468, 474, 476, 480, 486, 490, 492, 498, 500, 504, 510, 516, 520, 522, 528, 532, 534, 540, 544, 546, 550, 552, 558, 560, 564, 570, 572, 576, 580, 582, 588, 594, 600, 606, 608, 612, 616, 618, 620, 624, 630, 636, 640, 642, 644, 648, 650, 654, 660, 666, 672, 678, 680, 684, 690, 696, 700, 702, 704, 708, 714, 720, 726, 728, 732, 736, 738, 740, 744, 748, 750, 756, 760, 762, 768, 770, 774, 780, 784, 786, 792, 798, 800, 804, 810, 812, 816, 820, 822, 828, 832, 834, 836, 840, 846, 852, 858, 860, 864, 868, 870, 876, 880, 882, 888, 894, 896, 900, 906, 910, 912, 918, 920, 924, 928, 930, 936, 940, 942, 945, 948, 952, 954, 960, 966, 968, 972, 978, 980, 984, 990, 992, 996, 1000

输出[12500..12700]

12500, 12504, 12510, 12512, 12516, 12520, 12522, 12528, 12530, 12534, 12540, 12544, 12546, 12552, 12558, 12560, 12564, 12570, 12572, 12576, 12580, 12582, 12584, 12588, 12594, 12600, 12606, 12612, 12618, 12620, 12624, 12628, 12630, 12636, 12640, 12642, 12648, 12650, 12654, 12656, 12660, 12666, 12670, 12672, 12678, 12680, 12684, 12688, 12690, 12696, 12700

输出[25100..25300]

25100, 25104, 25110, 25116, 25120, 25122, 25128, 25130, 25134, 25140, 25144, 25146, 25152, 25158, 25160, 25164, 25168, 25170, 25172, 25176, 25180, 25182, 25188, 25194, 25200, 25206, 25212, 25216, 25218, 25220, 25224, 25228, 25230, 25232, 25236, 25240, 25242, 25245, 25248, 25254, 25256, 25260, 25266, 25270, 25272, 25278, 25280, 25284, 25290, 25296, 25300

更新:

  • 修复了16位溢出(+5个字节)的问题。感谢@deadcode的建议!
  • 简化的返回逻辑(-3字节)。再次感谢@deadcode的帮助。
  • 使用TEST代替CMP(-1字节)。谢谢@ l4m2!

1
我会建议更换JLEJBE到开始溢出导致它给假阴性前双号的范围内这可以测试。然后,它不会在12600(等分总和35760)处开始失败,而会在25200(等分总和74744)处开始失败。更好的方法是还检测进位标志并将其视为一个足够的数字,而无需计算实际的> 16位总和。
Deadcode

1
很好@Deadcode。我已经更新了以下跳转的代码,而不是更少的跳转。我明白了你的意思,在ADD BX之后执行JC,CX会在那里捕获未签名的溢出,并使它更正直到N = 65535。由于先前的CF表示为false,因此使标志测试和返回状态有些复杂。还更新了修复程序。
640KB

1
通过反转返回值的指定,可以节省3个字节,如果设置为CF,则设置CF;如果设置为CF,则清零。但是我建议先进行编辑以更正输出文档,因此在编辑历史记录中看起来不错。
Deadcode

1
同样,为了简单起见,规范应该是返回值在进位标志中,并且不要让其他标志大惊小怪。呼叫者应该使用JCJNC采取行动,以确保号码是否足够。
Deadcode

1
非常感谢您的所有帮助和意见。我已经更新了内联文档,并删除了“取消高尔夫”一词。老实说,我从来没有考虑过,但是我明白您的意思,因为除了内联注释外,没有什么不同。也同意makint的返回标志也更清晰。会在一点上工作。感谢您的关注和协助!
640KB


5

05AB1E,4个字节

ѨO‹

在线尝试!

这个怎么运作

Ñ        #list of divisors
 ¨       #remove last element (i.e the input from the list of factors)
  O      #sum the list 
   ‹     #is this sum less than the input? 

很抱歉在旧问题中发布内容,我只是在老旧文章中进行练习,并发现我的解决方案比第二个最佳的05AB1E解决方案要短。


4
Sorry to post in old question不用担心!我总是很高兴看到我的旧挑战的答案,并且在这里真的很受鼓舞。:)
DJMcMayhem


4

Java 8,53个字节(如果包含礼节代码,则更多)

return IntStream.range(1,n).filter(e->n%e<1).sum()>n;

在线尝试

说明:

IntStream.range(1,n) \\ numbers from 1 to n-1
filter(e->n%e<1)     \\ filter in numbers that perfectly divide the number n
sum()>n              \\ sum and compare to original number

4
很好的答案,但是对于Java 8,必须在字节数中包含该函数。再一次,return如果我没记错的话,可以删除,因此它会更短:(n->IntStream.range(1,n).filter(e->n%e<1).sum()>n如果正确,则不是100%,我几乎从不使用Java 8编程)。欢迎来到PPCG!
凯文·克鲁伊森

1
通过标准计数的正确计数应n->java.util.stream.IntStream.range(1,n).filter(e->n%e<1).sum()>n为65个字节(假设我把包装放在我的头顶上)
CAD97

4

Powershell,51 49字节

param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i

我希望我可以删除一些括号。

-2感谢AdmBorkBork,我们没有在初始范围内计算输入,而是在最终检查中将其考虑在内。

循环通过的范围1..$iNPUT,减1,找到其中(?)由当前数字输入的逆模数为$true(又名只有0) -然后-join所有的这些数字连同+iex生成的字符串来计算的话,则查看是否这些部分的总和大于输入。

PS C:\++> 1..100 | ? {.\abundance.ps1 $_}
12
18
20
24
30
36
40
42
48
54
56
60
66
70
72
78
80
84
88
90
96
100

您可以通过计算最高值并检查其大于输入值的2 param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i

3

MATL,6个字节

Z\sGE>

输出1表示大量数字,否则输出0。

这个怎么运作

Z\      % list the divisors of the implicit input
s       % add them
G       % push the input again
E       % double it
>       % compare
        % implicitly display result

3

QBIC,22字节

:[a/2|~a%b|\p=p+b}?p>a

这是对QBIC素数测试的改编。而不是计算除数并检查其是否小于三个,而是对适当的除数求和。这仅沿的一半进行1 to n,素性测试1 to n完全通过。

说明:

:       Get the input number, 'a'
[a/2|   FOR(b=1, b<=(a/2), b++)
~a%b    IF a MOD b != 0  --> QBasic registers a clean division  (0) as false. 
        The IF-branch ('|') therefor is empty, the code is in the ELSE branch ('\')
|\p=p+b THEN add b to runnning total p
}       Close all language constructs: IF/END IF, FOR/NEXT
?p>a    Print '-1' for abundant numbers, 0 otherwise.

3

JavaScript(ES6),33个字节

let g =
x=>(f=n=>--n&&n*!(x%n)+f(n))(x)>x
<input type=number min=1 value=1 step=1 oninput="O.innerHTML=g(+value)"><br>
<pre id=O>false</pre>


我确定递归答案将是最好的,但我不认为这样会很好。
尼尔

3

Japt9 7 6个字节

<Uâ1 x

由于ETHproductions,节省了2个字节。感谢obarakon,节省了1个字节。

在线尝试!


9个字符,10个字节。
Metoniem

@Metoniem我确定â至少是一个字节(1xE2)。
汤姆(Tom),

1
@Metoniem Japt使用ISO-8859-1编码,其中â是一个字节。
ETHproductions '02

如果â给定一个真实的参数,它将从剩余列表中删除实际的数字,因此您可以â1 x >U保存几个字节:-)
ETHproductions

@TomDevs不错!您可以<Uâ1 x保存一个字节。Japt U在程序前面添加。
奥利弗

3

Cubix,38个字节

/..?%?(O;0I:^.<.>;rrw+s;rUO?-<...O0L.@

在这里尝试

      / . .
      ? % ?
      ( O ;
0 I : ^ . < . > ; r r w
+ s ; r U O ? - < . . .
O 0 L . @ . . . . . . .
      . . .
      . . .
      . . .

0I:-用0,n,n(s,n,d)设置堆栈
^-循环的开始 )?-递减d并测试0。0退出循环
%?-针对n进行mod并测试。0导致;rrw+s;rU将s旋转到顶部并加d,将s旋转到底部并重新加入循环
;<-清理并重新加入循环。
在退出循环时
;<-从堆栈中删除d并重定向
-?-从s中删除n并测试,LOU@向左转0 ,输出和退出,负数0O@推零,输出和退出。正数;O消除差异并输出n。然后,路径经过左转弯,该左转弯将重定向到@出口


3

纯Bash,37个字节

for((;k++<$1;s+=$1%k?0:k)){((s>$1));}

感谢@Dennis重新排列代码-节省6个字节并消除了stderr的附带输出。

输入作为参数传递。

输出以退出代码返回:0表示丰富,1表示不丰富。

输出到stderr应该忽略。

测试运行:

for n in {1..100}; do if ./abundant "$n"; then echo $n; fi; done 2>/dev/null
12
18
20
24
30
36
40
42
48
54
56
60
66
70
72
78
80
84
88
90
96
100

您可以节省6个字节,同时避免将杂散输出到STDERR。tio.run/nexus/bash#S04sUbBTSEwqzUtJzCtRsLFRUHf1d1P/…–
Dennis,

2

RProgN,8字节

~_]k+2/<

讲解

~_]k+2/<
~           # Zero Space Segment
 _          # Convert the input to an integer
  ]         # Duplicate the input on the stack
   k+       # Get the sum of the divisors of the top of the stack
     2/     # Divded by 2
       <    # Is the Input less than the sum of its divisors/2.

在线尝试!


2

批处理,84字节

@set/ak=%1*2
@for /l %%j in (1,1,%1)do @set/ak-=%%j*!(%1%%%%j)
@cmd/cset/a"%k%>>31

否则-1,输出大量0。通过从中减去所有因子2n,然后将结果移31位以提取符号位,可以工作。备用公式,也为84字节:

@set k=%1
@for /l %%j in (1,1,%1)do @set/ak-=%%j*!(%1%%%%j)
@if %k% lss -%1 echo 1

输出1数量众多。通过从中减去所有因子n,然后将结果与进行比较来工作-n。(这set/a是Batch进行算术运算的唯一方法,因此我无法轻松调整循环。)


1
“(%1 %%%% j)”哦,批次:)
Bryan Boettcher

2

Perl 6,72 24字节

{$_ <sum grep $_%%*,^$_}
  • 程序参数:
  • 从生成列表1..a
  • 将所有数字除以a
  • 求和。
  • 检查该总和是否大于a

感谢@ b2gills。


$^a在第一个之后的每次出现都可以缩短为正义$a。但是如果您将它写成“#”,它甚至会更短。此外,如果您{$_ <sum grep $_%%*,^$_}还查看一个早期版本,则[+](LIST)可以工作(没有空格)
Brad Gilbert b2gills

@ BradGilbertb2gills谢谢!:)
Ven

2

J,19个字节

感谢Conor O'Brien将其减少到19个字节!

<[:+/i.#~i.e.]%2+i.

上一个:(34个字节)

f=:3 :'(+/((i.y)e.y%2+i.y)#i.y)>y'

如果丰富,则返回1,否则返回0。

输出:

   f 3
0
   f 12
1
   f 11
0
   f 20
1

欢迎来到PPCG!我们允许使用匿名函数,因此您可以删除开头f=:作为字节数的一部分。此外,通过转换为默认动词,您可以降低到19:<[:+/i.#~i.e.]%2+i.
Conor O'Brien

谢谢你的建议!但是,能否请您解释大写动词([:)和切换动词(〜)。我没有真正理解他们在这个默认动词中应该做的事情。
阻止

〜切换,所以它是ie#i。但是[:的目的是什么?
阻止

所以你知道叉子吧?(f g h) y' is the same as (fy)g(hy). When f`是一个上限,([: g h) y与大致相同g h y。至于~,这将切换左参数和右参数。重要的是要知道它~不是动词,但实际上是副词。它修饰动词。例如,我们可以有类似的东西2 %~ 8。在这里,进行~修改%以切换其参数,因此表达式等同于8 % 2
科纳·奥布莱恩

在fork链中,#~执行右边的动词后进行求值,因此它的左边参数成为右边的结果
Conor O'Brien

2

Pyth,11个字节

>sPf!%QTS

旧:

L!%Qb>sPy#S

我不能!%用作的pfn #,因为它是两个函数。让我伤心 :(。


L!%Qb>sPy#SQ    Program's argument: Q
L!%Qb           Define a lambda y, that takes b as an argument
 !%Qb           Return true if Q is divisible by b
          S     Make a range 1..Q
        y#      Filter that range with the lambda (y)
       P        Remove the last element (Q itself)
      s         Sum them
     >     Q    Check if that sum is greater than the program's argument

未定义函数似乎更短:>sPf!%QTS
FryAmTheEggman '17

2

k19 16 15字节

{x<+/&~(!x)!'x}

返回1true和0false。

在线尝试!

{             } /function(x)
       (!x)     /{0, 1, ..., x-1}
            '   /for each n in {0, 1, ..., x-1}:
           ! x  /    do (x mod n)
      ~         /for each, turn 0 -> 1, * -> 0 (map not)
     &          /get indices of 1's
   +/           /sum (fold add)
 x<             /check if x < the sum



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.