Tips for golfing in <all languages>

81

31

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

ajax333221

Posted 2012-03-26T22:53:40.920

Reputation: 3 188

5"Majority" by what metric? – ceased to turn counterclockwis – 2012-03-27T10:41:17.713

2@leftaroundabout by the metric of the same word – ajax333221 – 2012-03-27T22:01:34.707

8The 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. – ceased to turn counterclockwis – 2012-03-27T22:51:21.057

3leftroundabout, 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 [tag:tips] and a CW question. This is about helping others to golf, not about pissing them off. – Joey – 2012-04-05T06:10:53.467

15Hopefully nobody creates a language called <all languages>... – mbomb007 – 2016-04-04T21:19:10.527

Voting to close because most of the tips in this question will just be duplicated on the more dedicated tips page of any language they apply to. – mbomb007 – 2018-09-25T17:54:28.350

Answers

72

Merge Loops

You can usually merge two consequent loops, or two nested loops, into one.

Before:

for (i=0; i<a; i++) foo();
for (i=0; i<b; i++) bar();

After:

for (i=0; i<a+b; i++) i<a?foo():bar();

ugoren

Posted 2012-03-26T22:53:40.920

Reputation: 16 527

ugoren the loops are still not the same. @Gaffi is right. – kaoD – 2013-07-31T07:51:44.353

5@kaoD, in both cases foo is called a times, bar is called b times. This is because in "after", the loop runs a+b times, the first a call foo, the next ones call bar. – ugoren – 2013-07-31T08:31:09.390

I'm looking at this again (much, much later), and I don't understand my own question now. I maybe didn't understand the ternary operation before? The way I see it now, it makes sense. – Gaffi – 2013-07-31T11:42:11.530

1Woops, I read that very late in the night. You're right! – kaoD – 2013-07-31T19:12:10.850

3Very similar: for(y=0;y<Y;++y)for(x=0;x<X;++x) can often become for(i=0;i<X*Y;++i) with x replaced by i%X and y replaced by i/X. – Lynn – 2017-01-17T12:01:36.840

@Lynn See this Python tip for more info: http://codegolf.stackexchange.com/a/41217/34718

– mbomb007 – 2017-01-26T14:46:56.977

63

Just to mention the obvious:

Question your choice of algorithm and try something entirely new.

When golfing (especially harder problems that result in longer programs) all too often you might stick to the path you first chosen without trying other fundamental options. Of course, you may micro-golf one or a few lines at a time or a part of the overall idea, but often not try a totally different solution.

This was especially noticeable in Hitting 495 (Kaprekar) where deviating from the actual algorithm and looking for patterns you can apply to get to the same result was shorter in many languages (just not J).

The downside is that you possibly solve the same thing half a dozen times. But it works in really all languages except HQ9+ (where finding another way to output Hello World would be slightly futile).

Joey

Posted 2012-03-26T22:53:40.920

Reputation: 12 260

12+1 In addition to being good for golfing, this is good exercise for any programmer in many real-world situations! – Gaffi – 2012-04-05T15:49:50.993

52

Use Test-Driven Development

If the code must handle various inputs, then write comprehensive tests and make it easy to run them all very quickly. This allows you to try risky transforms one baby step at a time. Golfing then becomes like refactoring with perverse intent.

Adrian McCarthy

Posted 2012-03-26T22:53:40.920

Reputation: 679

2I love this method, which is one reason that I tend to include comprehensive test suites for all problems I write. – Joey – 2015-07-29T08:41:41.197

4I use a spinoff of this method. Since the problems themselves are usually rather simple, I write a program that does the job. Usually this is "readably golfed", so that it's succinct, but newlines etc. are there. I copy this file to a new location and golf it, checking every now and then that the programs return same values for some chosen inputs. If I ever make a mistake leaving me with a broken program, no memory of what I changed and no understanding of my golfed piece, I have something of a "specification" saved as a reference source. – shiona – 2013-12-24T16:30:10.347

@RubberDuck The Do not repeat yourself principle is often strictly followed. – Jonathan Frech – 2018-02-23T23:57:42.313

49

Try to reduce logical statements

For example, if A and B are booleans and your language treats booleans like numbers to some extent, A and (not B) and A>B are equivalent. For example in Python

