Fałszywe poligloty sumy dzielników


23

Zadanie

W tym wyzwaniu Twoim zadaniem jest napisanie programu w języku programowania L, który przyjmuje dodatnią liczbę całkowitą n i wyprowadza sumę odpowiednich dzielników n ( sekwencja A001065 na OEIS). Powinien zwrócić poprawny wynik dla dowolnego 1 ≤ n ≤ 10 000 . Oto pierwsze 10 wyników:

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

Co więcej, twój program musi być fałszywym poliglotą , co oznacza: Jest to poprawny program w innym języku programowania L ' i dla każdego wejścia 1 ≤ n ≤ 10 (przypadki testowe powyżej) zwraca sumę właściwych dzielników n , ale istnieje około 11 ≤ n ≤ 10 000, dla których nie zwraca poprawnego wyniku. Może zwrócić coś niepoprawnego, zapętlić na zawsze, zawiesić itp. Może dać zły wynik dla wszystkich n ≥ 11 , dla niektórych lub tylko jednego.

Zasady i punktacja

Możesz napisać pełny program lub funkcję i możesz mieć różne sposoby wprowadzania i wyświetlania w dwóch językach. Wygrywa najniższa liczba bajtów. Obowiązują standardowe zasady . W tym wyzwaniu różne główne wersje lub implementacje języka są uważane za odrębne.

Zauważ, że jeśli używasz języków programowania z kodowaniem innym niż ASCII (jak wiele osób robi to na tej stronie), w obu językach należy użyć tej samej sekwencji bajtów . Oznacza to, że musisz albo konwertować między potencjalnie różnymi stronami kodowymi, albo ponosić kary za wielobajtowe znaki Unicode.

Dodatkowe przypadki testowe

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

Odpowiedzi:


10

JavaScript (ES6), V8 / SpiderMonkey vs Chakra , 66 63 bajtów

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

Próbny

Wydajność

Dane wyjściowe powyższego fragmentu w Chrome i Firefox (wszystkie są prawidłowe):

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

Wyjście na zboczu (wyłączone o 1, począwszy od n = 11):

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

Czemu?

Specyfikacja .sort()metody nie narzuca algorytmu . Nie jest nawet wymagana stabilność. Dlatego każdy silnik JavaScript korzysta z własnej implementacji.

Jednak [0,1].sort(x=>x)daje [0,1]ze wszystkimi silnikami.

Jaka jest różnica?

Chakra przekazuje 1jako pierwszy parametr pierwszej (i jedynej) iteracji do funkcji wywołania zwrotnego (prosząc o porównanie 1z 0), podczas gdy V8 i SpiderMonkey przechodzą 0(prosząc o porównanie 0z 1).

Możesz użyć następującego fragmentu kodu, aby sprawdzić, co robi Twoja przeglądarka.


1
To jest akceptowalne rozwiązanie. Wyjaśnię to w głównym poście.
Zgarb

8

Python 2 i Python 3, 58 bajtów

TIO dla Python 2

TIO dla Python 3

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

Działa w Pythonie 2, ale dla każdego n> 10 wyświetla 0 w Pythonie 3.
Wszystko z powodu różnych podejść do porównywania ciągów z bajtami:

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

7

JavaScript (Node.js) i PHP , 73 70 bajtów

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

W obu językach jest to funkcja anonimowa. JavaScript daje poprawny wynik, ale PHP daje 0 dla wszystkich n> = 11 .

Wypróbuj JS!

Wypróbuj PHP!

Jak to działa

Oba języki na początku robią to samo: iterują od 1 do n-1, zachowując bieżącą sumę wszystkich liczb i, dla których n% i = 0 .

To, co powoduje różnicę w zachowaniu, to ostatnia część:

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

W JavaScript "$n"jest dosłownie ciągiem znaków. Porównanie >z 10rzutuje domyślnie na liczbę, ale ponieważ nie wygląda jak liczba, staje się NaN. NaN daje fałsz w porównaniu z liczbą w jakikolwiek sposób. W rezultacie $dzawsze jest zwracany.

