Eine Fülle von ganzen Zahlen!

40

Eine Zahl im Überfluss ist eine Zahl, bei der die Summe der richtigen Teiler größer ist als die ursprüngliche Zahl. Zum Beispiel sind die richtigen Teiler von 12:

1, 2, 3, 4, 6

Und diese Ergebnisse in 16 summieren. Da 16 größer als 12 ist, ist 12 reichlich vorhanden. Beachten Sie, dass dies nicht nicht enthalten „Perfect Zahlen“, zB Zahlen, die gleich der Summe ihrer echten Teiler, wie 6 und 28.

Ihre Aufgabe für heute ist es, ein Programm oder eine Funktion zu schreiben, die bestimmen, ob eine Zahl häufig vorkommt oder nicht. Ihr Programm sollte eine einzelne Ganzzahl als Eingabe verwenden und einen Wahrheits- / Falschwert ausgeben , je nachdem, ob er reichlich vorhanden ist oder nicht. Sie können davon ausgehen, dass die Eingabe immer gültig und größer als 0 ist. Bei schlechten Eingaben ist undefiniertes Verhalten also in Ordnung.

Sie können Ihre Eingabe und Ausgabe in jedem vernünftigen Format vornehmen, beispielsweise STDIN / STDOUT, Dateien oder Argumente / Rückgabewerte.

Als Referenz sind hier die zahlreichen Zahlen bis zu 100:

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

Weitere Informationen finden Sie unter A005101

Da es sich um , werden Standard-Schlupflöcher verweigert. Versuchen Sie, den kürzestmöglichen Code in der von Ihnen gewählten Sprache zu schreiben!

DJMcMayhem
quelle
11
"Die erste ungerade Menge ist 945 = 3 ^ 3 * 5 * 7, die 232. Menge!"
mbomb007
Die asymptotische Dichte zahlreicher Zahlen liegt irgendwo innerhalb des Intervalls [0,24761748, 0,24764422]. Berechnet mit dem in diesem Dokument enthaltenen Quellcode .
Deadcode
1
Ich versuche dies in Geometry Dash zu tun. Es ist ein Albtraum
MilkyWay90

Antworten:

41

ECMAScript Regex, 1085 855 597 536 511 508 504 Bytes

Übereinstimmungen mit zahlreichen Zahlen in ECMAScript Regex sind eine völlig andere Sache als in praktisch jeder anderen Regex-Variante. Das Fehlen von vorwärts / verschachtelten Rückverweisen oder Rekursionen bedeutet, dass es unmöglich ist, eine laufende Summe von irgendetwas direkt zu zählen oder aufrechtzuerhalten. Das Fehlen von Lookbehind macht es oft sogar zu einer Herausforderung, genügend Platz zum Arbeiten zu haben.

Viele Probleme müssen aus einer ganz anderen Perspektive angegangen werden, und Sie werden sich fragen, ob sie überhaupt lösbar sind. Es zwingt Sie, ein viel breiteres Netz zu ziehen, um herauszufinden, welche mathematischen Eigenschaften der Zahlen, mit denen Sie arbeiten, verwendet werden können, um ein bestimmtes Problem lösbar zu machen.

Bereits im März-April 2014 habe ich eine Lösung für dieses Problem in ECMAScript regex erstellt. Zuerst hatte ich allen Grund zu der Annahme , dass das Problem völlig unmöglich war, aber dann entwarf der Mathematiker Teukon eine Idee, die es ermutigend erscheinen ließ, es doch lösbar zu machen - aber er machte klar, dass er nicht die Absicht hatte, den Regex zu konstruieren (er) hatte mit mir am Konstruieren / Golfen früherer Regexe teilgenommen / kooperiert, stieß aber zu diesem Zeitpunkt an seine Grenzen und war damit zufrieden, seine weiteren Beiträge zum Theoretisieren einzuschränken.

Wie bei meinem regulären Ausdruck, der vor ein paar Tagen veröffentlicht wurde, gebe ich eine Warnung: Ich empfehle dringend, zu lernen, wie man unäre mathematische Probleme in regulärem ECMAScript löst. Es war eine faszinierende Reise für mich, und ich möchte sie keinem verderben, der sie möglicherweise selbst ausprobieren möchte, insbesondere denen, die sich für Zahlentheorie interessieren. In diesem Beitrag finden Sie eine Liste der nacheinander mit Spoiler-Tags gekennzeichneten empfohlenen Probleme, die Sie nacheinander lösen können.