if A and not B:
    foo()

is the same as:

if A>B:
    foo()

Wrzlprmft

Posted 2012-03-26T22:53:40.920

Reputation: 2 772

3@scragar, B>A or foo would evaluate foo if B==A which is not what we want. (Right?) – msh210 – 2016-06-19T07:54:39.370

2

Also, if you have long imbricated conditions (say with 5/6 parameters), you can use a Truth table and a Karnaugh map to find the shortest boolean expression for it

– Katenkyo – 2016-07-08T07:41:09.927

Technically they are not equivalent, if A is false then B will not be evaluated in the first version. – JayXon – 2019-09-11T08:46:20.917

@JayXon: Hence “if A and B are booleans”. If A and B are expressions, numbers, etc., you have to be more careful. – Wrzlprmft – 2019-09-11T09:42:28.773

@Wrzlprmft I interpreted that as anything that evaluates to a boolean, like (1>0) or all([]) because in codegolf you want to inline as much as possible, so having a boolean variable is less common than expressions. – JayXon – 2019-09-11T18:33:09.593

3I'd never have thought of that. – cjfaure – 2014-08-08T13:14:29.120

28B>A or foo() would be an even shorter way to express this, take advantage of lazy evaluation of boolean expressions to ensure it only calculates things when it needs to. – scragar – 2014-09-11T12:13:27.523

5@scragar: Correct, but this is not the point of this tip. (It is a valuable independent tip though.) – Wrzlprmft – 2014-09-11T12:22:40.483

34

Initialize variables using values you already have.

Instead of x=1, try to look for something that already equals 1.
For example, a function's return value: printf("..");x=0; -> x=!printf("..");. It's easiest with 0, because you can always negate, or when all you need is the right truth value (and don't care if it's 1 or 19).

ugoren

Posted 2012-03-26T22:53:40.920

Reputation: 16 527

4

in C you can use argc from main as 1. see: http://codegolf.stackexchange.com/questions/1034/reinvent-the-for-loop/5642#5642

– std''OrgnlDave – 2012-04-25T19:39:57.493

1@std''OrgnlDave, True, but this question is about things common to all languages. – ugoren – 2012-04-26T07:40:23.287

34

Use unary ~ for x+1 and x-1

This trick applies to languages that have a unary bitwise negation operator ~ and a unary regular negation operator -.

If your program, by chance, contains the expression -x-1, you can replace it with ~x to save bytes. This doesn't occur all too often, but watch what happens if we negate (-) both expressions: x+1 equals -~x! Similarly, x-1 equals ~-x. (Think of which way the tilde points: right is +, left is -.)

This is useful, because in all languages I can think of that have these operators, they have higher precedence than most operators. This allows you to save on parentheses. Watch how we save four bytes here:

(x+1)*(y-1)     ==>    -~x*~-y

Lynn

Posted 2012-03-26T22:53:40.920

Reputation: 55 648

30

Squeeze whitespace

Know the rules for whitespace in your language. Some punctuation marks, or other characters, might not need any surrounding whitespace. Consider this Bourne shell function:

f () { echo a; echo b; }

In Bourne shell, (); are metacharacters, and do not need surrounding whitespace. However, {} are words and need whitespace unless they are next to metacharacters. We can golf away 4 spaces next to ();, but must keep the space between { and echo.

f(){ echo a;echo b;}

In Common Lisp and PicoLisp, () are metacharacters. Consider this code to find the average of two numbers:

(/ (+ a b) 2)

We can golf away 2 spaces.

(/(+ a b)2)

Some languages have strange and subtle rules for whitespace. Consider this Ruby program, which prints the sum and product of a line of integers.

#!ruby -an
i=$F.map &:to_i
puts"#{i.reduce &:+} #{i.reduce &:*}"

Each & needs a space before itself. In Ruby, i=$F.map &:to_i means i=$F.map(&:to_i) where & passes a block parameter. But, i=$F.map&:to_i means i=$F.map.&(:to_i) where & is a binary operator.

This weirdness happens in languages, like Perl or Ruby, that use ambiguous punctuation. If in doubt, use a REPL or write short programs to test the whitespace rules.

kernigh

Posted 2012-03-26T22:53:40.920

Reputation: 2 615

1Why does there need to be a space between "{" and "echo", but not between ";" and "echo"? – Ryan – 2014-08-08T14:43:03.727

3I used the terms from the manual for OpenBSD sh(1), which says that "{" is a reserved word and ";" is a meta-character. Because of this, "{echo" is one word but ";echo" is two words. Other manuals might explain this differently. Also, the Z shell zsh has different rules. – kernigh – 2014-08-08T23:47:56.843

28

Single Letter Variable Names

You have 52 of them; use them all! Don't be afraid to try different approaches and compare lengths. Know the language and the specific shortcuts/library functions available.

ratchet freak

Posted 2012-03-26T22:53:40.920

Reputation: 1 334

826 for non-case-sensitive languages. :-) – Gaffi – 2012-03-27T21:13:42.580

