5
\$\begingroup\$

I'm pretty new to code golfing, so I gave one of my first shots to a space invader clone called "Invas!on". It's a little less than 500 bytes, fully ASCII generated, and covers moving around and shooting at the aliens. There is also a little point system.

My specific question is about generating enemy patterns. I want to generate something like this:

...x.x.x.x.x.x...          
..x.x.x.x.x.x.x..        
...x.x.x.x.x.x...

...and so on.

Currently, I'm using this code:

for(b=[],j=2;j<136;j+=2)b.push(j),j==14&&(j=41)||j==55&&(j=80)||j==94&&(j=121)

It's just a loop that pushes enemy positions into an array b. Positions are every two spaces on a line, with a varying margin on both sides.

What is the shortest way to do this?

\$\endgroup\$
9
  • 3
    \$\begingroup\$ Although asking for golfing advice is on on-topic here, this seems a bit too broad for the scope of CodeGolf.SE. I don't know what the people at CodeReview.SE think about questions trying to shorten code, but in principle this sounds like it would be suitable over there. \$\endgroup\$ Oct 16, 2014 at 23:56
  • 8
    \$\begingroup\$ @MartinBüttner: Won't they just kick it back here? CR.SE is about code improvement, not code reduction. Sending them golfed code is like serving up regurgitated meatballs to a master chef and asking "How can I make this better?" \$\endgroup\$
    – COTO
    Oct 17, 2014 at 3:31
  • 1
    \$\begingroup\$ Ok, thanks for the advice. I specified my question. \$\endgroup\$ Oct 17, 2014 at 8:09
  • 1
    \$\begingroup\$ @DavidSkx - I updated the question to be a bit more interesting and challenging. Feel free to revert back if you don't like it. \$\endgroup\$
    – Optimizer
    Oct 17, 2014 at 13:53
  • 2
    \$\begingroup\$ @Optimizer I've rolled your edit back because I don't think we need to strengthen the impression that asking for golfing advice isn't welcome here. By completely changing it into a kolmogorov challenge, it does give that feeling. No offense intended, obviously. \$\endgroup\$
    – Geobits
    Oct 17, 2014 at 13:58

1 Answer 1

5
\$\begingroup\$

58 : -20 bytes(25%) from OP

for(b=[],j=2;j<136;j+=j==14||j==94?29:j==55?27:2)b.push(j)

This should do the same thing as your code, but without all the ugly parentheses and explicit assignments. Since all you're really doing is adding each time, all you have to do is check how much to add.

I should note that I have no idea where you got the numbers from in the original code. Since it doesn't seem to match the pattern you gave, I assume the pattern is just an example (and the actual lines are longer), or there's something going on in your other code (not shown here). Either way, I matched up my positions with yours.


For a fixed pattern like this, though, it might be shorter to just encode it in a bitmap-style string or bitmasked integer. Doing it loop-style allows you to vary it a bit easier, but if your pattern is constant it's something to be aware of. For instance, your shown pattern has 51 positions, which are either "on" or "off". This means it needs 51 bits for a straight bitmask, which can fit in a single number:

000101010101010000010101010101010000010101010101000 = 0xAAA0AAA82AA8

So, if you can unpack that into an array efficiently, you may be able to score some more bytes. Unfortunately, I'm no Javascript whiz, so I couldn't get it shorter this way, leaving it at 61 bytes. Others may be able to improve upon this:

for(b=[],j=0,m=0xAAA0AAA82AA8;m>0;m>>>=1,j++)if(m&1)b.push(j)

So for this exact pattern, the first method is shorter (for me). If the pattern wasn't so evenly spaced (allowing simple additions), the second would most likely end up shorter.

\$\endgroup\$
4
  • 2
    \$\begingroup\$ You have to do m = m >>> 1, otherwise it is a signed integer, so m > 0 will fail. This can be made m>>>=1 \$\endgroup\$
    – soktinpk
    Oct 18, 2014 at 4:18
  • \$\begingroup\$ @soktinpk Thanks for that :D \$\endgroup\$
    – Geobits
    Oct 18, 2014 at 4:21
  • \$\begingroup\$ This is incredible, great work. \$\endgroup\$ Nov 1, 2015 at 12:24
  • \$\begingroup\$ I'm getting a problem with for(b=[],j=0,m=0xAAA0AAA82AA8;m>0;m>>>=1,j++)if(m&1)b.push(j), it only registers an array of 13 elements, which seems to only account for the first two rows... What's happened to the third row? \$\endgroup\$ Aug 9, 2016 at 0:26

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.