96
\$\begingroup\$

Adam West passed away, and I'd like to honor his memory here on PPCG, though I doubt he knew of our existence. While there are many, many different things that this man is known for, none are more prominent than his role as the original batman. I'll always remember my step-father still watching the old-school Batman and Robin to this day. This challenge is simplistic in nature, not at all in line with the complicated man that was Adam West. However, it's the best I could come up with, as this is the most iconic image of the man's career.


I wanted to post this earlier, but I was waiting for someone to come up with something better.


Output the following (with or without trailing spaces/newlines):

           *                         *
       ****          *     *          ****
     ****            *******            ****
   ******            *******            ******
  *********         *********         *********
 ***********************************************
*************************************************
*************************************************
*************************************************
 ***********************************************
  *****       *********************       *****
    ****       ***    *****    ***       ****
       **       *      ***      *       **

This is , the lowest byte-count will win.

\$\endgroup\$
14
  • 7
    \$\begingroup\$ You should forbid encoded strings. It is really not fun! \$\endgroup\$
    – sergiol
    Jun 13, 2017 at 22:47
  • 7
    \$\begingroup\$ He wasn't the original Batman. That honour belongs to Lewis Wilson. \$\endgroup\$
    – Shaggy
    Jun 13, 2017 at 22:55
  • 47
    \$\begingroup\$ When I saw the title, I thought the output was going to be "na-na-na-na-na-na-na-na na-na-na-na-na-na-na-na". \$\endgroup\$
    – D Krueger
    Jun 14, 2017 at 2:36
  • 3
    \$\begingroup\$ @DKrueger: make it so in another question :) \$\endgroup\$ Jun 14, 2017 at 14:46
  • 6
    \$\begingroup\$ Why didn't this start last year? Carrie Fisher, Prince, David Bowie and Alan Rickman! \$\endgroup\$ Jun 14, 2017 at 20:58

51 Answers 51

1
2
1
\$\begingroup\$

Braingolf, 590 580 579 577 428 423 312 bytes

-111 bytes because LeakyNun is a golfing god