So lesen keine weiteren , wenn Sie nicht einige tiefe einstellige regex Magie für Sie verwöhnen wollen . Mein vorheriger Beitrag war nur ein kleiner Vorgeschmack. Wenn Sie versuchen möchten, diese Magie selbst herauszufinden, empfehle ich dringend, zunächst einige Probleme in ECMAScript regex zu lösen, wie in dem oben verlinkten Beitrag beschrieben.

Vor der Veröffentlichung meiner ECMAScript regex, dachte ich , es wäre interessant , Martin Enders zu analysieren .NET reine Regex Lösung , ^(?!(1(?<=(?=(?(\3+$)((?>\2?)\3)))^(1+)))*1$). Es stellt sich als sehr einfach heraus, diesen regulären Ausdruck zu verstehen, und er ist elegant in seiner Einfachheit. Um den Kontrast zwischen unseren Lösungen zu demonstrieren, finden Sie hier eine kommentierte und hübsch gedruckte (aber nicht modifizierte) Version seines regulären Ausdrucks:

# 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.
)

Probieren Sie den .NET regulären Ausdruck online aus

Nun zurück zu meinem ECMAScript-regulären Ausdruck. Erstens ist es hier in rohem, Leerzeichen und Kommentaren freiem Format:

^(?=(((?=(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$)))+$

( \14Zur \14?Kompatibilität mit PCRE, .NET und praktisch jeder anderen Regex-Variante, die nicht ECMAScript ist, wechseln Sie zu. )

Probieren Sie es online!
Probieren Sie es online! (schneller, 537-Byte-Version des regulären Ausdrucks)

Und jetzt eine kurze Zusammenfassung der Geschichte dahinter.

Zunächst war mir zumindest nicht klar, dass es überhaupt möglich war, Primzahlen zuzuordnen. Und nachdem Sie das gelöst haben, galt dasselbe für Potenzen von 2. Und dann für Potenzen von zusammengesetzten Zahlen. Und dann perfekte Quadrate. Und selbst nach dieser Lösung schien es zunächst unmöglich, eine verallgemeinerte Multiplikation durchzuführen.

In einer ECMAScript-Schleife können Sie nur eine sich ändernde Nummer verfolgen. Diese Zahl darf die Eingabe nicht überschreiten und muss bei jedem Schritt verringert werden. Meine erste Regex für den Abgleich der korrekten Multiplikationsaussagen A * B = C war 913 Bytes. Dabei wurden A, B und C in ihre Primzahlen zerlegt. Teilen Sie für jeden Primfaktor das Primzahlfaktorpaar von A und C wiederholt auf durch ihre Primzahlbasis, bis diejenige, die A entspricht, 1 erreicht; Diejenige, die C entspricht, wird dann mit dem Primzahlfaktor von B verglichen. Diese beiden Potenzen derselben Primzahl wurden durch Addition zu einer einzigen Zahl "gemultiplext". Dies wäre bei jeder nachfolgenden Iteration der Schleife immer eindeutig trennbar, aus dem gleichen Grund, aus dem Positionszahlensysteme funktionieren.

Wir haben die Multiplikation mit einem völlig anderen Algorithmus auf 50 Bytes herabgesetzt (zu dem Teukon und ich unabhängig voneinander gelangen konnten, obwohl er nur ein paar Stunden brauchte und direkt dorthin ging, während ich selbst danach ein paar Tage brauchte habe ich darauf hingewiesen, dass es eine kurze Methode gibt): für A≥B ist A * B = C, wenn überhaupt, nur wenn C die kleinste Zahl ist, die C≡0 mod A und C≡B mod A-1 erfüllt. (Praktischerweise erfordert die Ausnahme von A = 1 keine spezielle Behandlung in regulären Ausdrücken, wobei 0% 0 = 0 eine Übereinstimmung ergibt.) Ich kann einfach nicht darüber hinwegsehen, wie ordentlich es ist, dass eine so elegante Art der Multiplikation in einer solchen existiert Minimaler Regex-Geschmack. (Und die Anforderung von A≥B kann durch die Anforderung ersetzt werden, dass A und B Primzahlen derselben Leistung sind. Für den Fall von A≥B kann dies unter Verwendung des chinesischen Restsatzes bewiesen werden.)

Wenn sich herausgestellt hätte, dass es keinen einfacheren Algorithmus für die Multiplikation gibt, wäre der Regex für die häufig vorkommende Zahl wahrscheinlich in der Größenordnung von zehntausend Bytes (selbst wenn man bedenkt, dass ich den 913-Byte-Algorithmus auf 651 Bytes reduziert habe). Es werden viele Multiplikationen und Divisionen ausgeführt, und ECMAScript regex verfügt über keine Subroutinen.

Seit dem 23. März 2014 beschäftige ich mich tangential mit dem Problem der Häufigkeiten, indem ich eine Lösung für ein Teilproblem entwerfe, das zu diesem Zeitpunkt zu sein schien: Den Primfaktor der höchsten Multiplizität zu identifizieren, so dass er aus N geteilt werden kann Am Anfang bleibt noch Platz für die nötigen Berechnungen. Zu dieser Zeit schien dies ein vielversprechender Weg zu sein. (Meine anfängliche Lösung war mit 326 Bytes ziemlich umfangreich und wurde später auf 185 Bytes verkleinert.) Der Rest der skizzierten Methode wäre jedoch äußerst kompliziert gewesen, so dass ich, wie sich herausstellte, einen anderen Weg eingeschlagen habe. Es hat sich als ausreichend erwiesen, den größten Primfaktor von N entsprechend dem größten Primfaktor auf N aufzuteilen; Dies für die höchste Multiplizität zu tun, hätte der Regex unnötige Komplexität und Länge verliehen.

Was blieb, war, die Summe der Teiler als Produkt von Summen anstelle einer geraden Summe zu behandeln. Wie erklärt teukon am 14. März 2014

Wir bekommen eine Zahl n = p 0 a 0 p 1 a 1 ... p k-1 a k-1 . Wir wollen die Summe der Faktoren von n behandeln, die (1 + p 0 + p 0 2 + ... + p 0 a 0 ) (1 + p 1 + p 1 2 + ... + p 1 a ist 1 ) ... (1 + p k-1 + p k-1 2 + ... + p k-1 a k-1 ).

Es hat mich umgehauen, das zu sehen. Ich hatte noch nie daran gedacht, die Aliquotsumme auf diese Weise zu berücksichtigen, und es war vor allem diese Formel, die die Lösbarkeit von Übereinstimmungen mit zahlreichen Zahlen in ECMAScript-Regex plausibel erscheinen ließ.

Anstatt zu testen, ob das Ergebnis einer Addition oder Multiplikation größer als N ist, oder zu testen, ob ein solches durch M vorgeteiltes Ergebnis größer als N / M ist, habe ich getestet, ob das Ergebnis einer Division kleiner als 1 ist die erste Arbeitsversion am 7. April 2014.

Die vollständige Geschichte meiner Golfoptimierungen dieses Regex ist auf Github. Ab einem bestimmten Punkt führte eine Optimierung dazu, dass der reguläre Ausdruck viel langsamer wurde. Ab diesem Zeitpunkt behielt ich zwei Versionen bei. Sie sind:

Regex für den Abgleich von vielen Zahlen.txt
Regex für den Abgleich von vielen Zahlen - Shortest.txt

Diese regulären Ausdrücke sind voll kompatibel mit ECMAScript und PCRE, aber eine aktuelle Optimierung beteiligte eine potenziell nicht-teilnehmende Capture - Gruppe mit \14, so durch PCRE Kompatibilität fallen und Wechsel \14?auf \14sie beide um 1 Byte reduziert werden.

Hier ist die kleinste Version mit dieser Optimierung (nur ECMAScript), die so umformatiert wurde, dass sie in einen StackExchange-Codeblock passt, für den (meistens) kein horizontales Scrollen erforderlich ist:

# 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$)
  )
)+$
Deadcode
quelle
Kommentare sind nicht für längere Diskussionen gedacht. Diese Unterhaltung wurde in den Chat verschoben .
DJMcMayhem
1
-98 bytes
Grimmy
27

