Divisores falsos suma políglotas

23

La tarea

En este desafío, su tarea es escribir un programa en un lenguaje de programación L que tome un entero positivo n , y genere la suma de los divisores apropiados de n ( secuencia A001065 en OEIS). Debería devolver la salida correcta para cualquier 1 ≤ n ≤ 10 000 . Aquí están las primeras 10 salidas:

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

Además, su programa debe ser un políglota falso , lo que significa lo siguiente. Es un programa válido en otro lenguaje de programación L ' , y para cada entrada 1 ≤ n ≤ 10 (los casos de prueba anteriores), devuelve la suma de divisores propios de n , pero existen unos 11 ≤ n ≤ 10 000 para los cuales No devuelve el resultado correcto. Puede devolver algo incorrecto, repetirse para siempre, bloquearse, etc. Puede dar un resultado incorrecto para todos los n ≥ 11 , para algunos de ellos o solo uno.

Reglas y puntaje

Puede escribir un programa completo o una función, y puede tener diferentes medios de entrada y salida en los dos idiomas. El conteo de bytes más bajo gana. Aplican reglas estándar de . En este desafío, las diferentes versiones principales o implementaciones de un lenguaje se consideran distintas.

Tenga en cuenta que si usa lenguajes de programación con codificaciones que no sean ASCII (como lo hacen muchos en este sitio), se debe usar la misma secuencia de bytes para ambos idiomas. Esto significa que debe convertir entre páginas de códigos potencialmente diferentes o sufrir penalizaciones por caracteres Unicode de varios bytes.

Casos de prueba adicionales

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

Respuestas:

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

Manifestación

Salida

Salida del fragmento anterior en Chrome y Firefox (todo correcto):

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

Salida en Edge (apagado en 1, comenzando en n = 11):

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

¿Por qué?

La especificación del .sort()método no impone ningún algoritmo . Ni siquiera se requiere que sea estable. Por lo tanto, cada motor de JavaScript utiliza su propia implementación.

Sin embargo, [0,1].sort(x=>x)da [0,1]con todos los motores.

Entonces, ¿cuál es la diferencia?

Lo que sucede aquí es que Chakra está pasando 1como el primer parámetro de la primera (y única) iteración a la función de devolución de llamada (solicitando una comparación de 1con 0), mientras que V8 y SpiderMonkey están pasando 0(solicitando una comparación de 0con 1).

Puede usar el siguiente fragmento para verificar qué está haciendo su navegador.

Arnauld
fuente
1
Esta es una solución aceptable. Lo aclararé en la publicación principal.
Zgarb
8

Python 2 y 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)

Funciona en python 2, pero por cada n> 10 generaría 0 en python 3.
Todo debido a diferentes enfoques en la comparación de cadenas con bytes:

  • en Python 2 '' == b''
  • en Python 3 '' != b''
Zarigüeya muerta
fuente
7

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

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

En ambos idiomas, esta es una función anónima. JavaScript da el resultado correcto, pero PHP da 0 para todos n> = 11 .

Pruébalo JS!

Pruébalo PHP!

Cómo funciona

Al principio, ambos idiomas hacen lo mismo: iterar de 1 a n-1, manteniendo una suma de todos los números i para los cuales n% i = 0 .

Lo que causa la diferencia en el comportamiento es la parte final:

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

En JavaScript, "$n"es solo un literal de cadena. La comparación> con 10lo convierte en un número implícitamente, pero como no parece un número, se convierte en NaN. NaN da falso en comparación con un número de cualquier manera. Como resultado,$d siempre se devuelve.

Sin embargo, en PHP, "$n"es una cadena que contiene el valor de $n. Cuando PHP convierte esto en un número, simplemente se convierte en el valor de $n. Si es mayor que 10, entonces 0se devuelve en lugar de $d.

Gato de negocios
fuente
7

05AB1E / Jelly ,  9  8 bytes

El código de bytes (hexadecimal):

d1 a8 4f 71 0d ad 53 fa

El uso de la página de códigos de Jelly devuelve resultados incorrectos para cualquier número excesivo (por ejemplo, una entrada de 12 retornos en 12lugar de 16):

ẎƭOqÆḌS«

Pruébalo en línea!

El uso de la página de códigos de 05AB1E devuelve resultados correctos:

ѨOqмλSú

Pruébalo en línea!

¿Cómo?

05AB1E analiza hasta e incluye el 71( q) que le indica que salga y luego detiene el análisis:

Ѩ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 analiza todo el programa por adelantado como tres enlaces debido al efecto de los bytes sin un significado asignado ƭy qactuando como delimitadores. El punto de entrada de un programa es su enlace 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
fuente
Eso es 05AB1E / Jelly?
Erik the Outgolfer
Sí, arreglado, gracias; Estaba escribiendo la explicación.
Jonathan Allan
ÆḌSDGuarda un byte.
Dennis
@ Dennis O mejor ÆḌSṚ.
Erik the Outgolfer
@Dennis - gracias, pensé en una forma diferente mientras comía :)
Jonathan Allan
6

Python 3 / Python 2 , 64 60 58 bytes

Gracias a @officialaimm por 2 bytes de descuento

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

En Python 3 esto da los resultados correctos. En Python 2, la salida es incorrecta para entradas que exceden10 . El código explota el redondeo de los banqueros, hecho por Python 3 pero no por Python 2.

Pruébalo en línea! Python 3 (correcto), Python 2 (incorrecto para n > 10).

Luis Mendo
fuente
No lo necesitarás [ ].
officialaimm
6

Python 3 / Python 2 , 47 bytes

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

Una función sin nombre, falsa en Python 2.

Pruébelo en línea para Python 3 o Python 2

En Python 2 /es división entera con argumentos enteros, mientras que en Python 3 es división.

Cuando nexcede 10 se 10/n evalúa a 0 en Python 2, pero a un pequeño número positivo en Python 3 (esto es cierto hasta el máximo requerido de 10,000 al menos).

Como tal, se 10/n>0evalúa Truepara Python 3 y range(10/n>0,n)es equivalente a range(1,n)mientras que en Python 2 se 10/n>0evalúa Falsecuando nexcede 10, con lo cual se range(10/n>0,n)convierte en equivalente a range(0,n)hacer n%dque se intente realizar una aritmética de módulo cero, elevando a ZeroDivisionError.

Jonathan Allan
fuente
5

Jalea / 05AB1E , 12 bytes

Lo que ve Jelly:

11⁻iẎƭO}qÆḌS

Pruébalo en línea!

Explicación:

qes admitido en la jalea, jalea de manera única "ve" lo que hay después de la q.

ÆḌS
ÆḌ  Proper divisors
  S Sum

Lo que ve 05AB1E:

11‹iѨO}qмλS

Pruébalo en línea!

Explicación:

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

Por supuesto, todo después de "dejar de fumar" en realidad no sucede.

Erik el Outgolfer
fuente
Ojalá ÆḌShubiera sido válido por sí solo ... ¡Respuesta extraordinaria!
Sr. Xcoder
@ Mr.Xcoder No estoy seguro de cómo мλSfuncionaría en 05AB1E.
Erik the Outgolfer
Enfatice en Deseo : P
Sr. Xcoder