풍부한 정수!


40

과잉수는 적절한 약수의 합이 원래 수보다 큰 임의의 수이다. 예를 들어, 12의 제수는 다음과 같습니다.

1, 2, 3, 4, 6

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

풍부한 수 의 점근 밀도 는 간격 [0.24761748, 0.24764422] 내에 있습니다. 이 백서에 포함 된 소스 코드를 사용하여 계산했습니다 .
데드 코드

1
Geometry Dash 에서이 작업을 수행하려고합니다. 악몽이다
MilkyWay90

답변:


41

ECMAScript를 정규식 1,085 855 597 536 511 508 504 바이트

ECMAScript 정규식에서 풍부한 숫자를 일치시키는 것은 실제로 다른 정규식 맛에서 수행하는 것과 완전히 다릅니다. 순방향 / 중복 역 참조 또는 재귀가 없으면 총계를 직접 계산하거나 유지하는 것이 불가능합니다. 뒤돌아보기가 부족하여 작업하기에 충분한 공간을 확보해야하는 경우가 종종 있습니다.

완전히 다른 관점에서 많은 문제에 접근해야하며, 문제가 해결 가능한지 궁금 할 것입니다. 작업중 인 숫자의 수학적 속성을 사용하여 특정 문제를 해결할 수있게하는 데 더 넓은 그물을 캐스트해야합니다.

2014 년 3 월 -4 월에 ECMAScript 정규식에서이 문제에 대한 솔루션을 구성했습니다. 처음에는 문제가 완전히 불가능하다고 생각한 모든 이유가 있었지만 수학자 teukon 은 결국 해결할 수 있도록 격려하는 사례를 만들어 낸 아이디어를 스케치했습니다. 이전 정규식을 건설 / 골프하는 것에 대해 나와 경쟁하고 협력했지만이 시점까지 그의 한계에 도달했으며 이론에 대한 추가 기여를 제한하기 위해 만족했습니다).

며칠 전에 게시 된 정규식과 마찬가지로 경고 메시지를 표시합니다. ECMAScript 정규식에서 단항 수학 문제를 해결하는 방법을 배우는 것이 좋습니다. 그것은 나를위한 매혹적인 여정이었습니다. 저는 스스로 그것을 시도하고 싶을 수도있는 사람, 특히 수 이론에 관심이있는 사람들을 위해 그것을 망치고 싶지 않습니다. 스포일러 태그가 붙은 권장 문제를 하나씩 해결하는 데 대한 목록은 해당 게시물참조하십시오 .

그래서 당신은 어떤 깊은 단항 정규식 마법 당신을 위해 버릇하지 않을 경우 더 이상 읽지 않습니다 . 내 이전 게시물은 작은 맛이었습니다. 이 마법을 스스로 파악하는 데 총력을 기울이고 싶다면 위에 링크 된 게시물에 요약 된 ECMAScript 정규식의 일부 문제를 해결하는 것이 좋습니다.

내 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의 소수를 반복적으로 나눕니다. A에 해당하는 것이 1에 도달 할 때까지 그들의 기본에 의해; C에 해당하는 것은 B의 주요 역률과 비교된다. 동일한 소수의이 두 전력은 함께 더함으로써 단일 수로 "다중화"되었다; 이것은 위치 숫자 시스템이 작동하는 것과 같은 이유로 루프의 각 후속 반복에서 항상 명확하게 분리 할 수 ​​있습니다.

우리는 완전히 다른 알고리즘을 사용하여 50 바이트로 곱셈을 얻었습니다 (teukon과 나는 독립적으로 도착할 수 있었지만 몇 시간 만에 도착했지만 곧바로 갔지만 그 후에도 며칠이 걸렸습니다) 짧은 방법이 존재한다는 점에주의를 기울였습니다) : A≥B의 경우 C가 C≡0 mod A 및 C≡B mod A-1을 만족하는 가장 작은 숫자 인 경우에만 A * B = C입니다. (편리하게도 A = 1의 예외는 정규 표현식에서 특별한 처리가 필요하지 않습니다. 0 % 0 = 0이면 일치합니다.) 최소한의 정규식 맛. (그리고 A≥B의 요구 사항은 A와 B가 같은 힘의 주요 힘이라는 요구 사항으로 대체 될 수 있습니다. A≥B의 경우, 이것은 중국의 나머지 정리를 사용하여 증명할 수 있습니다.)