12Often $ and _ can be used as identifiers. – Griffin – 2012-03-27T22:10:04.820

4@Gaffi: And more than enough for languages which allow Unicode identifiers, unless the task limits you to ASCII or counts bytes rather than characters. – hammar – 2012-03-27T22:25:36.563

not even considering that you can use the same name on different scopes, or reuse a variable you don't need anymore – proud haskeller – 2015-07-28T23:32:10.653

2@ is a valid variable name in T-SQL, use it instead of @a. – BradC – 2017-06-16T14:42:48.633

54 (plus in some languages ones with diacritics) in JS. – elipszilon – 2019-03-25T18:40:22.693

If you're counting bytes instead of unicode then using extended ascii might be a way to squeeze another ~120 identifiers if you need them(not that for a golf script you should need more than 26 anyway) – scragar – 2014-09-11T12:11:02.610

28

assign functions new names if used multiple times

x = SomeLongFunctionName
x(somedata)
x(somemoredata)
etc

Blazer

Posted 2012-03-26T22:53:40.920

Reputation: 1 902

Only if we use enough calls to x. – elipszilon – 2019-03-25T18:40:56.990

27

Write an explanation of your code

Writing an explanation forces you to thoroughly look at each part of your code again and to make your thoughts and choices in writing a certain passage explicit. In doing so, you might find that different approaches are possible which may save some bytes, or that you subconsciously made assumptions which don't necessarily hold.

This tip is similar to Question your choice of algorithm and try something entirely new; however, I have found that the step of actually writing down how each part is supposed to work is sometimes crucial for becoming aware of alternatives.

As a bonus, answers including an explanation are more interesting for other users and are hence more likely to be upvoted.

Laikoni

Posted 2012-03-26T22:53:40.920

Reputation: 23 676

25

Use the conditional operator.

A conditional operator

bool ? condition_true : condition_false

is more beneficial, character wise, than an IF statement.

if(a>b){r=a;}else{r=b;}

can be written as

r=a>b?a:b;

MrZander

Posted 2012-03-26T22:53:40.920

Reputation: 871

25Languages that don't have a ternary can use a&&b||c instead. Slightly longer, but still shorter than an if. – Michael Kohl – 2012-03-28T09:43:22.450

Then again, some can't use either option (VBA comes to mind), but both are still good suggestions. :-) – Gaffi – 2012-03-28T14:00:04.250

1Gaffi: VBA has Iff, although it's a function, so subject to evaluation of all arguments. – Joey – 2012-04-05T06:11:34.167

Using ternary in if statements can also be very helpful if(a ? b : c) – Jojodmo – 2015-12-24T19:49:59.550

4@MichaelKohl note that a&&b||c can return c when a is true iff b is false, a little edge case, but we shouldn't forget that ^^ – Katenkyo – 2016-07-08T07:45:45.623

@MichaelKohl Katenkyo's comment (what they meant, with more detail): Worth noting that, if a == 1 && b == 0, then both b and c will be evaluated. Here is the expression, with parens: ((a) && (b)) || (c). a&&b's result will be 0 in this case, so c will be evaluated, because the || gate will check for the second operand if the first one is 0. – Erik the Outgolfer – 2016-09-11T09:47:37.287

23

Double check your character count

Sounds like a no-brainer, but by being careful you might be able to "save" a few characters by not actually doing anything!

