# The first published picture of the Mandelbrot set

Here’s the picture of the first published picture of the Mandelbrot set.

Use the fewest bytes possible to write a program or function that outputs the following.

A trailing new line is permitted. Character * cannot be replaced by any other character.

Useful information: Center is $$\(-0.75, 0)\$$, $$\\Delta x = 0.035\$$, and $$\\Delta y = 1.66\Delta x\$$. Iteration count is 250.

As text (for checking):

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


Thanks @Sisyphus for providing the parameters.

• Is there a text form of the image we can use to check our output?
– xnor
Jan 13, 2021 at 4:25
• Just edited a text version in. Hopefully my quick image processing script got it correct. Jan 13, 2021 at 4:41
• Also relevant. Center is $(-0.75, 0)$, $\Delta x = 0.035$, and $\Delta y = 1.66\Delta x$. Iteration count is 250. Jan 13, 2021 at 5:00
• Do we have to print the spaces at the end? Jan 13, 2021 at 13:25
• Interesting side effect of printing *s is that half of the programs will necessarily contain the answer to life, the universe and everything. It's often used as a sample value in programs, but here it's actually relevant. Jan 13, 2021 at 15:36

# Ruby 2.5, 98 bytes

-15.upto(15){|y|68.times{|x|z=0;250.times{z=0.035*x-1.9751+y/17.21i+z*z};putc z.abs<2?42:32};puts}


Try it online!

Very straightforward implementation, with a little bit of trickery to allow using times instead of upto in the inner loop.

Unfortunately, loop merging is two bytes longer, although it may help in other languages:

-1034.upto(1104){|x|z=0;250.times{z=x%69*0.035-2.0101+x/69/17.21i+z*z};putc x%69>0?z.abs<2?42:32:10}

