95
\$\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\$ – ceased to turn counterclockwis Mar 27 '12 at 10:41
  • 5
    \$\begingroup\$ @leftaroundabout by the metric of the same word \$\endgroup\$ – ajax333221 Mar 27 '12 at 22:01
  • 10
    \$\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\$ – ceased to turn counterclockwis Mar 27 '12 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 Apr 5 '12 at 6:10
  • 24
    \$\begingroup\$ Hopefully nobody creates a language called <all languages>... \$\endgroup\$ – mbomb007 Apr 4 '16 at 21:19

40 Answers 40

1
2
4
\$\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\$
4
\$\begingroup\$

O(n^2) is your friend

You spend your time looking to get rid of O(n^2) algorithms and bring runtime and memory use down; golf turns that around - spend freely of CPU and Memory to bring code size down. Use nested loops, calculate 10x too much data instead of a complex exit condition, call sort() every loop iteration instead of storing the result.

Some questions have a runtime limit to push you to write a more efficient answer, even then knowing how fast your language and code runs can give you room to take liberties and still stay within it.

\$\endgroup\$
4
\$\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\$ – Jonathan Frech Feb 23 '18 at 23:51
  • \$\begingroup\$ @JonathanFrech But how are you going to prove it then? ;) \$\endgroup\$ – Erik the Outgolfer Feb 24 '18 at 0:30
  • 5
    \$\begingroup\$ Outsource the proof and trust. \$\endgroup\$ – Jonathan Frech Feb 24 '18 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\$ – Erik the Outgolfer Feb 24 '18 at 11:15
  • 1
    \$\begingroup\$ Using a K-map would be more systematic and guarantees an optimal solution. \$\endgroup\$ – ბიმო Dec 27 '18 at 22:37
3
\$\begingroup\$

Know the difference between "program" and "function" in your language

Many questions on codegolf.SE ask you to "write a program or function"; this gives you some freedom to play to the strengths of your language and runtime based on how it handles command line parameters, how much boilerplate it needs for defining functions and their parameters, for defining full programs, for reading user input in a running program.

e.g. for a question asking you to write a program or function which takes a number as input, multiplies it by 10 and prints the result:

in Python it might go this way:

print(10*int(input()))    # full program
lambda x:print(10*x)      # function

in APL, the other way:

⎕←10×⎕      # full program
{⎕←10×⍵}    # function

In languages with a lot of code to get a whole program to run such as Java, a function could be much shorter. In more dynamic scripting languages such as Perl with many command line options to change how the code acts, a full program with a command line switch could be the shortest. Taking input from an implicit $args might be shorter than input(), or defining a function with a parameter might be shorter than System.Console.ReadLine();

\$\endgroup\$
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 Apr 18 '18 at 19:32
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)
\$\endgroup\$
2
\$\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\$
2
\$\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\$
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\$
-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\$ – user202729 Nov 25 '17 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 Nov 25 '17 at 9:47
1
2

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.