Poliglot jumlah pembagi palsu

23

Tugas

Dalam tantangan ini, tugas Anda adalah menulis sebuah program dalam bahasa pemrograman L yang mengambil bilangan bulat positif n , dan menampilkan jumlah pembagi n yang tepat ( urutan A001065 pada OEIS). Ini harus mengembalikan output yang benar untuk 1 ≤ n ≤ 10 000 . Inilah 10 keluaran pertama:

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

Selain itu, program Anda harus berupa polyglot palsu , yang artinya sebagai berikut. Ini adalah program yang valid dalam bahasa pemrograman lain L ' , dan untuk setiap input 1 ≤ n ≤ 10 (kasus uji di atas), ia mengembalikan jumlah pembagi n yang tepat , tetapi ada sekitar 11 ≤ n ≤ 10.000 untuk itu tidak mengembalikan hasil yang benar. Mungkin mengembalikan sesuatu yang salah, berulang selamanya, macet dll. Ini dapat memberikan hasil yang salah untuk semua n ≥ 11 , untuk beberapa dari mereka atau hanya satu.

Aturan dan penilaian

Anda dapat menulis program atau fungsi lengkap, dan Anda dapat memiliki berbagai cara input dan output dalam dua bahasa. Hitungan byte terendah menang. Aturan standar berlaku. Dalam tantangan ini, berbagai versi utama atau implementasi bahasa dianggap berbeda.

Perhatikan bahwa jika Anda menggunakan bahasa pemrograman dengan pengkodean non-ASCII (seperti yang banyak dilakukan di situs ini), urutan byte yang sama harus digunakan untuk kedua bahasa. Ini berarti Anda harus mengonversi antara halaman kode yang berpotensi berbeda atau mengalami penalti untuk karakter Unicode multi-byte.

Kasus uji tambahan

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

Jawaban:

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

Demo

Keluaran

Keluaran cuplikan di atas di Chrome dan Firefox (semuanya benar):

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

Output on Edge (dimatikan oleh 1, mulai dari n = 11):

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

Mengapa?

Tidak ada algoritma yang ditentukan oleh spesifikasi untuk .sort()metode ini. Bahkan tidak diharuskan untuk menjadi stabil. Oleh karena itu, setiap mesin JavaScript menggunakan implementasinya sendiri.

Namun, [0,1].sort(x=>x)memberi [0,1]dengan semua mesin.

Jadi apa bedanya?

Apa yang terjadi di sini adalah bahwa Chakra dilewatkan 1sebagai parameter pertama dari iterasi pertama (dan satu-satunya) ke fungsi callback (meminta perbandingan 1dengan 0), sementara V8 dan SpiderMonkey lewat 0(meminta perbandingan 0dengan 1).

Anda dapat menggunakan potongan berikut untuk memeriksa apa yang sedang dilakukan browser Anda.

Arnauld
sumber
1
Ini adalah solusi yang bisa diterima. Saya akan mengklarifikasi di posting utama.
Zgarb
8

Python 2 dan Python 3, 58 byte

TIO untuk Python 2

TIO untuk Python 3

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

Ia bekerja di python 2, tetapi untuk setiap n> 10 akan menghasilkan 0 dalam python 3.
Semua karena pendekatan yang berbeda dalam membandingkan string dengan byte:

  • dalam Python 2 '' == b''
  • dalam Python 3 '' != b''
Possum Mati
sumber
7

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

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

Dalam kedua bahasa, ini adalah fungsi anonim. JavaScript memberikan hasil yang benar, tetapi PHP memberikan 0 untuk semua n> = 11 .

Cobalah JS!

Coba saja PHP!

Bagaimana itu bekerja

Kedua bahasa melakukan hal yang sama pada awalnya: iterasi dari 1 hingga n-1, menjaga jumlah berjalan semua angka i yang n% i = 0 .

Apa yang menyebabkan perbedaan perilaku adalah bagian terakhir:

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

Dalam JavaScript, "$n"hanya string literal. Perbandingan >dengan 10melemparkannya ke angka secara implisit, tetapi karena tidak terlihat seperti angka, itu menjadi NaN. NaN memberi false jika dibandingkan dengan angka dengan cara apa pun. Akibatnya, $dselalu dikembalikan.

