21
\$\begingroup\$

Desmos is mainly used as an online graphing calculator, but its graphical and mathematical functionalities can also be applied in certain coding challenges.

I know not that many people use Desmos on this site, but for the people that do, what are some tips for golfing in Desmos?

As usual, please keep the tips somewhat specific to Desmos, and one tip per answer.

\$\endgroup\$

15 Answers 15

12
\$\begingroup\$

(This is mainly a \$\LaTeX\$ trick that can save some bytes. This tip can likely apply to other languages that use \$\LaTeX\$.)

When dealing with exponents(e.g. x^{2}) or other operators that require the usage of brackets(e.g. \sqrt{5}), you can take out the brackets that are automatically there if there is only one digit/character in the exponent. So, x^{2} can be written as x^2. Likewise, \sqrt{5} can be shortened to \sqrt5.

Note that you cannot take out these brackets if there is more than one digit. For example, x^{10} is not the same as x^10.


This exponent trick can even work in summations, where it uses the same notation when indicating the stopping value.

For example, instead of writing...

\sum_{k=0}^{n}k^{3}

...it can be written as:

\sum{k=0}^nk^3

Because if this trick, it is better if you can find a way to maximize the amount of one digit exponential terms in your code, to eliminate the brackets.

For example, it is actually more byte efficient to write a^xa^y (6 bytes) instead of a^{x+y} (7 bytes).

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Extending the exponent trick a little further: you can save two bytes with xx^9 instead of x^{10} and one byte with 1/x^n instead of x^{-n}. \$\endgroup\$ Jun 21, 2021 at 6:21
  • 1
    \$\begingroup\$ @fireflame241 Could x^2 then be further shortened to just xx? Not sure, I've never used this language, but it looks like it might work based on your comment... \$\endgroup\$ Jun 21, 2021 at 15:35
  • \$\begingroup\$ @DarrelHoffman Yes, that works. \$\endgroup\$
    – Aiden Chow
    Jun 21, 2021 at 17:32
7
\$\begingroup\$

You can use /

Pasting in x/5 or 8/3 will give the same result as typing it, just not properly formatted - so in some cases, you don't need the bulky \frac{x}{y}.

\$\endgroup\$
1
  • \$\begingroup\$ It is actually not even necessary to use \frac at all in your code. If we consider fractions in the form (random stuff)/(more random stuff) vs. \frac{random stuff}{more random stuff}, we can see that the / way will always save at least 4 bytes over the \frac way, and even more in some cases, where you can remove the parentheses in the / way. \$\endgroup\$
    – Aiden Chow
    Jun 20, 2021 at 20:16
7
\$\begingroup\$

Parentheses are not always required for trig functions

For example, tan35.6x=0 is valid and treated as tan(35.6x)=0.

Similarly, tan^23x is treated as tan^{2}(3x).

\$\endgroup\$
4
  • \$\begingroup\$ On the topic of trig functions to powers, I believe you can only do trig functions ^2 ex: sin^2(x) works but sin^3(x) doesnt, so you would have to do sin(x)^3 instead \$\endgroup\$
    – Underslash
    Jun 21, 2021 at 8:05
  • \$\begingroup\$ @Underslash sin^{-1}(x) also works and calculates arcsin(x). \$\endgroup\$
    – Aiden4
    Jun 21, 2021 at 20:21
  • \$\begingroup\$ @Aiden4 Yep, that one works as well, but besides those nothing else works like that \$\endgroup\$
    – Underslash
    Jun 21, 2021 at 21:22
  • 2
    \$\begingroup\$ Wait... I just noticed that the example used (tan(35.6x)=0) is the equation for an isolated Bernard 😂 \$\endgroup\$
    – Aiden Chow
    Feb 23 at 3:57
6
\$\begingroup\$

Edit #2:

(Referring to the example in the first edit)

Apparently you can add a \ at the beginning of the function to make it work(see this comment), which I did not know as well. I guess that invalidates this tip, again.

Edit:

In fireflame241's comment, he brought to my attention that it is not required to have the \left and \right accompanying the bracket pairs. This is true for most cases. But after some testing, there are some cases where taking out the \left and \right does break the code. Specifically, if you are using any function(e.g. total or max) in addition to these brackets, the function will not work(see example below).

Example:

Suppose you want to compare the corresponding elements of two lists, a and b, and see how many of those corresponding elements are the same. That is, something like a=[1,2,3,4] and b=[2,2,3,5] will output 2(the second and third elements of each list are the same).

