Poliglotti con somma divisori falsi


23

L'obiettivo

In questa sfida, il tuo compito è scrivere un programma in un linguaggio di programmazione L che prenda un intero positivo n e produca la somma dei divisori propri di n ( sequenza A001065 su OEIS). Dovrebbe restituire l'uscita corretta per ogni 1 ≤ n ≤ 10 000 . Ecco le prime 10 uscite:

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

Inoltre, il tuo programma deve essere un poliglotta falso , il che significa quanto segue. È un programma valido in un altro linguaggio di programmazione L ' e per ogni input 1 ≤ n ≤ 10 (i casi di test sopra riportati) restituisce la somma dei divisori propri di n , ma esistono circa 11 ≤ n ≤ 10 000 per i quali non restituisce il risultato corretto. Potrebbe restituire qualcosa di errato, loop per sempre, crash ecc. Può dare un risultato errato per tutti n ≥ 11 , per alcuni di essi o solo per uno.

Regole e punteggio

Puoi scrivere un programma completo o una funzione e puoi avere diversi mezzi di input e output nelle due lingue. Vince il conteggio dei byte più basso. standard applicano le regole . In questa sfida, diverse versioni o implementazioni principali di una lingua sono considerate distinte.

Nota che se usi linguaggi di programmazione con codifiche non ASCII (come molti fanno su questo sito), la stessa sequenza di byte deve essere usata per entrambi i linguaggi. Ciò significa che è necessario convertire tra code page potenzialmente diverse o subire penalità per i caratteri Unicode multibyte.

Casi di prova aggiuntivi

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

Risposte:


10

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

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

dimostrazione

Produzione

Output dello snippet sopra riportato su Chrome e Firefox (tutti corretti):

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

Output on Edge (spento di 1, a partire da n = 11):

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

Perché?

Nessun algoritmo è imposto dalla specifica per il .sort()metodo. Non è nemmeno richiesto di essere stabile. Pertanto, ogni motore JavaScript utilizza la propria implementazione.

Tuttavia, [0,1].sort(x=>x)[0,1] con tutti i motori.

Quindi qual è la differenza?

Quello che sta succedendo qui è che Chakra sta passando 1come primo parametro della prima (e unica) iterazione alla funzione di callback (chiedendo un confronto di 1con 0), mentre V8 e SpiderMonkey stanno passando 0(chiedendo un confronto di 0con1 ).

Puoi utilizzare il seguente frammento per verificare che cosa sta facendo il tuo browser.


1
Questa è una soluzione accettabile Lo chiarirò nel post principale.
Zgarb,

8

Python 2 e Python 3, 58 byte

TIO per Python 2

TIO per Python 3

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

Funziona in python 2, ma per ogni n> 10 produrrebbe 0 in python 3.
Tutto a causa di approcci diversi nel confrontare stringhe con byte:

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

7

JavaScript (Node.js) e PHP , 73 70 byte

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

In entrambe le lingue, questa è una funzione anonima. JavaScript fornisce il risultato corretto, ma PHP fornisce 0 per tutti n> = 11 .

Provalo JS!

Provalo PHP!

Come funziona

All'inizio entrambe le lingue fanno la stessa cosa: iterate da 1 a n-1, mantenendo una somma corrente di tutti i numeri i i per i quali n% i = 0 .

Ciò che causa la differenza nel comportamento è la parte finale:

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

In JavaScript, "$n"è solo una stringa letterale. Il confronto> con lo 10converte implicitamente in un numero, ma poiché non sembra un numero, diventa NaN. NaN dà falso se confrontato con un numero in alcun modo. Di conseguenza,$d viene sempre restituito.

Tuttavia, in PHP, "$n"è una stringa contenente il valore di $n. Quando PHP lo converte in un numero, diventa semplicemente il valore di $n. Se è maggiore di 10, 0viene restituito anziché $d.


7

05AB1E / Jelly ,  9  8 byte

Il codice byte (esadecimale):

d1 a8 4f 71 0d ad 53 fa

L'uso della tabella codici Jelly restituisce risultati errati per qualsiasi numero eccessivo (ad esempio, un input di 12 ritorni 12anziché 16):

ẎƭOqÆḌS«

Provalo online!

Utilizzando la tabella codici 05AB1E si ottengono risultati corretti:

ѨOqмλSú

Provalo online!

Come?

05AB1E analizza fino a 71( incluso q) che indica di uscire e quindi interrompe l'analisi:

Ѩ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 analizza l'intero programma in anticipo come tre collegamenti a causa dell'effetto dei byte senza un significato assegnato ƭe qfungendo da delimitatori. Il punto di ingresso di un programma è il link finale:

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

Questo è 05AB1E / Jelly?
Erik the Outgolfer,

Sì, risolto, grazie; Stavo solo scrivendo la spiegazione.
Jonathan Allan,

ÆḌSDsalva un byte.
Dennis,

@Dennis O meglio ÆḌSṚ.
Erik the Outgolfer,

@Dennis - grazie, ho pensato a un modo diverso di mangiare :)
Jonathan Allan

6

Python 3 / Python 2 , 64 60 58 byte

Grazie a @officialaimm per 2 byte di sconto

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

In Python 3 questo dà i risultati corretti. In Python 2 l'uscita è errata per gli input in eccesso 10. Il codice sfrutta l'arrotondamento del banchiere, fatto da Python 3 ma non da Python 2.

Provalo online! Python 3 (corretto), Python 2 (sbagliato per n > 10).


Non avrai bisogno [ ].
officialaimm,

6

Python 3 / Python 2 , 47 byte

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

Una funzione senza nome, falsa in Python 2.

Provalo online per Python 3 o Python 2

In Python 2 /è divisione intera con argomenti interi, mentre in Python 3 è divisione.

Quando nsupera 10 viene 10/n valutato a 0 in Python 2, ma a un piccolo numero positivo in Python 3 (questo è certamente vero fino al massimo richiesto di almeno 10.000 ).

Come tali 10/n>0restituisce Trueper Python 3 ed range(10/n>0,n)è equivalente a range(1,n)mentre in Python 2 10/n>0restituisce Falsequando nsupera 10 dopo di che range(10/n>0,n)diventa equivalente a range(0,n)causa n%dper tentare di eseguire modulo azzerare aritmetica, sollevando unZeroDivisionError .


5

Gelatina / 05AB1E , 12 byte

Cosa vede Jelly:

11⁻iẎƭO}qÆḌS

Provalo online!

Spiegazione:

qnon è supportato in Jelly, quindi Jelly "vede" solo ciò che segue q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

Cosa vede 05AB1E:

11‹iѨO}qмλS

Provalo online!

Spiegazione:

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

Ovviamente tutto dopo "smettere" in realtà non accade.


Vorrei ÆḌSche fosse valido da solo ... Risposta straordinaria!
Mr. Xcoder,

@ Mr.Xcoder Non sono sicuro di come мλSfunzionerebbe in 05AB1E.
Erik the Outgolfer

Sottolineare che desidero : P
Mr. Xcoder,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.