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 Code-Golf handelt , werden Standard-Schlupflöcher verweigert. Versuchen Sie, den kürzestmöglichen Code in der von Ihnen gewählten Sprache zu schreiben!
quelle
Antworten:
ECMAScript Regex,
1085855597536511508504 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: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$)))+$
(
\14
Zur\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
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\14
sie 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:
quelle
Python 2 ,
4140 BytesDie 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%j
ergibt 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%j
n%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%j
ein ZeroDivisionError ausgelöst und das Programm mit einem Fehler beendet.quelle
~k<0
ist schick, aber ich denke,-1<k
macht auch den Trick;)Brachylog , 5 Bytes
Probieren Sie es online!
Erläuterung
quelle
Gelee , 3 Bytes
Probieren Sie es online!
Wie es funktioniert
quelle
Python , 44 Bytes
Probieren Sie es online!
quelle
range(n)
. Das lästige Modul von NullMathematica, 17 Bytes
Erläuterung
quelle
AbundantNumberQ
, so würde es ein paar Bytes sparen :)05AB1E ,
54 Bytes-1 Bytes dank Scottinet
Probieren Sie es online! oder Versuchen Sie es mit 0 bis 100
quelle
Retina ,
5045 BytesEingabe in Unary , Ausgabe
1
für viele Zahlen,0
sonst.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.)
quelle
Retina , 34 Bytes
Die Anzahl der Bytes setzt die Kodierung nach ISO 8859-1 voraus.
Eingabe in unary , Ausgabe
1
für viele Zahlen,0
sonst.Probieren Sie es online!
Erläuterung
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.Die Bühne selbst vergleicht einfach die Zeilenvorschübe (
¶
) und entfernt sie. Dies1>
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.Schließlich versuchen wir, die mindestens eine
1
Zeile 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, die1
für eine Vielzahl von Zahlen und0
ansonsten gelten.quelle
8086 Versammlung,
23282524 BytesZerlegt:
Beispiel Testprogramm, Test N = [12..1000]:
Ausgabe [2..1000]
Ausgabe [12500..12700]
Ausgabe [25100..25300]
Aktualisierung:
quelle
JLE
durchJBE
zu 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.JC
oder verwenden, umJNC
zu bestimmen, ob die Nummer reichlich vorhanden ist oder nicht.Eigentlich 5 Bytes
Probieren Sie es online!
quelle
05AB1E , 4 Bytes
Probieren Sie es online!
Wie es funktioniert
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.
quelle
Sorry to post in old question
Mach dir keine Sorgen! Ich bin immer glücklich , Antworten auf meinen alten Herausforderungen zu sehen, und es ist tatsächlich hier gefördert . :)PARI / GP , 15 Bytes
Die Variante
n->sigma(n,-1)>2
ist leider länger.quelle
Java 8, 53 Bytes (viel mehr, wenn Sie den zeremoniellen Code enthalten)
Probieren Sie es online aus
Erklärung:
quelle
return
wenn 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!n->java.util.stream.IntStream.range(1,n).filter(e->n%e<1).sum()>n
für 65 Bytes (vorausgesetzt, ich habe das Paket direkt über den Kopf bekommen)Powershell,
5149 BytesIch 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$i
nput 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-join
alle diese Zahlen zusammen mit+
undiex
der resultierenden Zeichenfolge berechnet Die Summe dieser Teile ist größer als die Eingabe.quelle
param($i)((1..$i|?{!($i%$_)})-join"+"|iex)-gt2*$i
MATL, 6 Bytes
Gibt 1 für viele Zahlen aus, sonst 0.
Wie es funktioniert
quelle
QBIC , 22 Bytes
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ätstest1 to n
vollständig durchläuft .Erläuterung:
quelle
JavaScript (ES6), 33 Byte
quelle
Japt ,
9 76 Bytes2 Bytes gespart dank ETHproductions. 1 Byte dank obarakon gespeichert.
Probieren Sie es online!
quelle
â
1 Byte, mindestens in Unicode (0xE2).â
es sich um ein einzelnes Byte handelt.â
ein wahrheitsgemäßes Argument angegeben wird, wird die aktuelle Nummer aus der verbleibenden Liste entfernt, sodass Sieâ1 x >U
ein paar Bytes sparen können :-)<Uâ1 x
ein Byte speichern. Japt fügt dasU
vor dem Programm hinzu.Cubix , 38 Bytes
Probieren Sie es hier aus
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;rU
dass 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, 0LOU@
dreht nach links, gibt aus und verlässt, negative0O@
drücken Null, gibt aus und verlässt. Positive;O
entfernen Differenz und geben n aus. Der Weg führt dann nach links zum@
Ausgangquelle
Pure Bash, 37 Bytes
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:
quelle
RProgN , 8 Bytes
Erklärt
Probieren Sie es online!
quelle
Batch, 84 Bytes
Ansonsten Ausgaben
-1
für eine große Anzahl0
. Subtrahiert alle Faktoren2n
und verschiebt dann das Ergebnis um 31 Stellen, um das Vorzeichenbit zu extrahieren. Alternative Formulierung, auch 84 Bytes:Ausgänge
1
für eine große Anzahl. Subtrahiert alle Faktoren vonn
und vergleicht das Ergebnis mit-n
. (set/a
Dies ist die einzige Methode von Batch zum Rechnen, sodass ich die Schleife nicht einfach anpassen kann.)quelle
Perl 6,
7224 Bytes1..a
.a
.a
.Vielen Dank an @ b2gills.
quelle
$^a
nach 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)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:
quelle
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.
(f g h) y' is the same as
(fy) g (hy). When
f` ist eine Kappe, entspricht([: g h) y
in etwag 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 haben2 %~ 8
. Hier~
ändert%
ihre Argumente wechseln, so dass der Ausdruck entspricht8 % 2
.#~
ausgewertet wird , nachdem die Verben sein Recht ausgeführt werden, so dass er das linke Argument das Ergebnis auf der rechten Seite wirdPyth, 11 Bytes
Alt:
Ich kann nicht
!%
als Pfn für verwenden#
, weil es zwei Funktionen ist. Das macht mich traurig :(.quelle
>sPf!%QTS
k ,
19 1615 BytesGibt
1
für true und0
für false zurück.Probieren Sie es online!
quelle
PowerShell , 43 Byte
Probieren Sie es online!
quelle
Common Lisp, 63 Bytes
Probieren Sie es online!
quelle
F #, 51 Bytes
Probieren Sie es online!
Filtert alle nicht gleichmäßig aufgeteilten Zahlen heraus,
n
summiert sie und vergleicht sie mit ihnenn
.quelle