Python 2 , 41 40 Bytes

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

Die Ausgabe erfolgt über den Exit-Code , daher ist 0 wahr und 1 falsch.

Probieren Sie es online!

Wie es funktioniert

Nachdem wir alle von n , k und j auf den Eingang von STDIN gesetzt haben, treten wir in die while- Schleife ein. Diese Schleife wird unterbrochen, sobald -k - 1 = ~ k ≥ 0 ist , dh k ≤ -1 / k <0 .

In jeder Iteration dekrementieren wir zuerst j , um nur die richtigen Teiler von n zu betrachten . Wenn j ein Teiler von n ist , n%jergibt sich 0 und j >> n% j * n = j / 2 0 = j wird von k subtrahiert . Wenn j jedoch n nicht teilt , ist dies positiv, und es wird mindestens n> log 2 j und j >> n% j * n = j / 2 n% j * n = 0 von k subtrahiert .n%jn%j*n

Für reichlich Zahlen k einen negativen Wert erreicht , bevor oder wenn j wird 1 , da die Summe von n ‚s richtigen Divisoren strikt größer ist , als n . In diesem Fall brechen wir die while- Schleife ab und das Programm wird normal beendet.

Wenn jedoch n ist nicht reichlich vorhanden, j erreicht schließlich 0 . In diesem Fall wird n%jein ZeroDivisionError ausgelöst und das Programm mit einem Fehler beendet.

