豊富な整数!


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

豊富な数の漸近密度は、区間内のどこかにあります[0.24761748、0.24764422]。このペーパーに含まれるソースコードを使用して計算されます。
デッドコード

1
これをGeometry Dashでやろうとしています。悪夢です
MilkyWay90

回答:


41

ECMAScriptの正規表現、1085の 855 597 536 511 508 504バイト

ECMAScript正規表現で豊富な数字を照合することは、実際に他の正規表現フレーバーで行うこととはまったく異なります。前方参照/ネストされた後方参照または再帰がないため、実行中の合計を直接カウントしたり保持したりすることはできません。後読みの欠如は、作業するのに十分なスペースを確保することさえしばしば困難になります。

多くの問題は完全に異なる視点からアプローチする必要があり、それらがまったく解決可能かどうか疑問に思うでしょう。特定の問題を解決可能にするために、使用している数値のどの数学プロパティを使用できるかを見つける際に、より広い範囲のネットをキャストする必要があります。

2014年3月から4月にかけて、ECMAScript正規表現でこの問題の解決策を構築しました。最初は、問題が完全に不可能であると疑うあらゆる理由がありましたが、数学者のチューコンは、結局それを解決可能に見せるための有望なケースを作るアイデアをスケッチしました-しかし、彼は正規表現を構築する意図がないことを明らかにしました(彼は以前の正規表現の構築/ゴルフで私と競合/協力していましたが、この時点で限界に達し、理論化へのさらなる貢献を制限することに満足していました)。

数日前に投稿した正規表現と同様に、警告を表示します。ECMAScript正規表現の単項数学問題を解決する方法を学ぶことを強くお勧めします。それは私にとって魅力的な旅であり、自分で試してみたいと思う人、特に数論に興味のある人のためにそれを台無しにしたくありません。連続してスポイラーでタグ付けされた推奨される問題のリストについては、その投稿参照して1つずつ解決してください。

だから、あなたには、いくつかの深い単項正規表現の魔法があなたのために台無しにしたくない場合はそれ以上を読んでいません。前回の投稿はちょっとした趣味でした。この魔法を自分で理解するためにショットを撮りたい場合は、上記のリンクに記載されている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$)))+$

(PCRE、.NET、およびECMAScriptではない他のすべての正規表現フレーバーとの互換性のために変更\14\14?ます)

オンラインでお試しください!
オンラインでお試しください!(正規表現の537バイトバージョンの高速化)

そして今、その背後にある物語の簡単な要約。

少なくとも私には、一般的な場合に素数を一致させることさえ可能であったことは、最初は非常に明白ではありませんでした。そして、それを解決した後、2の累乗にも同じことが適用され、次に合成数の累乗に適用されます。そして、完全な正方形。そして、それを解決した後でも、一般化された乗算を行うことは最初は不可能に思えました。

ECMAScriptループでは、1つの変化する数値のみを追跡できます。その数は入力を超えることはできず、すべてのステップで減少する必要があります。正しい乗算ステートメントA * B = Cを一致させるための最初の正規表現は913バイトで、A、B、およびCを素数に因数分解することで機能しました。 Aに対応するものが1に達するまで、それらのプライムベースによって。次に、Cに対応するものがBの素数の力率と比較されます。同じ素数のこれらの2つのべき数は、それらを加算することによって単一の数に「多重化」されました。これは、位置の数字システムが機能するのと同じ理由で、ループの後続の各反復で常に明確に分離できます。

完全に異なるアルゴリズムを使用して乗算を50バイトまで減らしました(これは、数時間しかかからず、彼はまっすぐに行きましたが、チューコンと私は独立して到達することができましたが、短い方法が存在することに気付いた):A≥Bの場合、A * B = Cがあれば、CがC≡0mod AおよびC≡Bmod A-1を満たす最小数である場合のみ (便利なことに、A = 1の例外は正規表現で特別な処理を必要としません。0%0 = 0は一致を生成します。)このような洗練された乗算方法がそのような最小限の正規表現の味。(A≥Bの要件は、AとBが同じべきの主要なべき乗であるという要件に置き換えることができます。A≥Bの場合、これは中国の剰余定理を使用して証明できます。)

