Gefälschte Divisorsummen-Polyglots

23

Die Aufgabe

In dieser Herausforderung besteht Ihre Aufgabe darin, ein Programm in einer Programmiersprache L zu schreiben , die eine positive ganze Zahl n annimmt und die Summe der richtigen Teiler von n ausgibt ( Sequenz A001065 auf OEIS). Es sollte die korrekte Ausgabe für 1 ≤ n ≤ 10 000 zurückgeben . Hier sind die ersten 10 Ausgänge:

0, 1, 1, 3, 1, 6, 1, 7, 4, 8

Außerdem muss Ihr Programm ein gefälschter Polyglot sein , was Folgendes bedeutet. Es ist ein gültiges Programm in einer anderen Programmiersprache L ' und gibt für jede Eingabe 1 ≤ n ≤ 10 (die obigen Testfälle) die Summe der richtigen Teiler von n zurück , es gibt jedoch einige 11 ≤ n ≤ 10 000 für die es gibt nicht das richtige Ergebnis zurück. Es kann etwas Falsches zurückgeben, eine Endlosschleife bilden, abstürzen usw. Es kann ein falsches Ergebnis für alle n ≥ 11 geben , für einige von ihnen oder nur für einen.

Regeln und Wertung

Sie können ein vollständiges Programm oder eine Funktion schreiben und in den beiden Sprachen unterschiedliche Ein- und Ausgabemöglichkeiten haben. Die niedrigste Byteanzahl gewinnt. Es gelten die Standardregeln für . Bei dieser Herausforderung werden verschiedene Hauptversionen oder Implementierungen einer Sprache als unterschiedlich betrachtet.

Beachten Sie, dass bei Verwendung von Programmiersprachen mit Nicht-ASCII-Codierungen (wie dies auf dieser Site häufig der Fall ist) für beide Sprachen dieselbe Bytefolge verwendet werden muss. Dies bedeutet, dass Sie entweder zwischen potenziell unterschiedlichen Codepages konvertieren müssen oder Strafen für Mehrbyte-Unicode-Zeichen erleiden müssen.

Zusätzliche Testfälle

20 -> 22
36 -> 55
180 -> 366
997 -> 1
2875 -> 869
10000 -> 14211
Zgarb
quelle

Antworten:

10

JavaScript (ES6), V8 / SpiderMonkey gegen Chakra , 66 63 Bytes

n=>[...Array(n)].map((_,d)=>s+=n%d?0:d,[0,n>10].sort(x=>s=x))|s

Demo

Ausgabe

Ausgabe des obigen Snippets auf Chrome und Firefox (alles korrekt):

[0,1,1,3,1,6,1,7,4,8,1,16,1,10,9,15,1,21,1,22]

Ausgabe an Flanke (aus um 1, beginnend bei n = 11):

[0,1,1,3,1,6,1,7,4,8,2,17,2,11,10,16,2,22,2,23]

Warum?

Die Spezifikation der .sort()Methode schreibt keinen Algorithmus vor . Es ist nicht einmal erforderlich, stabil zu sein. Daher verwendet jede JavaScript-Engine ihre eigene Implementierung.

Allerdings [0,1].sort(x=>x)gibt es [0,1]bei allen Motoren.

Was ist der Unterschied?

Was hier passiert, ist, dass Chakra 1als erster Parameter der ersten (und einzigen) Iteration an die Rückruffunktion übergeben wird (um einen Vergleich 1mit 0anzufordern), während V8 und SpiderMonkey übergeben werden 0(um einen Vergleich 0mit anzufordern 1).

Sie können das folgende Snippet verwenden, um zu überprüfen, was Ihr Browser tut.

Arnauld
quelle
1
Dies ist eine akzeptable Lösung. Ich werde es im Hauptbeitrag klären.
Zgarb
8

Python 2 und Python 3, 58 Bytes

TIO für Python 2

TIO für Python 3

lambda n:sum(i*(n<11or''==b'')for i in range(1,n)if n%i<1)

Es funktioniert in Python 2, aber für jedes n> 10 würde es in Python 3 0 ausgeben. Dies liegt
an unterschiedlichen Ansätzen beim Vergleichen von Strings mit Bytes:

  • in Python 2 '' == b''
  • in Python 3 '' != b''
Totes Opossum
quelle
7

JavaScript (Node.js) und PHP , 73-70 Byte

function($n){for($d=$i=0;++$i<$n;)$d+=$i*!($n%$i);return"$n">10?0:$d;}

In beiden Sprachen ist dies eine anonyme Funktion. JavaScript liefert das richtige Ergebnis, aber PHP liefert 0 für alle n> = 11 .

Probieren Sie es aus JS!

Probieren Sie es aus PHP!

Wie es funktioniert

Beide Sprachen machen zunächst das Gleiche: Iterieren Sie von 1 bis n-1 und behalten Sie dabei eine laufende Summe aller Zahlen i bei, für die n% i = 0 ist .

Was den Unterschied im Verhalten verursacht, ist der letzte Teil:

return"$n">10?0:$d;

In JavaScript "$n"ist dies nur ein String-Literal. Der Vergleich >mit 10wandelt es implizit in eine Zahl um, aber da es nicht wie eine Zahl aussieht, wird es zu NaN. NaN gibt falsch, wenn es mit einer Zahl in irgendeiner Weise verglichen wird. Infolgedessen $dwird immer zurückgegeben.

