12
\$\begingroup\$

Vyxal is a golfing language that has 500+ different commands (achieved through overloads), and is a known beater of Jelly, 05AB1E and most golfing languages.

Henceforth, it seems like a good idea to share some of the tips and tricks of the industry used to get terse programs in Vyxal.

One tip per answer, and no stupid tips like "oh remove comments and whitespace".

\$\endgroup\$
2
  • 6
    \$\begingroup\$ Can we actually enforce the "one tip per answer" please, unlike every other tips question ever? Even if answers are good, please downvote them if they contain more than one tip \$\endgroup\$
    – pxeger
    Apr 20 at 6:55
  • \$\begingroup\$ @pxeger I think that seems reasonable \$\endgroup\$
    – lyxal
    Apr 20 at 6:55

11 Answers 11

7
\$\begingroup\$

Brackets/Structures autocomplete

Totally not stolen from Tips for golfing in keg because Vyxal totally isn't supposed to be keg but 69 times better

If you have a structure (e.g. if/for/while/function/lambda) at the end of your program, and EOF follows, you can leave the closing bracket/semicolon off. Note that this only applies if you are submitting a full program.

For example:

9(0,)

Can be shortened to:

9(0,

And:

{:1=[1,]}

Can be shortened to:

{:1=[1,
\$\endgroup\$
6
\$\begingroup\$

Compress your strings and numbers

Nobody likes long strings. And nobody likes long numbers either. Luckily there's two ways of compressing strings and one way to compress numbers.

Dictionary Compression

Fun fact: Vyxal has access to a roughly 20k word "dictionary" (read: a list of words) which can be used to shorten strings with a) common English words or b) common 3 letter combinations.

To access the words in this dictionary, you need to get the String Compression Code (SCC) of the word and place it inside a normal string (the backtick ones). String Compression Code is simply a way of saying "the base 10 index of the word within the dictionary list converted to a bijective base-1611".

You can get the SCC of a word by using øD. For example:

`Hello`øD

(Try it Online!)

Tells you the SCC for Hello is ƈṡ. However, øD will also return the dictionary compression of a given string:

`Hello, World!`øD

Is turned into ƈṡ, ƛ€!.

øD is fully optimised and will always give you the shortest possible result. For example, compressing abcdef will return ėġḣ².

Base-255 Compression

But what if your string is a bunch of random letters that aren't in the dictionary at all? øD becomes useless for obvious reasons. In this case, you would use « delimited strings.

These strings take everything inside of them, converts it from a bijective base-255 (the vyxal codepage minus «) to base 10. It then converts that result to a bijective base-27 (the lower case alphabet plus space). Important: only stings containing lower case letters and spaces can be Base255 compressed3.

To get the Base255 compression of a string, you can use øc:

`ahroebeodbslnwksozlzbeoxbeodbsonwkdbdi`øc

Tells you that the compression is «∧pŀQb⟨ż₄∑ṄḞḊjẎɾ71(⁼~∇Ċβ«.

But what about numbers???

» strings have got you covered. øC will take an integer and return it converted to a bijective base-255 (the vyxal code page minus »:

69694204206969øC

Gives you »A⟩¾Ǐø7»

1: The bijective base 161 is simply the vyxal code page minus all printable ascii. This is so that SCCs can be embedded inside strings without creating a new string type.

2: Yeah, SCCs don't need to be surrounded by spaces - they can be inside ascii (a÷×b) or even next to each other (£÷¬¶). This is very intentional.

3: I originally allowed for upper and lower case inside base 255 strings, but found that strings are usually shorter when only allowing lower case.

\$\endgroup\$
5
\$\begingroup\$

Remember that mapping/filtering/reducing all cast numbers to ranges

Okay so say you want to apply something over the range [1, n] using Map, Filter or Reduce (or nverse reduce/foldr). Your first instinct might be to do this:

ɾλ....;M # or whatever command you're using

This is unnecessary, as the functional programming commands all cast numbers to range before doing their job, so:

λ....;M

is equivalent.

"But what if my range isn't [1, n], but instead [0, n] or [1, n) for example? Won't I need the corresponding range command?"

Well yes, but actually no if you use flags:

M Make implicit range generation start at 0 instead of 1

m Make implicit range generation end at n-1 instead of n

(source: flag help generated using the -h flag).

\$\endgroup\$
5
\$\begingroup\$

Use the multi-element lambdas if your lambda body is 1-3 bytes

Say you have the following:

λǐṅ;Ẋ

You can turn this into

‡ǐṅẊ

Because combines the next two elements (built-ins) into a single lambda. is for 1 element lambdas (good for when you want to reduce/filter/map a built-in without using v) and is for 3 element lambdas.

\$\endgroup\$
5
\$\begingroup\$

Use \ for single byte strings and for two byte strings

Sometimes you'll need a string of either one or two characters. You could do the following:

`A`
`AB`

But that has an extra backtick at the end. Instead, you can do this:

\A
‛AB

Important

\ pushes the next character as a string no matter what it is. will treat it as if the next two characters were wrapped in backticks (meaning that it will dictionary uncompress a single string compression code).

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

Use of filter lambda

Filter lambda (') can filter out the items which are not truthy from the stack, so you don't need a lambda map and close it and then find out the Truthy indices.

This is a code using the lambda map

ƛǐG5>;T›

But if you use filter lambda, it can be shortened to

'ǐG5>

the last 3 commands are no longer needed!

\$\endgroup\$
1
  • 2
    \$\begingroup\$ This also applies for map lambdas too \$\endgroup\$
    – lyxal
    Apr 20 at 7:46
4
\$\begingroup\$

Custom base decompression

When you're compressing a large amount of data with a limited charset, as in here, you can use a base-255 integer (»...») and the custom base decompression function τ.

For example, say you want to compress this ascii-art:

  /    
 / \   
\   \  
 \ / \ 
  /   /
 / \ / 
\   \  
 \ / \ 
  /   /
 / \ / 
\   \  
 \ / \ 
  /   /
 / \ / 
\   \  
 \ /   
  /    

You can just map 0 to \, 1 to /, and 2 to to get 576780841113635223227691120919222477677740273185690732841 in base-3, which compresses to »ɾĠ^;√⟑•ȮṙDǓ…⟩P½≠1⅛²ė"÷₆Ŀ».

Then, you can take out your compression guide \/ , and append τ to turn it into base-3 with those as values.

Finally, you can split into 17 pieces (for 17 lines) and output joined by newlines - Try it Online!

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

Use the register instead of a variable

Sometimes, you're using a variable over and over again, and it's using so many bytes, right? Well, if you only have 1 variable, you can use the register instead, and save a byte every time you use it!

For example, say you want to do x * 2 and x ^ x. You could do:

3→x ←xd, ←x←xe,

This saves 3 to x, then retrieves it and doubles it, then retrieves twice, and exponentiates. However, x is being used 4 times, so that's 8 bytes in variable references alone! Using the register will shorten this code a lot:

3£ ¥d, ¥¥e,

Instead of saving to and retrieving from a variable, we're using the register, which can be accessed using only 1 byte. Anytime you're using variables, you can replace one of the variables with the register to save some bytes!

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

Use the nameless variable

Vyxal has variables, set by and accessed by . But did you know that there's a nameless variable?

You can access this by just going followed by a non-alphabetic character (it doesn't matter what, and that will still be run). Ditto with setting.

It works in for loops - try 4(|←,).

In other words, it's an extra register that can easily save you a couple of bytes.

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

Use and for certain length checks

Say you have a string and you want to check whether its length is greater than 1, and the output only needs to be truthy or falsy.

You could go L1> for three bytes. Or, you could go for 1 byte.

Ḣ slices off the first character of a string and returns the rest, so running on a length 1 string returns an empty string, which is falsy; on a length ≥2 string, it returns a truthy non-empty string.

What about length >2? Just use ḢḢ, with the same logic as before, and still saving a byte.

Length = 1? There's literally a builtin for this - on strings or lists returns true only if the length is 1.

Length = 2? Just combine the two (Ḣ₃) - if you lop off a character and that string becomes length 1, it must've been length 2.

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

Converting characters to numbers in

When you want to convert characters to numbers, you have to use C, right? Well, there's another way. You can also use b. The b command, when used on a string, will convert each character to its ASCII value, then convert that to binary. You can then use B to convert that back to a decimal value!

`EEEE` b vB

Try it Online!

It's not too often that you'll be able to use bB and not be able to use C, but this can be quite useful in the right circumstances.

\$\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.