単純な乗算アルゴリズムが存在しないことが判明した場合、豊富な数の正規表現はおそらく1万バイト程度になります(私が913バイトのアルゴリズムを651バイトまでゴルフしたことを考慮しても)。多くの乗算と除算を行い、ECMAScript正規表現にはサブルーチンがありません。

私は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が与えられます。(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正規表現の豊富な数値マッチングの可解性をもっともらしいものにしたのはこの式でした。

最終的に、Nを超える加算または乗算の結果をテストする代わりに、またはMで事前に分割された結果がN / Mを超えることをテストする代わりに、除算の結果が1未満であるかどうかをテストしました。 2014年4月7日に最初の作業バージョン。

この正規表現の私のゴルフ最適化の完全な歴史はgithubにあります。ある時点で、1つの最適化により正規表現が大幅に遅くなるため、その時点から2つのバージョンを維持しました。彼らです:

豊富な数字を照合するための正規表現豊富な数字を照合するための正規表現-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

パイソン241の 40バイト

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

出力は終了コードを介して行われるため、0は真実で1は偽です。

オンラインでお試しください!

使い方

nk、およびjのすべてをSTDINからの入力に設定した後、whileループに入ります。このループは、-k-1 =〜k≥0、つまりk≤-1 / k <0になるとすぐに中断します

各反復では、最初にjをデクリメントして、nの適切な除数のみを考慮します。場合jはの約数であるNn%j収量0およびJ * >> N%のJ N = J / 2 0 = jがから差し引かれますK。ただし、jnを除算しない場合n%j正であるためn%j*n、少なくともn> log 2 jであり、j >> n%j * n = j / 2 n%j * n = 0kから減算されます。

豊富な数値の場合、nの適切な除数の合計は厳密にnより大きいため、kj1になる前またはそのときに負の値になります。この場合、whileループから抜け出し、プログラムは正常に終了します。

ただし、nが豊富でない場合、jは最終的に0になります。この場合、ZeroDivisionErrorがn%jスローされ、プログラムはエラーで終了します。


4
~k<0空想ですが、私-1<kもトリックを行うと思います;)
マーティンエンダー




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
私は.. Mathematicaが何のためにこの中に組み込まれています驚いていないよ
MrPaulch

1
@MrPaulchしかし、プログラムの長さを考慮すると、組み込みの名前は非常に長くなる可能性があります。>
コナーオブライエン

1
@ ConorO'Brien存在した場合、おそらくになるAbundantNumberQので、数バイト節約できます:)
ngenisis


7

網膜50 45バイト

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

入力単項、出力1過剰数のため、0それ以外の場合は。

このソリューションについては、Retina固有のものはありません。上記は、豊富な数字のみに一致する純粋な.NET正規表現です。

オンラインでお試しください!(上記の正規表現で10進数の入力をフィルタリングするテストスイート。)


6

網膜、34バイト

バイトカウントはISO 8859-1エンコードを前提としています。

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

^(1+)¶1\1

入力単項、出力1過剰数のため、0それ以外の場合は。

オンラインでお試しください!

説明

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

入力のすべての約数を取得することから始めます。これを行うには、正規表現の!すべての重複&)一致(M)を返します()(1+)$(?<=^\1+)。入力全体がそのサフィックスの倍数であるという条件で、正規表現は入力のサフィックスに一致します(サフィックスのコピーのみを使用して文字列の先頭に到達しようとすることで確認します)。正規表現エンジンが一致を検索する方法により、降順の除数のリストが作成されます(改行で区切られます)。

