43
\$\begingroup\$

CJam is a GolfScript-inspired stack-based golfing language, created by PPCG user aditsu.

So, in the vein of other language-specific tips questions:

What general tips do you have for golfing in CJam? Please post one tip per answer.

\$\endgroup\$
  • 4
    \$\begingroup\$ See also Tips for golfing in GolfScript; the languages are similar enough that many of the tricks can be adapted either way. \$\endgroup\$ – Ilmari Karonen Oct 12 '14 at 12:38
  • 2
    \$\begingroup\$ @IlmariKaronen After going through the answers in that question, I'd say only around half of them apply to CJam, due to syntactical or logical differences in the languages. \$\endgroup\$ – Optimizer Oct 12 '14 at 13:16

34 Answers 34

23
\$\begingroup\$

Correct modulo for negative numbers

It's often annoying that the result of the modulo operation gives the same sign as the first operand. E.g. -5 3% gives -2 instead of 1. More often than not you want the latter. The naive fix is to apply modulo, add the divisor once and apply modulo again:

3%3+3%

But that's long and ugly. Instead, we can use the fact that array indexing is always modular and does work correctly with negative indices. So we just turn the divisor into a range and access that:

3,=

Applied to -5, this gives 1 as expected. And it's only one byte longer than the built-in %!

If the modulus is a power of 2, you can save another byte using bitwise arihmetic (which is also a lot faster). Compare:

32,=
31&

For the special case of 65536 == 2^16 another byte can be saved by making use of the wrapping behaviour of the character type:

ci
\$\endgroup\$
13
\$\begingroup\$

Pushing concatenated character ranges

  • The string containing all digits "0123456789" can be written as

    A,s
    
  • The uppercase ASCII letters (A-Z) can be pushed as

    '[,65>
    

    which generates the string of all characters up to Z, then discards the first 65 (up to @).

  • All ASCII letters (A-Za-z) can be pushed as

    '[,65>_el+
    

    which works as above, then creates a copy, converts to lowercase and appends.

    But there's a shorter way to do it!

    Then often overlooked ^ operator (symmetric differences for lists) allows to create the same ranges while saving three bytes:

    '[,_el^
    

    '[, creates the range of all ASCII characters up to Z, _el creates a lowercase copy and ^ keeps only characters of both strings that appear in one but not both.

    Since all letters in the first string are uppercase, all in the second are lowercase and all non-letter characters are in both strings, the result in the string of letters.

  • The RFC 1642 Base64 alphabet (A-Za-z0-9+/) can be pushed using the above technique and appending the non-letters:

    '[,_el^A,s+"+/"+
    

    An equally short way of pushing this string makes use solely of symmetric differences:

    "+,/0:[a{A0":,:^
    

    How can we find the string at the beginning?

    All used character ranges (A-Z, a-z, 0-9, +, /) can be pushed as the symmetric difference of to range that start at the null byte, namely 'A,'[,^, 'a,'{,^, '0,':,^, '+,',,^ and '/,'0,^.

    Therefore, executing :,:^ on "A[a{):+,/0" will push the desired characters, but not in the right order.

    How do we find the right order? Brute force to the rescue! The program

    '[,_el^A,s+"+/"+:T;"0:A[a{+,/0"e!{:,:^T=}=
    

    iterates over all possible permutations of the string, applies :,:^ and compares the result to the desired output (permalink).

  • The radix-64 alphabet used, e.g, by crypt (.-9A-Za-z) can be generated using the above method:

    ".:A[a{":,:^
    

    This is the shortest method I know.

    Since all characters in the desired output are in ASCII order, iterating over permutations isn't needed.

  • Not all concatenated character ranges can be pushed in the desired order using :,:^.

    For example, the range 0-9A-Za-z;-? cannot be pushed by executing :,:^ on any permutation of "0:A[a{;@".

    However, we can find a rotated variation of the desired string that can, by using the code

    A,'[,_el^'@,59>]s2*:T;"0:A[a{;@"e!{:,:^T\#:I)}=Ip
    

    which will print (permalink) the following:

    10
    0:@[a{A;
    

    This means that

    "0:@[a{A;":,:^Am>
    

    has the same effect as

    A,'[,_el^'@,59>]s
    

    which can only be used with an empty stack without prepending a [.

\$\endgroup\$
11
\$\begingroup\$

Avoid {…}{…}?

Assume you have an integer on the stack. If it is odd, you want to multiply it by 3 and add 1; otherwise you want to divide it by 2.

A "normal" if/else statement would look like this:

_2%{3*)}{2/}?

However, using blocks is usually not the way to go, since {}{} already adds four bytes. ? can also be used to select one of two items on the stack:

_2%1$3*)@2/?

This is one byte shorter.


Block-? with an empty if statement is always a no-go. For example,

{}{2/}?

is two bytes longer than

{2/}|

If instead you have

{2/}{}?

and the thing you are checking on is non-negative integer, you can do

g)/

The new {}& and {}| are handy, but sometimes problematic if you cannot clutter the stack.

Still, in the case of

_{…}{;}?

you can use a temporary variable instead:

:T{T…}&
\$\endgroup\$
  • 1
    \$\begingroup\$ !)/ and g)/ are shorter in the examples. \$\endgroup\$ – jimmy23013 Oct 25 '14 at 18:14
