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.
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.
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
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 [
.
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…}&
!)/
and g)/
are shorter in the examples.
\$\endgroup\$
Commented
Oct 25, 2014 at 18:14
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).
"code0code1code2"5/=~
? Seems much more straightforward to me, and it's the same length.
\$\endgroup\$
Commented
Oct 18, 2015 at 19:12
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).[[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.
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.
\;
would only pop the element below the TOS. Did you mean ;;
?
\$\endgroup\$
Commented
Mar 10, 2017 at 15:57
e
and powers of tenAs 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].
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.
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.
$
as ternary ifWhen 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.
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.
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%
f~
...
\$\endgroup\$
Commented
Feb 13, 2015 at 17:42
f
expects a binary operator, ~
is unary; did you perhaps want :~
? Also, we can discuss this in chat
\$\endgroup\$
Commented
Feb 13, 2015 at 19:13
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 " * * * *########".
&
to check if an item is in a listFor
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.
z
and non-rectangular arraysThe 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.
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\$
Commented
Aug 28, 2015 at 2:32
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.
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.
(
and )
instead of 0=
and W=
.
\$\endgroup\$
Commented
Oct 11, 2014 at 23:57
:e<
and :e>
\$\endgroup\$
Commented
Jun 29, 2015 at 10:51
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
e9
.
\$\endgroup\$
Commented
Dec 26, 2014 at 15:20
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.
c
and 16-bit integersTo 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
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*+}/
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:
_|,(
0=
for stringsTo 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.
"xyz"c e# Pushes 'x.
c
extract the first element of any array, which would be more useful and consistent.
\$\endgroup\$
Commented
Apr 16, 2017 at 15:39
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:
]:\
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!
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.
]:m*:e_
, with any number of arrays
\$\endgroup\$
Commented
Jun 29, 2015 at 10:46
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.
e_
now
\$\endgroup\$
Commented
Jun 29, 2015 at 10:40
s
still works better.
\$\endgroup\$
Commented
Jun 29, 2015 at 11:51
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.
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.
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).
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
)
o
and p
. p
starts by converting the item to be printed to an unambiguous string representation. p
is equvalent to executing `oNo
.
\$\endgroup\$