Tipps zum Golfen in Clojure

16

Was sind Ihre Tipps zum Code-Golfen mit Clojure?

Ziel dieser Frage ist es, eine Liste von Techniken zusammenzustellen, die spezifisch für Clojure sind und bei allgemeinen Code-Golf-Problemen eingesetzt werden können.

mikera
quelle
Hmm .. sollte diese Art von Posts nicht in Meta sein (vorausgesetzt, ich bin nicht sicher, ob Meta vor mehr als 5 Jahren existiert hat)
Albert Renshaw

Antworten:

6

Verwenden Sie die Reader-Syntax für Lambdas.
Also benutze

#(+ % %2 %3)

Anstatt von

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

Sie können auch gelegentlich Leerzeichen entfernen:

#(if (< % 0) (- %) %)
#(if(< % 0)(- %)%)
user2429260
quelle
ist übrigens #(+ % %2 %3)gleichbedeutend mit +.
Bfontaine
4

Wo Sie Leerzeichen entfernen können:

  • Zwischen einer Zeichenfolge und irgendetwas anderem:

    (println(+"Hello, World!"1))
    
  • Zwischen Klammern und allem anderen:

    (for[x(range 5)](* x x))
    
  • Zwischen einer Zahl und allem anderen als Builtins oder Variablennamen:

    Allowed:
    (+ 1"Example")
    (map{1"-1"2"-2"}[1 2 3])
    
    Not allowed:
    (+1 2)
    
  • Zwischen @(Dereferenzierung für Atome) und Klammern.

Clismique
quelle
Auch vor dem Deref-Reader-Makro@
ASCII
1
Manchmal kann es auch vorkommen, dass Sie Dinge in einem neu anordnen letund einige Leerzeichen entfernen können.
NikoNyrh
Auch vor Parametern in anonymen Funktionen: #(+ 1(first%))=#(+ 1 (first %))
bfontaine
3

Zeichenfolgen können als Zeichenfolge behandelt werden

zB um die Zeichen in einer Zeichenkette alphabetisch zu sortieren:

(sort "hello")
=> (\e \h \l \l \o)
mikera
quelle
1
Saiten sind per Definition eine Folge von Zeichen in fast jeder Sprache, aber Sie können diesen Trick nicht in allen anwenden :-)
mellamokb
3
Oder besser gesagt, "Sequenz" hat in Clojure eine besondere Bedeutung, als dass Sie zusätzliche Tricks anwenden können: :-)
mikera
2

Verwenden Sie nth ... 0anstelle vonfirst

Wenn Sie das erste Element einer Sammlung abrufen möchten, speichern Sie ein Byte mit (nth ... 0)over first:

(first[2 3 4]): 14 bytes
(nth[2 3 4]0): 13 bytes (saves a byte!)
Clismique
quelle
Gleiches gilt für second(2 Bytes)
Uriel
1
Sie können auch Vektoren als Funktionen verwenden, sodass ([2 3 4]1)das Element bei Index 1 zurückgegeben wird. Dies sollte von Vorteil sein, wenn beispielsweise das Eingabeformat flexibel ist.
NikoNyrh
1

Verwenden Sie Übernehmen anstelle von Reduzieren

Zum Beispiel #(apply + %)ist ein Byte kürzer als #(reduce + %).

NikoNyrh
quelle
1

Vermeiden Sie lassen, wenn Sie bereits eine für haben

Zum Beispiel: #(for[a[(sort %)]...)statt #(let[a(sort %)](for ...)).

Für hat auch ein :letKonstrukt, aber es ist zu ausführlich für Code-Golf.

NikoNyrh
quelle
1

Verwenden Sie +und -anstelle von incunddec

Dies spart 1 Byte, wenn Sie inc/ decfür einen Ausdruck mit parens verwenden:

(inc(first[1 3 5]))
(+(first[1 3 5])1)
Clismique
quelle
1

Verwenden Sie ifbeim Testen auf Gleichheit Karten anstelle von s

;; 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
quelle
1

Binden Sie lange Funktionsnamen bei let an ein Einzelbytesymbol

Wenn Sie beispielsweise ein partitionoder frequenciesmehrere Male verwenden müssen, kann es hilfreich sein, sie an ein Einzelbytesymbol in einem letMakro zu binden . Andererseits lohnt es sich möglicherweise nicht, wenn Sie das nicht benötigen let, und der Funktionsname ist relativ kurz.

NikoNyrh
quelle
0

Verwenden Sie für anstelle der Karte

Zum Beispiel #(for[i %](Math/abs i))ist viel kürzer als das mapÄquivalent.

NikoNyrh
quelle