Dennis
quelle
4
~k<0ist schick, aber ich denke, -1<kmacht auch den Trick;)
Martin Ender
10

Gelee , 3 Bytes

Æṣ>

Probieren Sie es online!

Wie es funktioniert

Æṣ>  Main link. Argument: n

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

Python , 44 Bytes

lambda n:sum(i*(n%i<1)for i in range(1,n))>n

Probieren Sie es online!

Jonathan Allan
quelle
Es ist eine Schande, die Sie nicht tun können range(n). Das lästige Modul von Null
DJMcMayhem
10

Mathematica, 17 Bytes

Tr@Divisors@#>2#&

Erläuterung

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.
Genisis
quelle
1
Ich bin überrascht, dass Mathematica
diesbezüglich
1
@ MrPaulch In Anbetracht der Länge des Programms ist der eingebaute Name möglicherweise länger>.>
Conor O'Brien
1
@ ConorO'Brien Wenn es existieren würde, wäre es wahrscheinlich AbundantNumberQ, so würde es ein paar Bytes sparen :)
Genisis
7

Retina , 50 45 Bytes

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

Eingabe in Unary , Ausgabe 1für viele Zahlen, 0sonst.

An dieser Lösung ist nichts Retina-spezifisches. Das obige ist ein reiner .NET-regulärer Ausdruck, der nur mit zahlreichen Zahlen übereinstimmt.

Probieren Sie es online! (Testsuite, die Dezimaleingaben mit dem obigen regulären Ausdruck filtert.)

Martin Ender
quelle
6

Retina , 34 Bytes

Die Anzahl der Bytes setzt die Kodierung nach ISO 8859-1 voraus.

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

^(1+)¶1\1

Eingabe in unary , Ausgabe1für viele Zahlen, 0sonst.

Probieren Sie es online!

Erläuterung

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

Wir beginnen damit, alle Teiler der Eingabe zu erhalten. Dazu geben wir ( !) alle überlappenden ( &) Übereinstimmungen ( M) des regulären Ausdrucks zurück (1+)$(?<=^\1+). Der reguläre Ausdruck stimmt mit einem Suffix der Eingabe überein, vorausgesetzt, die gesamte Eingabe ist ein Vielfaches dieses Suffixes (was wir sicherstellen, indem wir versuchen, den Anfang der Zeichenfolge nur mit Kopien des Suffixes zu erreichen). Aufgrund der Art und Weise, wie die Regex-Engine Übereinstimmungen sucht, wird eine Liste von Teilern in absteigender Reihenfolge (durch Zeilenvorschübe getrennt) erstellt.