곱셈을위한 더 간단한 알고리즘이 없다는 것이 밝혀 졌다면 풍부한 수의 정규 표현식은 아마도 1 만 바이트 정도 일 것입니다 (내가 913 바이트 알고리즘을 651 바이트로 낮추었다는 것을 고려하더라도). ECMAScript 정규식에는 많은 곱셈과 나눗셈이 있으며 서브 루틴이 없습니다.

나는 2014 년 3 월 23 일에 다음과 같은 하위 문제로 보이는 것에 대한 솔루션을 구성함으로써 풍부한 수의 문제에 관해 작업하기 시작했습니다 : 가장 높은 다중성의 주요 요인을 식별하여 N에서 나눌 수 있음 처음에는 필요한 계산을 수행 할 공간을 남겨 둡니다. 당시 이것은 유망한 길로 보였습니다. (내 초기 솔루션은 326 바이트로 상당히 커졌고 나중에 185 바이트로 줄었습니다.) 그러나 스케치 된 나머지 방법은 매우 복잡했을 것입니다. N에서 가장 큰 주요 역률에 해당하는 N의 가장 큰 주요 역률을 나누는 것으로 충분합니다. 최고의 다중성을 위해 이것을하는 것은 정규식에 불필요한 복잡성과 길이를 추가했을 것입니다.

남은 것은 제수의 합을 직선의 합 대신에 합의 곱으로 취급하는 것입니다. 으로는 teukon에 의해 설명 2014 (14) 3 월 :

우리는 숫자 n = p 0 a 0 p 1 a 1 ... p k-1 a k-1을 부여 받습니다. 우리는 (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 ).

이것을보고 마음이 아 mind니다. 나는 그런 식으로 aliquot sum을 고려하지 않았으며, ECMAScript 정규식에서 풍부한 숫자 일치의 해결 가능성을 만드는 것은 다른 어떤 것 보다이 공식이었습니다.

결국 N을 초과하는 덧셈 또는 곱셈의 결과를 테스트하거나 M으로 미리 나눈 결과가 N / M을 초과하는지 테스트하는 대신 나눗셈 결과가 1보다 작 으면 테스트를 계속했습니다. 2014 년 4 월 7 일의 첫 번째 작업 버전.

이 정규식에 대한 골프 최적화의 전체 역사는 github에 있습니다. 특정 시점에서 하나의 최적화로 인해 정규식이 훨씬 느려졌으므로 그 시점부터 두 가지 버전을 유지했습니다. 그들은:

풍부한 숫자 를 일치시키는 정규식 .txt 풍부한 숫자 를 일치시키는 정규식 -shortest.txt

이러한 정규식은 ECMAScript 및 PCRE와 모두 완벽하게 호환되지만 최근에 참여하지 않을 가능성이있는 캡처 그룹을 사용하는 최근 최적화에 따라 \14PCRE 호환성을 삭제하고 변경 \14?하여 \141 바이트 씩 줄일 수 있습니다.

다음은 최적화가 적용된 (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

파이썬 2 , 41 40 바이트

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

출력은 종료 코드를 통해 이루어 지므로 0 은 정확하고 1 은 거짓입니다.

온라인으로 사용해보십시오!

작동 원리

n , kj 모두 를 STDIN의 입력으로 설정 한 후 while 루프에 들어갑니다 . 상기 루프는 -k-1 = ~ k ≥ 0 , 즉 k ≤ -1 / k <0이 되는 즉시 중단 될 것이다 .

각 반복에서 우리는 먼저 n을 적절한 제수 만 고려하도록 j 를 감소시킵니다 . 경우 j는 의 약수이고 , N은 , 수득 0J >> N %의 J = J * N / 2 0 = J가 감산 도착 케이 . 그러나, J는 않는다 하지 분할 N , 따라서 양의 최소한이다 N> 로그 2 JJ >> N %의 J = J * N / 2 N % J * N = 0 으로부터 감산 케이 .n%jn%jn%j*n

과잉수를 들어, K가 될 때 또는 그 이전에 음의 값에 도달 할 J가 된다 (1) 의 합이되기 때문에, N 의 약수가 적절한보다 확실히 크다 N . 이 경우 while 루프에서 벗어나 프로그램이 정상적으로 종료됩니다.

그러나 n 이 풍부 하지 않은 경우 j는 결국 0에 도달 합니다. 이 경우, n%j발생 ZeroDivisionError 과 오류와 함께 프로그램을 종료합니다.


4
~k<0멋지지만 -1<k트릭을 수행 한다고 생각 합니다.)
Martin Ender




