Redefinir operadores para definir funciones
La redefinición de operadores puede guardar muchos bytes entre paréntesis y comas.
Operadores unarios recursivos
Para un ejemplo unario, compare las siguientes implementaciones recursivas de la secuencia de Fibonacci:
F(n)=n>1?F(n-1)+F(n-2):n # 24 bytes
!n=n>1?!~-n+!(n-2):n # 20 bytes
!n=n>1?!~-n+!~-~-n:n # 20 bytes
Pruébalo en línea!
El operador redefinido conserva su precedencia inicial.
Tenga en cuenta que no podríamos simplemente cambiar a !
favor de ~
, ya ~
que ya está definido para enteros, mientras !
que solo está definido para booleanos.
Operadores binarios
Incluso sin recurrencia, redefinir un operador es más corto que definir una función binaria. Compare las siguientes definiciones de una prueba de divisibilidad simple.
f(x,y)=x==0?y==0:y%x==0 # 23 bytes
(x,y)->x==0?y==0:y%x==0 # 23 bytes
x->y->x==0?y==0:y%x==0 # 22 bytes
x\y=x==0?y==0:y%x==0 # 20 bytes
Pruébalo en línea!
Operadores binarios recursivos
A continuación se ilustra cómo redefinir un operador binario para calcular la función de Ackermann:
A(m,n)=m>0?A(m-1,n<1||A(m,n-1)):n+1 # 35 bytes
^ =(m,n)->m>0?(m-1)^(n<1||m^~-n):n+1 # 36 bytes
| =(m,n)->m>0?m-1|(n<1||m|~-n):n+1 # 34 bytes
m\n=m>0?~-m\(n<1||m\~-n):n+1 # 28 bytes
Pruébalo en línea!
Tenga en cuenta que ^
es incluso más largo que usar un identificador regular, ya que su precedencia es demasiado alta.
Como se mencionó antes
m|n=m>0?m-1|(n<1||m|~-n):n+1 # 28 bytes
no funcionaría para argumentos enteros, ya |
que ya está definido en este caso. La definición de enteros se puede cambiar con
m::Int|n::Int=m>0?m-1|(n<1||m|~-n):n+1 # 38 bytes
Pero eso es prohibitivamente largo. Sin embargo, se hace el trabajo si se pasa un flotador como argumento izquierdo y un entero como argumento de la derecha.