35
\$\begingroup\$

Introduction

Partly inspired by this StackOverflow question, let's draw an ASCII Lightning Bolt.

Write a program that takes a positive Integer n via STDIN or command line and outputs the ASCII Lightning Bolt below.

Input

Positive Integer n representing the number of lightning zig-zag tiers to draw.

Example Output

n=1

__
\ \
 \ \
  \ \
   \/

n=2

__
\ \
 \ \
__\ \
\  __\
 \ \
  \ \
   \/

n=3

__
\ \
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
  \ \
   \/

n=4

__
\ \
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
  \ \
   \/

. . . etc


Additional notes

  • You may write a function that takes n as the only argument and prints or returns the string.
  • Trailing spaces and new lines are okay.
  • No leading spaces except where appropriate for the designated pattern.
  • Shortest code in bytes wins.
\$\endgroup\$
  • 2
    \$\begingroup\$ How many of those challenges have we seen so far? \$\endgroup\$ – flawr Jun 5 '15 at 23:00
  • \$\begingroup\$ @flawr Too many 😯 \$\endgroup\$ – Beta Decay Jun 30 '15 at 16:34

29 Answers 29

19
\$\begingroup\$

Java, 201 196 189 186 182 bytes

Obviously not the best, but it is in Java.

class I{public static void main(String[]a){System.out.print(("__\na a"+new String(new byte[new Byte(a[0])-1]).replace("\0","__a\\  __\\\n a")+"  a   \\/").replace("a","\\ \\\n"));}}
\$\endgroup\$
  • 23
    \$\begingroup\$ Ah, Java, the language where you've already lost before you start typing the body of your main method. \$\endgroup\$ – David Richerby Jun 5 '15 at 12:56
  • 2
    \$\begingroup\$ I do sometimes think that the main shouldn't count towards byte count, and a few languages that have verbose keywords should maybe be allowed macros. Then it'd be interesting \$\endgroup\$ – Alec Teal Jun 6 '15 at 4:05
  • \$\begingroup\$ @AlecTeal Totally agree, some questions actually specify that they only require functional snippets, but most do not. \$\endgroup\$ – David Mulder Jun 6 '15 at 19:36
  • 6
    \$\begingroup\$ You may write a function that takes n as the only argument and prints or returns the string. So, umm, you should probably do that ;) \$\endgroup\$ – Geobits Jun 9 '15 at 17:33
  • \$\begingroup\$ It may be 6 months late, but codegolf.stackexchange.com/a/64713/42736 or using a function make it shorter. \$\endgroup\$ – J Atkin Jan 12 '16 at 23:42
10
\$\begingroup\$

CJam, 41 bytes

":¡ö cQïO[nu÷&,"255b6b"
 _\/X"f='X/~ri(*\

I can probably squeeze a few more bytes out, but here's some compression. I picked a base which would lead to no unprintables.

Try it online.

The lightning bolt is split into top + middle * (input-1) + bottom, where top, middle, bottom (compressed using base conversion) are

__
\. 

  \
.\.\
__\.\
\..__ 

    \
.\.\
..\.\
...\/

(Spaces are marked with .s)

40 bytes

Thanks to Optimizer

"¹Ñ³Û-+ÎDx^áÐ"254b6b"
_\ 0/"f=)/~ri(*\
\$\endgroup\$
  • \$\begingroup\$ 40 \$\endgroup\$ – Optimizer Jun 5 '15 at 14:00
  • \$\begingroup\$ thanks for the explanation with top + middle * (input-1) + bottom, it reminded me that powershell could multiply strings :P \$\endgroup\$ – Nacht Jun 9 '15 at 4:21
8
\$\begingroup\$

JavaScript (ES6) 76

Using template string, the 3 newlines are significant and counted.

Test running the snippet (Firefox only)

f=n=>`__
1 1${`__1\\  __\\
 1`.repeat(n-1)}  1   \\/`.replace(/1/g,`\\ \\
`)