14#
46*6394943[92+.6,5][8]#.[# ]#*[# ]#*#
[# ][#*][# ]#*[# ]#*[# ]#*...#
[# ][#*][# ][#*][# ]#*...#
# ..[#*][# ][#*][# ][#*]#
# .[#*][# ][#*][# ][#*]#
# [#*]#
&@#0[#*]#
!&@!&@# &@#.[#*]"
  "&@4645*643646366556[#*][# ][#*][# ][#*]"
    "[#*][# ]#*..# ...[#*]# ...#*..[# ][#*]#
[# ]#*.[# ]#*[# ]#*..[# ]#*[# ]#*.&@

Try it online!

Braingolf is not good at ASCII art, but dammit I tried.

No way in hell am I explaining this clusterf**k

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

///, 171 166 bytes

5 bytes saved because I was using \r\n in the source, lol.

/-/  //,/!!//'/**//&/*"//%/--//#/,,,,,!*//"/%-//!/''/"% &""" *
" !"%*% &%!
% !""!'&"!
- !*&"!'&"!'
-,&- ,&- ,*
 #'
!#
!#
!#
 #'
-!& ,,!& !*
%!" '*%!*%'& !
" *& &'&& '

Try it online!

Compressed by using successive iterations of replacing the "most economical" substrings with a single character. This is nearly optimal, though one of two things could be the case:

  1. I could get away with using some meta replacements (e.g. dynamically insert regexes)
  2. It is somehow more beneficial to replace less economical substrings first (unlikely).
\$\endgroup\$
1
\$\begingroup\$

braingasm, 187 bytes

XXX represents a string of 154 mostly unprintable bytes (here's a hexdump of the whole program).

"XXX",76[->$[<s[32.]z[42.]q[10.]>]>]

The string is is dumped onto the tape and its bytes are read in pairs in a sort of run-length encoding scheme: The first byte is initially either 0, 1 or 8, but then decremented by one to become -1, 0 or 7. Each of these numbers will only pass one of the following tests:

  • s - signed => print 32 (space)
  • z - zero => print 42 (asterisk)
  • q - prime => print 10 (newline)

The second byte of each pair is the number of times to print.

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

gawk, 284 264 bytes.

Uses LZW compression.

BEGIN{d["#"]="\n";d["$"]=" ";d["%"]="*";n=38
split("$&'($%),--%#/%3.&+(7.3318;5';B@6;=*B95I4DL=L?:QJ)T0HWZ[\\F]_`Q#adaceh[1ilOERVi2F>MqJIusX,v8}~62#",x,"")
while(++i<96){c=x[i];c in d||d[c]=p substr(p,1,1)
p&&d[sprintf("%c",n++)]=p substr(d[c],1,1)
printf p=d[c]}}
\$\endgroup\$
1
\$\begingroup\$

sed, 244 bytes

Alphabetic RLE. Uppercase letters encode stars, lower case encode spaces, underscores encode newlines. So 'A' -> '*', 'B' -> '**' etc. This script doesn't take advantage of the pattern's left-right symmetry, thus some of the strings are longer than 26 bytes; those strings are encoded using two letters.

s/.*/kAyAk_gDjAeAjDg_eDlGlDe_cFlGlFc_bIiIiIb_aZUa_ZW_YX_ZW_aZUa_bEgUgEb_dDgCdEdCgDd_gBgAfCfAgBg/;:L;y/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy/*ABCDEFGHIJKLMNOPQRSTUVWXY abcdefghijklmnopqrstuvwx/;s/[A-Z]/&*/g;s/[a-z]/& /g;tL;s/_/\n/g

I don't think it's possible to run sed without giving it a file to read. This program ignores the contents of the file you pass it, and prints a Batman symbol for each line in the file. The easiest way to invoke it in Bash is by passing it an empty here-string, eg:

sed<<<'' -f batman.sed

Or don't bother saving it to a file, just run it directly in the CLI:

sed<<<'' 's/.*/kAyAk_gDjAeAjDg_eDlGlDe_cFlGlFc_bIiIiIb_aZUa_ZW_YX_ZW_aZUa_bEgUgEb_dDgCdEdCgDd_gBgAfCfAgBg/;:L;y/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy/*ABCDEFGHIJKLMNOPQRSTUVWXY abcdefghijklmnopqrstuvwx/;s/[A-Z]/&*/g;s/[a-z]/& /g;tL;s/_/\n/g'

The annotated version:

# The compressed data string.
# Uppercase letters encode stars, lower case  encode spaces, underscores encode newlines
# Convert the current input line to the data string.
s/.*/kAyAk_gDjAeAjDg_eDlGlDe_cFlGlFc_bIiIiIb_aZUa_ZW_ZW_ZW_aZUa_bEgUgEb_dDgCdEdCgDd_gBgAfCfAgBg/

# Interpret letters as string lengths
# Start the loop
:L

# Transliterate each letter to the previous letter in alphabetical order,
# except 'A' goes to star and 'a' goes to space
y/ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxy/*ABCDEFGHIJKLMNOPQRSTUVWXY abcdefghijklmnopqrstuvwx/

# Append a star to an uppercase string
s/[A-Z]/&*/g

# Append a space to a lowercase string
s/[a-z]/& /g

# Goto the 'L" label at the top of the loop unless no `s` substitution
# was performed since the last goto
tL

# Convert underscores to newlines
s/_/\n/g

# The result is now printed, and execution returns to the start of the script 
# to process the next input line, if it exists.

Here's a version that does take advantage of the pattern's left-right symmetry. However, it's longer than the previous program, since it uses a rather complicated loop to split off each half-line and combine it with its reversed version.

sed, 261 bytes.

Needs the -r option on the commandline (or in the shebang), since it uses extended Regular Expressions.

s/.*/kAm_gDjAc_eDlD_cFlD_bIiE_aX_Y_Y_Y_aX_bEgK_dDgCdC_gBgAfB_/;:L;y/ABCDEFGHIJKLMNOPQRSTUVWXYabcdefghijklm/*ABCDEFGHIJKLMNOPQRSTUVWX abcdefghijkl/;s/[A-Z]/&*/g;s/[a-z]/& /g;tL;:a;h;s/_.*//;s/^(.*)(.)$/\1@&@/;:x;s/(@.)(.*)(.@)/\3\2\1/;tx;s/@//g;p;g;s/[^_]*_//;ta

This script shares some logic with the previous code, but here's an annotated version of the section that does the palindromisation, which was derived from the code for reversing a string given in the sed info pages.

# Palindromise a series of words.

# Start the outer loop    
:a
# Save the current pattern 
h

# Remove everything after the 1st word
s/_.*//

# Palindromise a line.

# Begin embedding the line between two markers
# Also insert the line, except for the last char, before the 1st marker
s/^(.*)(.)$/\1@&@/

# Loop to reverse the chars between the markers
:x;s/(@.)(.*)(.@)/\3\2\1/;tx

# Remove the markers
s/@//g

# Print the palindromised result and restore the pattern 
p;g

# Remove the word we just processed
s/[^_]*_//

# Goto to the 'a' label unless no `s` substitution was
ta
\$\endgroup\$
2
  • \$\begingroup\$ Using capitals and lowercases, that's pretty darn smart. \$\endgroup\$ Jun 16, 2017 at 18:39
  • \$\begingroup\$ @carusocomputing Thanks! I also used that in some of my Python versions. \$\endgroup\$
    – PM 2Ring
    Jun 16, 2017 at 18:52
1
\$\begingroup\$

Scala (169 chars) (Based on @snowman's answer)

Golfed:

var b=false;";1I1074:151:4054<7<4036<7<6029999901_10a10a10a01_0257E570447345437407271636172".foreach{a⇒print((if(b) "*" else " ")*(a-48));if(a < 49)println()else b = !b}

Ungolfed:

object Batman extends App {
var b = false
 ";1I1074:151:4054<7<4036<7<6029999901_10a10a10a01_0257E570447345437407271636172".foreach { a ⇒
    print((if (b) "*" else " ") * (a - 48))
    if (a < 49) println() else b = !b
  }
}
\$\endgroup\$
1
\$\begingroup\$

C# (.NET Core), 312 280 bytes

An improvement (?) on this by Carlos Alejo.

Uses smaller (int32 instead of int64) constants for initial "bitmap", uses an int (z) on the redundant entries (5 wide bands in middle), uses reflection technique to mirror the partial output.

Downside: requires a using System; statement in the header.

()=>{var s="";int z=33554431;foreach(var i in new[]{8192,245768,983055,4128783,8372255,z/2,z,z,z,z/2,8128511,1966983,196867}){s+=Convert.ToString(i,2).PadLeft(25,' ').Replace('0',' ').Replace('1','*');for(int j=s.Length-2;j>=s.Length-49;j--)s+=s.Substring(j,1);s+='\n';}return s;}

Try it online!

The trick with using a var for the redundant lines is from this by Hagen von Eitzen. Problem with that answer is that the output is incorrect, only 47 chars wide instead of 49.

If Carlos Alejo used that trick on his answer, the score would go down to 278:

()=>{var s="";var z=(1L<<49)-1;foreach(var i in new[]{0x2000000800,0x3c008200780,0xf000fe001e0,0x3f000fe001f8,0x7fc01ff007fc,z/2-1,z,z,z,z/2-1,0x7c07ffffc07c,0x1e0387c380f0,0x30103810180})s+=Convert.ToString(i,2).PadLeft(49,'0').Replace('0',' ').Replace('1','*')+'\n';return s;}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ In fact, I have just changed my answer after a complete redesign of the algorithm and now I use less than 200 bytes. \$\endgroup\$
    – Charlie
    Jun 22, 2017 at 7:17
1
\$\begingroup\$

JavaScript (ES6, no string encoding), 233 bytes

Golfed:

[[11,1,13],[7,4,10,1,3],[5,4,12,4],[3,6,12,4],[2,9,9,5],[1,24],[0,25],[0,25],[0,25],[1,24],[2,5,7,11],[4,4,7,3,4,3],[7,2,7,1,6,2]].map(a=>a.map((b,c)=>' *'[c%2].repeat(b)).join``).map(a=>a+a.split``.reverse().join``.slice(1)).join`
`

Ungolfed:

[
    [11, 1, 13],
    [7, 4, 10, 1, 3],
    [5, 4, 12, 4],
    [3, 6, 12, 4],
    [2, 9, 9, 5],
    [1, 24],
    [0, 25],
    [0, 25],
    [0, 25],
    [1, 24],
    [2, 5, 7, 11],
    [4, 4, 7, 3, 4, 3],
    [7, 2, 7, 1, 6, 2]
]
    .map(row => row
        .map((val, idx) => ' *'[idx % 2].repeat(val))
        .join``
    )
    .map(str => str + str
        .split``
        .reverse()
        .join``
        .slice(1)
    )
    .join`
`

Explanation

The matrix represents the left half of the logo as numbers of alternating character always starting with space, and including the middle character. Thus each list is a half-palindrome line, each number the number of times to repeat a character, and the parity of its index whether the character is a space (even) or asterisk (odd).

The first map replaces lists of numbers with lists of repeated characters and joins into a single string (per line).

The second map mirrors each string excluding the already-included middle character.

Lastly the lines are joined with newlines and the final result of the expression is the complete string, to be assigned or used as an argument.

Demo

o.innerHTML = [[11,1,13],[7,4,10,1,3],[5,4,12,4],[3,6,12,4],[2,9,9,5],[1,24],[0,25],[0,25],[0,25],[1,24],[2,5,7,11],[4,4,7,3,4,3],[7,2,7,1,6,2]].map(a=>a.map((b,c)=>' *'[c%2].repeat(b)).join``).map(a=>a+a.split``.reverse().join``.slice(1)).join`
`
<pre id=o></pre>

\$\endgroup\$
3
  • \$\begingroup\$ Welcome to PPCG. Here is a very quickly golfed 216 byte version to help you get started. \$\endgroup\$
    – Shaggy
    Jun 16, 2017 at 14:02
  • \$\begingroup\$ Thanks. I see some bits I can adopt to improve mine, while the encoded string I'll leave for someone else. I wanted to participate in the tribute to Adam West, but cheesy uses of compression and encoded strings are exactly why I won't be sticking around. :/ I'm not in it to win it - I'd rather restrict myself to more creative optimizations. \$\endgroup\$ Jun 16, 2017 at 14:20
  • \$\begingroup\$ Also, I just learned about ES6 tagged templates (stackoverflow.com/questions/29660381/…) from your version, and wow, WTF. :P \$\endgroup\$ Jun 16, 2017 at 14:22
1
\$\begingroup\$

Self-modifying Brainfuck, 700 bytes

<<...........>.<.........................>.<<.>.......>....<..........>.<.....>.<..........>....<<.>.....>....<............>.......<............>....<<.>...>......<............>.......<............>......<<.>..>.........<.........>.........<.........>.........<<.>.>...............................................<<.>>.................................................<<.>>.................................................<<.>>.................................................<<.>.>...............................................<<.>..>.....<.......>.....................<.......>.....<<.>....>....<.......>...<....>.....<....>...<.......>....<<.>.......>..<.......>.<......>...<......>.<.......>..
 *

Try it online!

Yes. This can probably be golfed. Do I want to though? Oh please no.

\$\endgroup\$
1
  • \$\begingroup\$ Pretty impressive that you're 80 bytes off of just printing it in cat. \$\endgroup\$ Jul 26, 2017 at 15:57
1
\$\begingroup\$

tcl, 325 317 303 302 300 299

Still very long:

proc F {n\ 5} {format %$n\s *}
proc R {n\ 49} {string repe * $n}
puts "[F 12][F 26]
[set f [F 8]][set T ***][F 11][F 6][F 12]$T
[F 6][set M $T[F 13]$T$T[F 13]]$T
   $T$M[R 5]
  [R 9][set H [F 10][R 8]]$H
 [R 47]
[R]
[R]
[R]
 [R 47]
  [R 5]$f[R 20]$f*$T
[F]$T$f**[F]*$T[F]**$f$T
$f*$f[F 7]**[F 7]$f*"

demo

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

Bubblegum, 70 bytes

00000000: cd8b a501 c000 10c4 fc4d f13a fbef 574e  .........M.:..WN
00000010: 195d a30e 6b81 ba82 2880 ddc1 9b75 54e6  .]..k...(....uT.
00000020: fab3 2856 6fc6 10c5 d2de 2629 be11 f8e3  ..(Vo.....&)....
00000030: a33e 1fc6 478d 20b2 efa2 5a42 13c5 d210  .>..G. ...ZB....
00000040: 350a bdc2 9c16                           5.....

Try it online!

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

Befunge, 139 bytes

I know this is a bit late now, but I wasn't around at the time the challenge was initially posted, and this looked like it would be a fun problem to solve in Befunge.

"YaA(!"***+"3{~X"7**+*"e~#"+*32223"a}|V"*+*v>,\2/34g1-:v:*55\+55\0-2<
_@#:*+** "+Ewn_"**+*"^iw/C"+*83:*9+**"+9_t"<^:g\8%2:p43_$$$>>:#,_$:#^

Try it online!

Explanation

* We start by pushing thirteen integers onto the stack, whose bits represent half of the pattern of the bat (the other half being a reflection). Each of these integers is offset by two, since that makes their Befunge representations slightly more compact.
* We then start the main loop, which will process one line/integer at a time. We subtract two to account for the offset, and we push push a null terminator and a newline onto the stack for later use when writing out the second half of the line.
* Next we get to the inner loop which iterates over the 25 bits in the number, taking the value mod 2 to extract a bit, and performing a table lookup on column 8 of the source (*) to obtain the character to output. The character is also pushed onto the stack for later use.
* Once this loop is complete, the first half of the line has been output, and the characters for the second half are in place on the stack in reverse order. We then simply output those characters with a standard string output sequence, and return to the start of the main loop.

Source code with execution paths highlighted

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

Taxi, 793 bytes

"           *                         *\n       ****          *     *          ****\n     ****            *******            ****\n   ******            *******            ******\n  *********         *********         *********\n ***********************************************\n*************************************************\n*************************************************\n*************************************************\n ***********************************************\n  *****       *********************       *****\n    ****       ***    *****    ***       ****\n       **       *      ***      *       **" is waiting at Writer's Depot.
Go to Writer's Depot:w 1 r 3 l 2 l.
Pickup a passenger going to Post Office.
Go to Post Office:n 1 r 2 r 1 l.
Go to Taxi Garage:n 1 r 1 l 1 r.

Try it online!

I would have hoped that something more fun than the naive solution would have been shorter.

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

C (gcc), 170 169 160 bytes

-9 bytes thanks to ceilingcat.

char*s="1Q111O19Q81ii81imP1mopppppppppppppppopppm2mpa4ia17AQ",o[50];main(i){for(;*s;s+=4,o[24]=o[23],puts(o))for(i=24;i--;)o[i]=o[48-i]=s[i/6]-49>>i%6&1?42:32;}

Try it online!

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

Vyxal j, 53 bytes

»&jṗ∧∴NżZ8D=→JβW↳z\T□≬'₴5≬≥ėĿwq`÷6bḭ⟑AjẎyt»‛* τ13/vøm

Try it Online!

\$\endgroup\$
0
\$\begingroup\$

T-SQL, 212 bytes

I wonder if I get extra bonus for making my script unreadable

Golfed:

DECLARE @x
bit=0,@ varchar(max)='=3Ke96<373<h76>9>h58>9>j4;;;;m3adcdcdcdad2479G9i669567659h9493858394'WHILE'!'<@
SELECT @=stuff(@,1,1,'')+replicate(char(32+10*@x),ascii(@)%50)+iif(ascii(@)>99,'
',''),@x-=1PRINT @

The way this works. The script takes a varchar and loop it for each character. The result is appended to the end of the varchar. The bit gets flipped every time the loop runs. This bit determine which character gets chosen.

Every character represents a number and will also include a line change when the ascii value is above 100+. The ascii value of each character determine how many characters to repeat(maximum 49).

values explained

2=ascii-50 produce 0 char no linebreak

3=ascii-51 produce 1 char no linebreak

:=ascii-60 produce 8 char no linebreak

d=ascii-100 produce 0 char linebreak

f=ascii-102 produce 2 char linebreak

Ungolfed:

DECLARE
  @x bit=0,
@ varchar(max)='=3Ke96<373<h76>9>h58>9>j4;;;;m3adcdcdcdad2479G9i669567659h9493858394'
WHILE @>'!'
  SELECT
    @=stuff(@,1,1,'')+
    replicate(char(32+10*@x),ascii(@)%50)+iif(ascii(@)>99,'
',''),
    @x-=1
PRINT @

Try it online ungolfed version

\$\endgroup\$
0
\$\begingroup\$

Stax, 43 bytes

¬H∙☼ßú¶ε╥M9rx⌠ªÅ`Fm■♦▓dL∩BF╚3♣æ7~εåIZ▼•sÿ4ú

Run and debug it

It's just the left-half, run-length encoded and then mirrored.

\$\endgroup\$
0
\$\begingroup\$

Julia, 177 bytes

println.(prod(get.(" ",reshape([fill.((1:38).%2,[11,1,20,4,10,1,8,4,12,4,3,6,12,4,2,9,9,5,1,99,1,24,2,5,7,11,4,4,7,3,4,3,7,2,7,1,6,2])...;],25,:),'*')[[1:25;24:-1:1],:],dims=1))

Stores only the left half encoded as the numbers of chars until the char changes. Could probably be improved upon with a better encoding.

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Python 3, 234 224 bytes

-10 bytes thanks to @Blue

for i in range(637):print(' *'[0x301038101800F01C3E1C0781F01FFFFF01F1FFFFFFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDFFFFFFFFFFFC7FC01FF007FC1F8007F000FC03C003F800780078010400F00002000000800>>i&1],end=['\n',''][(i+1)%49>0])

Try it online!

I made this version before searching through all the answers. It's different to all the other python answers, but definitely longer. As far as I can see, I'm using a different method to all of them, using bit shifting.

\$\endgroup\$
2
  • \$\begingroup\$ If you're using bit shifting, instead of the lengthy '*'if...else' ' construct, you could do ' *'[...] to save 6 bytes, for 12 bytes total. \$\endgroup\$
    – Blue
    Aug 6, 2019 at 14:03
  • \$\begingroup\$ @Blue Thanks! I've also applied this to the if...else at the end. I'll update this later. \$\endgroup\$ Aug 6, 2019 at 22:01
0
\$\begingroup\$

Duocentehexaquinquagesimal, 523 139 bytes

IŸcÓ|»lì8тï₃"—"šÙ‹çnFÙ}Xíâµ∞A!pβòΩž>qLqÖlŒηεÅBO&ô-}ܘāÅ„Å¢Úā´ÏΛ¯—¨ïAÚ∞·ÏƵŸ9ße³āEΔëнj'`Ï×"ë‡LkYмâÿÒAE;ýäÇη¼ÉÊÌg¡θ’A(wBlΣ<–£¼–7₄:*Â3
Åö0δ¬ë

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Zsh (+coreutils basenc), 164 bytes

Try it online doesn't have basenc; but you can see how it works by passing the string to this site. Choose text | decode:Ascii85:z85 | bytes:binary:none.

Similar to my Arecibo answer; I first encoded the bat logo into binary then converted to z85. This yielded a string of length 101. The below script decodes the z85-encoded string and turns 1,0 into *, (space).

basenc -d --z85<<<'01Ybg1onC>0TF?+0Pj1R06ywM0r8%uGz>(JFiS8]%nSc0}#uY@%nSc0%nSc0%nS
c0%nSbl%nSc0%bRZg%m^aQ&5D9z4/^BL90=@M'|basenc --base2msbf -w49|head -13|tr 01 ' *'

code formatted slightly for readability

\$\endgroup\$
1
2

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.