10

매스 매 티카, 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
Mathematica가이를 위해 내장되어 있지 않은 것에 놀랐습니다.
MrPaulch

1
@MrPaulch 프로그램의 길이를 고려할 때 내장의 이름이 더 길어질 수 있습니다.>.>
Conor O'Brien

1
@ ConorO'Brien 존재하는 경우 아마 AbundantNumberQ, 그래서 몇 바이트를 절약 할 것입니다 :)
ngenisis


7

망막 , 50 45 바이트

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

에 입력 단항 , 출력 1풍부한 숫자, 0그렇지.

이 솔루션에 대한 Retina 고유의 ​​것은 없습니다. 위의 내용은 많은 숫자와 일치하는 순수한 .NET 정규식입니다.

온라인으로 사용해보십시오! (위의 정규식으로 소수 입력을 필터링하는 테스트 스위트)


6

망막 , 34 바이트

바이트 수는 ISO 8859-1 인코딩을 가정합니다.

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

^(1+)¶1\1

에 입력 단항 , 출력 1풍부한 숫자, 0그렇지.

온라인으로 사용해보십시오!

설명

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

입력의 모든 제수를 얻는 것으로 시작합니다. 이를 위해 정규 표현식의 !모든 겹치는 ( &) 일치하는 ( M)을 반환 합니다 (1+)$(?<=^\1+). 전체 입력이 해당 접미사의 배수 인 경우 정규식은 입력의 접미사와 일치합니다 (접미사 사본 만 사용하여 문자열의 시작 부분에 도달하도록 보장 함). 정규식 엔진이 일치하는 항목을 찾는 방식으로 인해 내림차순으로 줄 바꿈으로 구분 된 제수 목록이 표시됩니다.