Here's what someone might do, after learning that you can take out the \left and \right:

total(\{a=b:1,0\})

In theory, this should work perfectly fine, but in reality, Desmos gives an error and it doesn't work. I'm pretty sure it's because it considers l to be a function, and t, o, and a to be variables in this situation. l, o, and t are not defined, so it gives an error saying so.

In cases like this, it would be better to do:

total(1-sign(a-b)^2)

as suggested by the tip below.


First tip to start it off.

When doing comparisons in your code, most of the times, it is better to try not to use brackets { } in your code, because they always require a \left and a \right to go with them, which increases byte count unnecessarily. Instead, we can utilize the sign function.

Consider a naive implementation that returns 0 if a=b, and returns 1 otherwise:
(22 bytes)

\left\{a=b:0,1\right\}

Instead of doing this, we can save 9 bytes by doing a little math instead:
(11 bytes)

sign(a-b)^2

This works because sign(x) returns -1 if x is negative, 0 if x=0, and 1 otherwise. a-b is 0 only when a=b, so sign(a-b) would be 0 only when a=b. If a does not equal b, it returns either -1 or 1. The ^2 is just to convert the -1 to a 1.

Even if we wanted to return 1 if a=b and 0 otherwise, we can still save 9 bytes by doing 1-sign(a-b)^2 instead of \left\{a=b:1,0\right\}.

\$\endgroup\$
7
  • 1
    \$\begingroup\$ The \left{ and \right} can be replaced with \{ and \} respectively, but it makes the expression unrenderable, see desmos.com/calculator/yezfbrlux5 with \{x<0:-x,x^2\}. (You can see the LaTeX with console.log(Calc.getState().expressions.list[0].latex) in the browser console). \$\endgroup\$ Jun 21, 2021 at 6:12
  • \$\begingroup\$ @fireflame241 Oh, I wasn't aware of that. I was wondering why something like \{\} worked, even though it doesn't render anything. In that case, this tip isn't really helpful. \$\endgroup\$
    – Aiden Chow
    Jun 21, 2021 at 6:52
  • \$\begingroup\$ @fireflame241 After some testing, I actually found some cases where taking out the \left and \right does break the code. See the edit. \$\endgroup\$
    – Aiden Chow
    Jun 21, 2021 at 20:05
  • 1
    \$\begingroup\$ This could be fixed with \operatorname{total}(\{a=b:1,0\}) or the shorter \total(\{a=b:1,0\}) \$\endgroup\$ Jun 21, 2021 at 20:07
  • \$\begingroup\$ @fireflame241 how are you supposed to paste that in? \$\endgroup\$
    – Underslash
    Jun 21, 2021 at 20:11
5
\$\begingroup\$

Logical negation

If you want to swap numbers that represent falsy and truthy values, you can use 0^x, where x is the value that needs to be logically negated. To make it work for negative numbers, you can use the absolute value (0^{abs(x)}), suggested by Aiden Chow.

\$\endgroup\$
3
  • \$\begingroup\$ \left|x\right| --> abs(x), making it shorter than your 2nd version. \$\endgroup\$
    – Aiden Chow
    Jun 20, 2021 at 20:29
  • \$\begingroup\$ @AidenChow Whoops, missed that \$\endgroup\$
    – user
    Jun 20, 2021 at 20:34
  • \$\begingroup\$ I just noticed something. Because we only care about the sign of x as opposed to its actual value, we can do 0^{xx} instead of 0^{abs(x)}. \$\endgroup\$
    – Aiden Chow
    Mar 8 at 7:53
4
\$\begingroup\$

You can use function parameters to assign variable values outside of that function, even though it throws an error. Using this, we can save bytes when we repeat expressions inside of functions.

For example, look at this code:

(45 bytes)

f(a)=sort(a)[1]+sort(a)[length(a)]-sort(a)[2]

There is a lot of sort(a)'s in that code, maybe we can shorten it?

Here is what many people might try to do to shorten this:

(49 bytes)

b(a)=sort(a)
f(a)=b(a)[1]+b(a)[length(a)]-b(a)[2]

It seems like making a function just for sort(a) should have helped, but in reality this is actually 4 bytes longer than the initial code.

What can we do then? Well, the following code will do it:

(37 bytes)

b=sort(a)
f(a)=b[1]+b[length(a)]-b[2]

b is using a function parameter a in declaring it, and Desmos is throwing an error because it seemingly doesn't understand this, but at the end, it still works somehow, so it is valid.

