Parsing
Converting strings to integers
x.toInteger()
x as Integer
x as int
Looping through list/string
for(a:args){a} // Java-style syntax; braces may be omitted if the body is only one statement
args.any{it} // Must return falsy value to keep iterating
args.min{it} // Sometimes useful for non-falsy values
// Costs 1 byte extra, but delegates calls to the value being iterated
args*.tap{println(replaceAll'a','b')}
// vs
args.any{println(it.replaceAll'a','b')}
// *.with instead of .collect. Also delegates calls to the value being iterated
a.collect{it.replaceAll'a','b'}
// vs
a*.with{replaceAll'a','b'}
a*.replaceAll('a','b')
Chained calls
// Sometimes you can omit the `.` and it'll still work for some reason.
args*.toLong().any{println it}
args*.toLong()any{println it}
// print/println/printf are defined on Object, so they can be called on anything
// This can save a byte sometimes with the same trick
"abc".any{print it};println()
"abc".any{print it}.println()
"abc".any{print it}println()
Looping through integers
10.times{}
for(n:0..9){} // better than .times when the variable is used at least twice and braces aren't needed
0.upto(10){}
(0..9).any{} // or any other list methods
0.step(10,2){} // loop with a step
Type Annotations
Type annotations are optional in Groovy and should usually be avoided. However they can sometimes actually make code shorter.
If you're storing an object in a variable anyway, the shortest way to invoke a class's constructor is:
ClassName v=[arg]
// vs
v=new ClassName(arg)
Typed variables can coerce values on assignment:
// Loop over the char values of the string
// Prints: 97 98 99 100
for(int c:'abcd')print"$c "
int i
// Typed variables are zero-initialized
// Prints: 0
println i
// We can do integer division without intdiv!
i=3/2
// Prints: 1
println i
i=5/2
// Prints: 2
println i
// However this still prints 2.5:
println(i=5/2)
Finally, if your solution is timing out, applying annotations to some of the variables can help Groovy optimize your code so it runs faster.
Misc
- Eval -
Eval.me(), or evaluate() to have access to current scope (Warning: slow)
sum can join a list of strings. It also allows applying a transform at the same time if a closure is passed.
- Short-circuiting is allowed:
i%2||println(i)
- Regex matching:
x.matches("...") -> x=~/.../
- Sometimes you can save a byte by converting a string to regex and avoiding parentheses:
println~(a+b).replace(...) vs println((a+b).replace(...)).
- In some situations, single-character strings can be treated like integers to save 1 byte. For example,
'a'==97 evaluates to true.
- Use spread-dot instead of
collect to apply a method call to all elements in a collection: x*.multiply(2)
- Reference DefaultGroovyMethods and StringGroovyMethods for extra methods Groovy adds to common JDK classes. EncodingGroovyMethods is also worth a look.
- Become familiar with the Groovy operators and how they're overloaded for various types. Some are very useful.
Packers
2:1
Spoiler
Decompressor
evaluate new String('...'.getBytes('UTF-16LE'))
If the hole has no arguments, Eval.me may be used instead of evaluate to save 1 byte.
Compressor
# python
print('CODE'.encode().decode('utf-16le'))