17
\$\begingroup\$

Since I've been seeing more ><> submissions floating around lately, I thought it might be a good idea to have a tips page.

Please stick to one tip per post, unless they are closely related.

Official Python interpreter

Official Interpreter on TIO

Online interpreter (some bugs present, but good for most cases)

Another Online Interpreter

\$\endgroup\$
4
  • 10
    \$\begingroup\$ I just realized while looking at the esolang page: the creator of ><> has a name that might sound like "harpoon". \$\endgroup\$
    – mbomb007
    Feb 24, 2015 at 15:32
  • \$\begingroup\$ How can I print a new-line in fish? \$\endgroup\$ Jun 29, 2015 at 22:09
  • \$\begingroup\$ @CaptainMan You can output code points with o, and since newline \n is ASCII 10 you can do ao. \$\endgroup\$
    – Sp3000
    Jun 30, 2015 at 1:32
  • \$\begingroup\$ @Sp thanks, I was trying CR instead of LF and was pushing d instead of a. \$\endgroup\$ Jun 30, 2015 at 1:39

9 Answers 9

5
\$\begingroup\$

Checking against 0

Using ?! instead of 0=? typically saves a byte.

However, just a standard ? may sometimes be better if you can afford a bit of restructuring

?!vA
  B

versus

?vB
 A
\$\endgroup\$
4
\$\begingroup\$

Checking for EOF

When EOF is reached, ><> pushes a -1 onto the stack, which can be checked in one of two ways:

:0(?
:1+?

For the purposes of checking for EOF, these two are negations, so which one is more beneficial depends on the structure of your program.

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

Jump to circumvent starting new lines

Starting a new line sometimes means wasting a lot of leading whitespace on the next line. In such a situation, jumping can be useful.

For instance,

[lots of code here]>[loop body]v
                   ^ ......... <

can be made to fit on one line like so:

[lots of code here][loop body][jump]

For a practical example, here's the Hello World program on one line:

"!dlroW ,olleH"l?!;oe0.
\$\endgroup\$
0
4
\$\begingroup\$

Using jumps as a conditional

Some times you'll wind up writing programs in ><> that require you to do different things upon receiving different inputs. Usually, you'd use conditionals (?) and direction changers to parse this. In some cases, that works fine (especially when there are fewer types of input to handle), but sometimes you end up with something looking like this. (Ignore the fact that this code can be reduced using some other tricks, it's just for demonstration)

i:"a"=?v:"b"=?v"c"=?v>
  .00n1< .00n2<.00n3<

While this is fine, it does have some whitespace (which I personally never like seeing) and it has a lot of repetition (=?v and .00n). Instead of that, you could use a jump and different lines as your conditionals. Here's an example:

i:"a")$"b")+1+0$.>
v1
v2
v3
<.00n

This shaves 10 bytes off. Here's what's happening:

i: We duplicate the input once so we can evaluate it twice

"a")$"b")+ This could be its own sort of tip, but what I'm doing here is checking to see if the input is greater than the character "a" and then if it's greater than the character "b" and adding the result. For "a," this will yield 0, for "b," 1, and for "c," 2.

1+0$. This is where the magic happens; we take the result of this previous simplification and add 1 (giving 1 for "a", 2 for "b", 3 for "c"), then push 0 and swap the values. When we reach the jump, this will move to the line corresponding to the value we've assigned to those characters (e.g. line 1 for "a"). N.B. Line 0 is the top of the program.

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

Using modulus to simplify input

This might be too simple of a tip, so if it is I'll just replace it or delete it.

Let's say you want to take input of two characters, "a" and "b" and return 1, and 2 for each, respectively. You'd probably use conditionals for this, since it makes the most sense, and I'll be using a more condensed form for this specific example.

i:"a")+1+n

This checks to see if the input is greater than "a" and adds 1. Since "a" will return 0 and "b" 1, this will give 1 and 2. This does the job pretty well, but in the case of our inputs, we could go even further.

i:3%n

In mod 3, 97, which is "a"s numerical equivalent, becomes 1, and 98, which is "b"s, becomes 2. For two different numbers, there is guaranteed a mod which gives unique results for both. For more than two, there is a mod that gives unique results, but I don't have the mathematical prowess to find the smallest one in a simple way (e.g. if you have the set {100,101,102,103}, mod 104 would give unique results for each value in it but not in a very helpful fashion). However, in most cases, with input being restricted to a couple alphabetical characters, you can often find a mod that works.

To find the smallest modulus that yields unique results for two numbers, a, and, b, you do as follows. Take the absolute value of the difference of a and b (|a - b|) and find the smallest number, n, which does not divide it. e.g. for 97 and 98, |98 - 97| = 1, and so 2 would be the smallest mod (but for our test program, this gives 1 for 97 and 0 for 98, so mod 3 is better).

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

Writing code that can run two ways

Trampolines (!) are very handy when you want your code to be run forwards and backwards (or up and down). These scenarios are somewhat unlikely, but for palindrome or similar challenges this tip could be useful.

Here's an example: I want to run some code once, then loop through the stack discarding values until I reach 0, and then go down. The pointer enters this loop from the >. You could use a jump to accomplish this, e.g.

?!v80.>ao (let's say I want to print a newline first)

but if the code we want to run once (the code past the >) makes the line longer than 16 characters, we no longer can use the jump in three characters. However, this is an example where it is trivial to run forwards and backwards...

?!v!?<>ao>

Going forwards, we print a newline and then hit ?!v which discards the value if it it isn't 0, then because of the trampoline we skip the next ? and go backwards. The same thing happens and the loop continues until we hit a 0.

This is an oddly specific example, but there are some (perhaps not many) applications.

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

Use char codes to store big numbers and use g to use them more than once

Typically, you'd encode a large number as a char code, for example if you need 1001 you might write 'ϩ' In utf-8 this character is encoded as 2 bytes. If you need this number again you can use [coordinates]g to get the char code at that position. This saves 1 byte as long as the character is in the 16 by 16 top left square.

For example

'ϩ'o'ϩ'o;

vs

'ϩ'o10go;

Same number of characters but 1 byte shorter

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

Use the code as infinite length array

You can store values in the source code area with the g and p commands. For example, you could use the 7th row as a array and access it like this:

i3g

This is significantly shorter than if you used the stack:

i[{:}]

The stack has a additional disadvantage is you need to compensate for any other data you want on the stack. The code box is always accessible regardless of the state of your stack. You can also easily create multiple arrays, or even a 2-dimentional array this way.

You don't even need to keep the row free, ><> will automatically add rows or columns when you write to them. You can read and write any number, even those not normally valid in source code, like line breaks and floating point numbers. This is a valid program that prints 0.5:

12,00p00gn;

Even if there is no character "0.5". This does not seem to work the same for strings.

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

Use i as a shorthand for -1 for programs that take no input, or after the input is exhausted

Pusing -1 is always a bit tricky, requiring 01- (3 bytes). However, the i command pushes -1 if there is no input. This can save 2 bytes.

For example to invert a number normally requites 0$- (3 bytes) but if you don't take input you can do i* (2 bytes)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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