Faux polyglottes de somme des diviseurs


23

La tâche

Dans ce défi, votre tâche consiste à écrire un programme dans un langage de programmation L qui prend un entier positif n et génère la somme des diviseurs appropriés de n ( séquence A001065 sur OEIS). Il doit renvoyer la sortie correcte pour tout 1 ≤ n ≤ 10 000 . Voici les 10 premières sorties:

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

De plus, votre programme doit être un faux polyglotte , ce qui signifie ce qui suit. C'est un programme valide dans un autre langage de programmation L ' , et pour chaque entrée 1 ≤ n ≤ 10 (les cas de test ci-dessus), il retourne la somme des diviseurs propres de n , mais il en existe 11 ≤ n ≤ 10 000 pour lesquels il ne renvoie pas le résultat correct. Il peut renvoyer quelque chose de incorrect, boucler pour toujours, planter, etc. Il peut donner un mauvais résultat pour tous n ≥ 11 , pour certains d'entre eux ou un seul.

Règles et notation

Vous pouvez écrire un programme complet ou une fonction, et vous pouvez avoir différents moyens d'entrée et de sortie dans les deux langues. Le nombre d'octets le plus bas gagne. Les règles de standard s'appliquent. Dans ce défi, différentes versions principales ou implémentations d'un langage sont considérées comme distinctes.

Notez que si vous utilisez des langages de programmation avec des encodages non ASCII (comme beaucoup le font sur ce site), la même séquence d'octets doit être utilisée pour les deux langages. Cela signifie que vous devez soit convertir entre des pages de codes potentiellement différentes, soit subir des pénalités pour les caractères Unicode multi-octets.

Cas de test supplémentaires

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

Réponses:


10

JavaScript (ES6), V8 / SpiderMonkey vs Chakra , 66 63 octets

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

Démo

Sortie

Sortie de l'extrait ci-dessus sur Chrome et Firefox (tout est correct):

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

Sortie sur Edge (désactivée par 1, à partir de n = 11):

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

Pourquoi?

Aucun algorithme n'est imposé par la spécification de la .sort()méthode. Il n'est même pas nécessaire d'être stable. Par conséquent, chaque moteur JavaScript utilise sa propre implémentation.

Cependant, [0,1].sort(x=>x)donne [0,1]avec tous les moteurs.

Alors quelle est la différence?

Ce qui se passe ici, c'est que Chakra passe en 1tant que premier paramètre de la première (et unique) itération à la fonction de rappel (demandant une comparaison de 1avec 0), tandis que V8 et SpiderMonkey passent 0(demandant une comparaison de 0avec 1).

Vous pouvez utiliser l'extrait de code suivant pour vérifier ce que fait votre navigateur.


1
Ceci est une solution acceptable. Je vais le clarifier dans le post principal.
Zgarb

8

Python 2 et Python 3, 58 octets

TIO pour Python 2

TIO pour Python 3

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

Cela fonctionne en python 2, mais pour chaque n> 10, il produirait 0 en python 3.
Tout cela en raison d'approches différentes pour comparer les chaînes avec les octets:

  • en Python 2 '' == b''
  • en Python 3 '' != b''

7

JavaScript (Node.js) et PHP , 73 70 octets

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

Dans les deux langues, il s'agit d'une fonction anonyme. JavaScript donne le résultat correct, mais PHP donne 0 pour tout n> = 11 .

Essayez-le JS!

Essayez-le PHP!

Comment ça marche

Les deux langues font la même chose au début: itérer de 1 à n-1, en gardant une somme cumulée de tous les nombres i pour lesquels n% i = 0 .

Ce qui cause la différence de comportement est la dernière partie:

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

En JavaScript, "$n"est juste un littéral de chaîne. La comparaison >avec le 10convertit implicitement en nombre, mais comme il ne ressemble pas à un nombre, il devient NaN. NaN donne faux par rapport à un nombre de quelque façon. En conséquence, $dest toujours retourné.

Cependant, en PHP, "$n"est une chaîne contenant la valeur de $n. Lorsque PHP convertit cela en un nombre, cela devient simplement la valeur de $n. S'il est supérieur à 10, il 0est renvoyé à la place de $d.


7

05AB1E / Jelly ,  9  8 octets

Le code octet (hexadécimal):

d1 a8 4f 71 0d ad 53 fa

L'utilisation de la page de codes de Jelly renvoie des résultats incorrects pour tout nombre excessif (par exemple, une entrée de 12 renvoie 12plutôt que 16):

ẎƭOqÆḌS«

Essayez-le en ligne!

L'utilisation de la page de codes de 05AB1E renvoie des résultats corrects:

ѨOqмλSú

Essayez-le en ligne!

Comment?

05AB1E analyse jusqu'à et y compris le 71( q) qui ordonne d'arrêter de fumer, puis arrête l' analyse:

Ѩ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 analyse l'ensemble du programme à l'avance comme trois liens en raison de l'effet des octets sans signification assignée ƭet qagissant comme des délimiteurs. Le point d'entrée d'un programme est son lien final:

Ẏ - 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

C'est 05AB1E / Jelly?
Erik the Outgolfer

Ouais, fixe, merci; J'écrivais juste l'explication.
Jonathan Allan

ÆḌSDenregistre un octet.
Dennis

@Dennis Ou mieux ÆḌSṚ.
Erik the Outgolfer

@Dennis - merci, pensé à une façon différente de manger :)
Jonathan Allan

6

Python 3 / Python 2 , 64 60 58 octets

Merci à @officialaimm pour 2 octets de moins

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

En Python 3, cela donne les résultats corrects. En Python 2, la sortie est incorrecte pour les entrées dépassant 10. Le code exploite l'arrondi bancaire, ce qui est fait par Python 3 mais pas par Python 2.

Essayez-le en ligne! Python 3 (correct), Python 2 (mauvais pour n > 10).


Vous n'en aurez pas besoin [ ].
officialaimm

6

Python 3 / Python 2 , 47 octets

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

Une fonction sans nom, fausse en Python 2.

Essayez-le en ligne pour Python 3 ou Python 2

En Python 2, /c'est la division entière avec des arguments entiers, tandis qu'en Python 3, c'est la division.

Lorsque ndépasse 10, il est 10/n évalué à 0 en Python 2, mais à un petit nombre positif en Python 3 (cela est certainement vrai jusqu'au maximum requis de 10 000 au moins).

En tant que tel, il 10/n>0évalue à Truepour Python 3 et range(10/n>0,n)est équivalent à range(1,n)tandis que dans Python 2 il 10/n>0évalue à Falsequand ndépasse 10, après quoi il range(10/n>0,n)devient équivalent à range(0,n)provoquer n%dune tentative d'effectuer une arithmétique modulo zéro, augmentant a ZeroDivisionError.


5

Gelée / 05AB1E , 12 octets

Ce que Jelly voit:

11⁻iẎƭO}qÆḌS

Essayez-le en ligne!

Explication:

qn'est pas pris en charge dans Jelly, donc Jelly ne "voit" que ce qui est après q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

Ce que 05AB1E voit:

11‹iѨO}qмλS

Essayez-le en ligne!

Explication:

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

Bien sûr, tout ce qui se passe après "quitter" ne se produit pas.


Je souhaite ÆḌSaurait été valable en soi ... Réponse extraordinaire!
M. Xcoder

@ Mr.Xcoder Je ne sais pas comment мλScela fonctionnerait dans 05AB1E.
Erik the Outgolfer

Insistez sur Je souhaite : P
M. Xcoder
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.