1>`¶

Die Bühne selbst vergleicht einfach die Zeilenvorschübe ( ) und entfernt sie. Dies 1>ist jedoch ein Limit, bei dem das erste Match übersprungen wird. Auf diese Weise werden alle Teiler mit Ausnahme der Eingabe selbst addiert. Wir erhalten die Eingabe in der ersten Zeile und die Summe aller korrekten Teiler in der zweiten Zeile.

^(1+)¶1\1

Schließlich versuchen wir, die mindestens eine 1Zeile mehr in der zweiten Zeile als in der ersten Zeile abzugleichen. In diesem Fall übersteigt die Summe der korrekten Teiler die Eingabe. Retina zählt die Anzahl der Übereinstimmungen mit diesem regulären Ausdruck, die 1für eine Vielzahl von Zahlen und 0ansonsten gelten.

Martin Ender
quelle
1
Es hat mich immer wieder erstaunt, wie man auf der Netzhaut rechnen kann. Ich würde gerne eine Erklärung sehen! :)
DJMcMayhem
1
@DJMcMayhem Sorry, habe vergessen, das früher hinzuzufügen. Getan.
Martin Ender
6

8086 Versammlung, 23 28 25 24 Bytes

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

Zerlegt:

; 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

Beispiel Testprogramm, Test 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

Ausgabe [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

Ausgabe [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

Ausgabe [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

Aktualisierung:

  • Behoben für 16-Bit-Überlauf (+5 Bytes). Danke @deadcode für die Vorschläge!
  • Vereinfachte Rückkehrlogik (-3 Bytes). Danke nochmal an @deadcode.
  • Verwenden Sie TEST anstelle von CMP (-1 Byte). Danke an @ l4m2!
640 KB
quelle
1
Ich würde vorschlagen, JLEdurch JBEzu ersetzen , um den Bereich der Zahlen zu verdoppeln, die getestet werden können, bevor Überläufe auftreten, die zu falschen Negativen führen. Anstatt bei 12600 (Aliquotsumme 35760) zu scheitern, beginnt der Fehler bei 25200 (Aliquotsumme 74744). Noch besser wäre es, auch das Übertragsflag zu erkennen und dieses als eine häufig vorkommende Zahl zu behandeln, ohne die tatsächliche> 16-Bit-Summe berechnen zu müssen.
Deadcode
1
Guter Fang @Deadcode. Ich habe den Code für den Sprung unten aktualisiert, anstatt weniger zu springen. Ich verstehe, was Sie meinen, wenn CX nach dem ADD BX eine JC durchführt, fängt er dort den vorzeichenlosen Überlauf ab und korrigiert ihn bis N = 65535. Erschwert das Testen von Flags und den Rückgabestatus ein wenig, da CF zuvor false implizierte. Mit Update auch aktualisiert.
640KB
1
Sie können 3 Bytes einsparen, indem Sie die Angabe Ihres Rückgabewerts invertieren. Ist dies nicht der Fall, wird CF gesetzt, andernfalls wird CF gelöscht. Ich würde jedoch empfehlen, die Bearbeitung durchzuführen, um zuerst die Ausgabedokumentation zu korrigieren, damit sie im Bearbeitungsverlauf gut aussieht.
Deadcode
1
Um die Dinge einfach zu halten, sollte angegeben werden, dass sich der Rückgabewert im Übertragsflag befindet und dass nichts mit den anderen Flags zu tun hat. Der Anrufer sollte JCoder verwenden, um JNCzu bestimmen, ob die Nummer reichlich vorhanden ist oder nicht.
Deadcode
1
Vielen Dank für all Ihre Hilfe und Ihre Kommentare. Ich habe die Inline-Dokumentation aktualisiert und den Begriff ungolfed entfernt. Ehrlich gesagt, habe ich nie viel darüber nachgedacht, aber ich verstehe Ihren Standpunkt dazu, da es mit Ausnahme von Inline-Kommentaren nicht anders ist. Vereinbaren Sie auch, dass die Rückgabe-Flags deutlicher werden. Werde gleich dran arbeiten. Danke für die Aufmerksamkeit und die Hilfe!
25.
5

05AB1E , 4 Bytes

ѨO‹

Probieren Sie es online!

Wie es funktioniert

Ñ        #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? 

Es tut mir leid, in der alten Frage etwas zu schreiben. Ich habe gerade alte Beiträge zur Übung durchgesehen und festgestellt, dass meine Lösung kürzer war als die nächstbeste 05AB1E-Lösung.

Weltraumschrott
quelle
4
Sorry to post in old questionMach dir keine Sorgen! Ich bin immer glücklich , Antworten auf meinen alten Herausforderungen zu sehen, und es ist tatsächlich hier gefördert . :)
DJMcMayhem
4

PARI / GP , 15 Bytes

n->sigma(n)>2*n

Die Variante n->sigma(n,-1)>2ist leider länger.

Charles
quelle
4

Java 8, 53 Bytes (viel mehr, wenn Sie den zeremoniellen Code enthalten)

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

Probieren Sie es online aus

Erklärung:

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
Gautam D
quelle
4
Gute Antwort, aber mit Java 8 müssen Sie die Funktion in Ihre Byteanzahl aufnehmen. Andererseits können Sie die fallen lassen, returnwenn ich mich nicht irre, so wird es noch kürzer: n->IntStream.range(1,n).filter(e->n%e<1).sum()>n(nicht 100%, wenn dies korrekt ist, programmiere ich fast nie in Java 8). Willkommen bei PPCG!
Kevin Cruijssen
1
Die korrekte Anzahl über die Standardanzahl wäre n->java.util.stream.IntStream.range(1,n).filter(e->n%e<1).sum()>nfür 65 Bytes (vorausgesetzt, ich habe das Paket direkt über den Kopf bekommen)
CAD97
4

Powershell, 51 49 Bytes

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

Ich wünschte, ich könnte ein paar Klammern entfernen.

-2 Dank AdmBorkBork wird die Eingabe nicht im Anfangsbereich gezählt, sondern nur bei der endgültigen Überprüfung berücksichtigt.

Durchlaufen Sie den Bereich von 1..bis zum $input minus 1 und finden Sie heraus, wo ( ?) das inverse Modulo der Eingabe durch die aktuelle Zahl ist $true(auch bekannt als nur 0). Dann werden -joinalle diese Zahlen zusammen mit +und iexder resultierenden Zeichenfolge berechnet Die Summe dieser Teile ist größer als die Eingabe.

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
colsw
quelle
Sie können zwei Bytes sparen, indem Sie den Höchstwert zählen und überprüfen, ob er größer als das param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i
Zweifache
3

MATL, 6 Bytes

Z\sGE>

Gibt 1 für viele Zahlen aus, sonst 0.

Wie es funktioniert

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

QBIC , 22 Bytes

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

Dies ist eine Anpassung an den QBIC-Primalitätstest . Anstatt die Divisoren zu zählen und zu überprüfen, ob sie kleiner als drei sind, werden die richtigen Divisoren summiert. Dies läuft nur entlang der Hälfte von 1 to n, wobei der Primalitätstest 1 to nvollständig durchläuft .

Erläuterung:

:       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.
steenbergh
quelle
3

JavaScript (ES6), 33 Byte

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>

ETHproductions
quelle
Ich war mir sicher, dass eine rekursive Antwort am besten wäre, aber ich dachte nicht, dass es so gut wäre.
Neil
3

Japt , 9 7 6 Bytes

<Uâ1 x

2 Bytes gespart dank ETHproductions. 1 Byte dank obarakon gespeichert.

Probieren Sie es online!

Tom
quelle
9 Zeichen, 10 Bytes.
Metoniem
@Metoniem Ich bin sicher, â1 Byte, mindestens in Unicode (0xE2).
Tom
1
@Metoniem Japt verwendet die ISO-8859-1-Codierung , bei der âes sich um ein einzelnes Byte handelt.
ETHproductions
Wenn âein wahrheitsgemäßes Argument angegeben wird, wird die aktuelle Nummer aus der verbleibenden Liste entfernt, sodass Sie â1 x >Uein paar Bytes sparen können :-)
ETHproductions
@ TomDevs Schön! Sie können <Uâ1 xein Byte speichern. Japt fügt das Uvor dem Programm hinzu.
Oliver
3

Cubix , 38 Bytes

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

Probieren Sie es hier aus

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

0I:- Stapelt den Stack mit 0, n, n (s, n, d)
^- Start der Schleife )?- Dekrementiere d und teste auf 0. 0 beendet loop-
%?mod gegen n und teste. 0 bewirkt, ;rrw+s;rUdass s nach oben rotiert und d addiert, s nach unten rotiert
;<und zur Schleife zurückkehrt. Bereinigen Sie die Schleife und schließen Sie sie wieder an.
Beim Verlassen der Schleife
;<- Entferne d vom Stapel und leite um
-?- Entferne n von s und teste, 0 LOU@dreht nach links, gibt aus und verlässt, negative 0O@drücken Null, gibt aus und verlässt. Positive ;Oentfernen Differenz und geben n aus. Der Weg führt dann nach links zum @Ausgang

MickyT
quelle
3

Pure Bash, 37 Bytes

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

Vielen Dank an @Dennis für die Neuordnung des Codes - das spart 6 Bytes und beseitigt die zufällige Ausgabe an stderr.

Die Eingabe wird als Argument übergeben.

Die Ausgabe wird im Exit-Code zurückgegeben: 0 für reichlich vorhanden, 1 für nicht reichlich vorhanden.

Die Ausgabe an stderr sollte ignoriert werden.

Testläufe:

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
Mitchell Spector
quelle
Sie können 6 Bytes einsparen, während Sie eine Streuausgabe an STDERR vermeiden. tio.run/nexus/bash#S04sUbBTSEwqzUtJzCtRsLFRUHf1d1P/…
Dennis
2

RProgN , 8 Bytes

~_]k+2/<

Erklärt

~_]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.

Probieren Sie es online!

Ein Taco
quelle
2

Batch, 84 Bytes

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

Ansonsten Ausgaben -1für eine große Anzahl 0. Subtrahiert alle Faktoren 2nund verschiebt dann das Ergebnis um 31 Stellen, um das Vorzeichenbit zu extrahieren. Alternative Formulierung, auch 84 Bytes:

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

Ausgänge 1für eine große Anzahl. Subtrahiert alle Faktoren von nund vergleicht das Ergebnis mit -n. ( set/aDies ist die einzige Methode von Batch zum Rechnen, sodass ich die Schleife nicht einfach anpassen kann.)

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

Perl 6, 72 24 Bytes

{$_ <sum grep $_%%*,^$_}
  • Programmargument: a.
  • Erstellen Sie eine Liste aus 1..a.
  • Nehmen Sie alle Zahlen, die Teiler von sind a.
  • Summiere sie.
  • Überprüfen Sie, ob diese Summe größer als ist a.

Vielen Dank an @ b2gills.

Ven
quelle
Jedes Vorkommen $^anach dem ersten kann auf gerade verkürzt werden $a. aber es ist noch kürzer, wenn Sie es schreiben als {$_ <sum grep $_%%*,^$_}Auch in einer früheren Version suchen, [+](LIST)funktioniert (keine Leerzeichen)
Brad Gilbert b2gills
@ BradGilbertb2gills Danke! :)
Ven
2

J, 19 Bytes

Vielen Dank an Conor O'Brien, der es auf 19 Bytes reduziert hat!

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

Zurück: (34 Bytes)

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

Gibt 1 zurück, wenn es reichlich vorhanden ist, und 0, wenn es nicht vorhanden ist.

Ausgabe:

   f 3
0
   f 12
1
   f 11
0
   f 20
1
Blöcke
quelle
Willkommen bei PPCG! Wir erlauben anonyme Funktionen, so dass Sie die führenden f=:als Teil Ihrer Byteanzahl entfernen können . Sie können auch zu 19 zurückkehren, indem Sie in ein implizites Verb konvertieren:<[:+/i.#~i.e.]%2+i.
Conor O'Brien
Danke für den Hinweis! Könnten Sie uns bitte das cap Verb ([:) und das switch Verb (~) erklären? Ich verstehe nicht wirklich, was sie in diesem stillschweigenden Verb tun sollen.
Blockiert den
~ schaltet so, dass es zB # i ist. aber was ist der Zweck von [:?
Blockiert den
Sie kennen sich also mit Gabeln aus, oder? (f g h) y' is the same as (fy) g (hy) . When f` ist eine Kappe, entspricht ([: g h) yin etwa g h y. Was ~schaltet dies die linke und rechte Argumente. Es ist wichtig zu wissen, dass dies ~kein Verb ist, sondern eigentlich ein Adverb. Es modifiziert ein Verb. Zum Beispiel könnten wir so etwas haben 2 %~ 8. Hier ~ändert %ihre Argumente wechseln, so dass der Ausdruck entspricht 8 % 2.
Conor O'Brien
In der Gabel Kette #~ausgewertet wird , nachdem die Verben sein Recht ausgeführt werden, so dass er das linke Argument das Ergebnis auf der rechten Seite wird
Conor O'Brien
2

Pyth, 11 Bytes

>sPf!%QTS

Alt:

L!%Qb>sPy#S

Ich kann nicht !%als Pfn für verwenden #, weil es zwei Funktionen ist. Das macht mich traurig :(.


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
Ven
quelle
Die >sPf!%QTS
Nichtdefinition
2

k , 19 16 15 Bytes

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

Gibt 1für true und 0für false zurück.

Probieren Sie es online!

{             } /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
zgrep
quelle
2

F #, 51 Bytes

let f n=Seq.filter(fun x->n%x=0){1..n-1}|>Seq.sum>n

Probieren Sie es online!

Filtert alle nicht gleichmäßig aufgeteilten Zahlen heraus, nsummiert sie und vergleicht sie mit ihnen n.

Ciaran_McCarthy
quelle