| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | 240923T060649Z | 鳴神裁四点一号 | |
| nan | 240126T160256Z | bigyihsu | |
| nan | 240719T015232Z | bigyihsu | |
| nan | 240131T223125Z | bigyihsu | |
| nan | 230722T234345Z | c-- | |
| nan | When taking a single character substring from a string and want to keep it as a string | 221217T044451Z | bigyihsu |
| 005 | When looping a constant n times | 221205T163612Z | bigyihsu |
| nan | 220928T134251Z | bigyihsu | |
| nan | Since an allowable output format is writing to reference arguments | 200623T004858Z | Purple P |
| nan | 190912T162304Z | Purple P | |
| nan | Need a string to contain a newline? Don't write \n | 190908T021035Z | Purple P |
| nan | 190226T164852Z | JayXon | |
| nan | Go has different operator precedence for bit operations | 190226T163251Z | JayXon |
| nan | Go compiler has predefined print and println functions that don't require importing fmt | 180221T000951Z | null |
| nan | You can put any number of opening braces on one line | 160929T190355Z | EMBLEM |
| nan | 160810T195318Z | Justin P | |
| nan | 160605T093826Z | user5340 | |
| nan | If you need to compare many different values to a single one | 160604T052346Z | EMBLEM |
| nan | 160315T053818Z | EMBLEM | |
| nan | Named return values can save a few bytes. For example | 160322T171256Z | EMBLEM |
Built-in functions print and println
According to The Go Programming Language Specification (Language version go1.23 (June 13, 2024):
Current implementations provide several built-in functions useful during bootstrapping. These functions are documented for completeness but are not guaranteed to stay in the language. They do not return a result.
Function Behavior print prints all arguments; formatting of arguments is implementation-specific println like print but prints spaces between arguments and a newline at the endImplementation restriction: print and println need not accept arbitrary argument types, but printing of boolean, numeric, and string types must be supported.
Obtw it can be found on Go 1.17 specification.
Thus printing primitive values can be done without importing the fmt package.
Example of defining a function to accept an integer to print:
import."fmt";func f(x int){Print(x);}
func f(x int){print(x);}
If your challenge have standard I/O applied, then print-ing the output instead of returning the output can save your bytes.
func f(x int)int{return x}
func f(x int)(y int){y=x}
func f(x int){print(x)}
rand.Perm is shorter than rand.Shuffle if and only if you can make an empty spare
These are 2 built-ins included in the math/rand and math/rand/v2 packages to help with shuffle elements:
rand.Permtakes ann intand returns an[]intthat contains half-right-open range[0,n).rand.Shuffletakes an index limitn intand a swapping function, and runs the swapping function on the half-right-open range[0,n). It is expected that the swapping function operates on a collection outside of its scope, i.e. it operates in-place.
For strings, always use rand.Perm.
Because strings in Go are immutable, it is better to use rand.Perm to shuffle elements in strings. Otherwise, a conversion to []rune and back to string is needed to be able to use rand.Shuffle. Given an input string s:
o:="";for _,i:=range Perm(len(s)){o+=s[i:i+1]} // 45 bytes, output on `o`
S:=[]rune(s);Shuffle(len(S),func(i,j int){S[i],S[j]=S[j],S[i]);s=string(S) // 66 bytes, output on `s`
For slices, it depends
The function to use for slices depends on whether you have an empty slice available to you. If you do, it is better to use rand.Perm. Given an input slice s and an empty output slice o:
for _,i:=range Perm(len(s)){o=append(o,s[i])} // 45 bytes, output on `o`
Shuffle(len(s),func(i,j int){s[i],s[j]=s[j],s[i]}) // 50 bytes, output on `s`
If you do not have an empty slice already available, your only option is to use rand.Shuffle and do it in-place:
o:=[]T{};for _,i:=range Perm(len(s)){o=append(o,s[i])} // 57 bytes + length of type name, output on `o`
Shuffle(len(s),func(i,j int){s[i],s[j]=s[j],s[i]}) // 50 bytes, output on `s`
Use range over int when iterating n times (Go 1.22 or newer)
Introduced in Go 1.22 is range-over-int, which iterates from 0 inclusive to the integer exclusive:
for i := range 123 {} // goes from 0 to 123 exclusive
It is also conveniently always shorter than the traditional 3-part for loop:
for i:=0;i<n;i++{}
for i:=range n{} // -2 bytes
However, this requires Go 1.22 or later.
Use min and max to clamp values (Go 1.21+)
Say you have 2 comparables l and h, where you must satisfy l <= h. It is 1 byte shorter to use the builtins than an if-statement.
// assuming
l,h := n, 0
if h<l{h=l}
h=max(h,l)
if l>h{l=h}
l=min(h,l)
// and the opposite
l,h := 0, n
if h>l{h=l}
h=min(h,l)
if l<h{l=h}
l=max(h,l)
Don't declare variables in the for's init statement:
for i:=0;i<n;i++{...}
By declaring it outside you may save a byte when you need a variable outside of it beacause you can now assign to it (=) instead of declaring it (:=):
i:=0
for;i<n;i++{...}
i=0
for;i<n;i++{...}
You might even save a byte if you're not using the for's post-statement by removing the semicolons
When taking a single character substring from a string and want to keep it as a string, use string slices to not get a rune:
string(s[0]) // 12 bytes
s[:1] // 4 bytes
string(s[10]) // 13 bytes
s[10:11] // 8 bytes
string(s[100]) // 14 bytes
s[100:101] // 10 bytes
string(s[1000]) // 15 bytes
s[1000:1001] // 12 bytes
string(s[10000]) // 16 bytes
s[10000:10001] // 14 bytes
This method is shorter than string(s[index]) up to getting from index 100000 and above, but indexing strings of that size are rare.
When looping a constant n times, for-range is shorter up to n <= 5
If you need to loop a constant number of times, a for range"..."{} loop (where ... is n characters) is shorter than a 3-part for loop up to n <= 5 iterations.
The two loop forms are equivalent at n == 5:
for range`|||||`{}
for i:=0;i<5;i++{}
Past n > 5, use a 3-part loop.
If you're using a C-style 3-part for-loop, if your loop variable isn't dependent on something outside of its scope for its initialization, declare it with your other variable declarations to save a byte.
In these examples, i is initialized independently of a
func f(){a:=3;for i:=0;i<a;i++{}}
// vs
func f(){a,i:=3,0;for;i<a;i++{}}
Since an allowable output format is writing to reference arguments, it may save bytes to pass a pointer instead of returning a value.
func f(a,b string)string{if g(a)>g(b){return a};return b}
func f(a,b string, s*string){s=&b;if g(a)>g(b){s=&a}}
Make full use of Go's first-class functions by assigning long library function names to one-letter variables.
import."strings"
r:=Replace
Need a string to contain a newline? Don't write \n, create a raw string with backquotes and put a literal newline in it.
s:="\n" // 7 bytes
s:=`
` // 6 bytes
A lot of stuff in the for range loop is optional.
Standard version:
for i,v:=range a{
// Do stuff
}
If i, v has already been defined and can be overwritten:
for i,v=range a{
// Do stuff
}
If you don't care about value:
for i:=range a{
// Do stuff
}
If you don't care about value and i has already been defined:
for i=range a{
// Do stuff
}
If you don't care about index or value:
for range a{
// Do stuff
}
If you want an infinite loop:
for{
// Do stuff
}
Go has different operator precedence for bit operations, <<, >>, &, etc. usually have lower precedence than + and - in most languages, but in Go they have the same precedence as * and /.
Precedence Operator
5 * / % << >> & &^
4 + - | ^
3 == != < <= > >=
2 &&
1 ||
This could be used to save some parentheses.
Most languages:
(a&b)*c
Go:
a&b*c
Go compiler has predefined print and println functions that don't require importing fmt, so instead of this.
package main
import."fmt"
func main(){Printf(`Hello World
`)}
You can write this.
package main
func main(){print(`Hello World
`)}
Note that this outputs to STDERR.
You can put any number of opening braces on one line, but a line that contains opening braces may contain at most one closing brace.
Correct:
func main(){if true{switch{case 1==1:for{break
}}}}
Also correct:
func main(){if true{switch{case 1==1:for{break}
}}}
Also correct:
func main(){if true{switch{case 1==1:for{
break}}}}
Incorrect:
func main() {
if true{for{break}}
}
Declaring Multiple Variables:
i,s:=0,""
var(i int;s string)
Int From String Conversion: (limited but sometimes helpful)
n:=byte("9"[0])-48 // actual type is uint8
n,_:=strconv.Atoi("9")
And Vice Versa
s:=string(9+48)
s:=strconv.Itoa(9)
Inspired by @EMBLEM's answer here.
You can put a package's functions in the global namespace when you import them like so:
package main
import ."fmt"
func main() {
Printf("Hello World!")
}
If you need to compare many different values to a single one, it may be more space-efficient to use a switch with a single case.
if x==1||x==2||x==3||x==4{}
switch x{case 1,2,3,4:}
You can name packages whatever you like when you import them.
package main
import f "fmt"
func main() {
f.Printf("Hello World\n")
}
Learned this here.
Named return values can save a few bytes. For example:
func x()string{
r:="" //Do stuff
return r}
You can save 3 bytes with
func x()(r string){
//Do stuff
return}
It's more useful if you need to declare multiple variables at the start of your function.