If you're using Windows, you may be inputting \r\n instead of just \r or \n when you hit Return - adding an extra byte per line! Turn control characters just to double check you're not doing this.

In Notepad++ you can convert all \r\n line endings to just \r by going to Edit > EOL Conversion > UNIX/OSX Format.

Also make sure you don't include any trailing whitespace in your character count! The line feed on the bottom line in your code is also inconsequential, so that won't need to be counted either.

Sean Latham

Posted 2012-03-26T22:53:40.920

Reputation: 1 423

I don't think I've ever seen a case where this has actually counted... – Jacob – 2015-07-27T22:59:38.663

4I've just had this problem myself (hence why I'm adding it). – Sean Latham – 2015-07-28T13:19:23.527

21

Read the question carefully

Code golfing is as much about understanding the question (what is asked and what is not asked, even though it would be implied in any other setting) as producing code that (may) only satisfy what is asked.

Any input other than what is explicitly asked for need not be handled. If there are some test cases and no generic requirement, your code may only work in those cases. Etc.

Tobia

Posted 2012-03-26T22:53:40.920

Reputation: 5 455

I think some OPs include a "Test cases subject to change; your code must still work after the change" notice, and really change them if they see just one answer hard-coding the testcases. – Erik the Outgolfer – 2016-09-11T09:49:50.987

15I think a better headline here would be "Don't handle non-required edge cases". The phrase "Try to find loopholes" brings to mind ways to avoid doing what is specified through some artful reinterpretation of the rules, whereas what you are offering is merely the good advice not to over-implement your solution. – Jonathan Van Matre – 2014-03-18T15:06:29.187

1Yes, but an artful reinterpretation of the rules is part of code golfing as well! (0 char solutions, etc.) – Tobia – 2014-03-18T18:57:05.323

8That would/should be a different answer, though. There's a fundamental difference between, for example, implementing a solution that only works for ints because OP didn't require float support, and an answer that prints the text "any prime greater than 100" because "you didn't say it had to be an actual prime number". – Jonathan Van Matre – 2014-03-18T19:20:56.430

21

Use bitwise operations for checking numbers between 0 and any 2n-1

Might be a bit of an edge case, but it could come in handy sometimes. It relies on the fact that all numbers to which m=2n-1 applies have the rightmost n bits set to 1.

So, 710 == 000001112, 1510 == 000011112, 3110 == 000111112 and so on.

The trick is x&~m. This will return true whenever x is not between 0 and m (inclusive), and false otherwise. It saves 6 bytes from the next shortest equivalent expression: x>=0&&x<=m, but obviously only works when m satisfies 2n-1.

Sean Latham

Posted 2012-03-26T22:53:40.920

Reputation: 1 423

18

Greater/Less than to save a digit:

//use:
if(n>9){A}else{B}
//instead of:
if(n<10){B}else{A}

Just remember to swap the code from if to the else and they will do exactly the same thing (or switch the sides of the inequality)!

Note: this can be applied with any power of 10 and their negatives: ...-100, -10, 10, 100...

(source link)

ajax333221

Posted 2012-03-26T22:53:40.920

Reputation: 3 188

I'm not sure I understand the point of this. What does this reduce from? – Gaffi – 2012-03-27T21:25:01.350

@Gaffi you save one character and they do exactly the same – ajax333221 – 2012-03-27T21:40:25.543

vs. what alternative? Sorry, not trying to be obstinate, I just don't get it. (newb, here, apparently...) – Gaffi – 2012-03-27T22:22:49.047