\$\endgroup\$
4
\$\begingroup\$

Change \prod to and \sum to

\prod can be replaced with , saving 2 bytes, and \sum with to save 1 byte. Important to note that these are not capital pi Π or capital sigma Σ, but their own distinct characters.

Similarly, \to can be replaced with , but this loses a byte to ->. in either case ( or ->), you can omit the next \ from a function.

Example: x\to\join(x,y) => x->join(x,y) saves 2 bytes.

(special thanks to @Aiden Chow for the correction about ->)

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Actually, simply pasting in -> for also works. So for example, a->join(a,b) will work, even though the -> isn't converted to when pasting it in: example. And furthermore, -> and essentially act the same way when pasting it in (no backslash problems or anything like that), so AFAIK, there is no reason to use over ->, as the latter will always save one byte over the former. \$\endgroup\$
    – Aiden Chow
    Dec 22, 2021 at 3:29
  • \$\begingroup\$ @AidenChow fixed, but keeping the bit about that symbol specifically in case it helps someone with a restricted source challenge or something :P \$\endgroup\$ Jun 28 at 20:38
3
\$\begingroup\$

For functions that use \operatorname{(function name)}, you can simply take out the entire \operatorname part and use the (function name). For example, instead of \operatorname{total}, you can simply write total.

\$\endgroup\$
3
\$\begingroup\$

Here's a cool piecewise trick.

When writing piecewise expressions in the form \{(condition):1,n\} for some value n, you can actually replace them with \{(condition),n\}, saving 2 bytes. I'm not aware of the full details on why this works, but the premise is that with any piecewise in the form \{(condition)\}, like \{x>0\}, if the (condition) is true, then it will return 1, otherwise, it will return undefined (if you are wondering why these values, it is because piecewise expressions are also used in domain/range restrictions). Notice how there is no true or false output in these type of piecewise experssions. This is because 1 and undefined are the "default" values when the true and/or false output is omitted. When writing \{(condition),n\}, you are omitting the true output, which means that it will default to 1, so it is essentially the same as \{(condition):1,n\}.

\$\endgroup\$
2
\$\begingroup\$

When constructing a list with ..., commas can usually be eliminated. For example, one might write [0,...,9] if they did not know about this, but you can actually save 2 bytes by writing [0...9] instead.

In cases where you want to specify the second element(to set your own common difference), the comma is only required between the first and second element. For example, instead of [0,2,...,50], you can write [0,2...50] instead.

Basically, you can replace ,..., with ... to save 2 bytes.

\$\endgroup\$
2
\$\begingroup\$

List comprehension tips

If you are unaware, a new feature has been released in Desmos a few months ago: list comprehensions

They are similar to Python list comprehensions, where you can essentially use loops to construct lists. This functionality now allows us to be able to emulate nested for loops in Desmos, which was previously much harder to do.

List comprehensions follow the below form:

[(expression in terms of var1, ... ,varN) for var1 = (list1), var2 = (list2), ... , varN = (listN)]

This will construct a list by looping through each var1, var2, ... , varN in a nested fashion.

There are some golfs you can do to save bytes in list comprehensions.

Let's take a simple list comprehension below:

\left[\left(a,b\right)\operatorname{for}a=\left[1...10\right],b=\left[1...10\right]\right]

Like any other function, you can simply take out the \operatorname from the for and it will still work. So all in all, you have something like this:

[(a,b)fora=[1...10],b=[1...10]]

Even though the for and a are together, Desmos will still be able to distinguish between them.


A quirk with list comprehensions (and nested for loops in general) is that you will actually get different lists based on the order of each list. Here's an example to illustrate my point (obviously not golfed completely for readability):

[a+b for a = [1,2,3], b = [2,4,6]] --> [3,4,5,5,6,7,7,8,9]
[a+b for a = [2,4,6], b = [1,2,3]] --> [3,5,7,4,6,8,5,7,9]

(Graph)

Generally, a list comprehension is generated following the pseudocode below (using the general list comprehension form that I mentioned earlier):

SET result to empty list

FOR each varN in (listN)
    .
     .
      .
    FOR each var2 in (list2)
        FOR each var1 in (list1)
            ADD (expression in terms of var1, ... , varN) to the end of result
        END FOR
    END FOR
      .
     .
    .
END FOR

PRINT result

A certain ordering of the lists can potentially save a few bytes over another if a code golf challenge requires the list output to be ordered in a certain way.

\$\endgroup\$
2
\$\begingroup\$

Use the dot calls of built-in functions

