What general tips do you have for golfing in Mathematica? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Mathematica (e.g. "remove comments" is not an answer).
45 Answers
Some built-in functions with long names can be replaced with shorter expressions.
For example:
Total
=>Tr
for 1d arraysTranspose
=>Thread
or
(\[Transpose]
)True
=>1<2
False
=>1>2
Times
=>1##&
Alternatives
=>$|##&
IntegerQ
=>⌊#⌋==#&
or1∣#&
(Thanks to @Misha Lavrov)a[[1]]
=>#&@@a
a[[All,1]]
=>#&@@@a
ConstantArray[a,n]
=>Array[a&,n]
orTable[a,n]
Union@a
=>{}⋃a
ora⋃a
ToExpression@n
=>FromDigits@n
ifn
is a numberDivisible[n,m]
=>m∣n
FromDigits[n,2]
=>Fold[#+##&,n]
ifn
is a list of0
s and1
sComplex@z
=>{1,I}.z
wherez
is a list of the form{x,y}
Rest@FoldList[f[#,#2]&,x,l]
=>t=x;(t=f[t,#])&/@l
Table[f[i,l],{i,Length@l}]
=>i=1;f[i++,l]&/@l
CoefficientList[f,x]
=>(f+O@x^n)[[3]]
if you know that the degree of the polynomialf
isn
and the constant term is not zeroFractionalPart[x]
=>Mod[x,1]
if x is nonnegative
-
5\$\begingroup\$ @belisarius
Thread[{{a,b},{c,d}}]
==Thread[List[{a,b},{c,d}]]
=={List[a,c],List[b,d]}
=={{a,c},{b,d}}
==Transpose[{{a,b},{c,d}}]
\$\endgroup\$ Commented Oct 10, 2014 at 4:29 -
2\$\begingroup\$ I think your
Fold
trick forFromDigits
also works for any other base except10
. E.g.FromDigits[n,5]
-->Fold[4#+##&,n]
(with the bonus of saving an extra byte for bases100
and1000
). \$\endgroup\$ Commented Nov 11, 2015 at 16:07 -
1\$\begingroup\$ @mbomb007 3 bytes in UTF-8. In fact this character is
U+F3C7
. \$\endgroup\$ Commented Nov 14, 2015 at 3:38 -
1\$\begingroup\$ I finally installed 10.3. If we're considering full programs, I don't think
Echo
is an option, because it prints>>
(and a space) to STDOUT before printing the actual string. \$\endgroup\$ Commented Dec 9, 2015 at 10:30 -
2\$\begingroup\$ For
Complex[x,y] => {1,I}.{x,y}
, I thinkx+y*I
is much shorter with the same effect? \$\endgroup\$ Commented Feb 27, 2018 at 1:54
Tips below vary from the most economical to the most often used:
Use Mathematica's high-level commands where possible, even bulky ones:
MorphologicalComponents
: Code-Golf: Count IslandsImage manipulation capabilities: e.g. Today (September 24) is HONDA birthday
Subsets
IntegerPartitions
Distance and Similarity measures: e.g.
EuclideanDistance
can be a byte saver. Note however, that it's usually shorter to writeTotal@Abs[a-b]
instead ofa~ManhattanDistance~b
andMax@Abs[a-b]
instead ofa~ChessboardDistance~b
.
Use
Graphics and
Text
for Ascii art: e.g Star programming! and Build an analog clockDedicated symbols:
logic and set operations symbols instead of their long form names: ⋂, ⋃, ∧, ∨
Map
andApply
:/@
,//@
.@@
,@@@
Prefix and infix notation:
Print@"hello"
in place ofPrint["hello"]
a~f~b
in place off[a,b]
When a function is used only once, a pure function may economize a character or two.
Joining strings in a list.
""<>{"a","b","c"}
instead ofStringJoin@{"a","b","c"}
Exploit listable functions. The longer the lists the better.
{a, b, c} + {x, y, z}= {a+x, b+y, c+z}
{2, 3, 4} {5, 6, 7}= {10, 18, 28}
{{a, b}, {c, d}}^{2, 3} = {{a^2, b^2}, {c^3, d^3}}
-
8\$\begingroup\$ It's always shorter to write
(Norm[#-#2]&)
instead ofEuclideanDistance
. \$\endgroup\$ Commented May 18, 2018 at 9:36
Lists with repeated values
This is quite a common vector to work with:
{0,0}
It turns out this can be shortened by a byte:
0{,}
Even more bytes are saved if the vector is longer than two zeros. This can also be used to initialise zero matrices, e.g. the following gives a 2x2 matrix of zeros:
0{{,},{,}}
This can also be used for non-zero values if they're sufficiently large or sufficiently many or negative. Compare the following pairs:
{100,100}
0{,}+100
{-1,-1}
0{,}-1
{3,3,3,3}
0{,,,}+3
But remember that starting at 6 values, you're better off with 1~Table~6
in this case (potentially earlier, depending on precedence requirements).
The reason this works is that ,
introduces two arguments to the list, but omitted arguments (anywhere in Mathematica) are implicit Null
s. Furthermore, multiplication is Listable
, and 0*x
is 0
for almost any x
(except for things like Infinity
and Indeterminate
), so here is what's happening:
0{,}
= 0*{,}
= 0*{Null,Null}
= {0*Null,0*Null}
= {0,0}
For lists of 1
s, you can use a similar trick by making use of exponentiation rules. There are two different ways to save bytes if you have at least three 1
s in the list:
{1,1,1}
1^{,,}
{,,}^0
-
7\$\begingroup\$ +1; this just goes to show that while Mathematica may have a built-in for everything, golfing in it can be a real challenge. \$\endgroup\$ Commented Nov 21, 2016 at 17:10
-
2\$\begingroup\$ If you want an array that's ultimately filled with 1s, then
1^{,,,}
is one byte smaller than0{,,,}+1
. \$\endgroup\$ Commented Nov 12, 2018 at 2:29 -
\$\begingroup\$ @MishaLavrov Oh, good catch. That makes it shorter at three values and you can also use
{,,}^0
. I'll edit the post. \$\endgroup\$ Commented Nov 12, 2018 at 9:30
Know your pure function arguments
When golfing code, you'll often employ a functional approach, where you use anonymous (pure) functions with the &
shorthand syntax. There are a lot of different ways to access the arguments of such a function, and you can often shave off a couple of bytes by having a good grasp on the possibilities.
Accessing single arguments
You probably know this if you've used pure functions before. The nth argument is referred to as #n
, and #
acts as an alias for #1
. So if, say, you want to write a function that takes as parameters another function and its argument (to pass the argument to that function), use
#@#2&
This does not work with negative numbers (such as you might use when accessing lists).
Accessing named arguments (new in V10)
One of the major new language features in Mathematica 10 is Association
s, which are basically key-value maps with arbitrary key types, written like
<| x -> 1, "abc" -> 2, 5 -> 3 |>
If such an association is passed in as the first argument to a pure function, you can access some if its arguments as named parameters:
{#, #2, #3, #abc, #xyz} & [<| "abc" -> "1st", "xyz" -> "2nd", abc -> "3rd" |>, "4th", "5th"]
(* {<| "abc" -> "1st", "xyz" -> "2nd", abc -> "3rd" |>, "4th", "5th", "1st", "2nd"} *)
Note that #
still refers to the entire association as expected. For the named parameters to work, the keys have to be strings (it won't work if you use undefined variables for instance), and those strings must begin with a letter and only contain letters and digits.
The "self" argument #0
A lesser known feature is that #0
also exists, and gives you the function object itself. This can be really useful in quines and generalised quines. In fact, the shortest Mathematica quine (I know of) is
ToString[#0][] & []
What's slightly annoying is that it won't give you the exact characters you entered. E.g. if use @
for function application, it will still render as [...]
and spaces will be inserted in some places. This will usually make the quine a bit longer than you'd like it to be, but it will always work, by golfing the quine first, and then just copying its output - which should now be a real quine.
Apart from quines, this also means that you can write recursive code without having to name your function. Compare these three (naive but golfed) Fibonacci implementations:
f@0=0;f@1=1;f@n_:=f[n-1]+f[n-2]
f@n_:=If[n<2,n,f[n-1]+f[n-2]]
If[#<2,#,#0[#-1]+#0[#-2]]&
Sequences of arguments
Now this is where the real magic starts. Sequences aren't used often in golfing, because Sequence
it's just too long a name to be worth it most of the time. But in pure functions is where they shine. If you're not familiar with sequences, they are basically like splats in some other languages, if you use a sequence in a List
or the argument list of a function, it's elements will automatically be expanded into separate slots. So
{1, Sequence[2, 3, 4], 5} == {1, 2, 3, 4, 5}
f["a", Sequence[0, {}], "b"] == f["a", 0, {}, "b"]
Now, in pure functions ##
or ##1
is a sequence of all the arguments. Likewise, ##2
is a sequence of all arguments starting from the second, ##3
all arguments starting from the third etc. So for a start, we can just reimplement Sequence
as ##&
, saving 5 bytes. As an example usage, this provides us with an alternative to Join@@list
(see this tip), which doesn't save any bytes, but is good to know about anyway:
##&@@@list
This effectively flattens the first level of a nested list. What else can we do with this? Here is a 1-byte saving for RotateLeft
:
RotateLeft@list
{##2,#}&@@list
For these things alone it's worth keeping this feature in mind. However, we can do better! Sequences get really interesting when consider that operators are actually implemented as functions under the hood. E.g. a+b
actually evaluates to Plus[a,b]
. So if we give that a sequence...
1+##&[1,2,3]
=> Plus[1,##]
=> Plus[1,1,2,3]
=> 7
This trick has been use in this tip to save a byte on Times
, because juxtaposition is technically also just an operator:
1##&[1,2,3]
=> Times[1,##]
=> Times[1,1,2,3]
=> 6
You can also use it to save a byte on Unequal
if you have a single-character value or variable you know is not in your arguments (N
will probably work in 99% of the cases):
Unequal[a,b,c]
N!=##&[a,b,c]
This gets even more interesting with unary operators and -
and /
- the latter two are actually implemented in terms of multiplication and exponentiation. Here is a list of things you can do, where the last column assumes that the function was passed the arguments a, b, c
:
Operator Function Expanded Equivalent to
+## Plus[##] Plus[a,b,c] a+b+c
1## Times[1,##] Times[1,a,b,c] a*b*c
-## Times[-1,##] Times[-1,a,b,c] -a*b*c
x+## Plus[x,##] Plus[x,a,b,c] x+a+b+c
x-## Plus[x,Times[-1,##]] Plus[x,Times[-1,a,b,c]] x-a*b*c
x## Times[x,##] Times[x,a,b,c] x*a*b*c
x/## Times[x,Power[##,-1]] Times[x,Power[a,b,c,-1]] x*a^b^c^-1
##/x Times[##,Power[x,-1]] Times[a,b,c,Power[x,-1]] a*b*c/x
x^## Power[x,##] Power[x,a,b,c] x^a^b^c
##^x Power[##,x] Power[a,b,c,#] a^b^c^x
x.## Dot[x,##] Dot[x,a,b,c] x.a.b.c
Other common operators are !=
, ==
, &&
, ||
. Less common ones to keep in mind are |
, @*
, /*
. To conclude, here is a little bonus trick:
#### Times[##,##] Times[a,b,c,a,b,c] (a*b*c)^2
Keep experimenting with these, and let me know if you find any other useful or particularly interesting applications!
-
\$\begingroup\$ I think you meant
{##2,#}&@@list
rather than{##2,#}&@list
. \$\endgroup\$– theoristCommented May 29, 2021 at 20:37 -
\$\begingroup\$ @theorist Good catch, thank you! \$\endgroup\$ Commented May 30, 2021 at 0:17
Sqrt@2
or 2^.5
=> √2
a[[1]]
=>a〚1〛
#+#2&
=>+##&
Flatten@a
=>Join@@a
(sometimes)
Function[x,x^2]
=>xx^2
or #^2&
a〚1;;-1;;2〛
=>a〚;;;;2〛
a〚2;;-1 ;;2〛
=>a〚2;;;;2〛
a〚All,1〛
=>a〚;;,1〛
{{1}}〚1,1〛
=>Tr@{{1}}
0&~Array~10
=>0Range@10
Range[10^3]
=>Range@1*^3
-
3\$\begingroup\$ Note that when measuring by bytes, using
〚
and〛
takes 3 bytes each (assume UTF8) \$\endgroup\$ Commented May 18, 2018 at 10:12 -
1\$\begingroup\$ Note that, while
Sqrt@2
⟹ √2,2^.5
!⟹ √2 (at least not exactly), as the latter will return a numerical result rather than a symbolic one, i.e., 1.14121... \$\endgroup\$– theoristCommented May 29, 2021 at 20:52
Operators as Functions
Inspired by Dennis's recent discovery for Julia I thought I'd look into this for Mathematica. I was aware that Mathematica defines a large number of unused operators, but never paid much attention to it.
For reference, the list of all operators can be found here in the form of a precedence table. The triangle in the last column indicates whether that operator has a built-in meaning or not. While not all of those that don't can be defined easily, most of them can.
Conveniently, there are two unused operators with a codepoint less than 256, such that they can be used as single bytes in an ISO 8859-1 encoded source file:
±
(0xB1) can be used either as a unary prefix operator or a binary infix operator.·
(0xB7) can be used as a variadic or n-ary infix operator, for n > 2.
There's one more catch though: for some weird reason when defining these operators you need one space in front of them, or else Mathematica tries to parse a multiplication. When using them you don't need any spaces though:
±x_:=2x
x_ ±y_:=x+y
x_ ·y_ ·z_:=x*y+z
Print[±5] (* 10 *)
Print[3±4] (* 7 *)
Print[3·4·5] (* 17 *)
Compare this with:
f@x_:=2x
x_~g~y_:=x+y
h[x_,y_,z_]:=x*y+z
Print[f@5] (* 10 *)
Print[3~g~4] (* 7 *)
Print[h[x,y,z]] (* 17 *)
So this saves one byte when defining the function and two bytes when using it. Note that the definition of ·
will not save bytes for four operands and will start costing bytes for more operands, but the usage may still save bytes, depending the precedence of operators used in the arguments. It's also good to note that you can cheaply define a variadic function that can then be called much more efficiently:
x_ ·y__:={y}
Print[1·2·3·4·5] (* {2, 3, 4, 5} *)
But note that it's not easily possible to call these variadic functions with a single argument. (You could do CenterDot[x]
or ##&[]·x
but if you actually need that there's a good chance you're better off with a different solution.)
Of course, this isn't saving anything for solutions where an unnamed function suffices, but sometimes you need to define helper functions for use later on, and sometimes it's shorter to define named functions e.g. to set up different definitions for different parameters. In those cases, using an operator instead can save a decent amount of bytes.
Note that using these ISO 8859-1 encoded files requires $CharacterEncoding
to be set to a compatible value, like the Windows default WindowsANSI
. On some systems this defaults to UTF-8
which won't be able to read these code points from single bytes.
-
\$\begingroup\$ This is really great, I did not know Mathematica had a list of operators, and even included their precedence. Those two operators you found I'm sure will come in handy. \$\endgroup\$– milesCommented Jun 17, 2016 at 9:03
Explore recursive solutions - Mathematica is multi-paradigm, but the functional approach is often the most economical.
NestWhile
can be a very compact solution to searching problems, andNestWhileList
andFoldList
are powerful when you need to return or process the results of intermediate iterations.Map (/@)
,Apply (@@, @@@)
,MapThread
, and really everything on Wolfram's Functional Programming documentation page is potent stuff.Shortened form for increment/decrement - For example, instead of
While[i<1,*code*;i++]
you can doWhile[i++<1,*code*]
Don't forget you can pre-increment/decrement - For example,
--i
instead ofi--
. This can sometimes save you a few bytes in the surrounding code by eliminating a preparatory operation.Corollary to David Carraher's #5: When the same function is used many times, assigning a symbol to it can save bytes. For example, if you are using
ToExpression
4 times in a solution,t=ToExpression
enables you to uset@*expression*
thereafter. However, before you do this consider whether the repeated application of the same function indicates an opportunity for a more economical recursive approach.
-
\$\begingroup\$
MapThread
can often be replaced by\[Transpose]
. TIO. \$\endgroup\$ Commented Jun 30, 2018 at 16:16
Choosing values based on integer
The naive approach to choose between y
and z
, depending on whether x
is 0
or 1
is
If[x<1,y,z]
However, there's a shorter way:
y[z][[x]]
This works because [[0]]
gives the Head
of an expression, in this case y
, whereas [[1]]
just gives the first element - in this case the first argument, z
.
You can even use this to choose between more than two values:
u[v,w][[x]]
Note that this won't work if u
is a function that actually evaluates to something. It's important that Mathematica keeps u[v,w]
as it is. However, this works in most cases, including if u
is a is a number, a string or a list.
Credits for this trick go to alephalpha - I discovered this in one of his answer.
If x
is 1-based instead of zero-based, just use
{y,z}[[x]]
or
{u,v,w}[[x]]
In some rare cases, you can even make use of the fact that multiplication is not evaluated for some values:
{"abc","def"}[[x]]
("abc""def")[[x]]
Note though that Mathematica will actually reorder the arguments, of a multiplication if it remains unevaluated, so the above is identical to
("def""abc")[[x]]
Don't use {}
if you are using @@@
.
In some cases, you may encounter an expression like:
f@@@{{a,b},{c,d}}
It is possible to reduce bytes by writing:
f@@@{a|b,c|d}
Alternatives
has a very low precedence, so it's generally okay to write expressions (a notable exception is pure functions; you can use it only in the leftmost element of Alternatives
).
f@@@{f@a|b~g~1,#^2&@c|d@2}
Note that f@@a|b|c
(instead of f@@{a,b,c}
) does not work because Apply
has a higher precedence than Alternative
.
In this case, you should simply use f@@{a,b,c}
.
Alternatives to Length
This has been entirely rewritten with some suggestions from LegionMammal978 and Misha Lavrov. Many thanks to both of them.
In many cases, Length
can be shortened a bit by making use of Tr
. The basic idea is to turn the input into a list of 1
s, so that Tr
sums them up which will then equal the length of the list.
The most common way to do this is to use 1^x
(for a list x
). This works because Power
is Listable
and 1^n
for most atomic values n
is just 1
(including all numbers, strings and symbols). So we can already save one byte with this:
Length@x
Tr[1^x]
Of course, this assumes that x
is an expression with higher precedence than ^
.
If x
contains only 0
s and 1
s, we can save another byte using Factorial
(assuming x
has higher precedence than !
):
Length@x
Tr[x!]
In some rare cases, x
might have lower precedence than ^
but still higher precedence than multiplication. In that case it will also have lower precedence than @
, so we really need to compare with Length[x]
. An example of such an operator is .
. In those cases, you can still save a byte with this form:
Length[x.y]
Tr[0x.y+1]
Finally, some remarks about what kind of lists this works on:
As mentioned at the top, this works on flat lists containing only numbers, strings and symbols. However, it will also work on some deeper lists, although it actually computes something slightly different. For an n-D rectangular array, using Tr
gives you the shortest dimension (as opposed to the first). If you know that the outermost dimension is the shortest, or you know they're all the same, than the Tr
-expressions are still equivalent to Length
.
-
3\$\begingroup\$ Just found an even shorter solution:
Length@x == Tr[1^x]
. Should work with most lists. \$\endgroup\$ Commented Dec 30, 2016 at 13:28 -
\$\begingroup\$ @LegionMammal978 that's amazing, thanks :). I'll edit it in soon. \$\endgroup\$ Commented Dec 30, 2016 at 13:33
-
1\$\begingroup\$ Twice now, I've found myself using
Tr[x!]
instead ofTr[1^x]
to save one byte in the special case wherex
only contains zeroes and ones. \$\endgroup\$ Commented Nov 17, 2017 at 7:29 -
\$\begingroup\$ @MishaLavrov That's really neat! :) \$\endgroup\$ Commented Nov 17, 2017 at 7:30
Don't write 0-argument functions
There is no need for code like this:
f[]:=DoSomething[1,2]
(*...*)
f[]
(*...*)
f[]
You can simply use a variable with :=
to force re-evaluation of the right-hand side:
f:=DoSomething[1,2]
(*...*)
f
(*...*)
f
This also means that you can alias any action that you perform often (even if it's just something like n++
) to a single character at the cost of 5 bytes. So in the case of n++
it pays back after the fourth use:
n++;n++;n++;n++
f:=n++;f;f;f;f
Mathematica 10 only
Operator forms
Mathematica 10 supports so-called "operator forms", which basically means some functions can be curried. Currying a function is to create a new function by fixing one of its operators. Say, you're using SortBy[list, somereallylongfunction&]
a lot of different list
s. Before, you probably would have assigned SortBy
to s
and the pure function to f
so
s=SortBy;
f=somereallylongfunction&;
list1~s~f;
list2~s~f;
list3~s~f;
Now you can curry SortBy
, which means you can now do
s=SortBy[somereallylongfunction&];
s@list1;
s@list2;
s@list3;
The same works for a lot of other functions, which take a list or function argument, including (but not limited to) Select
, Map
, Nearest
, etc.
ybeltukov over on Mathematica.SE was able to produce a complete list of these:
{"AllTrue", "AnyTrue", "Append", "Apply", "AssociationMap", "Cases",
"Count", "CountDistinctBy", "CountsBy", "Delete", "DeleteCases",
"DeleteDuplicatesBy", "Extract", "FirstCase", "FirstPosition",
"FreeQ", "GroupBy", "Insert", "KeyDrop", "KeyExistsQ", "KeyMap",
"KeySelect", "KeySortBy", "KeyTake", "Map", "MapAt", "MapIndexed",
"MatchQ", "MaximalBy", "MemberQ", "Merge", "MinimalBy", "NoneTrue",
"Position", "Prepend", "Replace", "ReplacePart", "Scan", "Select",
"SelectFirst", "SortBy", "StringCases"}
Composition and RightComposition
There are new shorthands for Composition
(@*
) and RightComposition
(/*
). An obviously contrived example where these can save characters is seen in the following three equivalent lines
Last@Range@# & /@ Range[5]
Last@*Range /@ Range[5]
Range /* Last /@ Range[5]
If you need a list of numbers sorted in reverse, don't use
Reverse@Sort@x
but
-Sort@-x
to save six bytes. Sorting by a negative value is also useful for SortBy
scenarios:
Reverse@SortBy[x,Last]
SortBy[x,-Last@#&]
-
2
-
1\$\begingroup\$ @JungHwanMin Oh, uhhh, yeah, that's much better. :) \$\endgroup\$ Commented Jul 8, 2017 at 6:39
Use Null
as an iteration variable
As has been mentioned elsewhere, missing arguments are interpreted as Null
. Since iterators such as those used in Sum
or Table
localize the iteration variable, symbols such as Null
can be used as the iteration variable, potentially saving bytes.
For example,
Sum[,{,10}]
is interpreted as Sum[Null,{Null,10}]
, which evaluates to the expected 55
.
Use %
to get a free variable
This tip is only applicable if Mathematica's REPL environment can be assumed. %
is not defined when code is run as a script.
When you can make use of the REPL features, don't do this:
a=someLongExpression;some[other*a,expression@a,using^a]
Instead, remember that Mathematica stores the last evaluated (newline-terminated) expression in %
:
someLongExpression;
some[other*%,expression@%,using^%]
The added newline costs a byte, but you are saving two by removing a=
, so overall this saves one byte.
In some cases (e.g. when you want to print the value of a
anyway), you can even leave off the ;
, saving two bytes:
someLongExpression
some[other*%,expression@%,using^%]
One or two bytes may seem fairly minor, but this is an important case, because it makes extraction of repeated expressions (which is a very common technique) much more useful when golfing:
The normal technique of extracting repeated expressions costs four bytes of overhead, which need to be saved by further uses of the expression. Here is a short table of the minimum number of uses of an expression (by length of the expression) for extraction into a named variable to save anything:
Length Min. Uses
2 6
3 4
4 3
5 3
6 2
... 2
By using the unnamed variable, it will be possible to save a couple of bytes much more often:
When ; is required When ; can be omitted
Length Min. Uses Length Min. Uses
2 5 2 4
3 3 3 3
4 3 4 2
5 2 ... 2
... 2
I don't think %%
or %n
can be used for golfing, because if you don't use them at least twice, you can just put the expression right where it's needed. And if you use it twice, the additional character in the variable name cancels out the savings from omitting some x=
.
-
\$\begingroup\$ Note that it doesn't work in script mode. \$\endgroup\$ Commented Nov 30, 2015 at 16:10
-
\$\begingroup\$ @alephalpha What is script mode? \$\endgroup\$ Commented Nov 30, 2015 at 16:13
-
-
\$\begingroup\$ @alephalpha Oh right, I shut off my brain there for a second... so that would mean it can't be really be used at all, unless the REPL environment can be assumed. \$\endgroup\$ Commented Nov 30, 2015 at 16:26
Mathematica 10.2: BlockMap
is Partition
+Map
This tip could also be titled, "Read the release notes, all of them". (For reference, here are the release notes for 10.2 and here of today's 10.3 release.)
Anyway, even minor releases contain a wealth of new features, and one of the more useful ones (for golfing) from 10.2 is the new BlockMap
function. It essentially combines Partition
and Map
, which is great for is golfers, because Partition
is used quite often, and it's a really annoyingly long function name. The new function won't shorten Partition
by itself, but whenever you want to map a function onto the partitions (which probably happens more often than not), you can now save a byte or two:
#&/@l~Partition~2
BlockMap[#&,l,2]
#&/@Partition[l,3,1]
BlockMap[#&,l,3,1]
The savings get even bigger when the new position of the unnamed function allows you to save yourself some parentheses:
#&@@(#&/@Partition[l,3,1])
#&@@BlockMap[#&,l,3,1]
Unfortunately, I have no idea why didn't also add BlockApply
while they were at it...
Also note that BlockMap
does not support the 4th parameter you can use with Partition
to get a cyclic list:
Partition[Range@5, 2, 1, 1]
(* Gives {{1, 2}, {2, 3}, {3, 4}, {4, 5}, {5, 1}} *)
BlockMap[f, Range@5, 2, 1, 1]
(* Nope... *)
-
\$\begingroup\$
MovingMap[f,list,n-1]
instead ofBlockMap[f,list,n,1]
whenn-1
is at least as short asn
;MovingMap
also supports padding with a constant/list (but on the left by default). \$\endgroup\$– attCommented Mar 1, 2022 at 9:01
Checking if a list is sorted
This is essentially a corollary of this tip but this is a sufficiently common task that I think it warrants its own answer.
The naive way to check if a list is in order is to use
OrderedQ@a
We can do one byte better with
Sort@a==a
However, this doesn't work if we don't have the thing we want to check in a variable already. (We'd need something like Sort[a=...]==a
which is unnecessarily long.) However, there's another option:
#<=##&@@a
The best thing is that this can be used to check whether the input is reverse sorted for the same byte count:
#>=##&@@a
One more byte can be saved if a) we know that the list elements are distinct and b) we know a lower bound between 0 and 9 (inclusive; or upper bound for reverse sorted order):
0<##&@@a
5>##&@@a
To see why this works, check out "Sequences of arguments" in the tip linked at the top.
-
\$\begingroup\$ Alternatively, (strict) lower-bound for reverse-sorted also work:
##>0&@@a
. Similar for upper-bound for sorted. \$\endgroup\$ Commented Oct 6, 2017 at 9:59 -
\$\begingroup\$ @user202729 Oh good point, feel free to edit (otherwise I'll try to do it on the weekend if I remember). \$\endgroup\$ Commented Oct 6, 2017 at 10:00
Repeating a string
Instead of StringRepeat[str,n]
use (0Range[n]+str)<>""
. Or if str
doesn't depend on any slot arguments, even better is Array[str&,n]<>""
as per this tip.
-
1\$\begingroup\$ Corollary: instead of
StringRepeat[s,n+1]
useArray[s&,n]<>s
(even when you already haven+1
in a variable, too). \$\endgroup\$ Commented Aug 31, 2016 at 13:49 -
1
You can stick an expression in Break
which can save one or two characters. Example (other details not golfed for clarity):
result = False;
Break[]
can be turned into
Break[result = False]
to save one character. If the expression in question does not have lower precedence than function application you can even save another character:
Print@x;
Break[]
can be turned into
Break@Print@x
Although undocumented, the argument to Break
seems to be returned by the surrounding loop, which can potentially lead to even more savings.
Here is a list with loads of operator input forms which can shorten a lot of things. Some of these have been mentioned in other posts, but the list is long and I'm always surprised to find a few new things on there:
-
\$\begingroup\$ However, this only works when the operator uses less UTF-8 bytes. \$\endgroup\$ Commented Oct 24, 2015 at 15:03
To remove all whitespace from a string s
, use
StringSplit@s<>""
That is, use StringSplit
's default (split into non-whitespace components) and simply join them back together. The same is probably still the shortest if you want to get rid of any other character or substring:
s~StringSplit~"x"<>""
Alternatives to Range
A very common task is to apply some sort of function to all numbers from 1 to a n
(usually given as input). There are essentially 3 ways to do this (using an unnamed identity function as an example):
#&/@Range@n
Array[#&,n]
Table[i,{i,n}]
I tend to go for the first one (for whatever reason), but this is rarely the best choice.
Using Array
instead
The above example shows that using Array
has the same byte count. However, it has the advantage that it is a single expression. In particular, if you want to further process the result with a function f
you can use prefix notation, which saves a byte over Range
:
f[#&/@Range@n]
f@Array[#&,n]
Furthermore, you may be able omit parentheses around your unnamed function which you might have needed with Range
, e.g.
15/(#&)/@Range@n
15/Array[#&,n]
If you don't want to use it further (or with an operator which has lesser precedence), you can instead write Array
itself in infix notation and also save a byte:
#&/@Range@n
#&~Array~n
Hence, Array
is almost certainly better than Range
.
Using Table
instead
Now table has to make up for 3 bytes, or at least 2 when infix notation is an option:
#&/@Range@n
i~Table~{i,n}
When not using infix notation, Table
might allow you to omit parentheses if your function consists of several statements:
(#;#)&/@Range@n
Table[i;i,{i,n}]
This is still longer, but gives extra savings with in the case mentioned below.
The real savings stem from the fact that Table
gives the running variable a name should not be dismissed. Often, you'll have nested unnamed functions where you want to use the outer variable inside one of the inner functions. When that happens, Table
is shorter than Range
:
(i=#;i&[])&/@Range@n
Table[i&[],{i,n}]
i&[]~Table~{i,n}
Not only do you save the characters for assigning i
, you might also be able to reduce the function to a single statement in the process, which allows you to use infix notation on top of it. For reference, Array
is also longer in this case, but still shorter than Range
:
(i=#;i&[])&~Array~n
When would you actually use Range
?
Whenever you don't need a function call to process the values, e.g. when the mapping can be performed via a vectorised operation. For instance:
5#&~Array~n
5Range@n
#^2&~Array~n
Range@n^2
Of course, it's also shorter if you don't want to map any function at all, e.g.
Mean@Array[#&,n]
Mean@Range@n
-
\$\begingroup\$ Finally someone else who uses
f/@Range[x]
regularly... \$\endgroup\$ Commented Oct 24, 2015 at 15:05
Finding the smallest number that satisfies a condition
Some construct like i=1;While[cond[i],i++]
is fine as is, but there is an alternative that is two bytes shorter:
1//.i_/;cond[i]:>i+1
The above code repeatedly replaces a number i
with i+1
while it meets the condition cond[i]
. In this case, i
starts at 1
.
Note that the default maximum number of iterations is 2^16 (= 65536). If you need more iterations than that, While
would be better. (MaxIterations->∞
is too long)
Storing functions and expressions in a variable
If your answer ends up using the same functions or expressions multiple times, you may want to consider storing them in variables.
If your expression is length l
and you use it n
times, it would normally use up l * n
bytes.
However, if you store it in a length-1 variable, it would take only 3 + l + n
bytes (or 2 + l + n
bytes, if you assign the variable where you won't need CompoundExpression (;)
or parentheses).
For example, let's consider a simple problem, finding twin primes less than N.
One could write this 54 byte solution:
Select[Range@#,PrimeQ@#&&(PrimeQ[#+2]||PrimeQ[#-2])&]&
In this example, the function PrimeQ
is used three times.
By assigning PrimeQ
a variable name, the byte count can be reduced. Both of the following are 48 bytes (54 - 6 bytes):
Select[p=PrimeQ;Range@#,p@#&&(p[#+2]||p[#-2])&]&
Select[Range@#,(p=PrimeQ)@#&&(p[#+2]||p[#-2])&]&
Abuse short-circuit evaluation
You can sometimes replace If
with a logical operator.
For instance, let's say you want to make a function that checks whether a number is prime, and print 2*(number) - 1
is if it's true:
If[PrimeQ@#,Print[2#-1]]&
It's shorter if you use &&
instead:
PrimeQ@#&&Print[2#-1]&
Even when you have multiple expressions, you still save byte(s):
If[PrimeQ@#,a++;Print[2#-1]]&
PrimeQ@#&&a++&&Print[2#-1]&
(* or *)
PrimeQ@#&&(a++;Print[2#-1])&
You can use ||
for cases when you want the condition to be False
:
If[!PrimeQ@#,Print[2#-1]]&
(* or *)
If[PrimeQ@#,,Print[2#-1]]&
(* can become *)
PrimeQ@#||Print[2#-1]&
These tricks work because logical operators can be short-circuited; the second argument and thereafter don't even need to be valid boolean expressions.
Of course, this does not work if you need the return value of If
or when you need both truthy and falsy arguments of If
.
Special characters
This post is community wiki. Feel free to edit and add more characters that you find useful.
Mathematica has many special named characters. Some of them are helpful for golfing. But these characters are hard to type outside Mathematica. Some are even in the Private Use Areas.
The following is a list of commonly used named characters, so that you can copy and paste.
Other than the 2-byte °
(\[Degree]
), all of these characters are 3 bytes long.
:\[Conjugate]
, conjugate of a complex number
:\[ConjugateTranspose]
, conjugate transpose of a matrix
:\[Cross]
, cross product∛
:\[CubeRoot]
, cube root°
:\[Degree]
, degree,Pi/180
:\[DirectedEdge]
, directed edges in a graph;->
often works instead∣
:\[Divides]
,a∣b
meansb
is divisible bya
∈
:\[Element]
, tests membership in a domain or region (e.g.Primes
,Ball[]
)⧦
:\[Equivalent]
, logical equivalence
:\[Function]
, anonymous functions; in 12.3+ you can write|->
:\[HermitianConjugate]
, the same as
(\[ConjugateTranspose]
)
:\[Implies]
, logical implication∞
:\[Infinity]
, infinity⋂
:\[Intersection]
, set intersection⌈⌉
:\[LeftCeiling]\[RightCeiling]
,⌈x⌉
is the ceiling ofx
⌊⌋
:\[LeftFloor]\[RightFloor]
,⌊x⌋
is the floor ofx
⊼
:\[Nand]
, logical nand⊽
:\[Nor]
, logical nor
:\[Piecewise]
,{{a,b}...}
is roughly equivalent toWhich[b,a,...,True,0]
√
:\[Sqrt]
, square root
:\[Transpose]
, transpose of a matrix
:\[UndirectedEdge]
, undirected edges in a graph;<->
often works instead⋃
:\[Union]
, set union
:\[VectorLess]
,xy
meansx[[i]]<y[[i]]
for everyi
:\[VectorLessEqual]
,xy
meansx[[i]]<=y[[i]]
for everyi
:\[VectorGreater]
,xy
meansx[[i]]>y[[i]]
for everyi
:\[VectorGreaterEqual]
,xy
meansx[[i]]>=y[[i]]
for everyi
:\[Xnor]
, logical xnor⊻
:\[Xor]
, logical xor
More can be found in this link: https://reference.wolfram.com/language/guide/ListingOfNamedCharacters.html
Using Optional (:)
Optional (:)
can be used to expand lists in replacements, without having to define a separate rule for the expansion.
This answer by me and this answer by @ngenisis are examples.
Usage
... /. {p___, a_: 0, b_, q___} /; cond[b] :> ...
The above replacement first uses the pattern {p___, a_, b_, q___}
and finds a match such that b
meets a certain condition.
When no such match is find, it omits a_
and instead searches for {p___, b_, q___}
. a
is not included in the search and is assumed to have the value 0
.
Note that the second pattern search would only work for b
that occurs at the beginning of the list; if a b
value satisfying a condition is in the middle, then {p___, a_, b_, q___}
(which has a higher precedence) would match it instead.
The replacement is equivalent to prepending a 0
when a b
satisfying a condition occurs at the beginning of the list. (i.e. there is no need to define a separate rule, {b_, q___} /; cond[b] :> ...
)
Know when (and when not) to use named pure function arguments
For code golf, pure Function
arguments are most commonly referenced using Slot
s; e.g. #
for the first argument, #2
for the second, etc. (see this answer for more details).
In many cases, you will want to nest Function
s. For example, 1##&@@#&
is a Function
which takes a list as its first argument and outputs the product of its elements. Here is that function in TreeForm
:
Arguments passed to the top level Function
can only fill Slot
s and SlotSequence
s present at the top level, which in this case means that the SlotSequence
in the inner Function
will not have any way of accessing arguments to the top level Function
.
In some cases, though, you may want a Function
nested within another Function
to be able to reference arguments to the outer Function
. For example, you may want something like Array[fun,...]&
, where the function fun
depends on an argument to the top level Function
. For concreteness, let's say that fun
should give the remainder of the square of its input modulo the input to the top level Function
. One way to accomplish this is to assign the top level argument to a variable:
(x=#;Array[Mod[#^2,x]&,...])&
Wherever x
appears in the inner Function
Mod[#^2,x]&
, it will refer to the first argument to the outer Function
, whereas #
will refer to the first argument to the inner Function
. A better approach is to use the fact that Function
has a two argument form where the first argument is a symbol or list of symbols that will represent named arguments to the Function
(as opposed to unnamed Slot
s). This ends up saving us three bytes in this case:
xArray[Mod[#^2,x]&,...]
is the three byte private use character U+F4A1
representing the binary infix operator \[Function]
. You may also use the binary form of Function
within another Function
:
Array[xMod[x^2,#],...]&
This is equivalent to the above. The reason is that, if you are using named arguments, then Slot
s and SlotSequences
are assumed to belong to next Function
above which does not use named arguments.
Now just because we can nest Function
s in this way, doesn't mean we always should. For example, if we wanted to pick out those elements of a list that are less than the input, we might be tempted to do something like the following:
Select[...,xx<#]&
It would actually be shorter to use Cases
and avoid the need for a nested Function
entirely:
Cases[...,x_/;x<#]&
Use ++
/--
to save parentheses
When their argument cannot be modified, PreIncrement
/PreDecrement
still return the incremented/decremented value, albeit with an error message. This can save bytes on increments/decrements that would otherwise require parentheses.
For example, to generate the golden ratio:
(√5+1)/2
√5/2+1/2
++√5/2
Note that this is not the case for constants and unassigned symbols, so ++1
, ++"2"
, ++Pi
, ++var
will not evaluate further (although ++I
does return 1+I
), and if all of its elements are such values, a list argument will also not evaluate. In these cases, we can prepend +
to the argument; +++x
is interpreted as ++(+x)
rather than +(++x)
. Try it online!
You can save a byte by working around Prepend
or PrependTo
:
l~Prepend~x
{x}~Join~l
{x,##}&@@l
or
l~PrependTo~x
l={x}~Join~l
l={x,##}&@@l
Unfortunately, this doesn't help for the more common Append
, which seems to be the shortest equivalent of an Array.push()
in other languages.