Tips for golfing in ><> (Fish)

14

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

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

Sp3000

Posted 2015-02-24T15:24:11.660

Reputation: 58 729

9I just realized while looking at the esolang page: the creator of ><> has a name that might sound like "harpoon". – mbomb007 – 2015-02-24T15:32:27.783

How can I print a new-line in fish? – Captain Man – 2015-06-29T22:09:53.443

@CaptainMan You can output code points with o, and since newline \n is ASCII 10 you can do ao. – Sp3000 – 2015-06-30T01:32:47.080

@Sp thanks, I was trying CR instead of LF and was pushing d instead of a. – Captain Man – 2015-06-30T01:39:24.447

Answers

5

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

Sp3000

Posted 2015-02-24T15:24:11.660

Reputation: 58 729

4

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.

Sp3000

Posted 2015-02-24T15:24:11.660

Reputation: 58 729

3

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.

Sp3000

Posted 2015-02-24T15:24:11.660

Reputation: 58 729

3

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.

cole

Posted 2015-02-24T15:24:11.660

Reputation: 3 526

3

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).

cole

Posted 2015-02-24T15:24:11.660

Reputation: 3 526

1

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.

cole

Posted 2015-02-24T15:24:11.660

Reputation: 3 526