Jednak w PHP "$n"jest ciągiem zawierającym wartość $n. Kiedy PHP rzuca to na liczbę, staje się po prostu wartością $n. Jeśli jest większy niż 10, to 0jest zwracane zamiast $d.


7

05AB1E / galaretka ,  9  8 bajtów

Kod bajtowy (szesnastkowy):

d1 a8 4f 71 0d ad 53 fa

Użycie strony kodowej Jelly zwraca nieprawidłowe wyniki dla dowolnej nadmiernej liczby (np. Wprowadzenie 12 zwraca 12zamiast 16):

ẎƭOqÆḌS«

Wypróbuj online!

Użycie strony kodowej 05AB1E zwraca prawidłowe wyniki:

ѨOqмλSú

Wypróbuj online!

W jaki sposób?

05AB1E analizuje do włącznie 71( q), która nakazuje wyjść, a następnie przestaje analizować:

Ѩ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

Galaretka analizuje cały program z góry jako trzy łącza ze względu na działanie bajtów bez przypisanego znaczenia ƭi qdziałające jako ograniczniki. Punktem wejścia programu jest jego ostatni link:

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

To 05AB1E / Galaretka?
Erik the Outgolfer

Tak, naprawione, dzięki; Właśnie pisałem wyjaśnienie.
Jonathan Allan

ÆḌSDzapisuje bajt.
Dennis

@Dennis Lub lepiej ÆḌSṚ.
Erik the Outgolfer

@Dennis - dzięki, pomyślałem o innym sposobie jedzenia :)
Jonathan Allan

6

Python 3 / Python 2 , 64 60 58 bajtów

Dzięki @officialaimm za 2 bajty wyłączone

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

W Pythonie 3 daje to prawidłowe wyniki. W Pythonie 2 wyjście jest niepoprawne dla wejść przekraczających 10. Kod wykorzystuje zaokrąglanie bankiera, które jest wykonywane przez Python 3, ale nie przez Python 2.

Wypróbuj online! Python 3 (poprawny), Python 2 (niewłaściwy dla n > 10).


Nie trzeba będzie [ ].
officialaimm

6

Python 3 / Python 2 , 47 bajtów

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

Funkcja nienazwana, fałszywa w Pythonie 2.

Wypróbuj online dla Python 3 lub Python 2

W Pythonie 2 /jest dzielenie całkowite z argumentami liczb całkowitych, podczas gdy w Pythonie 3 jest to dzielenie.

Gdy nprzekracza 10, w Pythonie 2 10/njest 0 , ale do małej dodatniej liczby w Pythonie 3 (jest to z pewnością prawda do maksymalnej wymaganej liczby co najmniej 10 000 ).

Jako takie 10/n>0Zwraca TruePythona 3 i range(10/n>0,n)odpowiada range(1,n), podczas gdy w Pythonie 2 10/n>0ocenia się False, gdy nprzekracza 10, w wyniku czego range(10/n>0,n)staje się odpowiednikiem range(0,n)powodując n%dpróba wykonania arytmetyka modulo zera, unosząc ZeroDivisionError.


5

Galaretka / 05AB1E , 12 bajtów

Co widzi Jelly:

11⁻iẎƭO}qÆḌS

Wypróbuj online!

Wyjaśnienie:

qnie jest obsługiwany w Jelly, więc Jelly „widzi” tylko to, co następuje po q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

Co widzi 05AB1E:

11‹iѨO}qмλS

Wypróbuj online!

Wyjaśnienie:

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

Oczywiście wszystko po „wyjściu” tak naprawdę się nie dzieje.


Chciałbym, żeby ÆḌSbył ważny sam ... Niezwykła odpowiedź!
Pan Xcoder

@ Mr.Xcoder Nie jestem pewien, jak мλSdziałałoby to w 05AB1E.
Erik the Outgolfer

Podkreśl, że życzę : P
Pan Xcoder
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.