¿Cuál es la forma más corta en que podemos expresar la función?
f(a,b)(c,d)=(a+c,b+d)
en notación sin punto?
pointfree.io nos da
uncurry (flip flip snd . (ap .) . flip flip fst . ((.) .) . (. (+)) . flip . (((.) . (,)) .) . (+))
que con un poco de trabajo se puede acortar a
uncurry$(`flip`snd).((<*>).).(`flip`fst).((.).).(.(+)).flip.(((.).(,)).).(+)
por 76 bytes. Pero esto todavía parece muy largo y complejo para una tarea tan simple. ¿Hay alguna forma de expresar la suma por pares como una función sin puntos más corta?
Para que quede claro lo que quiero decir con punto libre, una declaración de punto libre de una función implica tomar funciones y operadores existentes y aplicarlos entre sí de tal manera que se cree la función deseada. Acentos abiertos, paréntesis y valores literales ( []
, 0
, [1..3]
, etc.) son permitidos, pero como palabras clave where
y let
no lo son. Esto significa:
No puede asignar ninguna variable / función
No puedes usar lambdas
No puedes importar
(+)***(+)
.(+)<$>([1],2)<*>([3],4)
da([1,3],6)
.Respuestas:
44 bytes
Tengo esto de
\x y -> (fst x + fst y, snd x + snd y)
Pruébalo en línea!
fuente
44 bytes
-8 bytes gracias a Ørjan Johansen. -3 bytes gracias a Bruce Forte.
Pruébalo en línea!
Se traduce a:
67 bytes
-8 bytes gracias a Ørjan Johansen. -1 byte gracias a Bruce Forte.
Si se requiere salida de tupla:
Pruébalo en línea!
Sí, yo hacerlo manualmente no produce fruta madura. Pero estoy contento con la
[a] → (a, a)
conversión.Ahora si hubiera una función corta con
m (a → b) → a → m b
.fuente
mapM id[fst,snd]
es más corto.mapM id
es la versión de golf de la función que probablemente estás buscandosequence
.(<*>)
la firma que esm (a → b) → m a → m b
. Tan cerca ...Control.Lens.??
, que puede haber sido propuesto para su inclusión en la base en algún momento.(.mapM id[fst,snd])
like repetidolet r=(.mapM id[fst,snd]) in r(r.zipWith(+))
, pero no he podido hacer que el typechecker acepte una versión sin puntos.54 bytes
Sinceramente, dudo que superemos la solución de 44 bytes de @ H.PWiz, pero nadie estaba usando el hecho de que
(,)
implementa la clase de tipoFunctor
, así que aquí hay otra interesante que no está tan mal:Pruébalo en línea!
Explicación
La implementación de la clase de tipo
Functor
para 2 -Tuplas es muy similar a la deEither
(desde base-4.10.1.0 ):Lo que esto significa para este desafío es que la siguiente función agrega los segundos elementos mientras mantiene el primer elemento del segundo argumento:
Entonces, si solo obtuviéramos un poco de ayuda
helpPlz = \a b -> (fst a+fst b,snd b)
, podríamos hacer(helpPlz<*>).flip(fmap.(+).snd)
y estaríamos listos. Afortunadamente tenemos la herramientapointfree
que nos brinda:Entonces, simplemente volviendo a conectar esa función llegamos a la solución anterior (tenga en cuenta que
(<*>) = ap
está en la base ).fuente
60 bytes
No veo ningún
uncurry
amor aquí, así que pensé en aparecer y arreglar eso.Pensé, con todo el
fst
ysnd
, que desempacar los argumentos conuncurry
podría arrojar algunos resultados. Claramente, no fue tan fructífero como esperaba.fuente
uncurry
Es muy detallado. :( Pero puedes reemplazar los paréntesis más externos con$
.