In PHP "$n"ist dies jedoch eine Zeichenfolge, die den Wert von enthält $n. Wenn PHP dies in eine Zahl umwandelt, wird es einfach zum Wert von $n. Wenn es größer als ist 10, 0wird anstelle von zurückgegeben $d.

Geschäfts-Katze
quelle
7

05AB1E / Jelly ,  9  8 Bytes

Der Byte-Code (hexadezimal):

d1 a8 4f 71 0d ad 53 fa

Mit Jelly - Code-Seite gibt falsche Ergebnisse für jede übermäßige Zahl (zB eine Eingabe von 12 zurückkehrt , 12statt 16):

ẎƭOqÆḌS«

Probieren Sie es online!

Bei Verwendung der Codepage von 05AB1E werden korrekte Ergebnisse zurückgegeben:

ѨOqмλSú

Probieren Sie es online!

Wie?

05AB1E parst bis einschließlich 71( q), das zum Beenden auffordert, und beendet dann das Parsen:

ѨOq - Takes input from stdin
Ñ    - get divisors
 ¨   - remove right-most (the input value itself - yielding proper divisors)
  O  - sum
   q - quit (causing an implicit print of the top of the stack)
...мλSú is never parsed

Jelly analysiert das gesamte Programm im Voraus als drei Verknüpfungen, da die Bytes ohne zugewiesene Bedeutung wirken ƭund qals Begrenzer fungieren. Der Einstiegspunkt eines Programms ist das letzte Glied:

Ẏ - Link 1 (never used), tighten list
...ƭ delimits links 1 & 2)

O - Link 2 (never used), cast from characters to their ordinals
...q delimits link 2 and the main link

ÆḌS« - Main link: number, n
ÆḌ   - proper divisors
  S  - sum
   « - minimum of that and n
     - as a full-program: implicit print
Jonathan Allan
quelle
Das ist 05AB1E / Jelly?
Erik der Outgolfer
Ja, behoben, danke; Ich habe gerade die Erklärung aufgeschrieben.
Jonathan Allan
ÆḌSDSpeichert ein Byte.
Dennis
@ Tennis oder besser ÆḌSṚ.
Erik der Outgolfer
@ Tennis - danke, dachte über eine andere Art und Weise beim Essen :)
Jonathan Allan
6

Python 3 / Python 2 , 64 60 58 Bytes

Vielen Dank an @officialaimm für 2 Bytes aus

lambda n:sum(d*(round((n>10)*.5)==n%d)for d in range(1,n))

In Python 3 liefert dies die richtigen Ergebnisse. In Python 2 ist die Ausgabe bei Eingaben über falsch 10. Der Code nutzt die Rundung des Bankers, die von Python 3, aber nicht von Python 2 ausgeführt wird.

Probieren Sie es online! Python 3 (richtig), Python 2 (falsch für n > 10).

Luis Mendo
quelle
Du wirst nicht brauchen [ ].
offiziell
6

Python 3 / Python 2 , 47 Bytes

lambda n:sum(d*(n%d<1)for d in range(10/n>0,n))

Eine unbenannte Funktion, die in Python 2 gefälscht ist.

Probieren Sie es online für Python 3 oder Python 2

In Python 2 /ist es eine Ganzzahldivision mit Ganzzahlargumenten, während es in Python 3 eine Division ist.

Wenn 10n überschritten wird , ergibt dies in Python 2 den Wert 0, in Python 3 jedoch einen kleinen positiven Wert (dies gilt sicherlich bis zu dem von mindestens 10.000 geforderten Maximum ). 10/n

Als solche 10/n>0ausgewertet Truefür Python und 3 range(10/n>0,n)entspricht , range(1,n)während in Python 2 10/n>0ausgewertet , Falsewenn nmehr als 10 , woraufhin range(10/n>0,n)auf äquivalente wird range(0,n)bewirkt , n%dum zu versuchen modulo Null Arithmetik durchzuführen, eine Anhebung ZeroDivisionError.

Jonathan Allan
quelle
5

Jelly / 05AB1E , 12 Bytes

Was Jelly sieht:

11⁻iẎƭO}qÆḌS

Probieren Sie es online!

Erläuterung:

qwird in Jelly nicht unterstützt, daher "sieht" Jelly nur, was nach dem q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

Was 05AB1E sieht:

11‹iѨO}qмλS

Probieren Sie es online!

Erläuterung:

11‹iѨO}qмλS Implicit input multiple times
11           Push 11
  ‹          Less than 11?
   i   }     If equals 1, then
    Ñ         Divisors
     ¨        Remove last
      O       Sum
       q     Implicit print and quit
        м    Negative filter
         λ   Undefined, ignored error
          S  Split into chars

Natürlich passiert nicht alles nach dem "Beenden".

Erik der Outgolfer
quelle
Ich wünschte, ÆḌSwäre für sich allein gültig gewesen ... Außergewöhnliche Antwort!
Mr. Xcoder
@ Mr.Xcoder Ich bin mir nicht sicher, wie мλSdas in 05AB1E funktionieren würde.
Erik der Outgolfer
Hervorheben auf Ich wünsche : P
Mr. Xcoder