103
\$\begingroup\$

The aim of this post is to gather all the golfing tips that can be easily applied to <all languages> rather than a specific one.

Only post answers that its logic can be applied to the majority of the languages

Please, one tip per answer

\$\endgroup\$
7
  • 6
    \$\begingroup\$ "Majority" by what metric? \$\endgroup\$ Commented Mar 27, 2012 at 10:41
  • 5
    \$\begingroup\$ @leftaroundabout by the metric of the same word \$\endgroup\$
    – ajax333221
    Commented Mar 27, 2012 at 22:01
  • 12
    \$\begingroup\$ The problem is that many languages are (often short-lived) experimental ones with very untypical paradigms, for which typical programming expressions don't make any sense at all. So "majority of all languages" it virtually impossible to fulfill. You should restrict it in some way, e.g. to "majority of languages regularly used on codegolf.SE". At the moment, the answers look quite a lot like "the majority of remotely C-derived languages", but those, albeit the vast majority of all written code is written in them, are not the majority of languages. \$\endgroup\$ Commented Mar 27, 2012 at 22:51
  • 4
    \$\begingroup\$ leftroundabout, I guess we all know what they roughly mean. This is about mostly language-independent optimizations, i.e those not only useful in Brainfuck but maybe Python, C, Java and Fortran at once. General ideas that you can apply in many languages that work similarly. I don't think there is a need to be that precise and specific in tips and a CW question. This is about helping others to golf, not about pissing them off. \$\endgroup\$
    – Joey
    Commented Apr 5, 2012 at 6:10
  • 34
    \$\begingroup\$ Hopefully nobody creates a language called <all languages>... \$\endgroup\$
    – mbomb007
    Commented Apr 4, 2016 at 21:19

44 Answers 44

1
2
6
\$\begingroup\$

Use truth tables

An example condition can be (((A AND B) OR (A OR B)) AND C) OR (A OR C) with A, B and C being boolean variables. But it's so long! Is there any way to shorten it, and prove it acts the same after shortening? Well, truth tables to the rescue!

A B C D=A AND B E=A OR B F=D OR E G=F AND C H=A OR C I=G OR H
0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 1 1
0 1 0 0 1 1 0 0 0
0 1 1 0 1 1 1 1 1
1 0 0 0 1 1 0 1 1
1 0 1 0 1 1 1 1 1
1 1 0 1 1 1 0 1 1
1 1 1 1 1 1 1 1 1

The truth table above represents the possible values and outcomes of the example condition we specified earlier. D, E, F, G and H are variables which make our life a lot easier. You can see what they're assigned to at the top row of the table. The final variable, I, is the outcome of the condition. So, now that we have the outcomes handy, we can simplify the table to just the base variables and the final outcome:

A B C I
0 0 0 0
0 0 1 1
0 1 0 0
0 1 1 1
1 0 0 1
1 0 1 1
1 1 0 1
1 1 1 1

We can now relatively easily see that the condition above really reduces to just A OR C.

\$\endgroup\$
5
  • 3
    \$\begingroup\$ One can also try and ask WolframAlpha. \$\endgroup\$ Commented Feb 23, 2018 at 23:51
  • \$\begingroup\$ @JonathanFrech But how are you going to prove it then? ;) \$\endgroup\$ Commented Feb 24, 2018 at 0:30
  • 5
    \$\begingroup\$ Outsource the proof and trust. \$\endgroup\$ Commented Feb 24, 2018 at 1:01
  • \$\begingroup\$ @JonathanFrech Sorry, but you must be able to prove your answers by yourself, and Wolfram|Alpha doesn't have a proof, so I'm afraid it isn't going to help you much. :) \$\endgroup\$ Commented Feb 24, 2018 at 11:15
  • 3
    \$\begingroup\$ Using a K-map would be more systematic and guarantees an optimal solution. \$\endgroup\$ Commented Dec 27, 2018 at 22:37
5
\$\begingroup\$

Use bitwise operators in your if statements

In an if statement, you can (usually) use the bitwise operator "and" (usually & , if it is present) rather than && or and and save 1-2 bytes. Sames goes with other keywords (not is the same as a bitwise ! or ~ in many languages (saves 2 bytes), or is bitwise | in many languages (saves 1 byte), etc.).

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

Optimize Imports

Use glob imports over specific symbols, especially if you need multiple symbols from the path.

In rust:

use library::some_function; //bad: 25 bytes
use library::*; //good: 13 bytes

Renaming long symbol names may also be able to save you bytes if you use the symbol multiple times.

