16
3
What are your tips for code golfing using Clojure?
The aim of this question is to collect a list of techniques that are specific to Clojure and can be used in general code-golfing problems.
16
3
What are your tips for code golfing using Clojure?
The aim of this question is to collect a list of techniques that are specific to Clojure and can be used in general code-golfing problems.
6
Use reader syntax for lambdas.
So use
#(+ % %2 %3)
instead of
(fn [x y z] (+ x y z))
You can also eliminate whitespace some of the time:
#(if (< % 0) (- %) %)
#(if(< % 0)(- %)%)
by the way #(+ % %2 %3)
is equivalent to +
. – bfontaine – 2019-11-30T12:37:08.903
4
Between a string and anything else:
(println(+"Hello, World!"1))
Between brackets and anything else:
(for[x(range 5)](* x x))
Between a number and everything other than builtins or variable names:
Allowed:
(+ 1"Example")
(map{1"-1"2"-2"}[1 2 3])
Not allowed:
(+1 2)
Between @
(dereference for atoms) and brackets.
Also before the deref reader macro @
– ASCII-only – 2017-03-29T22:19:56.003
1Also at times you might be able to re-arrange stuff at a let
and get rid of some spaces. – NikoNyrh – 2017-12-14T21:56:23.827
Also before parameters in anonymous functions: #(+ 1(first%))
= #(+ 1 (first %))
– bfontaine – 2019-11-15T20:27:27.863
3
Strings can be treated as a sequence of chars
e.g. to sort the characters in a string alphabetically:
(sort "hello")
=> (\e \h \l \l \o)
1Strings are by definition a sequence of chars in almost every language, but you can't apply this trick in all of them :-) – mellamokb – 2011-06-12T21:44:52.557
3Or rather, "sequence" has a special meaning in Clojure than means you can apply extra tricks ::-) – mikera – 2011-06-13T11:24:34.160
2
nth ... 0
instead of first
To get the first element of a collection, using (nth ... 0)
over first
saves a byte:
(first[2 3 4]): 14 bytes
(nth[2 3 4]0): 13 bytes (saves a byte!)
same goes for second
(2 bytes) – Uriel – 2017-12-14T22:12:43.007
1Also you can use vectors as functions, so ([2 3 4]1)
returns the element at index 1. This should be benefitical if for example the input format is flexible. – NikoNyrh – 2017-12-15T20:30:12.790
1
For example #(apply + %)
is one byte shorter than #(reduce + %)
.
1
For example if you need to use partition
or frequencies
multiple times, it could be beneficial to bind them to a single-byte symbol in a let
macro. Then again it might not be worth it if you don't need the let
otherwise, and the function name is relatively short.
1
For example: #(for[a[(sort %)]...)
instead of #(let[a(sort %)](for ...))
.
For does also have a :let
construct but it is too verbose for code golf.
1
+
and -
instead of inc
and dec
This saves 1 byte if you're using inc
/dec
on an expression with parens:
(inc(first[1 3 5]))
(+(first[1 3 5])1)
1
if
s when testing for equality;; 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
0
For instance #(for[i %](Math/abs i))
is a lot shorter than the map
equvalent.
Hmm.. shouldn't these types of posts be in meta (granted I'm not sure meta existed 5+ years ago) – Albert Renshaw – 2017-03-30T00:14:32.473