1>`¶

ステージ自体は、単に改行()に一致し、それらを削除します。ただし、これ1>は制限であり、最初の一致をスキップします。したがって、これにより、入力自体を除くすべての除数が効果的に加算されます。最初の行に入力があり、2行目にすべての適切な除数の合計があります。

^(1+)¶1\1

最後1に、最初の行よりも2番目の行で少なくとも1つ以上の一致を試みます。その場合は、適切な除数の合計が入力を超えています。Retinaは、この正規表現の一致の数をカウントします。これは1、豊富な数などに使用され0ます。


1
網膜で数学ができる方法はいつも驚かされます。説明が見たいです!:)
DJMcMayhem

1
@DJMcMayhem早くそれを追加するのを忘れてしまいました。できた
マーティンエンダー

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の代わりにTESTを使用します(-1バイト)。@ l4m2へのThx!

1
私は交換することをお勧めJLEしてJBEオーバーフローが、それは偽陰性を与えることを引き起こして開始する前に、番号の範囲にこの缶テストを倍増します。次に、12600(アリコートの合計35760)で失敗し始める代わりに、25200(アリコートの合計74744)で失敗し始めます。さらに良いのは、キャリーフラグを検出し、16ビット以上の実際の合計を計算する必要なく、それを豊富な数として扱うことです。
デッドコード

1
@Deadcodeをキャッチします。ジャンプレスではなく、以下のジャンプ用にコードを更新しました。ADD BX、CXの後にJCを実行すると、そこで符号なしのオーバーフローをキャッチし、N = 65535まで修正します。以前はCFがfalseを暗示していたため、フラグのテストを複雑にし、状態を少し返します。修正も加えて更新。
640KB

1
戻り値の指定を反転することで3バイトを節約できます。CFが豊富な場合は設定され、豊富でない場合はクリアされます。しかし、最初に出力ドキュメントを修正するために編集を行うことをお勧めします。これにより、編集履歴で見栄えが良くなります。
デッドコード

1
また、物事を単純にするために、戻り値がキャリーフラグ内にあり、他のフラグと大騒ぎしないように指定する必要があります。発信者は、番号が豊富であるかどうかに基づいて、JCまたはJNCを使用する必要があります。
デッドコード

1
あなたの助けとコメントのすべてに感謝します。インラインドキュメントを更新し、ungolfedという用語を削除しました。正直言ってあまり考えたことはありませんが、インラインコメントを除いて違いはないので、それについてあなたの意見を見ることができます。また、リターンフラグを明確にすることについても同意します。その上で少し動作します。注意と支援をありがとう!
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倍の入力よりも大きいということチェックすることにより、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

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 â少なくともユニコード(0xE2)で1バイトであると確信しています。
トム

1
@Metoniem Japt は、シングルバイトであるISO-8859-1エンコーディングを使用しâます。
ETHproductions

â真実の引数が与えられた場合、残りのリストから実際の番号が削除されるのでâ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を削除してテスト、0 LOU@が左に曲がり、出力と終了、マイナスが0O@0をプッシュ、出力と終了。正;Oは差を取り除き、nを出力します。その後、パスは左折して@出口にリダイレクトします


3

Pure 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

STDERRへの浮遊出力を回避しながら、6バイトを節約できます。tio.run/nexus/bash#S04sUbBTSEwqzUtJzCtRsLFRUHf1d1P/...
デニス

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/aBatchが算術を行う唯一の方法なので、ループを簡単に調整することはできません。)


1
「(%1 %%%% j)」、バッチ:)
ブライアンベッチャー

2

Perl 6の、72の 24バイト

{$_ <sum grep $_%%*,^$_}
  • プログラム引数:a。
  • からリストを生成します1..a
  • の約数であるすべての数値を取りますa
  • それらを合計します。
  • その合計がより大きいかどうかを確認しaます。

@ b2gillsに感謝します。


$^a最初の後に出現するものはすべて、に短縮できます$a。あなたのようにそれを書く場合でも、短いです{$_ <sum grep $_%%*,^$_}。また、以前のバージョン、見て[+](LIST)作品(スペースなし)
ブラッド・ギルバートがb2gills

@ BradGilbertb2gillsありがとう!:)
ベン

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.
コナー・オブライエン

アドバイスをありがとう!ただし、cap動詞([:)とswitch動詞(〜)について説明してください。私は彼らがこの暗黙の動詞で何をすべきか本当に理解していません。
ブロック

〜が切り替わり、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です。
コナーオブライエン

フォークチェーンで#~は、右側の動詞が実行された後に評価されるため、左側の引数が右側の結果になります
コナーオブライエン

2

Pyth、11バイト

>sPf!%QTS

古い:

L!%Qb>sPy#S

!%pfnとして使用することはできません#。2つの関数だからです。私を悲しくさせる :(。


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

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



弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.