In rust:

//bad: 100 bytes
use library::*;
fn main(){
    some_very_long_function_name();
    some_very_long_function_name();
}
//good: 76 bytes
use library::some_very_long_function_name as f;
fn main(){
    f();
    f();
}

If you only use a symbol once, using its fully qualified pathname will save bytes.

In rust:

//bad: 48 bytes
use library::*;
fn main(){
    some_function()
}
//good: 41 bytes
fn main(){
    library::some_function()
}

Which techniques to use varies widely based on the language, what symbols you use, and how you use them. If your use case is complicated trying multiple styles will help you find the shortest. Also, make sure you know your language- they all have their own quirks. For example, Java supports glob imports and fully qualified paths but not symbol renaming.

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

Combine multiple/nested if checks using And/Or when possible.

i.e.:

if (a && (b || c)) {

}

instead of:

if (a) {
    if (b) {
        //Do Stuff
    } elseif (c) {
        //Do same stuff
    }
}
\$\endgroup\$
2
  • 6
    \$\begingroup\$ Also, use bitty conditionals (&, `|) to remove more characters. \$\endgroup\$
    – FUZxxl
    Commented Aug 13, 2012 at 18:33
  • 2
    \$\begingroup\$ Although using bitwise & instead of && removes 1 character in some cases it messes up the operator precedence and you will have to put parentheses to make it work.Use it wisely. \$\endgroup\$ Commented Jul 4, 2015 at 22:24
4
\$\begingroup\$

eval() is perfectly safe

In more dynamic languages it can help to make a string of code and then eval() it (or the equivalent in your language), as a way to repeat chunks of code by inserting the code into the right places as a string replace without the overhead of defining and calling functions, or to loop N times without loop boilerplate.

e.g. in Python to print "hello" five times:

for i in range(5):print("hello")

exec('print("hello");'*5)

e.g. in PowerShell calling [math]::Truncate() three times becomes slightly shorter as a function, and slightly shorter again doing a string replace on code and then evaluating it:

$a=[math]::Truncate($a/$b);$b=[math]::Truncate($c/$a);$c=[math]::Truncate($d/$e)

function T($a,$b){[math]::Truncate($a/$b)};$a=T $a $b;$b=T $c $a;$c=T $d $e

'$a=T($a/$b);$b=T($c/$a);$c=T($d/$e)'|% r*ce T [math]::Truncate|iex
\$\endgroup\$
4
\$\begingroup\$

Don't be afraid to put non-printables in your code.

Sometimes, instead of using escapes like \0, \x1f, \033, \n, or \u0003, you can just put the codepoint in the string verbatim. You may need to input code points manually using keyboard shortcuts, a hex editor, or a good old printf "\x1f" >> file

Note that you cannot copy and paste null bytes on Windows.

Since Stack Exchange doesn't play well with non-printables (and they are difficult to read), I like to represent them by <kbd> tags: (make sure to use language-all and escape < and > in the code block)

<!-- language-all: lang-c -->
<pre><code>char str[]="abc<kbd>00</kbd>def";</code></pre>
char str[]="abc00def";

This is very useful for making lookup tables in languages where strings can be indexed like arrays for their codepoint, such as C, C++, asm, C#, and Python (with b''), since the non-printables consist of the first 32 bytes.

int l[]={2,9,31,7};l[x]; // 23 bytes
"02091f07"[x]; // 10 bytes

This also can apply to invalid UTF-8 sequences, but that is very fragile in practice and far less useful.

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

Find better ways to initialise your variables

Some other answers came close to mentioning this already, but in many (strictly typed?) languages, it's shorter to initialise x as empty string like:

x:=""

or x as empty rune (char) like:

x:=''

than

var x string

and

var x rune

Using preexisting values is obviously preferred, but not so easy.

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

Use LF instead of CRLF

If you use CRLF line endings, each newline will count as two characters. Changing this to LF will save one character per newline in your code.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ This works even for some unexpected languages. QBasic's editor uses CRLF, unsurprisingly for a language that was distributed with DOS. But if you create a file with LF line endings in a different editor, QBasic will run it just fine. \$\endgroup\$
    – DLosc
    Commented Oct 10, 2022 at 21:53
  • 1
    \$\begingroup\$ duplicate-ish \$\endgroup\$
    – emanresu A
    Commented Oct 11, 2022 at 1:39
2
\$\begingroup\$

Don't declare variables in for-loops

If for-loops have one statement inside of them, you can move the iterating variable's initialisation with the other variables that you already have declared.

int a=1;for(int i=1;i<n;)a*=++i;  // 32 bytes
int a=1,i=1;for(;i<n;)a*=++i;     // 29 bytes

Also, if you have multiple un-nested for-loops, it would be better if you reuse the same variable. This sort of ties in with this answer.

int a=1;for(int i=1;i<n;)a*=++i;for(int j=2;j<n;)a-=j++; // 56 bytes
int a=1,i=1;for(;i<n;)a*=++i;for(i=2;i<n;)a-=i++;        // 49 bytes

(I know you can do a=i=1, but that is not the point)


Now if you don't have any statement before the for-loop (and you only have 1 for-loop), it would be best to initialise the variable inside the for-loop

for(int i=0;i<99;)i*=2;       // 23 bytes
int i=0;for(;i<99;)i*=2;      // 24 bytes
\$\endgroup\$
1
  • \$\begingroup\$ for some language you can just for(int a=1,i=1;i<n;)a*=++i;for(i=2;i<n;)a-=i++; and using a and i outside is fine \$\endgroup\$
    – l4m2
    Commented Apr 18, 2018 at 19:32
2
\$\begingroup\$

Abs

Instead of

i<Math.abs(n)

,writing

i<n|i<-n

is shorter in some languages

EDIT:

i*i<n*n

is usually shorter suggested by ceilingcat

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

Using float -> integer conversion automatic truncates for flooring (positive values) in most languages that don't strongly enforce types:

f.floor     # Ruby
f.to_i      # -1 byte
int $f      # Perl
0|$f        # -2 bytes
parseInt(f) # Javascript (Never use Math.floor)
0|f

This will truncate downwards (for positive values), and to get the ceil instead, it can be achieved with the same trick by reflecting the value across 0 (not true in all languages / implementations, not always shorter):

(i/5.0).ceil # Ruby
-(i/-5)
0-i/-5       # for integers of i, provided by ShadowRanger
\$\endgroup\$
2
1
\$\begingroup\$

Use magic numbers / magic strings

Code golfers tend to forget using magic numbers while they're golfing, so I'm putting some ways to make magic numbers here.

  • The easiest way a magic number can be used is if the list or string you need to encode is one of two values (and then you can use bit-shifts and logical and to access the bitwise values stored in the magic number).

    • e.g. this answer is a pretty good usage of this type of magic numbers.
  • You can also construct magic numbers/strings via brute force or a similar method.

\$\endgroup\$
0
\$\begingroup\$

plenty of larger powers (^) where an alternative representation is a lot cleaner :

   2 ^         10 ->  4^5
   2 ^         16 ->  4^8 (also 2^2^2^2)

   2 ^         12 ->  8^4
   2 ^         15 ->  8^5

   2 ^         24 ->  8^8
   2 ^         32 -> 16^8
   2 ^         48 ->  8^16
   2 ^         64 -> 16^16

   2 ^        256 -> 2^4^4 (also (4^8)^16, or 16^64)
   2 ^       1024 -> 2^4^5

   2 ^        128 -> 4^8^2 (also 16^32)
   2 ^       4096 -> 2^8^4
   2 ^       8192 -> 4^8^4

   2 ^         48 -> 8^4^2
   2 ^      65536 -> 2^4^8 (also 2^2^2^2^2)

   2 ^        512 -> 4^4^4
   2 ^     131072 -> 4^4^8

 even ridiculously large powers such as

   2 ^   16777216 -> 2^8^8
   2 ^   33554432 -> 4^8^8

   2 ^     524288 -> 4^4^9
   2 ^  268435456 -> 4^8^9

   2 ^ 1073741822 -> 2^(8^10-2) # very close to exponent 
                                # upper limit of GMP
\$\endgroup\$
-1
\$\begingroup\$

Overloading for function

I find useful for golfing to use as C++ templates and give to the sys the chance of create function for the type (it would reduce the code written by one human).

Too if there are + function that use + or - the same algorithm, write all in one function only, that depends from one parameter for say what result one want. In this way recently condense 3 function in one with near 50% written code less; reference palpn() function in codegolf.stackexchange.com/a/148745/58988 .

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can you give example of your recent answer? \$\endgroup\$
    – DELETE_ME
    Commented Nov 25, 2017 at 8:59
  • \$\begingroup\$ @user202729 The function palpn() in codegolf.stackexchange.com/a/148745/58988 it would reassume 3 function "find next palindrome", "find previous palindrome" "say if arg it is palindrome" \$\endgroup\$
    – user58988
    Commented Nov 25, 2017 at 9:47
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.