Поліглоти підробленої суми дільника


23

Завдання

У цьому завданні ваше завдання полягає в тому, щоб написати програму мовою програмування L, яка приймає додатне ціле число n , і виводить суму власних дільників n ( послідовність A001065 на OEIS). Він повинен повернути правильний вихід для будь-яких 1 ≤ n ≤ 10 000 . Ось перші 10 виходів:

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

Крім того, у вашій програмі повинен бути фальшивий поліглот , що означає наступне. Це дійсна програма іншою мовою програмування L ' , і для кожного введення 1 ≤ n ≤ 10 (тестові випадки вище) вона повертає суму належних дільників n , але існує близько 11 ≤ n ≤ 10 000, для яких це не повертає правильний результат. Він може повернути щось неправильне, назавжди цикл, збій і т. Д. Це може дати неправильний результат для всіх n ≥ 11 , для деяких з них або лише одного.

Правила та оцінка

Ви можете написати повну програму або функцію, і ви можете мати різні засоби введення та виведення на двох мовах. Виграє найменший байт. Діють стандартні правила . У цьому виклику розглядаються різні основні версії або реалізації мови.

Зауважте, що якщо ви використовуєте мови програмування з кодуваннями, що не належать до ASCII (як це робиться на цьому сайті), для обох мов повинна використовуватися однакова послідовність байтів . Це означає, що вам потрібно або конвертувати між потенційно різними кодовими сторінками, або понести штрафи за багатобайтові символи Unicode.

Додаткові тестові випадки

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

Відповіді:


10

JavaScript (ES6), V8 / SpiderMonkey vs Chakra , 66 63 байт

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

Демо

Вихід

Вихід вищевказаного фрагмента для Chrome і Firefox (все правильно):

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

Вихід на край (вимкнено на 1, починаючи з n = 11):

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

Чому?

Ніякі алгоритми не накладаються специфікацією .sort()методу. Це навіть не потрібно, щоб бути стабільним. Тому кожен механізм JavaScript використовує власну реалізацію.

Однак [0,1].sort(x=>x)дає [0,1]з усіма двигунами.

То яка різниця?

Тут відбувається те, що Чакра переходить 1як перший параметр першої (і єдиної) ітерації до функції зворотного виклику (запитуючи порівняння 1з 0), тоді як V8 та SpiderMonkey проходять 0(запитуючи порівняння 0з 1).

Ви можете використовувати наступний фрагмент, щоб перевірити, що робить ваш браузер.


1
Це прийнятне рішення. Я уточню це в головному дописі.
Згарб

8

Python 2 та Python 3, 58 байт

TIO для Python 2

TIO для Python 3

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

Він працює в python 2, але для кожного n> 10 він виводить 0 у python 3.
Все через різні підходи при порівнянні рядків з байтами:

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

7

JavaScript (Node.js) та PHP , 73 70 байт

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

В обох мовах це анонімна функція. JavaScript дає правильний результат, але PHP дає 0 для всіх n> = 11 .

Спробуйте JS!

Спробуйте PHP!

Як це працює

Спочатку обидві мови роблять те саме: ітерайте від 1 до n-1, зберігаючи загальну суму всіх чисел i, для яких n% i = 0 .

Що викликає різницю в поведінці - це заключна частина:

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

У JavaScript - "$n"це просто літеральний рядок. Порівняння >з 10кидає його числом неявно, але оскільки воно не схоже на число, воно стає NaN. NaN дає хибне порівняння з числом будь-яким способом. Як результат, $dзавжди повертається.

Однак у PHP "$n"- це рядок, що містить значення $n. Коли PHP передає це число, воно просто стає значенням $n. Якщо це більше, ніж 10, то 0повертається замість $d.


7

05AB1E / желе ,  9  8 байт

Байт-код (шістнадцятковий):

d1 a8 4f 71 0d ad 53 fa

Використання кодової сторінки Jelly повертає невірні результати для будь-якої надмірної кількості (наприклад, введення з 12 повернень, 12а не 16):

ẎƭOqÆḌS«

Спробуйте в Інтернеті!

Використання кодової сторінки 05AB1E повертає правильні результати:

ѨOqмλSú

Спробуйте в Інтернеті!

Як?

05AB1E аналізує до та включаючи 71( q), який вказує вийти, а потім зупиняє розбір:

Ѩ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 розбирає всю програму наперед, як три ланки завдяки ефекту байтів без присвоєного значення, ƭі qвиступає в якості роздільників. Місце вступу програми - це остаточне посилання:

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

Це 05AB1E / желе?
Erik the Outgolfer

Так, виправлено, спасибі; Я просто писав пояснення.
Джонатан Аллан

ÆḌSDзберігає байт.
Денніс

@Dennis Або краще ÆḌSṚ.
Erik the Outgolfer

@Dennis - дякую, подумав інший спосіб під час їжі :)
Джонатан Аллан

6

Python 3 / Python 2 , 64 60 58 байт

Завдяки @officialaimm за 2 байти

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

У Python 3 це дає правильні результати. У Python 2 вихідне значення неправильне для входів, що перевищують 10. Код використовує округлення банкіра, яке робиться Python 3, але не Python 2.

Спробуйте в Інтернеті! Python 3 (правильно), Python 2 (неправильно n > 10).


Вам не знадобиться [ ].
officialaimm

6

Python 3 / Python 2 , 47 байт

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

Безіменна функція, підроблена в Python 2.

Спробуйте в Інтернеті для Python 3 або Python 2

У Python 2 /- ціле ділення з цілими аргументами, тоді як у Python 3 - це ділення.

При nперевищенні 10 10/n оцінюється до 0 в Python 2, але до малого додатного числа в Python 3 (це, безумовно, справедливо до максимуму, необхідного 10,000 принаймні).

Як такий 10/n>0оцінюється Trueдля Python 3 і range(10/n>0,n)є еквівалентом, range(1,n)коли в Python 2 10/n>0оцінюється, Falseколи nперевищує 10, після чого range(10/n>0,n)стає еквівалентним range(0,n)викликати n%dспробу виконання арифметики за нульовим модулем, піднімаючи a ZeroDivisionError.


5

Желе / 05AB1E , 12 байт

Що бачить Джеллі:

11⁻iẎƭO}qÆḌS

Спробуйте в Інтернеті!

Пояснення:

qне підтримується в Jelly, тому Jelly лише "бачить", що після цього q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

Що бачить 05AB1E:

11‹iѨO}qмλS

Спробуйте в Інтернеті!

Пояснення:

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

Звичайно, все після "виходу" насправді не відбувається.


Я хотів ÆḌSби, щоб він був дійсним самостійно ... Надзвичайна відповідь!
Містер Xcoder

@ Mr.Xcoder Я не впевнений, як мλSби працювати у 05AB1E.
Erik the Outgolfer

Підкресліть бажаю : P
Містер Xcoder
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.