Conseils pour jouer au golf à Clojure

16

Quels sont vos conseils pour jouer au golf à l'aide de Clojure?

Le but de cette question est de rassembler une liste de techniques spécifiques à Clojure et pouvant être utilisées dans des problèmes généraux de golf de code.

mikera
la source
Hmm .. ces types de messages ne devraient-ils pas être en méta (d'accord, je ne suis pas sûr que la méta existait il y a 5+ ans)
Albert Renshaw

Réponses:

6

Utilisez la syntaxe du lecteur pour les lambdas.
Alors utilisez

#(+ % %2 %3)

au lieu de

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

Vous pouvez également éliminer les espaces blancs une partie du temps:

#(if (< % 0) (- %) %)
#(if(< % 0)(- %)%)
user2429260
la source
soit dit en passant #(+ % %2 %3)est équivalent à +.
bfontaine
4

Où vous pouvez supprimer les espaces:

  • Entre une chaîne et autre chose:

    (println(+"Hello, World!"1))
    
  • Entre parenthèses et toute autre chose:

    (for[x(range 5)](* x x))
    
  • Entre un nombre et tout autre que les noms intégrés ou variables:

    Allowed:
    (+ 1"Example")
    (map{1"-1"2"-2"}[1 2 3])
    
    Not allowed:
    (+1 2)
    
  • Entre @(déréférence pour les atomes) et crochets.

clismique
la source
Également avant la macro du lecteur deref@
ASCII uniquement
1
Parfois, vous pourrez peut-être réorganiser des choses à un letet vous débarrasser de certains espaces.
NikoNyrh
Aussi avant les paramètres dans les fonctions anonymes: #(+ 1(first%))=#(+ 1 (first %))
bfontaine
3

Les chaînes peuvent être traitées comme une séquence de caractères

par exemple pour trier les caractères d'une chaîne par ordre alphabétique:

(sort "hello")
=> (\e \h \l \l \o)
mikera
la source
1
Les chaînes sont par définition une séquence de caractères dans presque toutes les langues, mais vous ne pouvez pas appliquer cette astuce dans toutes :-)
mellamokb
3
Ou plutôt, "séquence" a une signification particulière dans Clojure que signifie que vous pouvez appliquer des astuces supplémentaires: :-)
mikera
2

Utiliser nth ... 0au lieu defirst

Pour obtenir le premier élément d'une collection, l'utilisation de (nth ... 0)over firstenregistre un octet:

(first[2 3 4]): 14 bytes
(nth[2 3 4]0): 13 bytes (saves a byte!)
clismique
la source
il en va de même pour second(2 octets)
Uriel
1
Vous pouvez également utiliser des vecteurs comme fonctions, donc ([2 3 4]1)renvoie l'élément à l'index 1. Cela devrait être avantageux si, par exemple, le format d'entrée est flexible.
NikoNyrh
1

Utilisez Appliquer au lieu de réduire

Par exemple, #(apply + %)un octet est plus court que #(reduce + %).

NikoNyrh
la source
1

Évitez de laisser si vous avez déjà un pour

Par exemple: #(for[a[(sort %)]...)au lieu de #(let[a(sort %)](for ...)).

For a aussi une :letconstruction mais elle est trop verbeuse pour le code golf.

NikoNyrh
la source
1

Utilisez +et -au lieu de incetdec

Cela économise 1 octet si vous utilisez inc/ decsur une expression avec des parens:

(inc(first[1 3 5]))
(+(first[1 3 5])1)
clismique
la source
1

Utilisez des cartes au lieu de ifs lorsque vous testez l'égalité

;; 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
la source
1

Liez les noms de fonction longs à let à un symbole à un octet

Par exemple , si vous devez utiliser partitionou frequenciesplusieurs fois, il pourrait être bénéfique pour les lier à un symbole unique octet dans une letmacro. Là encore, cela ne vaut peut-être pas la peine si vous n'avez pas besoin du letcontraire, et le nom de la fonction est relativement court.

NikoNyrh
la source
0

Utiliser pour au lieu de la carte

Par exemple, #(for[i %](Math/abs i))est beaucoup plus court que l' mapéquivalent.

NikoNyrh
la source