Draw an ASCII Lightning Bolt

35

4

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.

CzarMatt

Posted 2015-06-04T21:47:41.443

Reputation: 1 769

2How many of those challenges have we seen so far? – flawr – 2015-06-05T23:00:08.463

@flawr Too many – Beta Decay – 2015-06-30T16:34:23.403

Answers

19

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"));}}

Olivia Trewin

Posted 2015-06-04T21:47:41.443

Reputation: 351

23Ah, Java, the language where you've already lost before you start typing the body of your main method. – David Richerby – 2015-06-05T12:56:57.583

2I 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 – Alec Teal – 2015-06-06T04:05:34.090

@AlecTeal Totally agree, some questions actually specify that they only require functional snippets, but most do not. – David Mulder – 2015-06-06T19:36:55.393

6You may write a function that takes n as the only argument and prints or returns the string. So, umm, you should probably do that ;) – Geobits – 2015-06-09T17:33:00.040

It may be 6 months late, but http://codegolf.stackexchange.com/a/64713/42736 or using a function make it shorter.

– J Atkin – 2016-01-12T23:42:09.733

10

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(*\

Sp3000

Posted 2015-06-04T21:47:41.443

Reputation: 58 729

40 – Optimizer – 2015-06-05T14:00:37.897

thanks for the explanation with top + middle * (input-1) + bottom, it reminded me that powershell could multiply strings :P – Nacht - Reinstate Monica – 2015-06-09T04:21:56.637

8

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>

edc65

Posted 2015-06-04T21:47:41.443

Reputation: 31 086

7

PowerShell, 72 63 bytes

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

%{$a="\ \
";"__
$a"+" $a`__$a\  __\
"*($_-1)+" $a  $a   \/"}

Nacht - Reinstate Monica

Posted 2015-06-04T21:47:41.443

Reputation: 481

For code golf, I think \r\n still counts as \n, since it does the same thing – MilkyWay90 – 2019-04-01T23:42:10.723

6

Pyth, 60 54 bytes (Thanks @isaacg)

My first attempt at Pyth, probably very bad.

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

Verify it here.

JNV

Posted 2015-06-04T21:47:41.443

Reputation: 389

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 \. – isaacg – 2015-06-07T14:22:34.787

@isaacg Thanks. – JNV – 2015-06-07T14:32:10.437

6

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.

Martijn

Posted 2015-06-04T21:47:41.443

Reputation: 713

4

CJam, 50 bytes

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

Try it here

Ypnypn

Posted 2015-06-04T21:47:41.443

Reputation: 10 485

4

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#?

Hand-E-Food

Posted 2015-06-04T21:47:41.443

Reputation: 7 912

Woah, nice golfing, especially in BF! – MilkyWay90 – 2019-04-01T23:44:20.803

4

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

Captain Man

Posted 2015-06-04T21:47:41.443

Reputation: 386

3

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"
__
\ \
 \ \
__\ \
\  __\
 \ \
  \ \
   \/

r3mainer

Posted 2015-06-04T21:47:41.443

Reputation: 19 135

1Some 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. – nutki – 2015-06-05T10:25:11.063

3

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

Michael M.

Posted 2015-06-04T21:47:41.443

Reputation: 12 173

Cool! What it is doing? – rpax – 2015-06-06T08:35:09.517

1

@rpax I used base64 encoding to avoid \ and \n . Have a look at atob documentation

– Michael M. – 2015-06-07T17:57:52.297

3

C, 101 bytes

My not so original implementation in c

f(n){puts("__\n\\ \\");for(;--n;puts(" \\ \\\n__\\ \\\n\\  __\\"));puts(" \\ \\\n  \\ \\\n   \\/");}

Johan du Toit

Posted 2015-06-04T21:47:41.443

Reputation: 1 524

3

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

fsacer

Posted 2015-06-04T21:47:41.443

Reputation: 131

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.

– VisualMelon – 2015-06-05T19:27:56.750

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!] – sellotape – 2015-06-06T14:38:36.070

Nice tips, it was hard to verbatim formatting in order :) – fsacer – 2015-06-06T15:50:34.263

3

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.

user41392

Posted 2015-06-04T21:47:41.443

Reputation:

1Hey, 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");}} – fsacer – 2015-06-06T10:19:48.970

Nice, and just curious, but why did you change the type of e from int to var? It's still 3 characters :P – None – 2015-06-06T10:31:09.997

No reason, maybe because I love var keyword :) – fsacer – 2015-06-06T10:32:49.800

3

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
__
\ \
 \ \
__\ \
\  __\
 \ \
__\ \
\  __\
 \ \
  \ \
   \/

justbrowsing

Posted 2015-06-04T21:47:41.443

Reputation: 131

Here is the consensus on counting command-line flags. So I think you've done that right. – Martin Ender – 2015-06-07T11:06:16.987

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 \\/"} http://pastebin.com/NCznF9kH

– manatwork – 2015-06-07T15:26:51.793

3

Python 97 82 78char:

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

This is my first code golf

@(^_^)@

Test here

Pwed

Posted 2015-06-04T21:47:41.443

Reputation: 31

This is python 3? Will that input() work for integers? – Renae Lider – 2015-06-10T20:52:52.277

2

Google Sheets, 60 Bytes

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

="__
\ \
 \ \
"&REPT("__\ \
\  __\
 \ \
",A1-1)&"  \ \
   \/

Taylor Scott

Posted 2015-06-04T21:47:41.443

Reputation: 6 709

2

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

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

Try it online!

Xcali

Posted 2015-06-04T21:47:41.443

Reputation: 7 671

2

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''' \ \
  \ \
   \/
''')

TheNumberOne

Posted 2015-06-04T21:47:41.443

Reputation: 10 855

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. – randomra – 2015-06-05T08:14:18.013

You can save one byte by changing i in [0] to i in[0]. – mbomb007 – 2015-06-05T19:19:16.317

Welcome! A single line print in the loop is also shorter: for i in[0]*~-n:p(' \\ \\\n__\\ \\\n\\ __\\'). – randomra – 2015-06-05T21:20:10.260

2

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.

aragaer

Posted 2015-06-04T21:47:41.443

Reputation: 431

2

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

Matty

Posted 2015-06-04T21:47:41.443

Reputation: 471

Have you tried using %s formatting for the middle part? – Sp3000 – 2015-06-06T04:11:02.450

@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. :( – Matty – 2015-06-06T09:52:26.213

2

F#, 98 characters, 105 bytes

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

Hand-E-Food

Posted 2015-06-04T21:47:41.443

Reputation: 7 912

2

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…

manatwork

Posted 2015-06-04T21:47:41.443

Reputation: 17 865

1for n:=2 to n do also works. – randomra – 2015-06-13T23:00:02.973

Thank you, @randomra. I think was ~18 years ago when I was aware of this possibility… Nice to remember it. – manatwork – 2015-06-14T12:25:07.400

2

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

TobiasR.

Posted 2015-06-04T21:47:41.443

Reputation: 161

1

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.

mazzy

Posted 2015-06-04T21:47:41.443

Reputation: 4 832

1

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$'"   \/"

Brian

Posted 2015-06-04T21:47:41.443

Reputation: 1 209

1

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;

kuldeep.kamboj

Posted 2015-06-04T21:47:41.443

Reputation: 625

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; – Octfx – 2015-06-05T14:02:07.177

In addition: remove the $i=0; remove the brackets for the for loop; increment the counter inside the loop (echo($i++?"…). – Blackhole – 2015-06-07T12:34:00.343

1

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

ECS

Posted 2015-06-04T21:47:41.443

Reputation: 361

1

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.

randomra

Posted 2015-06-04T21:47:41.443

Reputation: 19 909

Try it online! (includes decimal conversion) but I was able to do it in 45 bytes: Try it online! (includes decimal conversion). – Neil – 2019-01-27T10:45:32.180