Su empresa recién está comenzando un proyecto, y por primera vez decidió usar un estilo de código de programación funcional. Sin embargo, su jefe es muy inseguro y no quiere usar funciones integradas, y requiere que implemente las funciones principales. En particular, es necesario escribir las funciones: Map
, Nest
, Apply
, Range
, Fold
y Table
en un idioma de su elección. El jefe es un hombre muy ocupado, y quiere tener los programas lo más cortos posible, para no perder el tiempo leyendo. También le gustaría que no use bucles, por lo tanto, tendrá una reducción del 10% en el recuento de bytes por no usar bucles.
Los requisitos detallados de las funciones están a continuación:
Mapa
La Map
función toma dos parámetros: f
y list
where f
es una función y list
es una lista de valores. Debe devolver el f
aplicado a cada elemento de list
. Por lo tanto, funcionará como tal:
Map(f,{a,b,c})
devoluciones
{ f(a), f(b), f(c) }
y
Map(f, {{a,b},{b,c}})
devoluciones
{ f({a,b}), f({b,c})}
Nido
La Nest
función toma tres parámetros, así: f
, arg
, times
donde f
es una función, arg
es su argumento de partida, y times
es cuántas veces se aplica la función. Debería devolver una expresión con tiempos f
aplicados times
a arg
. Por lo tanto, funcionará como tal:
Nest(f, x, 3)
devoluciones
f(f(f(x)))
y
Nest(f, {a,b}, 3)
devoluciones
f(f(f({a,b})))
Aplicar
La Apply
función toma dos parámetros: f
y args
dónde f
es una función y args
una lista. Debería aplicarse f
a la args
. Por lo tanto:
Apply(f, {a,b,c})
devoluciones
f(a,b,c)
Distancia
La Range
función toma un entero r
y genera los enteros hasta ese número. Por lo tanto:
Range(5)
devoluciones
{ 1, 2, 3, 4, 5}
Doblez
La Fold
función toma tres parámetros f
, arg
, others
donde f
es una función, arg
es un parámetro simple, y others
una lista. Funcionará como tal:
Fold(f, x, {a, b, c, d})
devoluciones
f(f(f(f(x,a),b),c),d)
Mesa
Las funciones de la tabla deben tomar una función f
y un parámetro llamado iterator
en la forma: {iMin, iMax}
donde iMin
y iMax
son enteros. Debe aplicar f
sobre el rango especificado. Por lo tanto:
Table(f, {0, 5})
devoluciones
{f(0), f(1), f(2), f(3), f(4), f(5)}
He usado la definición de estas funciones de la página de programación funcional de Mathematica , así que dirígete allí si necesitas más orientación. Tenga en cuenta que no necesitará implementar todas las versiones de las funciones que se muestran en esa página, sino solo aquellas escritas en esta publicación.
Las lagunas estándar no se permiten como de costumbre.
En caso de que su lenguaje no permita que las funciones se pasen como argumentos, debe implementar esta capacidad y agregarla a su respuesta. Sin embargo, el recuento de bytes de esta operación no se agregará al total.
Este es el código de golf, por lo que gana el código más corto. ¡¡¡Buena suerte!!!
fuente
Table
funciona aquí. ¿Se supone que es tu ejemploTable(f, {x, 0, 5})
? Tampoco entiendo el propósitox
, ya que solo aplica la función al rango.Respuestas:
Haskell,
muchos bytes anteriores cuentan127 * 0.9 = 114.3 bytesSin bucles, solo recursión.
#
es el mapa:(*2) # [1,2,3]
->[2,4,6]
&
es nido:((*2) & 3) 4
->48
i
se aplica:i (*2) 7
->14
r
es rango:r 4
->[1,2,3,4]
?
se pliega:((+) ? 0) [1,2,3,4]
->10
%
es la tabla:(*2) % (2,4)
->[4,6,8]
Según lo solicitado, una versión no golfista con comentarios. Tenga en cuenta,
&
y?
son operadores infijos ternarios, que requieren paréntesis adicionales cuando se los llama o el patrón coincide.Gracias a @dfeuer y @Zgarb por algunos consejos útiles
fuente
m#q=reverse$f((:).m)[]q
. Esta es la misma longitud que la tuya, pero mucho más difícil de leer.!
por lo que es un nombre en lugar de un operador:i f=f
.Python 2, 305.1 bytes (-10%
376369366349339 bytes)Cuando se expande, equivalente a:
No hay bucles!
Bueno, hace mucho trabajo
eval
y si tu jefe no puede soportar los bucles, ODIA la evaluación. Pero van a tener que soportarloSe
range
aprecia una forma de hacerlo en una lambda, así que no tengo que hacer ninguna función (Shudder).Explicaciones:
m=lambda f,l:eval("["+"f(l.pop()),"*len(l)+"][::-1]")
n=lambda f,x,l:eval("f("*l+"*x"+")"*l)
r=lambda i:e("r(i-1)+"*(i>1)+"[i]")
eval
edite, devuelva[0]
o utilice la recursividad para obtener los resultados anteriores y agregue el índice actual a la lista. Lo evalúaa=lambda f,a:eval("f(a["+
r (len (a))[1:-1].replace(",","-1],a[")+"-1])")
a
. Lo evalúa!f=lambda f,x,l:eval("f("*len(l)+"x,["+
r (len (l))[1:-1].replace(",","-1]),l[")+"-1])")
t=lambda f,n,x:eval("[f("+
r (x) [n-1:].replace(",","),f(")[1:-1]+")]")
Mapa, nido, rango, aplicar, doblar, tabla.
Gracias @ Zgarb por una lambda para el rango!
fuente
r=lambda i:[]if i<1 else r(i-1)+[i]
? Sin bucles, solo recursión.eval
para mostrarles cómo los bucles no son tan malos :)e=eval
:r=lambda i:e("r(i-1)+"*(i>1)+"[i]")
Javascript ES6, 197 * 0.9 = 177.3 bytes
Mapa (
M=(f,l)=>F((a,b)=>[...a,f(b)],[],l)
):Utiliza Fold para concatenar los resultados de
f
aplicado a cada miembro del
en una lista vacía. El uso de funciones integradas reduce esto aM=(f,l)=>l.map(f)
(¿no lo usó porque parece barato ...?).Nido (
N=(f,x,n)=>f(--n?N(f,x,n):x)
):Aplicar de forma
f
recursiva hasta quen
se reduzca a 0.Aplicar (
A=(f,l)=>f(...l)
):Utiliza la propagación (
...
operador) para aplicarl
af
.Rango (
R=n=>n--?[...R(n),n+1]:[]
):Concat
n
a llamada recursiva de Range hasta quen
se reduzca a 0.Doblar (
F=(f,x,l,n=l.length)=>n--?f(F(f,x,l,n),l[n]):x
):Se aplica la llamada recursiva de doblez y la
n
-ésimo elemento de lal
af
hasta quen
se decrementa a 0. El uso de las funciones integradas reduce a estoF=(f,x,l)=>l.reduce(f,x)
(de nuevo, barato parecido ...).Tabla (
T=(f,i)=>([n,x]=i,M(q=>f(q+n-1),R(x-n+1)))
):Primero se inicializa
n
yx
en iMin e iMax usando destructuring ([n,x]=i
), luego usa Range para construir la tabla de valores de iMin a iMax.f
luego se aplica sobre la tabla usando Map y se devuelve el resultadofuente
Python 3, 218 bytes
La versión ilegible:
La versión (más) legible:
Yendo aunque sea una lambda a la vez:
Función de mapa
P
P=lambda f,x:[f(_)for _ in x]
Solo un simple iterador. No hay mucho que decir aquí.
Función de nido
Y
Y=lambda f,x,z:Y(f,f(x),z-1)if z else x
Recurrente hasta llegar a
z
cero, aplicandof
cada vez. La cláusula if al final se siente torpe; Quizás haya una mejor manera de terminar con la recursión.Aplicar función
T
T=lambda f,x:f(*x)
Python tiene un buen operador de expansión para hacer todo el trabajo pesado por mí.
Función de rango
H
H=lambda f,x=0:(H(f-1)if~-f else[])+[f]
Este fue más difícil de lo que esperaba. Terminé tomando un enfoque recursivo. Nuevamente, la construcción if-else ocupa muchos bytes, y creo que se puede mejorar. ¿Por qué tiene un muñeco
x=0
, preguntas? Es así que cuando lo comprimo con elexec
, puedo reemplazarlo en=lambda f,x
lugar de solo=lambda f
.Función de plegado
O
O=lambda f,x,z:O(f,f(x,z[0]),z[1:])if z else x
Muy contento con este. Simplemente corta el primer elemento de la matriz cada vez que se repite, hasta que no quede nada.
Función de tabla
N
N=lambda f,x:(N(f,[x[0],x[1]-1])if x[1]-x[0]else[])+[f(x[1])]
Este es horrible y estoy seguro de que hay margen de mejora. Intenté usar las funciones de rango y mapa previamente definidas para una
map(f,range(x,y))
especie de construcción, pero sin mucho éxito. Terminé haciendo un enfoque recursivo terrible que comparte cierta similitud con la función de rango.Todas las lambdas están envueltas en una
exec
con unareplace
para acortar significativamente el recuento de bytes.fuente
[f(_)for _ in x]
podría acortarsemap(f,x)
, pero luego recordé cuál era el desafíoJulia, 181 bytes
No hay bonificación para mí; Usé bucles generosamente. Lo siento jefe, pero los bucles en Julia son eficientes.
Agregar los puntos suspensivos después de un argumento a una función rompe una matriz, tupla o lo que sea que tenga en argumentos de funciones regulares. De lo contrario, la función pensará que está intentando pasar una matriz (o tupla, etc.). No tiene ningún efecto para argumentos únicos.
Nombres de funciones:
M
N
A
R
F
T
fuente
tinylisp , 325 * 0.9 = 292.5
El lenguaje es más nuevo que la pregunta, pero no va a ganar de todos modos.
Define las funciones
A
(aplicar),M
(mapa),N
(anidar),R
(rango),T
(tabla) yF
(plegar), junto con un par de funciones auxiliares.T
espera una lista de dos enteros para su segundo argumento.Tinylisp ni siquiera tiene construcciones de bucle; todo se logra utilizando la recursividad. Varias de estas funciones no son recursivas de la cola , por lo que si las llama en listas grandes, probablemente arruinarán la pila de llamadas. Todos podrían implementarse con recursión de cola ... pero tomaría más bytes, y este es el código de golf.
Aquí hay una versión ampliada con espacios en blanco y palabras reales para los nombres, que deberían ser bastante legibles si está familiarizado con Lisp. (He alias la mayoría de las construcciones de tinylisp excepto
q
(cita) yi
(si)).Explicación adicional disponible a pedido.
Salida de muestra
Utiliza el entorno REPL de mi implementación de referencia. Usé
q
(cita) para la función unaria ys
(resta) como la función binaria para estos ejemplos, así como la función@
(definida en este código) que devuelve una lista de sus argumentos.fuente
Python 2.x: 450,6 bytes (493 bytes antes del 10% de descuento)
Respuesta de golf:
Esta pregunta fue divertida. Decidí escribir mis funciones sin usar los equivalentes de Python (aunque eso podría haber sido un vacío legal válido) y escribir las funciones como si Python soportara la recursión de cola. Para que esto funcione, utilicé muchos parámetros opcionales que permiten que las llamadas requeridas sigan funcionando.
A continuación tengo listados sin golf para cada función.
Apply
:Map
:Nest
:Tenga en cuenta que esta función requiere que el pasado
function
pueda representar múltiples argumentos de forma variable. Otro enfoque habría sido exigir que la función siempre recibiera una lista única, pero eso habría requerido que las funciones aprobadas pudieran interpretar listas de argumentos. Hubo suposiciones de cualquier manera, así que elegí la que mejor se adaptaba al resto del sistema.Range
:Fold
:Table
:Aquí hay una salida de muestra usando las siguientes funciones auxiliares:
fuente
Ceilán,
370* 0.9 = 333364 * 0.9 = 327.4La mayoría de esas funciones ya están disponibles en el paquete de idioma de Ceylon (aunque a veces con una firma un poco diferente), pero las estamos definiendo aquí como se solicita en la pregunta.
En realidad, solo dos de las funciones (
t
yf
) están utilizando la recursividad (sobre listas y enteros, respectivamente), las otras se basan en ellas. (Aplicar es un poco atípico, realmente no se relaciona con los demás).Interpreto "Lista" como el tipo secuencial de Ceylon, que es una secuencia de elementos ordenada inmutable (posiblemente vacía).
[R*]
significaSequential<R>
, por alguna razón, también podemos escribirloR[]
, que es un byte más corto.Un tipo de función es
Callable<R, A>
, dondeA
es un tipo de tupla para los argumentos, como[X, Y, Z]
(es decir, algún subtipo deAnything[]
). Como atajo podemos escribir enR(X,Y,Z)
lugar deCallable<R,[X,Y,Z]>
.Alias
Integer
comoI
para guardar algunos bytes.Aquí hay una versión formateada (y ligeramente comentada):
Usando "bucles"
Table and Map se puede implementar de manera más corta usando bucles (en realidad, una comprensión de secuencia):
Aunque no estoy seguro si el uso del
..
operador para el rango entero cuenta como una función incorporada. Si esto está permitido, el código resultante es este, longitud 312:(Podría hacerse aún más corto definiendo
r(I i) => 1..i
, dando como resultado una puntuación de 301. Aunque eso se parece aún más a hacer trampa).Si
..
no está permitido, tendremos que implementarlo nuevamente. Podemos usar estas implementaciones parar
yt
(con lom
anterior):Esto da como resultado 348 bytes, mejor que la versión completamente recursiva, pero no después de aplicar la bonificación.
fuente
Groovy (146 Bytes) (146 * 90% = 131.4)
PD: No sé lo que estás considerando como un 'bucle' en este contexto, solo apliqué el bono después de que OP me lo dijo y lo eliminaré si 2-3 usuarios adicionales dicen estas funciones de colección e iteradores son bucles y eso no merezco la bonificación. Además, si desea llamarme sobre mi uso de 1..it, hágalo y lo reelaboraré / actualizaré mi bytecount.
Ejemplo de entrada / salida
Salida
Pruébelo usted mismo: https://groovyconsole.appspot.com/edit/5203951758606336
fuente