Golfing with GolfScript

codegolf

Edit (2018-06-10): This is old and GolfScript is dead. There are better languages for golfing out there, so I recommend learning a newer one if you really want to compete. This still has a nice introduction to stack based languages.


I’ve been lurking around CodeGolf and decided I’d better learn GolfScript, since it seems to be the dominate golfing language. After searching for a bit, I couldn’t find a site that clearly explained the stack-based esoteric language. So today, I’ll be teaching you how to golf with a 7 iron GolfScript. You can try all the examples at w0lf’s online tester.

There are four basic types: integers, strings, arrays, and blocks. Strings are just arrays of ints, but they are outputted as as characters. GolfScript programs are built using these by pushing them on the stack.

1 1 +

This will put 1 on the stack twice, then pop them off and add them. At the end of all GolfScript programs, the stack is printed out. This program will in turn print 2. There also doesn’t need to be a space between operators, but there does need ot be for numbers. 1 1+ will work, but 11+ will return 11.

A key feature of GolfScript is defining code blocks. This is done by using { and }.

{-1*-}:add;

This program creates a block that pushes -1 to the stack, multiplies, then subtracts. The : assigns this to add, and ; pops it from the stack. Even though we popped it, we can still use it as a normal operator.

{-1*-}:add;1 1 add

Blocks don’t have to have [a-zA-Z], you can assign any character to it.

{-1*-}:+;1 1 +

This assigns the block to +, which overrides the previous +. This new + only works with integers, while the old one worked with arrays, strings, and blocks.

[1 2 3][4 5]+   ->  [1 2 3 4 5]
{.}{*}+:square  ->  {. *}

The second example shows the + combining the two blocks and putting them to into a new one. The . operator pushes the top value of the stack back onto the stack.

Control Flow

Control Flow isn’t the most intuitive thing in the world. if, do, while, and until all act as operators, but with special inputs.

1 2 3 if -> 2
0 5 2 if -> 2

The if syntax is a little weird compared to normal languages, but on par for esoteric ones: <boolean> <true> <false> if. The true block will be executed if the boolean is not 0, {}, "", or []. The false block will be executed if the boolean is one of those.

The rest of the Brady Bunch are a little weird, here’s a do loop.

5{1-..}do      -> 4 3 2 1 0 0
10 1+{1-..}do; -> 10 9 8 7 6 5 4 3 2 1 0

do loops will execute their block and pop the stack. If the popped value is not 0 (or any of the values mentioned above), it will do the block again.

5{1-.}{.}while

while loops will execute the first block and pop. If the value is not 0, then it will execute the second block.

5{.}{1-.}until

until loops will execute the first block and pop. If the value is 0, then it will execute the second block. These aren’t too useful because they are only fired when 0, but they’re there.

Boolean logic

To fire control flow blocks, we either need 0 or not 0. We can get these values by comparing numbers.

3 4 <   -> 1
4 3 >   -> 1
5 5 =   -> 1

8 3 <   -> 0
6 7 >   -> 0
2 3 =   -> 0

< will push 1 if the first input is less than the second input, 0 if not. > will push if greater, and = will push if they’re equal to each other.

We can also get <= and >= by NOTing the output of the opposite.

5 4 <!  -> 1
5 5 <!  -> 1
4 5 <!  -> 0

2 4 >!  -> 1
4 4 >!  -> 1
4 2 >!  -> 0

Operators

There are dozens of operators, so if you want to read up on them go to a WayBack of the site.


Golfing

Now that the basics are out of the way, I’ll be showing you how you can get started golfing. Let’s start with an easy one, reversing a number.

To start with this, we’ll assume the number we want reversed is already on the stack, and we’ll leave the output as the only thing on the stack, since the stack is printed at the end of every program.

We’ll start with a `, which will convert the input to a string. Then we’ll push a -1, which we’ll use in a %. We’re treating the string as a list of characters and indexing it with -1. Then ~ to evaluate it back to a number. So out entire program is `-1%~, which is quite small. That’d be at least 5 lines of Java or any other OOP language.

1234 `-1%~   -> 4321

Now let’s look at random list sorting.

First we’ll make a list of 0 to 9 using 10,. Then, we’ll pop that number off, generate a rand up to 9, and put it in a block: {;9rand}. And finally, we’ll sort the 0-9 list randomly using $: 10,{;9rand}$. This will create a random number that only uses 0-9 once.

Here are some tips when golfing with GolfScript:

Use operators the their advantage

There are a million operators in GolfScript, each with their own functions, so use them to your advantage. Just check out this answer for reversing a string.

Use other people’s code

If your question is finding a range of primes, and someone already has the prime sorting done, it’s okay to use their code. Credit is much obliged, though.

Refer to the language spec

There’s a whole list of operators and functions, so use it! There’s no shame on refreshing the language.

Have fun

It’s golfing, not a World Championship. You’ll learn from every answer you get wrong and right.