Poliglotas da soma do divisor falso

23

A tarefa

Nesse desafio, sua tarefa é escrever um programa em uma linguagem de programação L que recebe um número inteiro positivo n e gera a soma dos divisores adequados de n ( sequência A001065 no OEIS). Ele deve retornar a saída correta para qualquer 1 ≤ n ≤ 10 000 . Aqui estão as 10 primeiras saídas:

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

Além disso, seu programa deve ser um poliglota falso , o que significa o seguinte. É um programa válido em outra linguagem de programação L ' e, para cada entrada 1 ≤ n ≤ 10 (os casos de teste acima), retorna a soma dos divisores adequados de n , mas existem 11 ≤ n ≤ 10 000 para os quais não retorna o resultado correto. Pode retornar algo incorreto, repetir para sempre, travar etc. Pode dar um resultado errado para todos os n ≥ 11 , para alguns deles ou apenas um.

Regras e pontuação

Você pode escrever um programa ou uma função completa e pode ter diferentes meios de entrada e saída nos dois idiomas. A menor contagem de bytes vence. PadrãoAplicam-se as regras . Nesse desafio, diferentes versões principais ou implementações de uma linguagem são consideradas distintas.

Observe que, se você usar linguagens de programação com codificações não ASCII (como muitas fazem neste site), a mesma sequência de bytes deverá ser usada para ambas as linguagens. Isso significa que você deve converter entre páginas de códigos potencialmente diferentes ou sofrer penalidades por caracteres Unicode de vários bytes.

Casos de teste adicionais

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

Respostas:

10

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

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

Demo

Saída

Saída do snippet acima no Chrome e Firefox (todos corretos):

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

Saída no Edge (desligado por 1, começando em n = 11):

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

Por quê?

Nenhum algoritmo é imposto pela especificação do .sort()método. Nem é necessário ser estável. Portanto, cada mecanismo JavaScript usa sua própria implementação.

No entanto, [0,1].sort(x=>x)[0,1] com todos os motores.

Então qual a diferença?

O que está acontecendo aqui é que o Chakra está passando 1como o primeiro parâmetro da primeira (e única) iteração para a função de retorno de chamada (solicitando uma comparação de 1com 0), enquanto V8 e SpiderMonkey estão passando 0(solicitando uma comparação de 0com 1).

Você pode usar o seguinte snippet para verificar o que seu navegador está fazendo.

Arnauld
fonte
1
Esta é uma solução aceitável. Vou esclarecer isso no post principal.
Zgarb 01/08/19
8

Python 2 e Python 3, 58 bytes

TIO para Python 2

TIO para Python 3

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

Ele funciona no python 2, mas para cada n> 10 ele produziria 0 no python 3.
Tudo devido a diferentes abordagens na comparação de strings com bytes:

  • em Python 2 '' == b''
  • em Python 3 '' != b''
Gambá morto
fonte
7

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

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

Nos dois idiomas, essa é uma função anônima. JavaScript fornece o resultado correto, mas o PHP fornece 0 para todos n> = 11 .

Experimente JS!

Experimente o PHP!

Como funciona

Os dois idiomas fazem o mesmo no início: itere de 1 a n-1, mantendo uma soma contínua de todos os números i para os quais n% i = 0 .

O que causa a diferença de comportamento é a parte final:

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

Em JavaScript, "$n"é apenas uma string literal. A comparação >com o 10lança para um número implicitamente, mas como não se parece com um número, torna-se NaN. NaN fornece false quando comparado a um número de qualquer forma. Como resultado, $dé sempre retornado.

No entanto, no PHP, "$n"é uma sequência que contém o valor de $n. Quando o PHP lança isso em um número, ele simplesmente se torna o valor de $n. Se for maior que 10, 0será retornado em vez de $d.

Gato de negócios
fonte
7

05AB1E / Jelly ,  9  8 bytes

O código de bytes (hexadecimal):

d1 a8 4f 71 0d ad 53 fa

O uso da página de códigos de Jelly retorna resultados incorretos para qualquer número excessivo (por exemplo, uma entrada de 12 retornos em 12vez de 16):

ẎƭOqÆḌS«

Experimente online!

O uso da página de códigos do 05AB1E retorna resultados corretos:

ѨOqмλSú

Experimente online!

Quão?

05AB1E analisa até e incluindo o 71( q) que instrui para sair e, em seguida, para de analisar:

Ѩ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

O Jelly analisa o programa inteiro antecipadamente como três links, devido ao efeito dos bytes sem um significado atribuído, ƭe qatuando como delimitadores. O ponto de entrada de um programa é o link final:

Ẏ - 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
fonte
Isso é 05AB1E / Jelly?
Erik the Outgolfer
Sim, fixo, obrigado; Eu estava apenas escrevendo a explicação.
Jonathan Allan
ÆḌSDsalva um byte.
Dennis
@ Dennis Ou melhor ÆḌSṚ.
Erik the Outgolfer
@ Dennis - graças, pensou em uma maneira diferente, enquanto se come :)
Jonathan Allan
6

Python 3 / Python 2 , 64 60 58 bytes

Obrigado a @officialaimm por 2 bytes de desconto

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

No Python 3, isso fornece os resultados corretos. No Python 2, a saída está errada para entradas que excedem 10. O código explora o arredondamento do banqueiro, que é feito pelo Python 3, mas não pelo Python 2.

Experimente online! Python 3 (correto), Python 2 (errado para n > 10).

Luis Mendo
fonte
Você não vai precisar [ ].
officialaimm
6

Python 3 / Python 2 , 47 bytes

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

Uma função sem nome, falsa no Python 2.

Experimente on-line para Python 3 ou Python 2

No Python 2 /é uma divisão inteira com argumentos inteiros, enquanto no Python 3 é uma divisão.

Quando nexcede 10, é 10/n avaliado em 0 no Python 2, mas em um pequeno número positivo no Python 3 (isso certamente é verdade até o máximo exigido de 10.000, no mínimo).

Como tal, 10/n>0avalia Truepara o Python 3 e range(10/n>0,n)é equivalente a range(1,n)enquanto no Python 2 10/n>0avalia Falsequando nexcede 10, quando range(10/n>0,n)se torna equivalente a range(0,n)causar n%da tentativa de executar a aritmética do módulo zero, aumentando a ZeroDivisionError.

Jonathan Allan
fonte
5

Jelly / 05AB1E , 12 bytes

O que Jelly vê:

11⁻iẎƭO}qÆḌS

Experimente online!

Explicação:

qnão é suportado no Jelly, portanto, o Jelly apenas "vê" o que está depois do q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

O que 05AB1E vê:

11‹iѨO}qмλS

Experimente online!

Explicação:

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

É claro que tudo depois de "sair" não acontece realmente.

Erik, o Outgolfer
fonte
Eu gostaria ÆḌSque tivesse sido válido por si só ... Resposta extraordinária!
Mr. Xcoder
@ Mr.Xcoder Não sei ao certo como мλSfuncionaria no 05AB1E.
Erik the Outgolfer
Enfatize o que eu desejo : P
Sr. Xcoder 01/08/19