Consejos para jugar al golf en Clojure

16

¿Cuáles son sus consejos para el golf de código con Clojure?

El objetivo de esta pregunta es recopilar una lista de técnicas que son específicas de Clojure y que se pueden utilizar en problemas generales de código de golf.

mikera
fuente
Hmm .. no deben estos tipos de mensajes estar en meta (concedidas No estoy seguro de meta existió hace más de 5 años)
Albert Renshaw

Respuestas:

6

Use la sintaxis del lector para lambdas.
Entonces usa

#(+ % %2 %3)

en lugar de

(fn [x y z] (+ x y z))

También puede eliminar espacios en blanco algunas veces:

#(if (< % 0) (- %) %)
#(if(< % 0)(- %)%)
usuario2429260
fuente
por cierto #(+ % %2 %3)es equivalente a +.
bfontaine
4

Donde puede eliminar espacios en blanco:

  • Entre una cuerda y cualquier otra cosa:

    (println(+"Hello, World!"1))
    
  • Entre paréntesis y cualquier otra cosa:

    (for[x(range 5)](* x x))
    
  • Entre un número y todo lo que no sean nombres incorporados o variables:

    Allowed:
    (+ 1"Example")
    (map{1"-1"2"-2"}[1 2 3])
    
    Not allowed:
    (+1 2)
    
  • Entre @(desreferencia para átomos) y paréntesis.

clismique
fuente
También antes de la macro de lector deref@
solo ASCII
1
También a veces puede reorganizar las cosas en letay deshacerse de algunos espacios.
NikoNyrh
También antes de los parámetros en funciones anónimas: #(+ 1(first%))=#(+ 1 (first %))
bfontaine
3

Las cadenas se pueden tratar como una secuencia de caracteres

por ejemplo, para ordenar alfabéticamente los caracteres de una cadena:

(sort "hello")
=> (\e \h \l \l \o)
mikera
fuente
1
Las cadenas son, por definición, una secuencia de caracteres en casi todos los idiomas, pero no puedes aplicar este truco en todos ellos :-)
mellamokb
3
O más bien, "secuencia" tiene un significado especial en Clojure que significa que puedes aplicar trucos adicionales: :-)
mikera
2

Usar en nth ... 0lugar defirst

Para obtener el primer elemento de una colección, el uso de (nth ... 0)over firstguarda un byte:

(first[2 3 4]): 14 bytes
(nth[2 3 4]0): 13 bytes (saves a byte!)
clismique
fuente
lo mismo ocurre con second(2 bytes)
Uriel
1
También puede usar vectores como funciones, por lo que ([2 3 4]1)devuelve el elemento en el índice 1. Esto debería ser beneficioso si, por ejemplo, el formato de entrada es flexible.
NikoNyrh
1

Use aplicar en lugar de reducir

Por ejemplo, #(apply + %)es un byte más corto que #(reduce + %).

NikoNyrh
fuente
1

Evite dejar si ya tiene un para

Por ejemplo: en #(for[a[(sort %)]...)lugar de #(let[a(sort %)](for ...)).

Para también tiene una :letconstrucción, pero es demasiado detallado para el golf de código.

NikoNyrh
fuente
1

Use +y en -lugar de incydec

Esto ahorra 1 byte si está usando inc/ decen una expresión con parens:

(inc(first[1 3 5]))
(+(first[1 3 5])1)
clismique
fuente
1

Use mapas en lugar de ifs cuando pruebe la igualdad

;; if n=3 then A else B
(if (= 3 n) A B) ; (if(=3n)AB)
({3 A} n B)      ; ({3A}nB) -> -3 chars

;; if n=2 or n=3 then A else B
(if (#{2 3} n) A B) ; (if(#{23}n)AB)
({2 A 3 A} n B)     ; ({2A3A}nB) -> -4 chars
bfontaine
fuente
1

Vincula los nombres de funciones largos en let a un símbolo de un solo byte

Por ejemplo, si necesita usarlo partitiono frequenciesvarias veces, podría ser beneficioso vincularlos a un símbolo de un solo byte en una letmacro. Por otra parte, puede que no valga la pena si no necesita lo letcontrario, y el nombre de la función es relativamente corto.

NikoNyrh
fuente
0

Usar para en lugar de mapa

Por ejemplo, #(for[i %](Math/abs i))es mucho más corto que el mapequivalente.

NikoNyrh
fuente