For most list built-ins that don't require any arguments, they can be called using dot calls instead.

Let's say that the built-in function is called f, and the list is L. You can then use a dot call to use the function like L.f (3 bytes) instead of f(L) (4 bytes), which saves 1 byte. For example, instead of using mean(L), you can instead use L.mean for -1 bytes.

Here is some examples of dot calls being used on a list, and you can find a full list of the built-in functions that allow for dot calls here (Find the folder that is named "Functions that allow dot call"). Note that the full list does put parentheses () after the dot call (like L.mean()), but that can be taken out (L.mean works).

\$\endgroup\$
2
\$\begingroup\$

Regressions

A regression can be used to solve an equation and can be shorter than explicitly typing out the expression for its solution.

For example, the golden ratio can be calculated in 6 bytes, aa-a~1, with the result being stored in a, which is shorter than the 11-byte equivalent 5^{.5}.5+.5.

\$\endgroup\$
1
\$\begingroup\$

Counting the number of digits of a number

The number of digits of a non-negative integer n is:

(19 bytes)

floor(log(n+0^n))+1

This works because when Desmos calculates a number to the power of zero, it will automatically convert the entire exponential term to 1. We use this to our advantage with 0^n, which returns 1 for n=0 (because any number to the power of 0 is calculated as 1, even though the base is 0), and returns 0 for any positive integer.

If n is guaranteed to be a positive integer (n can't be zero), then the formula becomes:

(13 bytes)

floor(logn)+1

If you need to find the number of digits of any integer n, then the formula is:

(28 bytes)

k=abs(n)
floor(log(k+0^k))+1

^ (Could probably be shorter but I can't see it at the moment)

\$\endgroup\$
1
\$\begingroup\$

Removing \left's and \right's from piecewise expressions

(A clarification of this tip that's been edited to oblivion)

When using a piecewise expression, you may have noticed that if you took out the \left and \right from a piecewise expression, it doesn't work. So, for example, the following doesn't work when directly pasted into Desmos:

\{x<0:x,x^3\}

But if you include the \left and \right, it does work:

\left\{x<0:x,x^3\right\}

To fix this issue, you can add a newline in front of the expression that includes the piecewise. In our case, the code to paste into Desmos is:


\{x<0:x,x^3\}

Even though the actual expression doesn't render properly, the graph of the piecewise expression should still show. Note that the piecewise expression will be fragile, which means that while you have selected the expression, most button presses (including buttons like Ctrl) will break the code.


The downside of doing this trick is that every built-in function with the expression that includes the piecewise is not recognized by the Desmos parser. That means that you have to add a \ in front of every built-in function to force Desmos to recognize it as a built-in function, adding one byte per built-in. For example, the following code won't work:


f(l)=min(\{l=0:l.max,l\})

But the following code does work:


f(l)=\min(\{l=0:l.\max,l\})

As a result, if you use too many built-in functions in the same expression as a piecewise expression, you should consider another approach that doesn't involve any piecewise expressions.

For example, consider the following code (it doesn't do anything useful, but it has a whole bunch of built-in functions):

(64 bytes)


f(l)=\{\sort([1...l.\max+1],\join(l,2,3,l.\mean))=l.\median,0\}

It can be shortened by doing the following:

(60 bytes)

f(l)=0^{(sort([1...l.max+1],join(l,2,3,l.mean))-l.median)^2}

Overall, code in the form:


\{a=b,0\}

which includes \$k\$ built-in functions, can be shortened to:

0^{(a-b)^2}

given that \$k\ge2\$. It will save \$k-1\$ bytes.

Similarly, code in the form:


\{a=b:0,1\}

which includes \$k\$ built-in functions, can be shortened to:

1-0^{(a-b)^2}

given that \$k\ge2\$. It will save \$k-1\$ bytes.

These are just two common examples. Techniques will vary based on what you are trying to do.


Because of this, code that includes piecewise expressions usually will have to be pasted in one expression at a time. This is because if you paste the entire code at once, expressions that don't have a piecewise expression in them will still have to include \'s in front of every built-in function in order to work. If you instead paste in the expressions that include piecewise expressions separately, you can avoid this issue.

For example, consider the following code:

L=l.length
f(l)=\{\sort([1...L],l)<L/2,0\}

If you paste this entire code into Desmos all at once, it will not work, because it expects a \ in front of length.

But if you first paste in:

L=l.length

Then paste in:


f(l)=\{\sort([1...L],l)<L/2,0\}

The code will work.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.