1>`¶

스테이지 자체는 단순히 줄 바꿈 ( )과 일치 하고 제거합니다. 그러나이 1>제한은 첫 번째 일치를 건너 뜁니다. 따라서 입력 자체를 제외한 모든 제수를 효과적으로 더합니다. 첫 번째 줄의 입력과 두 번째 줄의 모든 적절한 제수의 합으로 끝납니다.

^(1+)¶1\1

마지막으로 1첫 번째 줄보다 두 번째 줄에서 하나 이상을 일치시킵니다 . 이 경우 적절한 제수의 합이 입력을 초과합니다. 망막이 될 것입니다이 정규식의 일치의 수 계산 1풍부한 번호에 대한 0그렇지 않으면.


1
망막에서 수학을 할 수있는 방법은 항상 놀랍습니다. 설명을보고 싶습니다! :)
DJMcMayhem

1
@DJMcMayhem 이전에 추가하는 것을 잊었습니다. 끝난.
Martin Ender 2012

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에서 다시 한 번 도움을줍니다.
  • CMP (-1 바이트) 대신 TEST를 사용하십시오. Thx에서 @ l4m2까지!

1
오버플로가 시작되기 전에 테스트 할 수있는 숫자 범위를 두 배로 대체 JLE하여 JBE잘못된 음수를 발생시키는 것이 좋습니다. 그런 다음 12600 (aliquot sum 35760)에서 실패하기 시작하지 않고 25200 (aliquot sum 74744)에서 실패하기 시작합니다. 캐리 플래그를 감지하고 실제> 16 비트 합을 계산할 필요없이이를 풍부한 수로 취급하는 것이 더 좋습니다.
데드 코드

1
@Deadcode를 잘 잡으십시오. 점프 점프 대신 아래 점프 코드를 업데이트했습니다. ADD BX 후 JC를 수행하면 CX가 서명되지 않은 오버플로를 포착하여 N = 65535까지 올바르게 할 것입니다. 이전에 CF가 false를 암시 했으므로 플래그 테스트를 복잡하게하고 상태를 약간 반환합니다. 수정 사항으로 업데이트되었습니다.
640KB

1
CF가 풍부하고 설정되지 않은 경우 CF를 설정하여 반환 값의 사양을 반전시켜 3 바이트를 절약 할 수 있습니다. 그러나 출력 문서를 먼저 수정하려면 편집을 수행하는 것이 좋습니다. 그래서 편집 기록에서 멋지게 보입니다.
Deadcode

1
또한 일을 단순하게 유지하려면 반환 값이 carry 플래그에 있고 다른 플래그와 관련된 소란이 없도록 스펙을 지정해야합니다. 발신자는 번호가 풍부한 지 여부에 따라 사용 JC하거나 JNC조치를 취해야합니다.
Deadcode

1
모든 도움과 의견에 감사드립니다. 인라인 설명서를 업데이트하고 ungolfed라는 용어를 제거했습니다. 솔직히 그다지 많은 생각을하지는 않았지만 인라인 주석을 제외하고는 다르지 않기 때문에 그것에 대한 귀하의 의견을 봅니다. 또한 반환 플래그를 명확하게 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

PARI / GP , 15 바이트

n->sigma(n)>2*n

n->sigma(n,-1)>2불행히도이 변종 은 더 길다.


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에 오신 것을 환영합니다!
케빈 Cruijssen

1
표준 카운트를 통한 올바른 카운트 n->java.util.stream.IntStream.range(1,n).filter(e->n%e<1).sum()>n는 65 바이트입니다 (패키지를 머리 위로
가져간

4

파워 쉘, 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 배보다 큰지 확인하여 2 바이트를 절약 할 수 있습니다.param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i
AdmBorkBork

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 원시성 테스트에 대한 적응 입니다. 제수를 세고 3보다 작은 지 확인하는 대신 적절한 제수를 합산합니다. 이것의 절반을 따라 진행되며 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

자바 스크립트 (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>


나는 재귀 대답이 가장 좋을 것이라고 확신했지만 이것이 좋은 것이라고 생각하지 않았습니다.
Neil

3

Japt , 9 7 6 바이트

<Uâ1 x

ETH 프로덕션 덕분에 2 바이트를 절약했습니다. obarakon 덕분에 1 바이트를 절약했습니다.

온라인으로 사용해보십시오!


9 자, 10 바이트
Metoniem

@Metoniem â적어도 유니 코드에서 (0xE2)는 1 바이트입니다.
Tom

1
@Metoniem JAPT는 사용 ISO-8859-1 인코딩 되는, â단일 바이트이다.
ETHproductions

경우 âtruthy 인수를 주어 당신이 할 수 있도록, 그것은, 나머지 목록에서 실제 번호를 제거합니다 â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;rUs를 맨 위로 회전시키고 d를 추가하고, s를 맨 아래로 회전하고 루프를 다시 결합합니다
;<.- 루프를 정리하고 다시 결합합니다.
종료 루프에서
;<-스택에서 d를 제거하고 경로 재 지정
-?-s에서 n을 제거하고 테스트하면 0 LOU@은 왼쪽으로 돌아가고 출력 및 종료, 음 0O@은 0을 푸시하고 출력 및 종료합니다. 양수는 ;O차이를 제거하고 출력 n. 그런 다음 경로는 왼쪽 방향으로 진행되어 @출구로 리디렉션됩니다.


3

퓨어 배쉬, 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

STDERR 로의 스트레이 출력을 피하면서 6 바이트를 절약 할 수 있습니다. 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배치의 유일한 산술 방법이므로 루프를 쉽게 조정할 수 없습니다.)


1
"(% 1 %%%% j)"oh, batch :)
Bryan Boettcher

2

펄 6, 72 24 바이트

{$_ <sum grep $_%%*,^$_}
  • 프로그램 인수 : a.
  • 에서 목록을 생성하십시오 1..a.
  • 의 제수 인 모든 수를 취하십시오 a.
  • 그들을 합치십시오.
  • 해당 합계가보다 큰지 확인하십시오 a.

@ b2gills에게 감사합니다.


$^a첫 번째 항목 이후의 모든 항목 을 그냥 단축 할 수 있습니다 $a. 그러나 {$_ <sum grep $_%%*,^$_}이전 버전을보고, [+](LIST)작동 함 (공백 없음)
Brad Gilbert b2gills

트윗 담아 가기 :)
Ven

2

J, 19 바이트

19 바이트로 잘라 준 Conor O'Brien에게 감사합니다!

<[:+/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.
코너 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

2

k , 19 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



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.