• Note that the 8th row (and its counterpart in the lower part) is one * shorter than expected. Jan 13, 2021 at 13:44
• This can be fixed by using 1.9751. Jan 13, 2021 at 14:08
• @Arnauld Aha, did I neatly avoided a floating-point error when porting this to Charcoal by golfing .035*x-1.975 to .035*(x-85)+1 (well it's golfier in Charcoal at least)?
– Neil
Jan 13, 2021 at 15:15
• @Arnauld Good catch. Fixed. Jan 13, 2021 at 21:25

# Wolfram Language (Mathematica), 8685 84 bytes

-1 thanks to sanchez

Print@@@Array[If[Re@Nest[#^2+c&,c=.035#2+I.0581#,199]<2,"*"," "]&,8{4,9},-5{3,79/7}]


Try it online!

Uses the constants found by Sisyphus.

Mathematica does have such functions as MandelbrotSetIterationCount and MandelbrotSetMemberQ (which, with the default 1000 iterations, produces a slightly different image). Unfortunately, MandelbrotSetIterationCount's name is a bit too long, while setting the MaxIterations option for MandelbrotSetMemberQ makes it even more verbose.

• if you use Grid@ instead of Print@@@ you can omit the second If-argument. ," ". and using Re instead of Abs saves one more. Jan 14, 2021 at 1:07
• @sanchez Grid formats output in the REPL, but not that of a script. Nice one with Re.
– att
Jan 14, 2021 at 1:15
• Ah yes, the classic "Mathematica has a builtin for this, but it's too long" Jan 15, 2021 at 18:12

# MATL, 45 bytes

Some numerical constants have been taken from Sisyphus' answer

Thanks to @Arnauld for a correction!

O8W:"U-1.9751:.035:.4-15:15!17.21j/++]|2<42*c


Try it online!

### How it works

O                  % Push 0
8W                 % Push 2^8, that is, 256
:                  % Range. Gives [1 2 ... 256]
"                  % For each. This iterates 256 times
U                %   Square, element-wise
-1.9751:.035:.4  %   Push range from -1.9751 to 0.4 (actually to 0.37) with step 0.035
-15:15           %   Push range from -15 to 15 (with step 1)
!                %   Transpose into a column vector
17.21j/          %   Divide by 17.21j, element-wise
+                %   Add element-wise to result from previous iteration
]                  % End
|                  % Absolute value, element-wise
2<                 % Less than 2? Element-wise
42*                % Multiply by 42 (ASCII code of '*'), element-wise
c                  % Convert to char (char 0 is displayed as space). Implicit display


As a curious note, the program uses : with three different meanings:

• Unary range function (: appplied to 256)
• Ternary range literal (-1.9751:.035:.4)
• Binary range literal (-15:15)
• Sisyphus' answer is slightly off. You can use 1.9751 to fix it. Jan 13, 2021 at 14:30
• @Arnauld Thank you! Corrected Jan 13, 2021 at 16:05

# 05AB1E, 56 bytes

Feels very long.

67ÝƵú*Ž


Try it online!

Since 05AB1E does not support complex numbers the computation is done in a more manual way, keeping complex numbers as pairs [a, b]:

$$(a+bi)^2 = (a^2-b^2) + 2abi$$

D        # duplicate the pair
n       # square each part: [a^2, b^2]
Æ      # reduce by subtraction: a^2-b^2
s     # swap to copy
P    # take the product: a*b
·   # double it: 2*a*b
‚  # pair both results: [a^2-b^2, 2*a*b]


$$|a+bi|>2 \Leftrightarrow \sqrt{a^2+b^2}>2 \Leftrightarrow a^2 + b^2 > 4$$

n        # square each part: [a^2, b^2]
O       # take the sum: a^2+b^2
4›     # is this larger than 4: a^2+b^2>4


Complete code commented:

67ÝƵú*Ž\n@-тn/          # generate the x coordinates: ([0..67]*350-19751)/10000
67Ý                     # push the range [0 .. 67]
Ƶú*                  # multiply each value by 350
Ž\n@-             # subtract 19751 from each
тn/          # divide by 100**2

15D(Ÿт*Ž6À/             # generate the y coordinates: [15..-15]*100/1721
15D                     # push 15 twice
(                    # negate one copy
Ÿ                   # take the inclusive range [15 .. -15]
т*                 # multiply each value by 100
Ž6À/             # divide by 1721

δ‚                      # create a grid of all x-y pairs
ε                     # map over each line:
ε                    #  map over each pair:
₅F                } #  iterate 255 times
#  (produces the same output as 250 iterations)
DnÆsP·‚           #    square the current value
D        #    duplicate current value
nO4›©   #    check if the magnitude is larger than 2
#  #    if this is the case, stop the loop
#    this is necessary because the program will actually crash if trying to continue with infinite values
„* ®è               #  index with the last result of |z|>2 into the string "* "
]                      # close all loops
ø                       # transpose the grid
J                      # join each line into a single string
»                     # join lines by newlines


# R, 151 138 bytes

Edit: -13 bytes thanks to Giuseppe

write(matrix(unlist(Map(rep,c(" ","*"),utf8ToInt("T #^%^$Y (S\" /Q3 !I8I;E>D=8$$?6*!?5, >2! - =!_#")-31)),68)[,c(1:16,15:1)],1,68,,"")  Try it online! Encodes the run lengths of  s and *s for the top half as a text string, converts these to a matrix (together with itself reversed by row), and outputs using cat. Bearing in mind that actually calculating the Mandelbrot set in R costs only 123 bytes, including full-colour graphic display, this might not be the golfiest solution... but the text encoding was fun anyway... • 138 bytes. You can probably reduce it further by encoding using unprintables and getting rid of the -31. Jan 13, 2021 at 17:46 # JavaScript (ES6), 128 ... 124 123 bytes Based on the parameters used by @Sisyphus. f=(k=2138)=>k? *[k--%69&&-~(g=X=>++n>>8?X*X+Y*Y<4:g(X*X-Y*Y-k%69*.035+.3699,Y=2*X*Y-(16+~(k/69))/17.21))(Y=n=0)]+f(k):''  Try it online! ### Commented f = (k = 2138) => // f is a recursive function taking a counter k // which encodes: x = k mod 69 // y = floor(k / 69) - 15 k ? // if k is not equal to 0: \n *[ // character lookup: k-- % 69 && // append a linefeed if k mod 69 = 0 // (decrement k afterwards) -~( // otherwise use the result of ... g = X => // ... the recursive function g which takes X // and also uses Y and an iteration counter n ++n >> 8 ? // increment n; if it's not equal to 256: X * X + Y * Y < 4 // return true if X² + Y² is less than 4 : // else: g( // do a recursive call to g with: X * X - Y * Y // the updated X: - k % 69 * .035 // X² - Y² - x * 0.035 + 0.3699 + .3699, // Y = 2 * X * Y // the updated Y: - (16 + ~(k / 69)) // 2XY + y / 17.21 / 17.21 // ) // end of recursive call )(Y = n = 0) // initial call to g with X = Y = n = 0 ] // end of character lookup + f(k) // append the result of a recursive call : // else: '' // stop the recursion  • Nice work! Kudos! – Jay Jan 13, 2021 at 14:38 # Charcoal, 74 73 bytes Ｆ¹⁶«Ｆ⁶⁸«≔⁰θ≔⁰ηＦφ«≔⁺⊕×·⁰³⁵⁻κ⁸⁵⁻×θθ×ηηζ≔⁺∕ι¹⁷·²¹⊗×θηη≔ζθ»§ *‹⁺×θθ×ηη⁴»⸿»‖Ｏ↑  Don't try it online! Link is to verbose version of code. Performs 1,000 iterations, so it's too slow for TIO. It can be made faster by halving the number of iterations, which costs a byte: Ｆ¹⁶«Ｆ⁶⁸«≔⁰θ≔⁰ηＦ⊘φ«≔⁺⊕×·⁰³⁵⁻κ⁸⁵⁻×θθ×ηηζ≔⁺∕ι¹⁷·²¹⊗×θηη≔ζθ»§ *‹⁺×θθ×ηη⁴»⸿»‖Ｏ↑  Try it online! Link is to verbose version of code. Previous 74-byte compression-based version: ”}∧q÷W9r¤1αlIχ‽§heＹ⟧>℅ν⊞P ～E .Q×jn⁵\6⧴<¤< Ｕ#V‽↶³≧JJＤ‴>π v‹»λê= ↨∨｜>zθ9”‖Ｏ↓  Try it online! Link is to verbose version of code. Explanation: Works by printing the top half as a compressed string literal and reflecting it. I also tried printing the bottom half and reflecting, but this increased the byte count to 78 bytes. I also tried printing the reflection of the image and for the bottom half this reduced the byte count to 75 bytes but for the top half it actually increased it to 81 bytes. I also tried using manual run length encoding but I couldn't even get it as low as 81 bytes. Previous 75-byte even faster pure Charcoal calculation version (uses the original 250 iterations): Ｆ¹⁶«Ｆ⁶⁸«≔⁰θ≔⁰ηＦ²⁵⁰«≔⁺⊕×·⁰³⁵⁻κ⁸⁵⁻×θθ×ηηζ≔⁺∕ι¹⁷·²¹⊗×θηη≔ζθ»§ *‹⁺×θθ×ηη⁴»⸿»‖Ｏ↑  Try it online! Link is to verbose version of code. If Python exponentiation worked on inf then it would have been only 73 bytes: Ｆ¹⁶«Ｆ⁶⁸«≔Ｅ²¦⁰θＦ²⁵⁰ＵＭθ⎇ν⁺∕ι¹⁷·²¹⊗×μ§θ⁰⁺⊕×·⁰³⁵⁻κ⁸⁵⁻Ｘμ²Ｘ§θ¹¦²§ *›⁴ΣＸθ²»⸿»‖Ｏ↑  Don't try it online! Link is to verbose version of code. With some hacky uses of PythonEvaluate and EvaluateVariable to get around the fact that the version of Charcoal on TIO doesn't support complex numbers I can do it in 58 bytes: Ｆ¹⁶«Ｆ⁶⁸«≔⁰θＦ²⁵⁰≔⁺⁺∕ιＵＶ17.21j⊕×·⁰³⁵⁻κ⁸⁵×θθθ§ *‹▷absθ²»⸿»‖Ｏ↑  Try it online! Link is to verbose version of code. 54 bytes using the newer version of Charcoal on ATO: Ｆ¹⁶«Ｆ⁶⁸«≔⁰θＦ²⁵⁰≔⁺⁺∕ιＩ17.21j⊕×·⁰³⁵⁻κ⁸⁵×θθθ§ *‹↔θ²»⸿»‖Ｏ↑  Attempt This Online! Link is to verbose version of code. Saves 1 byte by using Cast("17.21j") instead of PythonEvaluate("17.21j") and 3 bytes by using Abs(q) instead of EvaluateVariable("abs", q). # Perl 5, 127 bytes say for@o='e1q4o6o5j119d31@bD12ZIZLVOUNI1155PG;2PF=1OC21>1N2p4'=~s/./($i++%2?'*':$")x(-48+ord$&)/ger=~/.{68}/g,reverse@o[0..14]


Try it online!

say                                        #prints each line + \n newline at end
for @o=                                    #for all lines, also saved in array @o
'e1q4o6o5j119d31@bD12ZIZLVOUNI1155PG;2PF=1OC21>1N2p4' #lengths for spaces and *s
=~ s/./ ($i++%2?'*':$") x (-48+ord$&) /ger #...decode into lengths and output #...space or * of each length =~ /.{68}/g, #...partition lines on every 68th char reverse@o[0..14] #add mirror of first 15 lines  # Bubblegum, 97 bytes Using zopfli --i 10000 --deflate -c mandlebrot.txt | xxd and no trailing spaces. Increasing iterations beyond 10000 doesn't seem to make a difference. 00000000: c595 a901 c040 0c80 7ca6 8866 ff01 2bb1 .....@..|..f..+. 00000010: 574c f0d0 debf 05a6 4850 3c88 e216 9105 WL......HP<..... 00000020: f869 829a f63b 5ab2 30c1 6f3f 81c4 06d2 .i...;Z.0.o?.... 00000030: 23a5 e19a 9908 1124 4700 0933 a2f4 d618 #......$G..3....
00000040: 3afd 1ffa 545c ac49 df1d 619b f6c6 c1c1  :...T\.I..a.....
00000050: 15e4 ee0e eb97 a8b0 c114 4e5e a8d9 02f3  ..........N^....
00000060: 01                                       .


Try it online!

• Honestly so surprised there is no Bubblegum to brainfuck transpiler...
– Jay
Jan 19, 2021 at 23:03

# Python 3, 218 217 200 191 bytes

lambda:a+['*'*64]+a[::-1]
D=2**31
a=[f'{y:68b}'.translate(' *'*25)for y in[4**7,30<<12,63<<12,31<<12,3143680,125828992,33554412,D//8-8,D//4-2,D-1,D-2,6082*D-1,16378*D-1,32766*D-2,458750*D-4]]


Try it online!

Terrible score, but I wanted to see how it would look with bitmasks in the style of a typical challenge

-1 thanks to @thedefault

-17 thanks to @xnor

-9 thanks to @benrg

# Python 3, 165 bytes

lambda:a+["*"*64]+a[::-1];a=[''.join((i-31)%64*' *'[i-31>>6]for i in j)for j in b'T@Rc@Qe@Rd@M h@Hb o@Js a!@Gx@F{@D~@D}@7 d\$\x7f@6j!\x7f@5l ~@1a m }'.split(b"@")]


Try it online!

Run-length encoded.

• I think 16384 can be replaced by 4**7. Jan 13, 2021 at 12:05
• Could this not also generate the Julia set? given a different range? Then the question is how to fix the input vectors, most interesting. Garbage in garbage out
– Jay
Jan 13, 2021 at 14:06
• Extracting a constant: Try it online!
– xnor
Jan 14, 2021 at 0:36
• f'{y:68b}'.translate(' *'*25) saves 9 bytes. Jan 15, 2021 at 5:42
• Multiplying by D instead of 25 saves another byte at the cost of slightly increased RAM usage. Jan 15, 2021 at 5:49

# Python 2.6, 128 bytes

print"x\xda\xbd\x94\xa1\x15\x001\x0c\x85|\xa7@\xb3\xff\x80'\xbf\x0e\xe2\xf0\xf0\xfa\xda4\x14|E\xd2\xe2i\x14)\xa2\xa8\x1eM\x9dv\xb7\x99\xeb@_\xf4\xc7\x0b\x81\xd6p\xf4Hl\x88\xaaK\x84\x88#G\x1c\xca\xbd\xa1xi<;\xfd\x0c\xfd*\xfe\x7f\x93>\x1d}LC\xe3\xff\x8f\x1b\xd6G\x88\xf0\xe7\x12\xad\xcb{T\xd1*R=\xf0\x03-<\x12|".decode("zip")


This is an ASCII-fied version of the program. The actual program is encoded in latin-1 and looks like:

00000000: 7072 696e 7422 78da bd94 a115 5c78 3030  print"x.....\x00
00000010: 310c 857c a740 b3ff 8027 bf0e e2f0 f0fa  1..|.@...'......
00000020: da34 147c 45d2 e269 1429 a2a8 1e4d 9d76  .4.|E..i.)...M.v
00000030: b799 eb40 5ff4 c70b 81d6 70f4 486c 88aa  ...@_.....p.Hl..
00000040: 4b84 8823 471c cabd a178 693c 3bfd 0cfd  K..#G....xi<;...
00000050: 2afe 7f93 3e1d 7d4c 43e3 ff8f 1bd6 4788  *...>.}LC.....G.
00000060: f0e7 12ad cb7b 54d1 2a52 3df0 032d 3c12  .....{T.*R=..-<.
00000070: 7c22 2e64 6563 6f64 6528 227a 6970 2229  |".decode("zip")


Since Python 2.7, the default encoding of a file is now ASCII instead of Latin-1, so you need to prepend the file with #coding=L1 for the smaller version to run.

Try it online!

This is quite a boring answer: I zipped the original image into a string S then run print S.decode('zip').

• Ah, you are right, my apologies! Jan 16, 2021 at 8:49

# C (gcc), 212 200 bytes

double atof(),x;s;Y=16;main(a,b)int**b;{for(;--Y+16;puts(""))for(x=-1.975;s=x<2;x+=.035,printf(L" *"+s/251))for(_Complex y=x+Y*.0581i,z=a/3*y;s++<251&cabs(z=z*z+(a>2?atof(b[1])+1i*atof(b[2]):y))<2;);}


Try it online!

Thanks to @KevinCruijssen for -1. Julia set coordinates can be added as command line args.

Slightly golfed less.

double atof(),x;s;
Y=16;
main(a,b)int**b;{
for(;--Y+16;puts(""))
for(x=-1.975;s=x<2;x+=.035,printf(L" *"+s/251))
for(_Complex y=x+Y*.0581i,z=a/3*y;s++<251&cabs(z=z*z+(a>2?atof(b[1])+1i*atof(b[2]):y))<2;);
}

• If you change the s<251 to s++<251 you can remove the s++ at the end for -1. Feb 3, 2021 at 8:29

# C, gcc, 141140138137 136 bytes

Try it

y=16,x;main(i){for(;--y+16;puts(""))for(x=68;x--;printf(L" *"+i/221))for(typeof(0.i)z=i=0;cabs(z)<2&i++<220;z=z*z-x*.035+.37+y*.0581i);}


Compile using gcc. -lm may be required.

• good call @ceilingcat Feb 11, 2021 at 18:38

# Pyth, 87 bytes

jsX0_Bms.e*b@" *"kCMdc."n
K{„‹–¥\dmnl4’_·N—2#‘¦óE,Á–¦#Óç>§óÔí¤:—A1åìJV~t…Á"\n*\*64

Try it here!

Above preview does not display all characters in the code! The link leads to a working and copyable source.

{i}{i}{i}ii{c}{c}{c}{c}{c}ccc{i}c{d}{c}cccc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{c}c{i}cccc{d}{c}ccc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{c}{i}cccccc{d}{c}cc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{c}c{i}ccccc{d}{c}cc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}cccccc{i}c{d}c{i}ccccccccc{d}{c}c{d}{d}ddc{i}{i}ii{c}{c}{c}{c}c{i}ccc{d}c{i}{c}cccccc{d}ccccccc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}ccc{i}{c}{c}{d}c{i}cc{d}cc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{i}{c}{c}ccccc{d}ccc{d}{d}ddc{i}{i}ii{c}{c}{c}ccccccccc{i}{c}{c}cccccccc{d}c{d}{d}ddc{i}{i}ii{c}{c}{c}ccccccc{i}{c}{c}{c}c{d}{d}{d}ddc{i}{i}ii{c}{c}{c}ccccccc{i}{c}{c}{c}{d}c{d}{d}ddc{i}{i}ii{c}{c}cccc{i}c{d}c{i}ccccc{d}ccccc{i}{c}{c}{c}cc{d}{d}{d}ddc{i}{i}ii{c}{c}ccc{i}{c}c{d}cc{i}{c}{c}{c}cc{d}{d}{d}ddc{i}{i}ii{c}{c}cc{i}{c}ccc{d}c{i}{c}{c}{c}c{d}c{d}{d}ddc{i}{i}ii{c}cccccccc{i}cc{d}c{i}{c}cccc{d}c{i}{c}{c}{c}{d}cc{d}{d}ddc{i}{i}{i}ii{c}{c}{c}{c}{c}{c}cccc{d}cccc{d}{d}ddc{i}{i}ii{c}cccccccc{i}cc{d}c{i}{c}cccc{d}c{i}{c}{c}{c}{d}cc{d}{d}ddc{i}{i}ii{c}{c}cc{i}{c}ccc{d}c{i}{c}{c}{c}c{d}c{d}{d}ddc{i}{i}ii{c}{c}ccc{i}{c}c{d}cc{i}{c}{c}{c}cc{d}{d}{d}ddc{i}{i}ii{c}{c}cccc{i}c{d}c{i}ccccc{d}ccccc{i}{c}{c}{c}cc{d}{d}{d}ddc{i}{i}ii{c}{c}{c}ccccccc{i}{c}{c}{c}{d}c{d}{d}ddc{i}{i}ii{c}{c}{c}ccccccc{i}{c}{c}{c}c{d}{d}{d}ddc{i}{i}ii{c}{c}{c}ccccccccc{i}{c}{c}cccccccc{d}c{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{i}{c}{c}ccccc{d}ccc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}ccc{i}{c}{c}{d}c{i}cc{d}cc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}c{i}ccc{d}c{i}{c}cccccc{d}ccccccc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}cccccc{i}c{d}c{i}ccccccccc{d}{c}c{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{c}c{i}ccccc{d}{c}cc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{c}{i}cccccc{d}{c}cc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{c}c{i}cccc{d}{c}ccc{d}{d}ddc{i}{i}ii{c}{c}{c}{c}{c}ccc{i}c{d}{c}cccc{d}{d}ddc