Поддельные делители суммы полиглотов


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 (как это делают многие на этом сайте), для обоих языков должна использоваться одинаковая последовательность байтов . Это означает, что вы должны либо конвертировать между потенциально разными кодовыми страницами, либо подвергаться штрафам за многобайтовые символы Юникода.

Дополнительные тестовые случаи

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

Ответы:


10

JavaScript (ES6), V8 / SpiderMonkey против чакры , 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]

Выход на Edge (выкл на 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]со всеми двигателями.

Так в чем же разница?

Здесь происходит то, что Chakra передает 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

Используя кодовую страницу Jellÿ по возвращает неправильные результаты для любого избыточного количества (например , ввод 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 / Jelly?
Эрик Outgolfer

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

ÆḌSDсохраняет байт.
Деннис

@ Денис Или лучше ÆḌSṚ.
Эрик 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бы, чтобы он действовал сам по себе ... Необычный ответ!
Мистер Кскодер

@ Mr.Xcoder Я не уверен, как мλSбудет работать в 05AB1E.
Эрик Outgolfer

Подчеркну, что я хочу : P
г-н Xcoder
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.