// TEST

go=_=>O.innerHTML=f(I.value)

go()
N: <input id=I value=3><button onclick='go()'>Test</button>
<pre id=O></pre>

\$\endgroup\$
7
\$\begingroup\$

PowerShell, 72 63 bytes

Stupid Windows and your \r\n... This could have been 67 59 bytes!

%{$a="\ \
";"__
$a"+" $a`__$a\  __\
"*($_-1)+" $a  $a   \/"}
\$\endgroup\$
  • \$\begingroup\$ For code golf, I think \r\n still counts as \n, since it does the same thing \$\endgroup\$ – MilkyWay90 Apr 1 at 23:42
6
\$\begingroup\$

PHP - 84 79 78 bytes

<?php
define('N',3); // <- didnt count these bytes as TS said I could take var N as input
?>
<?="__
\ \
 \ \ ".str_repeat("
__\ \
\  __\
 \ \ ",N-1)."
  \ \ 
   \/"

View the result source or wrap in <pre /> to check results. The newlines are required in the code.
The -1 could be moved to the define, but I considered that a cheat.

1st improvement: replace \n with actual newlines
2nd: Since I can define a var, I used a CONTANT, safes the $. +an unneeded space in str_repeat
3rd: Accidentally removed the -1, but saved a byte by using <?= instead of echo.

\$\endgroup\$
6
\$\begingroup\$

Pyth, 60 54 bytes (Thanks @isaacg)

My first attempt at Pyth, probably very bad.

"__
\ \ "VtQ" \ \ 
__\ \ 
\  __\ ")" \ \ 
  \ \ 
   \/

Verify it here.

\$\endgroup\$
  • \$\begingroup\$ Welcome to Pyth! By the way, Pyth allows literal newlines in its strings, which would be 1 character shorter than \n. Also, the first \\ in the program could be just a \ . \$\endgroup\$ – isaacg Jun 7 '15 at 14:22
  • \$\begingroup\$ @isaacg Thanks. \$\endgroup\$ – JNV Jun 7 '15 at 14:32
4
\$\begingroup\$

CJam, 50 bytes

"__
\ \
"q~(" \ \
__\ \
\  __\
"*" \ \
"_S\"   \/"

Try it here

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

Brainfuck, 164 bytes

,<++++++++++++++++[>--->+>++++++>++>++++++>+++<<<<<<-]>->--->---->>->-<..<<<.>.>
.<.<.>>.<.>.<.<.<[>>>>..<<.>.<.<.>.>..>..<<.<.>>.<.>.<.<.<-]>>>..<.>.<.<.>>...<.
>>>.

With comments:

Initialise n and character set with i as counter
Memory = in♪\ _/
,<++++++++++++++++[>--->+>++++++>++>++++++>+++<<<<<<-]>->--->---->>->-

Draw top of lightning bolt
<..<<<.>.>.<.<.>>.<.>.<.<.<

Draw lightning bolt zigzags
[>>>>..<<.>.<.<.>.>..>..<<.<.>>.<.>.<.<.<-]

Draw lightning bolt tip
>>>..<.>.<.<.>>...<.>>>.

Okay, how this Brainfuck answer beating Java and C#?

\$\endgroup\$
  • \$\begingroup\$ Woah, nice golfing, especially in BF! \$\endgroup\$ – MilkyWay90 Apr 1 at 23:44
4
\$\begingroup\$

><> (Fish), 409 bytes

Run by fish.py bolt.fish --value n where bolt.fish is the program name and n is your positive integer input.

\
\         "__"       a
\         "\ \"      a
\         " \ \"     a
\r1-:?!vr "__\ \"    a
\     !0  "\  __\"   a
\     !6  " \ \"  a04.
>r   9a.  "__\ \"    \
      /   "\  __\"  \ 
       /  " \ \"   \  
        / "  \ \" \   
         /"   \/"\    
                 aaaaa
|o|!~r           /    
         \        /   
        \          /  
       \            / 
      \              /

It's not short, but it looks cool. My attempt was to try to make it look like a lightning strike. Also, it always errors on completion.

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

Perl, 69+1

69 characters, plus 1 for the -n command line switch to fetch input from stdin.

$s="\\ \\$/";print"__$/$s $s".("__$s\\  __\\$/ $s"x--$_)."  $s   \\/"

Usage example:

perl -ne '$s="\\ \\$/";print"__$/$s $s".("__$s\\  __\\$/ $s"x--$_)."  $s   \\/"' <<<"2"
__
\ \
 \ \
__\ \
\  __\
 \ \
  \ \
   \/
\$\endgroup\$
  • 1
    \$\begingroup\$ Some improvements possible: perl -pe'$_="__\ns s"."__s\\ __\\\n s"x--$_." s \\/";s!s!\\ \\\n!g'. Also \n can be replaced with a literal line break for another 3 character saved. \$\endgroup\$ – nutki Jun 5 '15 at 10:25
3
\$\begingroup\$

Javascript (ES6), 86

Not gonna win, but I love 1-line solution and I hate slashes.

f=n=>atob("X18KXCBc"+"CiBcIFwKX19cIFwKXCAgX19c".repeat(n-1)+"CiBcIFwKICBcIFwKICAgXC8")
\$\endgroup\$
  • \$\begingroup\$ Cool! What it is doing? \$\endgroup\$ – rpax Jun 6 '15 at 8:35
  • 1
    \$\begingroup\$ @rpax I used base64 encoding to avoid \\ and \n . Have a look at atob documentation \$\endgroup\$ – Michael M. Jun 7 '15 at 17:57
3
\$\begingroup\$

C, 101 bytes

My not so original implementation in c

f(n){puts("__\n\\ \\");for(;--n;puts(" \\ \\\n__\\ \\\n\\  __\\"));puts(" \\ \\\n  \\ \\\n   \\/");}
\$\endgroup\$
3
\$\begingroup\$

C#, 221 Bytes

class C{static void Main(string[]n){int e=System.Int32.Parse(n[0]);var o=@"__{0}\ \{0} \ \{0}";while(e>1){o+=@"__\ \{0}\  __\{0} \ \{0}";e--;}System.Console.WriteLine(o + @"  \ \{0}   \/{0}",System.Environment.NewLine);}}

This isn't the best, or the smallest answer, but I figured I'd give it a try. Fsacer's answer is much shorter and I think you should check it out. I just decided to do this just as an alternative method really.

\$\endgroup\$
  • 1
    \$\begingroup\$ Hey, here I easily dropped it to 182B. Code: class C{static void Main(string[]n){var e=int.Parse(n[0]);var o=@"__{0}\ \{0} \ \{0}";while(e-->1){o+=@"__\ \{0}\ __\{0} \ \{0}";}System.Console.Write(o+@" \ \{0} \/{0}","\n");}} \$\endgroup\$ – fsacer Jun 6 '15 at 10:19
  • \$\begingroup\$ Nice, and just curious, but why did you change the type of e from int to var? It's still 3 characters :P \$\endgroup\$ – user41392 Jun 6 '15 at 10:31
  • \$\begingroup\$ No reason, maybe because I love var keyword :) \$\endgroup\$ – fsacer Jun 6 '15 at 10:32
3
\$\begingroup\$

C#, 166 bytes

class I{static void Main(string[]a){System.Console.Write(("__\na a"+"".PadLeft(int.Parse(a[0])-1).Replace(" ",@"__a\  __\
 a")+@"  a   \/").Replace("a",@"\ \
"));}}

EDIT 1: improved the result from 186B to 173B
EDIT 2: saved 1B by using PadLeft instead of PadRight
EDIT 3: saved 8B by dropping PadLeft's second parameter and using verbatim string literals

\$\endgroup\$
  • \$\begingroup\$ Nice... You can do away with the public at the start, and instead of using a char array, you can use String.PadRight(int, char), which is shorter and will let you use an ascii char which doesn't need escaping. \$\endgroup\$ – VisualMelon Jun 5 '15 at 19:27
  • \$\begingroup\$ Some tweaks: * drop the second parameter to PadLeft(); it's implied (-4) * change 2 of the strings to verbatim (the OP says newlines are fine, and we only need \n, not full \r\n, so -4) End result: class I{static void Main(string[]a){System.Console.Write(("__\na a"+"".PadLeft(int.Parse(a[0])-1).Replace(" ",@"__a\ __\ a")+" a \\/").Replace("a",@"\ \ "));}} [I can't display newlines in comments, but you can edit the original answer!] \$\endgroup\$ – sellotape Jun 6 '15 at 14:38
  • \$\begingroup\$ Nice tips, it was hard to verbatim formatting in order :) \$\endgroup\$ – fsacer Jun 6 '15 at 15:50
3
\$\begingroup\$

Awk, 101+8 bytes

101 characters, plus 8 for -v n=$1 to get integer from shell.

'{l="\\ \\";print"__\n"l"\n "l;for(i=1;i<n;++i)print"__"l"\n\\  __\\\n "l}END{print"  "l"\n   \\/"}'

New to this SE site, unclear if those parameters should count.

Ungolfed

awk 
-v n=$1
'{
  l="\\ \\";
  print "__\n"l"\n "l;
  for(i=1; i<n; ++i)
    print "__"l"\n\\  __\\\n "l
}
END
{
  print "  "l"\n   \\/"
}'

Usage example:

lightning() { echo | awk -v n=$1 '{l="\\ \\";print"__\n"l"\n "l;for(i=1;i<n;++i)print"__"l"\n\\  __\\\n "l}END{print"  "l"\n   \\/"}'; }
lightning 3
__
\ \
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
  \ \
   \/
\$\endgroup\$
  • \$\begingroup\$ Here is the consensus on counting command-line flags. So I think you've done that right. \$\endgroup\$ – Martin Ender Jun 7 '15 at 11:06
  • \$\begingroup\$ Let's formulate it as “calculated that right”, because definitely not done right. If the variable assignment is put after the code, there is no need for the -v part. Not mentioning that the whole variable idea is unnecessary, just like the separate END block. 89 characters: {l="\\ \\";print"__\n"l"\n "l;for(;--$1;)print"__"l"\n\\ __\\\n "l;print" "l"\n \\/"} pastebin.com/NCznF9kH \$\endgroup\$ – manatwork Jun 7 '15 at 15:26
3
\$\begingroup\$

Python 97 82 78char:

print(("__\nl l"+"__l\  __\\\n l"*~-input()+"  l   \/").replace('l','\ \\\n'))

This is my first code golf

@(^_^)@

Test here

\$\endgroup\$
  • \$\begingroup\$ This is python 3? Will that input() work for integers? \$\endgroup\$ – Renae Lider Jun 10 '15 at 20:52
2
\$\begingroup\$

C, 119 108 bytes

p(t){for(;t;t/=4)putchar(" \\_\n"[t%4]);}main(c){for(p(13434);p(836),--c;p(57154842));p(265488);puts("/");}

First attempt, 150 bytes

v(a){putchar(a);}s(b){b--?v(32),s(b):v(92);}l(b){s(b);s(1);v(10);}main(c){for(puts("__\n\\ \\");l(1),--c;puts("__\\ \\\n\\  __\\"));l(2);s(3);v(47);}

main is accepting an int argument, so run like this: ./lightning . . . to pass 4 as argument.

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

Python 3, 126 118 117 bytes

Just something to get us started with.

n=int(input())
p=print
p('__\n\\ \\')
for i in[0]*~-n:p(r''' \ \
__\ \
\  __\
''',end='')
p(r''' \ \
  \ \
   \/
''')
\$\endgroup\$
  • \$\begingroup\$ If you don't need the loop variable, you can iterate trough [0]*(n-1) to get n-1 iterations. You can also write (n-1) as ~-n. \$\endgroup\$ – randomra Jun 5 '15 at 8:14
  • \$\begingroup\$ You can save one byte by changing i in [0] to i in[0]. \$\endgroup\$ – mbomb007 Jun 5 '15 at 19:19
  • \$\begingroup\$ Welcome! A single line print in the loop is also shorter: for i in[0]*~-n:p(' \\ \\\n__\\ \\\n\\ __\\'). \$\endgroup\$ – randomra Jun 5 '15 at 21:20
2
\$\begingroup\$

Python 2, 76 bytes

print'__\n\ \\\n \ \\\n'+r'''__\ \
\  __\
 \ \
'''*~-input()+'  \ \\\n   \/'

Just print the first three lines, then print the next three lines n-1 times, and then print the final 2 lines. All in one go.

And here is a nice try at an alternative that (unfortunately) uses exactly the same number of bytes:

print('__\n| |'+'__|\  __\\\n |'*~-input()+'  |   \/').replace('|','\ \\\n')
\$\endgroup\$
  • \$\begingroup\$ Have you tried using %s formatting for the middle part? \$\endgroup\$ – Sp3000 Jun 6 '15 at 4:11
  • \$\begingroup\$ @Sp3000 I need braces around it to make it work with the *, that gives me 77 bytes - or not inlining it, but that costs 79 bytes. :( \$\endgroup\$ – Matty Jun 6 '15 at 9:52
2
\$\begingroup\$

F#, 98 characters, 105 bytes

let l n=(@"__♪◙\z"+String.replicate(n-1)@" \z__\z\  __\♪◙"+ @" \z  \z   \/").Replace("z"," \\\n")
\$\endgroup\$
2
\$\begingroup\$

CJam 54 Chars

not the shortest, but since i started CJam today, im happy with it.

rd(:T;{'__}:W~N{'\:XSXN}:V~SV{WVXSSWXNSV;N}T*SSVSSSX'/

Try it

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

Pascal: 149 142 141 137 characters

var n:Word;begin
Read(n);Writeln('__'#10'\ \'#10' \ \');for n:=2to n do Writeln('__\ \'#10'\  __\'#10' \ \');Write('  \ \'#10'   \/')end.

After all, Pascal's only golfing strength is that backslashes need no escaping…

\$\endgroup\$
  • 1
    \$\begingroup\$ for n:=2 to n do also works. \$\endgroup\$ – randomra Jun 13 '15 at 23:00
  • \$\begingroup\$ Thank you, @randomra. I think was ~18 years ago when I was aware of this possibility… Nice to remember it. \$\endgroup\$ – manatwork Jun 14 '15 at 12:25
2
\$\begingroup\$

Google Sheets, 60 Bytes

Anonymous worksheet function that takes input from range [A1] and outputs to the calling cell.

="__
\ \
 \ \
"&REPT("__\ \
\  __\
 \ \
",A1-1)&"  \ \
   \/
\$\endgroup\$
2
\$\begingroup\$

Perl 5, 58 + 1 (-n) = 59 bytes

say'__
\ \
 \ \ 
'.'__\ \
\  __\
 \ \
'x--$_.'  \ \
   \/'

Try it online!

\$\endgroup\$
1
\$\begingroup\$

SpecBAS - 135 104 bytes

The apostrophe in PRINT statements moves cursor to a new line.

SpecBAS lets you incorporate ASCII characters in a string via way of #n, so have built in some carriage returns (ASCII 13).

Built a string up using carriage returns and other characters, then used REP$ to repeat it the required number of times.

1 LET b$="\ \": INPUT n: PRINT "__"'b$+REP$(#13" "+b$+#13"__"+b$+#13"\  __\",n-1)'" ";b$'"  ";b$'"   \/"
\$\endgroup\$
1
\$\begingroup\$

PHP 155

$l=PHP_EOL;echo$l;echo "__$l";for($i=0;$i<$argv[1];$i++){if($i>=1)echo "__\\ \\$l\\  __\\$l";else echo "\\ \\$l";echo " \\ \\$l";}echo "  \\ \\$l   \\/$l";

Ungolfed Version

$n = $argv[1];

echo PHP_EOL;
echo '__'.PHP_EOL;
for($i=0;$i<$n;$i++)
{
    if($i>=1) {
        echo '__\\ \\'.PHP_EOL.'\\  __\\'.PHP_EOL;

    }
    else
    {
        echo '\\ \\'.PHP_EOL;
    }   
    echo ' \\ \\'.PHP_EOL; 


}    
echo '  \\ \\'.PHP_EOL;
echo '   \\/';
echo PHP_EOL;
\$\endgroup\$
  • \$\begingroup\$ Your code can be further improved, got it down to 121 bytes. echo$l=PHP_EOL,"__$l";$g="\\ \\$l";for($i=0;$i<$argv[1];$i++){echo($i?"__$g\\ __\\$l":$g)," $g";}echo" $g",' \\/',$l; \$\endgroup\$ – Octfx Jun 5 '15 at 14:02
  • \$\begingroup\$ In addition: remove the $i=0; remove the brackets for the for loop; increment the counter inside the loop (echo($i++?"…). \$\endgroup\$ – Blackhole Jun 7 '15 at 12:34
1
\$\begingroup\$

Java, 183 180 bytes

class L{public static void main(String[]a){String b="__\n\\ \\\n \\ \\\n";for(int i=1;i<new Long(a[0]);++i)b+="__\\ \\\n\\  __\\\n \\ \\\n";System.out.print(b+"  \\ \\\n   \\/");}}

Lua, 110 bytes

function l(n)print("__\n\\ \\\n \\ \\\n"..string.rep("__\\ \\\n\\  __\\\n \\ \\\n",n-1).."  \\ \\\n   \\/")end
\$\endgroup\$
1
\$\begingroup\$

Retina, 46 bytes

.+
__#r r$0x  r   \/
1x

1
__r\  __\# r
r
\ \#   

Takes input as unary.

Each line should go to its own file and # should be changed to newline in the files. This is impractical but you can run the code as is, as one file, with the -s flag, keeping the # markers. You can change the #'s to newlines in the output for readability if you wish. E.g.:

> echo -n 11|retina -s lightning|tr # '\n'
__
\ \
 \ \
__\ \
\  __\
 \ \
  \ \
   \/

The algorithm is very simple. The pairs of lines (regex - substitute pairs) do the following substitution steps:

  • Surround input with the top and bottom of the lightning.
  • Subtract 1 from the unary input.
  • Change every unary digit into the middle part of the lightning.
  • Decompress the compressed \ \ parts of the lightning to get the desired output.
\$\endgroup\$
  • \$\begingroup\$ Try it online! (includes decimal conversion) but I was able to do it in 45 bytes: Try it online! (includes decimal conversion). \$\endgroup\$ – Neil Jan 27 at 10:45
1
\$\begingroup\$

Powershell, 59 bytes

'__
\ \'
,' \ \
__\ \
\  __\'*--$args[0]
' \ \
  \ \
   \/'

Test script:

$f = {

'__
\ \'
,' \ \
__\ \
\  __\'*--$args[0]
' \ \
  \ \
   \/'

}

&$f 1
&$f 2
&$f 3
&$f 4

Output:

__
\ \
 \ \
  \ \
   \/
__
\ \
 \ \
__\ \
\  __\
 \ \
  \ \
   \/
__
\ \
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
  \ \
   \/
__
\ \
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
  \ \
   \/

Explanation:

This script is traditional top+middle+bottom. There is only one smart thing: the comma before the middle string force to repeat an array element rather than a string. Therefore, each middle is displayed on a new line.

\$\endgroup\$

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.