Namun, dalam PHP, "$n"adalah string yang berisi nilai $n. Ketika PHP melemparkan ini ke angka, itu hanya menjadi nilai $n. Jika lebih besar dari 10, maka 0dikembalikan sebagai ganti $d.

Kucing Bisnis
sumber
7

05AB1E / Jelly ,  9  8 byte

Kode byte (heksadesimal):

d1 a8 4f 71 0d ad 53 fa

Menggunakan halaman kode Jelly menghasilkan hasil yang salah untuk angka berlebihan (mis. Input dari 12 pengembalian 12bukan 16):

ẎƭOqÆḌS«

Cobalah online!

Menggunakan halaman kode 05AB1E menghasilkan hasil yang benar:

ѨOqмλSú

Cobalah online!

Bagaimana?

05AB1E mem-parsing hingga dan termasuk 71( q) yang memerintahkan untuk berhenti dan kemudian berhenti mem- parsing:

Ѩ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 mem-parsing seluruh program di muka sebagai tiga tautan karena efek byte tanpa makna yang ditetapkan, ƭdan qbertindak sebagai pembatas. Titik masuk program adalah tautan terakhirnya:

Ẏ - 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
sumber
Itu 05AB1E / Jelly?
Erik the Outgolfer
Ya, sudah diperbaiki, terima kasih; Saya hanya menulis penjelasannya.
Jonathan Allan
ÆḌSDmenghemat satu byte.
Dennis
@ Dennis Atau lebih baik ÆḌSṚ.
Erik the Outgolfer
@ Dennis - terima kasih, memikirkan cara yang berbeda saat makan :)
Jonathan Allan
6

Python 3 / Python 2 , 64 60 58 byte

Berkat @officialaimm untuk 2 byte off

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

Dalam Python 3 ini memberikan hasil yang benar. Dalam Python 2 ouput salah untuk input yang melebihi 10. Kode mengeksploitasi pembulatan bankir, yang dilakukan oleh Python 3 tetapi tidak oleh Python 2.

Cobalah online! Python 3 (benar), Python 2 (salah untuk n > 10).

Luis Mendo
sumber
Anda tidak perlu [ ].
officialaimm
6

Python 3 / Python 2 , 47 byte

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

Fungsi yang tidak disebutkan namanya, palsu di Python 2.

Cobalah online untuk Python 3 atau Python 2

Dalam Python 2 /adalah pembagian integer dengan argumen integer, sedangkan dalam Python 3 adalah divisi.

Ketika nmelebihi 10 10/n mengevaluasi ke 0 di Python 2, tetapi ke angka positif kecil di Python 3 (ini tentu benar hingga maksimum yang diperlukan setidaknya 10.000 ).

Karena itu 10/n>0mengevaluasi Trueuntuk Python 3 dan range(10/n>0,n)setara dengan range(1,n)sementara di Python 2 10/n>0mengevaluasi Falseketika nmelebihi 10 dimana range(10/n>0,n)menjadi setara dengan range(0,n)menyebabkan n%dupaya untuk melakukan modulo nol aritmatika, menaikkan a ZeroDivisionError.

Jonathan Allan
sumber
5

Jelly / 05AB1E , 12 byte

Apa yang Jelly lihat:

11⁻iẎƭO}qÆḌS

Cobalah online!

Penjelasan:

qtidak didukung dalam Jelly, jadi Jelly hanya "melihat" apa yang terjadi setelah q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

Apa yang dilihat 05AB1E:

11‹iѨO}qмλS

Cobalah online!

Penjelasan:

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

Tentu saja semuanya setelah "berhenti" sebenarnya tidak terjadi.

Erik the Outgolfer
sumber
Saya berharap ÆḌSakan valid sendiri ... Jawaban luar biasa!
Tn. Xcoder
@ Mr.Xcoder Saya tidak yakin bagaimana cara мλSkerjanya di 05AB1E.
Erik the Outgolfer
Tekankan pada yang saya inginkan : P
Mr. Xcoder