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
45 Answers 45
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();
-
\$\begingroup\$ ugoren the loops are still not the same. @Gaffi is right. \$\endgroup\$kaoD– kaoD2013年07月31日 07:51:44 +00:00Commented Jul 31, 2013 at 7:51
-
7\$\begingroup\$ @kaoD, in both cases
foois calledatimes,baris calledbtimes. This is because in "after", the loop runsa+btimes, the firstacallfoo, the next ones callbar. \$\endgroup\$ugoren– ugoren2013年07月31日 08:31:09 +00:00Commented Jul 31, 2013 at 8:31 -
1\$\begingroup\$ Woops, I read that very late in the night. You're right! \$\endgroup\$kaoD– kaoD2013年07月31日 19:12:10 +00:00Commented Jul 31, 2013 at 19:12
-
5\$\begingroup\$ Very similar:
for(y=0;y<Y;++y)for(x=0;x<X;++x)can often becomefor(i=0;i<X*Y;++i)withxreplaced byi%Xandyreplaced byi/X. \$\endgroup\$lynn– lynn2017年01月17日 12:01:36 +00:00Commented Jan 17, 2017 at 12:01 -
1\$\begingroup\$ @Lynn See this Python tip for more info: codegolf.stackexchange.com/a/41217/34718 \$\endgroup\$mbomb007– mbomb0072017年01月26日 14:46:56 +00:00Commented Jan 26, 2017 at 14:46
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).
-
16\$\begingroup\$ +1 In addition to being good for golfing, this is good exercise for any programmer in many real-world situations! \$\endgroup\$Gaffi– Gaffi2012年04月05日 15:49:50 +00:00Commented Apr 5, 2012 at 15: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()
Mind that more care is required if A and B simply behave similar to booleans but are of another type. Also, in many situations you can optimise this further, but that’s beyond the point of this tip.
-
4\$\begingroup\$ I'd never have thought of that. \$\endgroup\$cjfaure– cjfaure2014年08月08日 13:14:29 +00:00Commented Aug 8, 2014 at 13:14
-
38\$\begingroup\$
B>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. \$\endgroup\$scragar– scragar2014年09月11日 12:13:27 +00:00Commented Sep 11, 2014 at 12:13 -
5\$\begingroup\$ @scragar: Correct, but this is not the point of this tip. (It is a valuable independent tip though.) \$\endgroup\$Wrzlprmft– Wrzlprmft2014年09月11日 12:22:40 +00:00Commented Sep 11, 2014 at 12:22
-
3\$\begingroup\$ @scragar,
B>A or foowould evaluatefooifB==Awhich is not what we want. (Right?) \$\endgroup\$msh210– msh2102016年06月19日 07:54:39 +00:00Commented Jun 19, 2016 at 7:54 -
2\$\begingroup\$ 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 \$\endgroup\$Katenkyo– Katenkyo2016年07月08日 07:41:09 +00:00Commented Jul 8, 2016 at 7:41
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.
-
5\$\begingroup\$ I 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. \$\endgroup\$shiona– shiona2013年12月24日 16:30:10 +00:00Commented Dec 24, 2013 at 16:30
-
2\$\begingroup\$ I love this method, which is one reason that I tend to include comprehensive test suites for all problems I write. \$\endgroup\$Joey– Joey2015年07月29日 08:41:41 +00:00Commented Jul 29, 2015 at 8:41
-
\$\begingroup\$ @RubberDuck The Do not repeat yourself principle is often strictly followed. \$\endgroup\$Jonathan Frech– Jonathan Frech2018年02月23日 23:57:42 +00:00Commented Feb 23, 2018 at 23:57
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.
-
2\$\begingroup\$ +1 See also, README Driven Development. \$\endgroup\$roblogic– roblogic2021年10月11日 06:54:00 +00:00Commented Oct 11, 2021 at 6:54
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
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).
-
5\$\begingroup\$ in C you can use argc from main as 1. see: codegolf.stackexchange.com/questions/1034/reinvent-the-for-loop/… \$\endgroup\$std''OrgnlDave– std''OrgnlDave2012年04月25日 19:39:57 +00:00Commented Apr 25, 2012 at 19:39
-
4\$\begingroup\$ @std''OrgnlDave, True, but this question is about things common to all languages. \$\endgroup\$ugoren– ugoren2012年04月26日 07:40:23 +00:00Commented Apr 26, 2012 at 7:40
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.
-
1\$\begingroup\$ Why does there need to be a space between "{" and "echo", but not between ";" and "echo"? \$\endgroup\$Ryan Dougherty– Ryan Dougherty2014年08月08日 14:43:03 +00:00Commented Aug 8, 2014 at 14:43
-
5\$\begingroup\$ I 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. \$\endgroup\$kernigh– kernigh2014年08月08日 23:47:56 +00:00Commented Aug 8, 2014 at 23:47
assign functions new names if used multiple times
x = SomeLongFunctionName
x(somedata)
x(somemoredata)
etc
-
3\$\begingroup\$ Only if we use enough calls to
x. \$\endgroup\$elipszilon– elipszilon2019年03月25日 18:40:56 +00:00Commented Mar 25, 2019 at 18:40
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.
-
8\$\begingroup\$ 26 for non-case-sensitive languages. :-) \$\endgroup\$Gaffi– Gaffi2012年03月27日 21:13:42 +00:00Commented Mar 27, 2012 at 21:13
-
13\$\begingroup\$ Often
$and_can be used as identifiers. \$\endgroup\$Griffin– Griffin2012年03月27日 22:10:04 +00:00Commented Mar 27, 2012 at 22:10 -
5\$\begingroup\$ @Gaffi: And more than enough for languages which allow Unicode identifiers, unless the task limits you to ASCII or counts bytes rather than characters. \$\endgroup\$hammar– hammar2012年03月27日 22:25:36 +00:00Commented Mar 27, 2012 at 22:25
-
5\$\begingroup\$
@is a valid variable name in T-SQL, use it instead of@a. \$\endgroup\$BradC– BradC2017年06月16日 14:42:48 +00:00Commented Jun 16, 2017 at 14:42 -
1\$\begingroup\$ 54 (plus in some languages ones with diacritics) in JS. \$\endgroup\$elipszilon– elipszilon2019年03月25日 18:40:22 +00:00Commented Mar 25, 2019 at 18:40
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;
-
33\$\begingroup\$ Languages that don't have a ternary can use
a&&b||cinstead. Slightly longer, but still shorter than anif. \$\endgroup\$Michael Kohl– Michael Kohl2012年03月28日 09:43:22 +00:00Commented Mar 28, 2012 at 9:43 -
\$\begingroup\$ Then again, some can't use either option (VBA comes to mind), but both are still good suggestions. :-) \$\endgroup\$Gaffi– Gaffi2012年03月28日 14:00:04 +00:00Commented Mar 28, 2012 at 14:00
-
1\$\begingroup\$ Gaffi: VBA has
Iff, although it's a function, so subject to evaluation of all arguments. \$\endgroup\$Joey– Joey2012年04月05日 06:11:34 +00:00Commented Apr 5, 2012 at 6:11 -
7\$\begingroup\$ @MichaelKohl note that
a&&b||ccan returncwhenais true iffbis false, a little edge case, but we shouldn't forget that ^^ \$\endgroup\$Katenkyo– Katenkyo2016年07月08日 07:45:45 +00:00Commented Jul 8, 2016 at 7:45 -
1\$\begingroup\$ @MichaelKohl Katenkyo's comment (what they meant, with more detail): Worth noting that, if
a == 1 && b == 0, then bothbandcwill be evaluated. Here is the expression, with parens:((a) && (b)) || (c).a&&b's result will be0in this case, socwill be evaluated, because the||gate will check for the second operand if the first one is0. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2016年09月11日 09:47:37 +00:00Commented Sep 11, 2016 at 9:47
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
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.
e.g. if the question says "print the prime numbers from 1 to 100 inclusive", the largest prime printed will be 97 and you can change your loop end condition from 100 to 97 and save 1 byte. The question does not say you need to test 98, 99, 100 for primality, so don't do that.
e.g. 2. if the question says "print these numbers" then it does not say your answer must calculate the numbers. It might be shorter to store the expected output and decode and print it, than to write a calculator for it, e.g. storing 97 98 99 100 as a string of ASCII characters 'abcd'.
-
20\$\begingroup\$ I 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. \$\endgroup\$Jonathan Van Matre– Jonathan Van Matre2014年03月18日 15:06:29 +00:00Commented Mar 18, 2014 at 15:06
-
2\$\begingroup\$ Yes, but an artful reinterpretation of the rules is part of code golfing as well! (0 char solutions, etc.) \$\endgroup\$Tobia– Tobia2014年03月18日 18:57:05 +00:00Commented Mar 18, 2014 at 18:57
-
11\$\begingroup\$ That 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". \$\endgroup\$Jonathan Van Matre– Jonathan Van Matre2014年03月18日 19:20:56 +00:00Commented Mar 18, 2014 at 19:20
-
\$\begingroup\$ 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. \$\endgroup\$Erik the Outgolfer– Erik the Outgolfer2016年09月11日 09:49:50 +00:00Commented Sep 11, 2016 at 9:49
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.
-
\$\begingroup\$ I don't think I've ever seen a case where this has actually counted... \$\endgroup\$Jacob– Jacob2015年07月27日 22:59:38 +00:00Commented Jul 27, 2015 at 22:59
-
8\$\begingroup\$ I've just had this problem myself (hence why I'm adding it). \$\endgroup\$Sean Latham– Sean Latham2015年07月28日 13:19:23 +00:00Commented Jul 28, 2015 at 13:19
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)
-
11\$\begingroup\$ Related: If you are sure an outcome can't be negative, you could use
<1instead of==0as zero-check (or>0instead of!=0for the mirrored check). \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2016年06月21日 11:28:55 +00:00Commented Jun 21, 2016 at 11:28 -
4\$\begingroup\$ Shouldn't you add a note about
xbeing an integer? \$\endgroup\$Adalynn– Adalynn2017年06月19日 16:14:28 +00:00Commented Jun 19, 2017 at 16:14
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.
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.
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...
-
\$\begingroup\$ I'm not sure I understand the point of this. What does this reduce from? \$\endgroup\$Gaffi– Gaffi2012年03月27日 21:25:01 +00:00Commented Mar 27, 2012 at 21:25
-
\$\begingroup\$ @Gaffi you save one character and they do exactly the same \$\endgroup\$ajax333221– ajax3332212012年03月27日 21:40:25 +00:00Commented Mar 27, 2012 at 21:40
-
1\$\begingroup\$ vs. what alternative? Sorry, not trying to be obstinate, I just don't get it. (newb, here, apparently...) \$\endgroup\$Gaffi– Gaffi2012年03月27日 22:22:49 +00:00Commented Mar 27, 2012 at 22:22
-
1\$\begingroup\$ Ah, 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...) \$\endgroup\$Gaffi– Gaffi2012年03月28日 10:53:44 +00:00Commented Mar 28, 2012 at 10:53
-
11\$\begingroup\$ Also 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)vsif(n<1e5)\$\endgroup\$scragar– scragar2014年09月11日 12:15:29 +00:00Commented Sep 11, 2014 at 12:15
Reuse function parameters instead of new variables
-
1\$\begingroup\$ Well 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.. \$\endgroup\$Griffin– Griffin2012年03月27日 22:09:12 +00:00Commented Mar 27, 2012 at 22:09 -
7\$\begingroup\$ I 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. \$\endgroup\$ugoren– ugoren2012年03月30日 18:27:15 +00:00Commented Mar 30, 2012 at 18:27
-
\$\begingroup\$ 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) \$\endgroup\$masterX244– masterX2442014年02月18日 14:11:05 +00:00Commented Feb 18, 2014 at 14:11
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;
}
-
6\$\begingroup\$ You can also simplify the
ifstatement away in these cases:m|=i>=100. (And you can also simplify thei>=100toi>99in this case but that's not very relevant here) \$\endgroup\$marinus– marinus2013年07月16日 21:53:54 +00:00Commented Jul 16, 2013 at 21:53
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.
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)&&cneeds no parentheses:a&b&&cjust as(a*b)+cdoes not. a+(b<<c)can be rewritten asa+b*2**c.
That doesn ́t save anything for this example, but it will ifcis 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<dwitha<b&c<d(unless you need the short circuit evaluation)
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
-
7\$\begingroup\$ The 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}. \$\endgroup\$Martin Ender– Martin Ender2014年12月21日 11:39:02 +00:00Commented Dec 21, 2014 at 11:39 -
1\$\begingroup\$ Perl provides something similar:
qw(Foo Bar Baz Quux)becomes a list of strings. \$\endgroup\$BenGoldberg– BenGoldberg2016年12月16日 01:17:08 +00:00Commented Dec 16, 2016 at 1:17 -
\$\begingroup\$ @BenGoldberg: Although for Perl, you often want to avoid even
qw, using barewords that aren't existing functions as strings, or using glob operations, either of which saves even theqw, e.g.(Foo,Bar,Baz,Quux)or<Foo Bar Baz Quux>\$\endgroup\$ShadowRanger– ShadowRanger2023年03月16日 22:15:27 +00:00Commented Mar 16, 2023 at 22:15
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
-
1\$\begingroup\$ And if the
foris the final statement, the;becomes optional \$\endgroup\$elipszilon– elipszilon2019年03月25日 18:46:45 +00:00Commented Mar 25, 2019 at 18:46
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.
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:
×ばつ⎕ # full progra×ばつ⍵} # 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();
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)
-
\$\begingroup\$ In which language can you do assignment inside a call? or is that a keyword arg? \$\endgroup\$cat– cat2015年12月24日 17:40:42 +00:00Commented Dec 24, 2015 at 17:40
-
4\$\begingroup\$ I 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;setsbtoc, and then setsatob+1. \$\endgroup\$lynn– lynn2015年12月25日 01:22:51 +00:00Commented Dec 25, 2015 at 1:22 -
4\$\begingroup\$ Ruby does this the best. It gives the
=operator a higher precedence on the left than the right, so1+x=2is valid and evaluates to3\$\endgroup\$Cyoce– Cyoce2017年02月07日 22:22:53 +00:00Commented Feb 7, 2017 at 22:22 -
1\$\begingroup\$ @Cyoce afaik it´s that way in all languages where an assignment is an expression. \$\endgroup\$Titus– Titus2018年02月24日 11:02:13 +00:00Commented Feb 24, 2018 at 11:02
-
1\$\begingroup\$ Most of these tips are pretty obvious but still helpful :-) \$\endgroup\$Wezl– Wezl2020年05月04日 19:07:19 +00:00Commented May 4, 2020 at 19:07
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.
-
\$\begingroup\$ Shouldn't the first example just be
p(x-1)*2? \$\endgroup\$Cyoce– Cyoce2017年02月07日 22:25:17 +00:00Commented Feb 7, 2017 at 22:25
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]):
-
\$\begingroup\$ That's a cool one, I'll have to try it! \$\endgroup\$stokastic– stokastic2014年09月11日 13:18:43 +00:00Commented Sep 11, 2014 at 13:18
-
4\$\begingroup\$ Which languages have an
all(array-of-Booleans)built-in? \$\endgroup\$Peter Taylor– Peter Taylor2014年09月11日 13:50:18 +00:00Commented Sep 11, 2014 at 13:50 -
3\$\begingroup\$ Ruby has it.
[a>0,a<10,a+b==4,a+3<1].all?\$\endgroup\$kernigh– kernigh2014年10月06日 19:22:36 +00:00Commented Oct 6, 2014 at 19:22 -
5\$\begingroup\$ Although if this were Python you'd be using something like
if 10>a>0 and a+b==4>1>a+3:\$\endgroup\$Sp3000– Sp30002014年11月29日 03:30:42 +00:00Commented Nov 29, 2014 at 3:30 -
1\$\begingroup\$ @Sp3000 actually,
if 10>a>0>a+2 and a+b==4:becausea+3<1isa+2<0. which on second thought, isn't possible, soif 0:. XP \$\endgroup\$proud haskeller– proud haskeller2015年07月28日 23:40:11 +00:00Commented Jul 28, 2015 at 23:40
Utilize language version / compiler / environment quirks / new features
This is especially useful for polyglots, 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.
<all languages>... \$\endgroup\$