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"));}}
|improve this answer|||||
\$\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(*\
|improve this answer|||||
\$\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 - Reinstate Monica 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>

|improve this answer|||||
\$\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   \/"}
|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ For code golf, I think \r\n still counts as \n, since it does the same thing \$\endgroup\$ – MilkyWay90 Apr 1 '19 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.

|improve this answer|||||
\$\endgroup\$
6
\$\begingroup\$

Pyth, 60 54 bytes (Thanks @isaacg)

My first attempt at Pyth, probably very bad.

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

Verify it here.

|improve this answer|||||
\$\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

|improve this answer|||||
\$\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#?

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ Woah, nice golfing, especially in BF! \$\endgroup\$ – MilkyWay90 Apr 1 '19 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.

|improve this answer|||||
\$\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"
__
\ \
 \ \
__\ \
\  __\
 \ \
  \ \
   \/
|improve this answer|||||
\$\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")
|improve this answer|||||
\$\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   \\/");}
|improve this answer|||||
\$\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.

|improve this answer|||||
\$\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

|improve this answer|||||
\$\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
__
\ \
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
  \ \
   \/
|improve this answer|||||
\$\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

|improve this answer|||||
\$\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.

|improve this answer|||||
\$\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''' \ \
  \ \
   \/
''')
|improve this answer|||||
\$\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')
|improve this answer|||||
\$\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")
|improve this answer|||||
\$\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

|improve this answer|||||
\$\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…

|improve this answer|||||
\$\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)&"  \ \
   \/
|improve this answer|||||
\$\endgroup\$
2
\$\begingroup\$

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

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

Try it online!

|improve this answer|||||
\$\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$'"   \/"
|improve this answer|||||
\$\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;
|improve this answer|||||
\$\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
|improve this answer|||||
\$\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.
|improve this answer|||||
\$\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 '19 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.

|improve this answer|||||
\$\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.