11
\$\begingroup\$

Switch statements

CJam doesn't have switch statements. Nested if statements work just as well, but {{}{}?}{}? is already 12 bytes long...

If we can transform the condition into a small, non-negative integer, we can transform all case statements in a delimited string and evaluate the corresponding result.

For example, if we want to execute code0 if the integer of the stack is 0, code1 if it is 1, and code2 if it is 2, we can either use

_{({code2}{code1}?}{;code0}?

or

[{code0}{code1}{code2}]=~

or

"code0 code1 code2"S/=~

S/ splits the string into ["code0" "code1" "code2"], = extracts the corresponding chunk, and ~ evaluates the code.

Click here to see switch statements in action.

Finally, as suggested by suggested by @jimmy23013 and @RetoKoradi, we can shorten the switch even more in some cases. Say code0, code1 and code2 have lengths L0, L1 and L2, respectively.

If L0 = L1 ≥ L2

"code0code1code2"L/=~

can be used instead, where L is L0. Instead of splitting at a delimiter, / splits the string into chunks of equal length here.

If L0 ≥ L1 ≥ L2 ≥ L0 - 1,

"cccooodddeee012">3%~

can be used instead. > removes 0, 1 or 2 elements from the beginning of the string, and 3% extracts every third element (starting with the first).

\$\endgroup\$
  • \$\begingroup\$ For the last example, does that have any advantage over "code0code1code2"5/=~? Seems much more straightforward to me, and it's the same length. \$\endgroup\$ – Reto Koradi Oct 18 '15 at 19:12
  • \$\begingroup\$ @RetoKoradi If all snippets have the same length, there's no advantage. For different length, your method can be both shorter and longer than the modulus method. \$\endgroup\$ – Dennis Oct 18 '15 at 21:16
11
\$\begingroup\$

Golfing common array and string values

There are certain short arrays or strings that crop up every now and then, e.g. to initialise grids. Naively, these can cost 4 or more bytes, so it's worth looking for operations on built-in values which will give the same result. Especially base conversion is often useful.

  • [0 1] can be written as 2,.
  • [1 0] can be written as YYb (i.e. 2 in binary).
  • [1 1] can be written as ZYb (i.e. 3 in binary).
  • The matrix [[0 1] [1 0]] can be written as 2e!.
  • [LL] can be written as SS/ (splitting a single space by spaces).
  • "\"\"" can be written as L`.
  • "{}" can be written as {}s.

The latter can be extended to cases where you want all bracket types to save another byte:

  • "[{<()>}]" can be written as {<()>}a`.
  • "()<>[]{}" can be written as {<()>}a`$.

Especially the base conversion trick can be useful to keep in mind for some obscurer cases that pop up every now and then. E.g. [3 2] would be E4b (14 in base 4).

In even rarer cases you might even find the factorisation operator mf useful. E.g. [2 7] is Emf.

Please feel free to extend this list if you come across any other examples.

\$\endgroup\$
10
\$\begingroup\$

Clearing the stack

If you just want to clear the entire stack, wrap it in an array and pop it:

];

What's a bit more tricky is, if you've done a lot of computations, but only want to keep the top stack element and discard everything beneath. The naive approach would be to store the top element in a variable, clear the stack, push the variable. But there's a much shorter alternative: wrap the stack in an array and extract the last element:

]W=

(Thanks to Optimizer who showed this to me the other day.)

Of course, if there's only two elements on the stack, \; is shorter.

\$\endgroup\$
  • \$\begingroup\$ \; would only pop the element below the TOS. Did you mean ;;? \$\endgroup\$ – CalculatorFeline Mar 10 '17 at 15:57
  • 1
    \$\begingroup\$ @CalculatorFeline the second half of the answer is about clearing everything but the TOS. \$\endgroup\$ – Martin Ender Mar 10 '17 at 16:39
9
\$\begingroup\$

e and powers of ten

As in oh-so-many other languages, you can write 1e3 instead of 1000 in CJam.

This works for non-integer bases and even for non-integer exponents as well. For example, 1.23e2 pushes 123.0 and 1e.5 pushes 3.1622776601683795 (square root of 10).

What's not immediately obvious is that 1e3 is actually two tokens:

  • 1 pushes the integer 1 on the stack.

  • e3 multiplies it by 1000.

Why is that important?

  • You can call e<numeric literal> on something that's already on the stack.

    2 3 + e3 e# Pushes 5000.
    
  • You can map e<numeric literal> over an array.

    5 , :e3  e# Pushes [0 1000 2000 3000 4000].
    
\$\endgroup\$
9
\$\begingroup\$

Euclidean norms

The straightforward way of calculating the Euclidean norm of a vector, i.e., the square root of the sum of the squares of its elements, is

2f#:+mq

However, there's a much shorter way.

mh, the hypotenuse operator, pops two integers a and b from the stack and pushes sqrt(a2 + b2).

If we have a vector x := [x1 … xn], n > 1 on the stack, :mh (reduce by hypotenuse) will achieve the following:

  • First x1 and x2 are pushed and mh is executed, leaving sqrt(x12 + x22), on the stack.

  • Then, x3 is pushed and mh is executed again, leaving
    sqrt(sqrt(x12 + x22)2 + x32) = sqrt(x12 + x22 + x32) on the stack.

  • After xn has been processed, we're left with sqrt(x12 + … xn2), the Euclidean norm of x.

If n = 1 and x1 < 0, the above code will produce an incorrect result. :mhz works unconditionally. (Thanks to @MartinBüttner for pointing that out.)

I've used this trick for the first time in this answer.

\$\endgroup\$
  • 2
    \$\begingroup\$ Of course, this has implications for numerical analysis of your program... \$\endgroup\$ – Peter Taylor Oct 17 '15 at 22:22
8
\$\begingroup\$

Convert from base n with a list of numbers greater than n

CJam converts a list to a number with this formula: A0*nl + A1*nl-1 + A2*nl-2 + Al*n0 (with nonnegative n). n is the base and l is the list length. This means Ai can be any integer, which doesn't have to be in the range of [0,n).

Some examples:

  • 0b extracts the last item and cast it to integer. Works like W=i and saves a byte if it wasn't integer. But everything else in the list must also be able to cast into integer.
  • 1b returns the sum. Works like :i:+ and saves two bytes if they weren't integers. It also works with empty lists while :+ doesn't.
  • [i{_1&9 32?_@\m2/}16*;]W%:c converts a character to a string of line endings and tabs, which can be converted back with 2bc. The encoding function isn't easy to be golfed in a code-golf program, though. But you don't usually need that.
  • You can use the following code to convert a string to Unicode characters not in 16 bit, which can be converted back with 2A#b128b:c. (Explanations will be added later. Or perhaps I'll write a new version later.)

    128b2A#b         " Convert to base 1024. ";
    W%2/)W%\:+       " Convert to two base 1024 digit groups. ";
    [0X@
    {
      _54+
      @I+_Am>@\-
      _Am<@+ 0@-@1^
    }fI
    ]);)
    @\+[~+]2A#b_2G#<!{2A#b}*
    \W%+:c
    

The similar method works with any set of n integers which have different values mod n, if you can find some way to get rid of the most significant digit.

\$\endgroup\$
8
\$\begingroup\$

Using $ as ternary if

When you don't mind leaking memory, i.e., leaving unused elements on the stack that you'll later clear with ];, the copy operator $ can be a handy substitute for the ternary operator ?.

? works well if you manage to compute the condition before pushing the two items to choose from, but more often than not, the condition actually depends on those items, and having it on top of them results much more natural.

If you have A B C on the stack, you can execute

!$

instead of

\@?

to copy B if C is truthy and A otherwise.

If C is an actual Boolean (0 or 1), you can execute

$

instead of

@@?

to copy A if C is truthy and B otherwise.

\$\endgroup\$
  • \$\begingroup\$ In hindsight, this is a rather obvious trick, but I had never thought of it before. I've used it for the first time in this answer. \$\endgroup\$ – Dennis Jul 4 '15 at 21:36
7
\$\begingroup\$

Map for Nested Lists

Say you've got a nested list, like a matrix:

[[0 1 2][3 4 5][6 7 8]]

Or an array of strings:

["foo""bar"]

And you want to map a block onto the nested level (i.e. apply it to each number or each character). The naive solution is a nested %:

{{...}%}%

However, you can actually push the inner block onto the stack and then use f%. f is "map with additional parameter", so it will map % onto the outer list, using the block as the second parameter:

{...}f%

Saves two bytes.

Another neat trick to do something like for (i=0; i<5; ++i) for (j=0; j<5; ++j) {...} is

5,_f{f{...}}

The outer f will map onto the first range, supplying the second range as an additional parameter. But now, if you use f again, only the top stack element is an array, so you f maps the inner block onto that, supplying the outer "iteration variable" as an additional parameter. This means the inner block is runs with i and j on the stack.

This has the same number of characters as just mapping a block onto a Cartesian product (although the latter gets shorter if you need the pairs as arrays):

5,_m*{~...}%

The difference is that this version yields a single array of results for all pairs, whereas the double-f yields a nested list, which can be useful if you want to store the results in a grid, with the iterator variables being the coordinates.

Thanks to Dennis for showing me this trick.

0.6.4 Update

f and : have now been immensely improved by taking any other operator including themselves. This means you can save even more bytes now. Mapping an operator onto a nested list got even shorter now:

{:x}%
{x}f%
::x

This doesn't really help with mapping blocks onto nested lists though.

As for the applying blocks or operators to the Cartesian product, this also got shorter now, for blocks as well as operators:

5,_f{f{...}}
5,_ff{...}

5,_f{fx}
5,_ffx

What's nice is that you can now nest these. So you can apply an operator just as easily to the third level down a list:

:::x

Or a block with some trickery:

{...}ff%
\$\endgroup\$
  • \$\begingroup\$ Great update. But there is still no f~... \$\endgroup\$ – jimmy23013 Feb 13 '15 at 17:42
  • \$\begingroup\$ @user23013 f expects a binary operator, ~ is unary; did you perhaps want :~? Also, we can discuss this in chat \$\endgroup\$ – aditsu Feb 13 '15 at 19:13
  • \$\begingroup\$ Am I missing something about this 0.6.4 update? I still get error messages doing those tricks, like Unhandled char after ':': : (link) \$\endgroup\$ – Runer112 Feb 13 '15 at 21:40
  • 2
    \$\begingroup\$ @Runer112 Works for me. Make sure you reload properly (i.e. not from cache). Depending on your browser Ctrl+F5 should work. \$\endgroup\$ – Martin Ender Feb 13 '15 at 21:41
  • \$\begingroup\$ @MartinBüttner It was indeed caused by silly caching. Thanks. \$\endgroup\$ – Runer112 Feb 13 '15 at 21:43
7
\$\begingroup\$

Vectorized operators for ASCII art

For many ASCII art challenges, it is useful to generate two different patterns to superpose them later. Vectorized operators can be very helpful to achieve different types of superpositions.

One useful property of operator vectorization is that the operator is only executed once for each element of the shorter string/array, while the elements of the larger one that do not have counterparts remain untouched.

  • .e<

    The minimum operator e< work for pairs of strings, characters, arrays and integers; it pops two items from the stack and pushes the lower on e back.

    Since a space has a lower code point than all other printable ASCII characters, .e< can be used to "erase" parts of a generated pattern:

    "\/\/\/\/\/" "    " .e<
    
    e# This pushes "    \/\/\/".
    

    For a full example, see my answer to Me Want Honeycomb.

  • .e>

    The maximum operator e> works as the minimum operator, with the opposite result.

    Again, because of the low code point of the space, .e> can be used to insert a pattern of printable characters in a block of spaces:

    [[" " " " " " " "] [" " " " " " " "]][["+" "" "-" ""]["" "*" "" "/"]] ..e>
    
    e# This pushes [["+" " " "-" " "] [" " "*" " " "/"]].
    

    For a full example, see my answer to Seven Slash Display.

  • .e&

    The logical AND operator e& pushes its left argument if it is falsy and its right argument otherwise.

    If neither pattern contains falsy elements, this can be used to inconditionally impose one pattern over another one:

    "################" " * * * *" .e&
    
    e# This pushes " * * * *########".
    

    For a full example, see my answer to Print the American Flag!.

  • .e|

    The logical OR operator e| can be used as above, with reversed argument order:

    " * * * *" "################" .e|
    
    e# This pushes " * * * *########".
    
\$\endgroup\$
6
\$\begingroup\$

Use & to check if an item is in a list

For

1 [1 2 3] #W>
1 [1 2 3] #)

You can use

1 [1 2 3] &,
1 [1 2 3] &

instead, which returns 0/1 and truthy/falsey respectively.

\$\endgroup\$
6
\$\begingroup\$

z and non-rectangular arrays

The zip operator z transposes the rows and columns of a two-dimensional1 array A, whose elements can also be iterables.

For non-rectangular arrays – unlike the built-in zip functions in, e.g., Python (truncates the rows to the same length) or Ruby (pads the rows with nil) – CJam simply converts the columns of the array into rows, ignoring their lengths and gaps.

For example, zipping the array

[
  [1]
  [2 4]
  [3 5 6]
]

is equivalent to zipping the array

[
  [1 4 6]
  [2 5]
  [3]
]

or the array

[
  [1]
  [2 4 6]
  [3 5]
]

as all three actions push

[
  [1 2 3]
  [4 5]
  [6]
]

on the stack.

While this means that z is not an involution (which would be useful on occasions), it has a few applications.

For example:

  • We can align the columns of an array to the top (i.e., turn the first array into the second) by zipping twice:

    zz
    
  • Minor modifications of the above method can be used for similar problems.

    For instance, to align the columns of an array to the bottom (i.e., to turn the second array into the first), we can zip twice with reversed row order:

    W%zzW%
    
  • Given an array of strings, we can compute the length of the longest string like this:

    :,:e>
    

    However, by zipping and calculating the number of rows of the result, we can save three bytes:

    z,
    

1 If any of the "rows" of A is not iterable, z treats them as singletons, so zipping works for arbitrary arrays.

\$\endgroup\$
  • 1
    \$\begingroup\$ Just a different way of visualizing the same thing, but for me the behavior is much more logical if I picture z converting columns into rows, while empty values are skipped. In the example, the first column in the input is 1, 2, 3, the second column is 4, 5 (empty position is skipped), and the third column is 6. These are then the rows of the result. \$\endgroup\$ – Reto Koradi Aug 28 '15 at 2:32
  • \$\begingroup\$ @RetoKoradi That's a much better way to describe it. \$\endgroup\$ – Dennis Aug 28 '15 at 3:04
6
\$\begingroup\$

Exceptions

All exceptions are fatal in CJam. Since output to STDERR is ignored by default, we can use this to our advantage.

All operator in CJam work by popping zero or more elements from the stack, perform some task and push zero or more elements on the stack. Exceptions occur while the task is performed, so this still pops the elements, but nothing is pushed in return.

Here are a few use cases:

  • Clearing a small stack

    To clear a stack that contains two elements, @ can be used. @ tries to pop three stack elements, but fails after popping the second.

    Any other operator that pops three elements would serve the same purpose.

    See it in action here.

  • Removing two or three elements from the stack

    Any operator that is not implemented for these particular elements can be used to pop two or three elements from the stack right before exiting.

    To pop two elements, b works if one of them is a character or none of them is an integer.

    To pop three elements, t works if none of the bottom-most two is an iterable, the bottom-most iterable is empty or none of them is an integer.

  • Exiting from a loop

    On occasions, we need to exit from a loop when an integer becomes zero or a string becomes too short. Rather than testing for these conditions, if the involved operations fail for zero, the empty string or singletons, we can simply let the program take its natural course.

    For an example involving arithmetic, see here.

    For an example involving strings, see here.

  • Conditional execution

    If the source code should not be executed for certain types of input, we sometimes can use an operator that fails that kind of input.

    For example, i will fail for strings that do not evaluate to an integer and ew will fail for strings of length 0 or 1.

    See it in action here.

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

Max/Min from an array

Here is one for starters!

When you need to find the maximum or minimum number from an array, the easiest and smallest way is to sort the array and then take out the first or last element.

So if the array is in variable A

A$W=

is the maximum and

A$0=

is the minimum.

Get both at the same time is also possible

A$)\0=

This might seem obvious after reading, but anyone's first attempt tends to go towards the usage of e< or e> via iterating through the array, which goes like

A{e<}*

which is 2 bytes longer, and even longer if you want both max and min.

\$\endgroup\$
  • \$\begingroup\$ Of course, if you don't mind the rest of the array remaining on the stack, you can actually use ( and ) instead of 0= and W=. \$\endgroup\$ – Martin Ender Oct 11 '14 at 23:57
  • \$\begingroup\$ Now there is :e< and :e> \$\endgroup\$ – aditsu Jun 29 '15 at 10:51
  • \$\begingroup\$ @aditsu Though, they are not shorter than the tip above. \$\endgroup\$ – Optimizer Jun 29 '15 at 11:07
5
\$\begingroup\$

Use a timestamp for large numbers

If you need a very large, but arbitrary number, you'll usually either use scientific notation like 9e9 or raise one of the large built-in variables to a similar power, like KK#. However, if you don't care what the actual number is, and it doesn't need to be consistently the same (e.g. as the upper bound for a random number), you can do it in two bytes using

es

instead. This gives the current timestamp in milliseconds, and is on the order of 1012

\$\endgroup\$
  • 3
    \$\begingroup\$ Also note that if you want a large arbitrary number, and want to discard a positive number together, you can use e9. \$\endgroup\$ – jimmy23013 Dec 26 '14 at 15:20
5
\$\begingroup\$

Checking that two strings/arrays are not equal

Sometimes you want a truthy value when two strings or arrays are not equal, and a falsy value if they are. The obvious solution is two bytes:

=!

Check for equality, and invert the result. However, under some conditions you can use

#

When # is applied to two arrays it actually searches for the second array as a subarray of the first (and gives you the index where the subarray starts). So if the two arrays are the same, the subarray will be found right at the start and give 0, which is falsy. But if the second array cannot be found, it will give -1 which is truthy.

The reason we need some additional condition on the two arrays is that this also yields a falsy value if the second array is a non-trivial prefix of the first, e.g.:

"abc""ab"#

gives 0 although the strings are not the same. The simplest condition which rules out this case is if you know that both arrays will be the same length - in that case if one is a prefix of the other, you know that they are equal. But in specific circumstances there may be weaker conditions that are also sufficient. For instance, if you know that the strings are sorted, a prefix would always be the first string, not the second.

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

c and 16-bit integers

To add (or subtract) unsigned 16-bit integers with proper wrapping, you can use +65536% or +2G#%.

However,

+ci

is a lot shorter. Characters wrap arround at 65536, so casting to Character (c) then to Long (i) has a similar effect to 65536%, with the added benefit that the result will not be negative.

The same trick can be used to push 65535:

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

Power sets

Say you have an array and you want an array with all possible subsets of that array. The trick is to start with an empty array, and then, for each element, duplicate the subsets you already have, and add the new element to them (keeping previous result where the element wasn't added). Note that you need to initialise the stack with the base case, i.e. an array containing only an empty array: That could look like this:

[1 2 3 4 5]La\{1$f++}/

The nice thing about this is, you can immediately run some computation on the subset, potentially without added characters. Say you want the products of all subsets. In that case, the base case is an array containing 1, and at each step, you take the previous list of possible products, duplicate it, and multiply everything in the duplicate by the new element:

[1 2 3 4 5]1a\{1$f*+}/
\$\endgroup\$
4
\$\begingroup\$

Check if items in a list are all the same

I think this also worth mentioning. Use:

)-

Returns truthy if not all the same, or empty list if all the same. Errors if the list is empty.

In case the item extracted might be an array (or string) itself:

)a-

Use ! or !! to get boolean values. In case the item extracted might be an array, and there are at most two kind of different items, and you want it to be 1 if not all the same, this is shorter:

_|,(
\$\endgroup\$
4
\$\begingroup\$

0= for strings

To retrieve the first element of an array, you have to use 0= (or (, if you don't mind leaving the rest of the array on the stack).

However, if that array is a string, casting to character is sufficient.

Example

"xyz"c e# Pushes 'x.
\$\endgroup\$
  • \$\begingroup\$ I don't see why CJam doesn't just let c extract the first element of any array, which would be more useful and consistent. \$\endgroup\$ – Esolanging Fruit Apr 16 '17 at 15:39
4
\$\begingroup\$

Rotating an array (or the stack) one unit to the left

CJam has the rotate left operator m<, which is normally what you should use to rotate an array an arbitrary number of units to the left.

In some cases, you can also use (+ to shift and append:

[1 2 3]       (+ e# Pushes [2 3 1].
[[1] [2] [3]] (+ e# Pushes [[2] [3] 1].

The second example did not work because the arrays first element is also an iterable, so + concatenated instead of appending.

Also, if you want to dump the rotated array on the stack, you can use :\ (reduce by swapping) unconditionally:

[1 2 3]       :\ e# Pushes 2 3 1.
[[1] [2] [3]] :\ e# Pushes [2] [3] [1].

As long as you don't have an open [, this trick can also be used to rotate the entire stack, i.e., to bring the bottom-most stack item to the top:

]:\
\$\endgroup\$
3
\$\begingroup\$

Printing a list and clearing the stack

Lets say your stack has a list of strings/numbers/etc. on top and some other extra items below it. i.e.

123 "waste" ["a" "b" "rty" "print" "me" "please"]

Now you are interested in printing the last list only, so you do

S*]W=

which outputs

a b rty print me please

Which seems really smart as we use the clearing the stack trick and only print the list joined with spaces (which might not be the desired way of printing a list at times).

This can be golfed further!

p];

That's 2 bytes shorter!

and if you have only 1 item on stack other than the list, its even shorter!

p;

The beauty of p is that it removes the top most item from stack, stringifies it (also adds a newline at the end) and prints to STDOUT instantly, without waiting for completion of the code.

So the above code will output

["a" "b" "rty" "print" "me" "please"]

which is the exact representation of a list when it was in stack!

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

Cartesian products or all possible combinations of two or more sets

CJam has an inbuilt Cartesian product calculator m* which takes the top two arraylists/strings on stack and create all possible pairs from it. For example

[1 2 3 4]"abc"m*

leaves

[[1 'a] [1 'b] [1 'c] [2 'a] [2 'b] [2 'c] [3 'a] [3 'b] [3 'c] [4 'a] [4 'b] [4 'c]]

as the stack

But what if you want all possible combinations from more than 2 lists/strings. You use m* that many times ? For example

[1 2 3 4][5 6]"abc"m*m*

will leave the following on stack

[[1 [5 'a]] [1 [5 'b]] [1 [5 'c]] [1 [6 'a]] [1 [6 'b]] [1 [6 'c]] [2 [5 'a]] [2 [5 'b]] [2 [5 'c]] [2 [6 'a]] [2 [6 'b]] [2 [6 'c]] [3 [5 'a]] [3 [5 'b]] [3 [5 'c]] [3 [6 'a]] [3 [6 'b]] [3 [6 'c]] [4 [5 'a]] [4 [5 'b]] [4 [5 'c]] [4 [6 'a]] [4 [6 'b]] [4 [6 'c]]]

Notice that the products are still pairs, where one of the item is a pair itself. This is not expected and we want flattened combinations.

There is an easy way to do that. Just wrap every list that you want for your cartesian product in an array, pairwise create Cartesian products and flatten it each time:

[1 2 3 4][5 6]"abc"]{m*{(+}%}*

This leaves

[['a 5 1] ['b 5 1] ['c 5 1] ['a 6 1] ['b 6 1] ['c 6 1] ['a 5 2] ['b 5 2] ['c 5 2] ['a 6 2] ['b 6 2] ['c 6 2] ['a 5 3] ['b 5 3] ['c 5 3] ['a 6 3] ['b 6 3] ['c 6 3] ['a 5 4] ['b 5 4] ['c 5 4] ['a 6 4] ['b 6 4] ['c 6 4]]

on stack.

Want the order maintained ?, simply swap the before adding the popped item back to the array. i.e.

{m*{(\+}%}*

Want only permutations ?

{m*{(+$}%_&}*

Want only unique elements in the combinations ?

{m*{(+_&}%}*

That's all folks. for now.

\$\endgroup\$
  • 1
    \$\begingroup\$ Now you can also do ]:m*:e_, with any number of arrays \$\endgroup\$ – aditsu Jun 29 '15 at 10:46
3
\$\begingroup\$

Operating on strings

Sometimes if you are working with a complex data structure, while the items in it are simple, converting to strings may help.

For example, if you want to get the first or last few items in a 2D array of bits, and don't care about the returned type, sA< saves a byte from 0=A< or :+A<.

Or if you want to modify some bits in the input, you can modify the string before evaluating it.

Or if you got this structure and want to convert it to a simple list:

[[[[[[[[[1]2]3]4]5]6]7]8]9]

You can do it with many characters in other ways:

[a{~)\}h;]W%

But it can be much shorter with strings:

s:~

It's shorter even if it may have numbers with more than one digit:

[`La`-~]

Or:

`']-~]

If you don't need another array containing many of such arrays.

\$\endgroup\$
  • \$\begingroup\$ There is e_ now \$\endgroup\$ – aditsu Jun 29 '15 at 10:40
  • \$\begingroup\$ @aditsu See this answer and comment. Sometimes s still works better. \$\endgroup\$ – jimmy23013 Jun 29 '15 at 11:51
  • \$\begingroup\$ Sure, when you can work with a string directly, it's shorter. \$\endgroup\$ – aditsu Jun 29 '15 at 12:43
3
\$\begingroup\$

Using N instead of La

In many cases you need something initialized to an array containing an empty array as its only element, which is La, seemingly unnecessarily 1 byte longer.

In many cases you also need to add a newline after each element before printing, which would be something like No or N*.

But if both are true, sometimes you may find out that you can just initialize the array with N, which has the newline character as its only element. Make sure you only prepend things to the elements in the rest of your code, and the first thing to prepend is always a character or an array. Or only append, if a leading newline is acceptable and that makes it shorter.

Sometimes S also works if you need to separate the output with spaces.

In rarer cases, the initial element has to be a string. But you still can use Na which might be shorter than appending the newline afterwards.

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

Splitting on one or more occurrences

Say you have a string "abbcdbbfghbdbb" and you want to split it on b

"abbcdbbfghbdbb"'b/

This leaves on stack:

["a" "" "cd" "" "fgh" "d" "" ""]

Notice the empty strings ? Those are there because two b were together and nothing was in between them. At times, you want to avoid this. You can do this by

"abbcdbbfghbdbb"'b/La-

or filtering out empty strings

"abbcdbbfghbdbb"'b/{},

but that is 3 extra bytes.

A little less known operator for this particular use case is %. Apart from doing mod and map and splitting based on number ("abcd"2% = "ac"), % can also split on strings/arrays. So for the above use case:

"abbcdbbfghbdbb"'b%

will leave

["a" "cd" "fgh" "d"]

on stack.

Thanks for @user23013 for pointing this out in one of my answers today.

\$\endgroup\$
  • \$\begingroup\$ I think this should be named "also learn GolfScript", which has better examples in the documentation. \$\endgroup\$ – jimmy23013 Jan 2 '15 at 9:00
  • \$\begingroup\$ @user23013 but we are never sure what all is similar to GS and what is not. \$\endgroup\$ – Optimizer Jan 2 '15 at 9:06
2
\$\begingroup\$

Use fold/reduce as infix foreach

We have :x as a shorthand for {x}% and or {x}* (depending on whether x is unary or binary). Unfortunately, there is no equivalent infix operator to shorten {x}/. However, very often when we do {x}/, x is actually a binary operator which repeatedly modifies the item lying underneath on the stack. If that's the case, and said item is not an array, we can save a byte by abusing fold/reduce as foreach:

5 [1 2 3 4]{-}/  e# Gives -5
5 [1 2 3 4]+:-

This works because fold always leaves the first element untouched. Unfortunately, it doesn't save a byte, when the modified element is an array, because adding it would unwrap it. However, sometimes you're lucky enough that your array already contains that element at the front, in which case reduce should be kept in mind (instead of manually removing the element before using {}/ on the remainder).

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

print and println

CJam has print operator: o. It works but stack is printing immediately after all the code has executed. You can stop it if you clear the stack at the end of program. Simply put this at the end:

];

To println you can use oNo or p (works as `oNo)

\$\endgroup\$
  • 3
    \$\begingroup\$ There's a larger difference between o and p. p starts by converting the item to be printed to an unambiguous string representation. p is equvalent to executing ​`oNo. \$\endgroup\$ – Dennis Feb 11 '16 at 15:52

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.