@Gaffi the second line is shorter than the first one (count them if you don't believe me) – ajax333221 – 2012-03-27T23:40:11.917

1Ah, I see. Works on any integer transition from 9 to 10, 99 to 100, etc. Sorry that took me so long! (I say integer only, because I can see an issue with n = 9.5...) – Gaffi – 2012-03-28T10:53:44.013

@scragar That would produce a float instead of an int . – ckjbgames – 2017-01-26T20:17:03.543

Only works if n is an int. – elipszilon – 2019-03-25T18:43:13.007

8Also in some languages(if supported) if your numbers are large/small enough the scientific notation may actually save you some chars instead: if(n>99999) vs if(n<1e5) – scragar – 2014-09-11T12:15:29.490

18

Reuse function parameters instead of new variables

Griffin

Posted 2012-03-26T22:53:40.920

Reputation: 4 349

1Well for example, in C, your main function is always passed the number of arguments supplied to the program (which is 1 - the program name - by 'default') so with main(i){... you now have a variable with the value of 1 without having to do any assignments. 2 chars saved there.. – Griffin – 2012-03-27T22:09:12.560

6I think it's quite specific to the C. Script languages don't need declarations, and in most compiled languages defining a variable isn't longer than defining a parameter. – ugoren – 2012-03-30T18:27:15.300

in java when needing a array inside a function which has same type as one parameter you can save off a few bytes by putting that parameter as last and make it a vararg parameter; (used that to shave off some bytes on a function to find longest word in a sentence) – masterX244 – 2014-02-18T14:11:05.367

17

Use > and < instead of >= and <=

When checking against hard-coded integer values, use > and < instead of >= and <= where possible. For example, using

if(x>24&&x<51)

Is 2 bytes shorter than using

if(x>=25&&x<=50)

Jojodmo

Posted 2012-03-26T22:53:40.920

Reputation: 1 569

4Related: If you are sure an outcome can't be negative, you could use <1 instead of ==0 as zero-check (or >0 instead of !=0 for the mirrored check). – Kevin Cruijssen – 2016-06-21T11:28:55.530

1Shouldn't you add a note about x being an integer? – Zacharý – 2017-06-19T16:14:28.647

15

use - instead of !=

for numeric comparisons:

If a equals b, a-b results in 0, which is falsy. Anything else than 0 is truthy; so
if used in a boolean context, a-b <=> a!=b

If you use it with if/else or with the ternary operator, this can also save you one byte for equality:
a==b?c:d <=> a-b?d:c

Titus

Posted 2012-03-26T22:53:40.920

Reputation: 13 814

15

Avoid premature loop breaks

If running through a loop to check for 1 or more instances of a boolean check, it might make for a more efficient program to exit the loop on the first true value. However, removing the break and looping through all iterations allows for shorter code.

int main() {
bool m = false;
int n = 1000;
for (int i = 0; i < n; i++) {
if (i >= 100) {
m = true;
break; // remove this line
}
} 
return 0;
}

Gaffi

Posted 2012-03-26T22:53:40.920

Reputation: 3 411

5You can also simplify the if statement away in these cases: m|=i>=100. (And you can also simplify the i>=100 to i>99 in this case but that's not very relevant here) – marinus – 2013-07-16T21:53:54.417

12

Split strings for long arrays

Most languages have a way to split a string into an array of strings around a token of some kind. This will inevitably be shorter than an array literal once the length reaches a language-dependent threshold, because the extra overhead per string will be one copy of a one-char token rather than (at least) two string delimiters.

E.g. in GolfScript

["Foo""Bar""Baz""Quux"]  # 23 chars

becomes

"Foo
Bar
Baz
Quux"n/  # 20 chars

For some languages, the threshold is as low as one string. E.g. in Java,

new String[]{"Foo"}  // 19 chars

becomes

"Foo".split("~")  // 16 chars

Peter Taylor

Posted 2012-03-26T22:53:40.920

Reputation: 41 901

6The notable exception is Ruby, which provides an array-of-strings literal which automatically splits on spaces at the cost of two bytes: %w{Foo Bar Baz Quux}. – Martin Ender – 2014-12-21T11:39:02.393

1Perl provides something similar: qw(Foo Bar Baz Quux) becomes a list of strings. – BenGoldberg – 2016-12-16T01:17:08.253

12

Understand what other people did

In addition to being fun, if you examine other people's code, you can sometimes discover a good algorithm that you didn't think about, or a trick (sometimes an obvious one) that you overlook.

Sometimes there is an existing answer that you can translate to another language, and benefit from the other language's goodies.

anatolyg

Posted 2012-03-26T22:53:40.920

Reputation: 10 719

10

know your operator precedence

Whenever You combine several expressions, check the operator precedence table for your language to see if you can reorder stuff to save parentheses.

Examples:

  • In all languages that I know, bitwise operators have a higher precedence than boolean operators: (a&b)&&c needs no parentheses: a&b&&c just as (a*b)+c does not.
  • a+(b<<c) can be rewritten as a+b*2**c.
    That doesn´t save anything for this example, but it will if c is a small integer literal (<14).
  • Bitwise operations have a lower precedence than most arithmetic operations, so if your language implicitly casts boolean to int, you can save a byte on a<b&&c<d with a<b&c<d (unless you need the short circuit evaluation)

Titus

Posted 2012-03-26T22:53:40.920

Reputation: 13 814

8

Use unary ~ for a-b-1 and a+b+1

In addition to @Lynn's suggestions regarding x+1-~x; and x-1~-x, you can also golf a-b-1 and a+b+1.

a-b-1    // 5 bytes
a+~b     // 4 bytes

a+b+1    // 5 bytes
a-~b     // 4 bytes

It might look like a tip you won't use all that often, kinda like using ~x instead of -x-1 doesn't happen often, but I've used it enough times to see it as a useful tip here. Especially with array-indexing you might use these above in some cases.

Kevin Cruijssen

Posted 2012-03-26T22:53:40.920

Reputation: 67 575

7

Shorter for-loops

If you have X statements {inside} your for-loop, you can move X-1 statements (inside) the for-loop after the second semicolon for(blah;blah;HERE) to save 3 bytes. (separate the statements by using a comma ,)

Instead of

for(int i=0;i<9;){s+=s.length();println(i++);}

you can move one of the statements into the for-loop's ( braces) while leaving the other out

for(int i=0;i<9;println(i++))s+=s.length();

and save 3 bytes (saved 1 more byte thanks to @ETHProductions)


Put simply,

instead of

for(blah;blah;){blah 1;blah 2;...;blah X}

move the statements around so you end up with this

for(blah;blah;blah 2,...,blah X)blah 1;

and save 3 bytes

user41805

Posted 2012-03-26T22:53:40.920

Reputation: 16 320

@ETHproductions Thanks for golfing a tip :) – user41805 – 2017-01-17T18:42:57.947

And if the for is the final statement, the ; becomes optional – elipszilon – 2019-03-25T18:46:45.120

6

Compress or/and streaks

Simple trick I've come up with when trying to squeeze a long streak of conditions chained by ands (or ors, in this case just substitute 'all' with 'any').

Eg:

if a>0 and a<10 and a+b==4 and a+3<1:

Becomes

if all([a>0,a<10,a+b==4,a+3<1]):

LemonBoy

Posted 2012-03-26T22:53:40.920

Reputation: 339

@Sp3000 actually, if 10>a>0>a+2 and a+b==4: because a+3<1 is a+2<0. which on second thought, isn't possible, so if 0:. XP – proud haskeller – 2015-07-28T23:40:11.990

In K, "all" is &/ (AND reduce) and "any" is |/ (OR reduce). Most APL derivatives have an equivalent juxtaposition. – JohnE – 2015-12-24T15:53:20.073

JavaScript (ES6) lets you do [someArray].every(_=>_) for and and [someArray].some(_=>_) for or. Of course, if you use this more than once, you should alias i=_=>_ – Cyoce – 2016-04-05T18:36:46.513

Python also has all(). – mbomb007 – 2017-01-26T14:55:53.603

That's a cool one, I'll have to try it! – stokastic – 2014-09-11T13:18:43.403

4Which languages have an all(array-of-Booleans) built-in? – Peter Taylor – 2014-09-11T13:50:18.133

3Ruby has it. [a>0,a<10,a+b==4,a+3<1].all? – kernigh – 2014-10-06T19:22:36.777

4Although if this were Python you'd be using something like if 10>a>0 and a+b==4>1>a+3: – Sp3000 – 2014-11-29T03:30:42.950

@PeterTaylor Haskell has too – proud haskeller – 2014-11-29T17:31:35.380

6

Rely on the compiler to provide the required performance.

Be sure to know which optimisations are guaranteed by the compiler and at which optimisation levels, and use them liberally. And even if performance isn't a concern requirement, you can still test with optimisations on, and then only discount one character because your code is still technically valid without the compiler flag.

Consider the following Haskell function to compute 2^n (ignoring the fact that Haskell already has a built-in exponentiation operator or three) (23 characters):

p 0=1;p x=p(x-1)+p(x-1)

The problem is - it's horrendously slow, it runs in exponential time. This might make your code untestable or to fail any performance constraints given by the question. You might be tempted to use a temporary variable or an immediately invoked function literal to avoid repeated function calls (25 characters):

p 0=1;p x=(\y->y+y)$p$x-1

But the compiler can already do that for you, you just need set -O as a compiler flag! Instead of spending few extra characters per site to eliminate common subexpressions manually, just tell the compiler to do basic optimisations for you for a grand total of one character or two across the entire program.

John Dvorak

Posted 2012-03-26T22:53:40.920

Reputation: 9 048

@ETHproductions yep, sorry, I did – John Dvorak – 2017-01-17T18:43:36.223

Shouldn't the first example just be p(x-1)*2? – Cyoce – 2017-02-07T22:25:17.323

5

Utilize language version / compiler / environment quirks / new features

This is especially useful for s, but can be applied to other challenges. Sometimes, a compiler bug can golf off a byte, a implementation bug can allow you to save a few chars, or a really bleeding-edge feature can improve your score.

user68584

Posted 2012-03-26T22:53:40.920

Reputation:

5

Maybe somewhat obvious but...

Make use of operator return values

Keep in mind that the assignment operator returns a value!

For example, if you want to add y to x and then check if x is greater than something, you can do

if(25<x+=y)

instead of

x+=y;if(x>25)

Or maybe you want to find the length of a string after trimming it:

strlen(s=trim(s))

Rather than

s=trim(s);strlen(s)

orp

Posted 2012-03-26T22:53:40.920

Reputation: 241

In which language can you do assignment inside a call? or is that a keyword arg? – cat – 2015-12-24T17:40:42.140

2I think assignments are expressions (with the assigned variable's new value as their expression value) in at least C, C++, C#, and Java. a = (b=c)+1; sets b to c, and then sets a to b+1. – Lynn – 2015-12-25T01:22:51.197

@Lynn Try a=1+b=c. And you can add PHP and JavaScript to your list. – Titus – 2017-01-16T00:31:33.083

2Ruby does this the best. It gives the = operator a higher precedence on the left than the right, so 1+x=2 is valid and evaluates to 3 – Cyoce – 2017-02-07T22:22:53.587

@Cyoce afaik it´s that way in all languages where an assignment is an expression. – Titus – 2018-02-24T11:02:13.250

4

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.).

ckjbgames

Posted 2012-03-26T22:53:40.920

Reputation: 1 287

4

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
    }
}

Gaffi

Posted 2012-03-26T22:53:40.920

Reputation: 3 411

2Although 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. – DollarAkshay – 2015-07-04T22:24:03.747

5Also, use bitty conditionals (&, `|) to remove more characters. – FUZxxl – 2012-08-13T18:33:13.150

4

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.

cat

Posted 2012-03-26T22:53:40.920

Reputation: 4 989

2

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

user41805

Posted 2012-03-26T22:53:40.920

Reputation: 16 320

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 – l4m2 – 2018-04-18T19:32:59.467

2

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.

Erik the Outgolfer

Posted 2012-03-26T22:53:40.920

Reputation: 38 134

1

One can also try and ask WolframAlpha.

– Jonathan Frech – 2018-02-23T23:51:34.687

@JonathanFrech But how are you going to prove it then? ;) – Erik the Outgolfer – 2018-02-24T00:30:24.007

3Outsource the proof and trust. – Jonathan Frech – 2018-02-24T01:01:01.793

@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. :) – Erik the Outgolfer – 2018-02-24T11:15:13.227

Using a K-map would be more systematic and guarantees an optimal solution.

– ბიმო – 2018-12-27T22:37:00.147

1

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)

Unihedron

Posted 2012-03-26T22:53:40.920

Reputation: 1 115

0

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 .

RosLuP

Posted 2012-03-26T22:53:40.920

Reputation: 3 036

Can you give example of your recent answer? – user202729 – 2017-11-25T08:59:19.010

@user202729 The function palpn() in https://codegolf.stackexchange.com/a/148745/58988 it would reassume 3 function "find next palindrome", "find previous palindrome" "say if arg it is palindrome"

– RosLuP – 2017-11-25T09:47:58.883