97
\$\begingroup\$

I always used a Mandelbrot image as the 'graphical' version of Hello World in any graphical application I got my hands on. Now it's your guys' turn.

  • Language must be capable of graphical output or drawing charts (saving files disallowed)
  • Render a square image or graph. The size at least 128 and at most 640 across*
  • The fractal coordinates range from approximately -2-2i to 2+2i
  • The pixels outside of the Mandelbrot set should be colored according to the number of iterations before the magnitude exceeds 2 (excluding* black & white)
  • Each iteration count must have a unique color*, and neighboring colors should preferably be easily distinguishable by the eye
  • The other pixels (presumably inside the Mandelbrot set) must be colored either black or white
  • At least 99 iterations
  • ASCII art not allowed

* unless limited by the platform, e.g. graphical calculator

Allowed:
Allowed
Disallowed:
Disallowed
(shrunken images)

Winning conditions:

Shortest version (size in bytes) for each language will get a mention in this post, ordered by size.
No answer will ever be 'accepted' with the button.

Leaderboard:

/* Configuration */

var QUESTION_ID = 23423; // Obtain this from the url
// It will be like https://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";
var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk";
var OVERRIDE_USER = 17419; // This should be the user ID of the challenge author.

/* App */

var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page;

function answersUrl(index) {
  return "https://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function commentUrl(index, answers) {
  return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(answer_page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      answers_hash = [];
      answer_ids = [];
      data.items.forEach(function(a) {
        a.comments = [];
        var id = +a.share_link.match(/\d+/);
        answer_ids.push(id);
        answers_hash[id] = a;
      });
      if (!data.has_more) more_answers = false;
      comment_page = 1;
      getComments();
    }
  });
}

function getComments() {
  jQuery.ajax({
    url: commentUrl(comment_page++, answer_ids),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      data.items.forEach(function(c) {
        if (c.owner.user_id === OVERRIDE_USER)
          answers_hash[c.post_id].comments.push(c);
      });
      if (data.has_more) getComments();
      else if (more_answers) getAnswers();
      else process();
    }
  });  
}

getAnswers();

var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/;

var OVERRIDE_REG = /^Override\s*header:\s*/i;

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  var valid = [];
  
  answers.forEach(function(a) {
    var body = a.body;
    a.comments.forEach(function(c) {
      if(OVERRIDE_REG.test(c.body))
        body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>';
    });
    
    var match = body.match(SCORE_REG);
    if (match)
      valid.push({
        user: getAuthorName(a),
        size: +match[2],
        language: match[1],
        link: a.share_link,
      });
    else console.log(body);
  });
  
  valid.sort(function (a, b) {
    var aB = a.size,
        bB = b.size;
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  valid.forEach(function (a) {
    if (a.size != lastSize)
      lastPlace = place;
    lastSize = a.size;
    ++place;
    
    var answer = jQuery("#answer-template").html();
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", a.user)
                   .replace("{{LANGUAGE}}", a.language)
                   .replace("{{SIZE}}", a.size)
                   .replace("{{LINK}}", a.link);
    answer = jQuery(answer);
    jQuery("#answers").append(answer);

    var lang = a.language;
    lang = jQuery('<a>'+lang+'</a>').text();
    
    languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang, user: a.user, size: a.size, link: a.link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang_raw.toLowerCase() > b.lang_raw.toLowerCase()) return 1;
    if (a.lang_raw.toLowerCase() < b.lang_raw.toLowerCase()) return -1;
    return 0;
  });

  for (var i = 0; i < langs.length; ++i)
  {
    var language = jQuery("#language-template").html();
    var lang = langs[i];
    language = language.replace("{{LANGUAGE}}", lang.lang)
                       .replace("{{NAME}}", lang.user)
                       .replace("{{SIZE}}", lang.size)
                       .replace("{{LINK}}", lang.link);
    language = jQuery(language);
    jQuery("#languages").append(language);
  }

}
body {
  text-align: left !important;
  display: block !important;
}

#answer-list {
  padding: 10px;
  width: 290px;
  float: left;
}

#language-list {
  padding: 10px;
  width: 290px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.sstatic.net/Sites/codegolf/all.css?v=ffb5d0584c5f">
<div id="language-list">
  <h2>Shortest Solution by Language</h2>
  <table class="language-list">
    <thead>
      <tr><td>Language</td><td>User</td><td>Score</td></tr>
    </thead>
    <tbody id="languages">

    </tbody>
  </table>
</div>
<div id="answer-list">
  <h2>Leaderboard</h2>
  <table class="answer-list">
    <thead>
      <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr>
    </thead>
    <tbody id="answers">

    </tbody>
  </table>
</div>
<table style="display: none">
  <tbody id="answer-template">
    <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>
<table style="display: none">
  <tbody id="language-template">
    <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr>
  </tbody>
</table>

\$\endgroup\$
14
  • 8
    \$\begingroup\$ "Easily distinguished by the eye" is hard to make objective. ...Also, apart from your personal association of the two, the Mandelbrot set has nothing to do with Hello World, so it's best to omit that from the title unless you are deliberately trolling the search engines. \$\endgroup\$ – Jonathan Van Matre Mar 7 '14 at 21:50
  • 1
    \$\begingroup\$ Related: ASCII Mandelbrot (although some of the answers posted there aren't ASCII and could probably fit better as answers to this question). \$\endgroup\$ – Peter Taylor Mar 7 '14 at 22:44
  • 3
    \$\begingroup\$ I've seen a few people now mentioning that they render the Mandelbrot as a "Hello World". I've done that too, for something like 30 years. The Mandelbrot is the perfect "Hello World" because it shows both that you have pixel access to the display and gives a good feel for compute bound performance on the new platform. \$\endgroup\$ – Roger Dahl Mar 9 '14 at 2:00
  • 7
    \$\begingroup\$ Great idea to ask a question which requires a combination of mathematical and aesthetic sensitivities, then impose all the the design decisions in advance. \$\endgroup\$ – jwg Mar 10 '14 at 8:25
  • 3
    \$\begingroup\$ Anyone manages to make one in brainfuck WINS, I'd say :D \$\endgroup\$ – MadTux Mar 10 '14 at 18:45

36 Answers 36

1
2
3
\$\begingroup\$

Floater, 620 pixels

A language I made up when I got inspired by my own challenge, as well as from the esoteric language Piet.

enter image description here

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Link to a language and description of the code? Or actually, what is the code? \$\endgroup\$ – MD XF Sep 26 '17 at 3:20
3
\$\begingroup\$

Tcl/Tk, 316

322 324 336 348 349 351 352 353 354 355

Now a shorter version using 3 letter #RGB shorthands style color triplets (instead of #RRGGBB triplets), which results in different colors.

And some more golfing.

rename set s
grid [canvas .c -w 640 -he 640]
.c cr i 320 320 -i [s p [image c photo -w 640 -h 640]]
time {incr x
s y 0
time {incr y
s a 0
s b 0
s n 0
while \$n<99 {s A [expr $a*$a-$b*$b+$x[s f *4/639.-2]]
if [s b [expr 2*$a*$b+$y$f]]*$b+[s a $A]*$a>4 break
incr n}
$p p [format #%03x [expr $n*41]] -t $x $y} 640} 640

fractal


Tcl/Tk, 325

331 333 345 357 358 360 361 362 364 365

I think I would win if the criterium was beauty!

rename set s
grid [canvas .c -w 640 -he 640]
.c cr i 320 320 -i [s p [image c photo -w 640 -h 640]]
time {incr x
s y 0
time {incr y
s a 0
s b 0
s n 0
while \$n<99 {s A [expr $a*$a-$b*$b+$x[s f *4/639.-2]]
if [s b [expr 2*$a*$b+$y$f]]*$b+[s a $A]*$a>4 break
incr n}
$p p [format #%06x [expr $n*16777215/99]] -t $x $y} 640} 640

Presentation:

fractal

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Nice. You can reduce a few characters (down to 380, I think) by adding rename set s at the top and then replacing all the set by s \$\endgroup\$ – user7795 Apr 4 '17 at 0:00
2
\$\begingroup\$

SmileBASIC, 126 bytes

X=RNDF()*4-2Y=RNDF()*4-2@N
N=N+16I=X+S*S-T*T
T=Y+S*T*2S=I
IF N<#L&&S*S+T*T<4GOTO@N
GPSET X*50+99,Y*50+99,RGB(99XOR N,N,N)EXEC.

enter image description here

\$\endgroup\$
3
  • \$\begingroup\$ Nice use of randoms to save on loops \$\endgroup\$ – Mark Jeronimus Feb 19 '17 at 9:07
  • \$\begingroup\$ Should make it 240x240, but I guess that would be longer. \$\endgroup\$ – snail_ Mar 20 '17 at 12:28
  • \$\begingroup\$ Code golf is about what you can get away with, not what you should do. \$\endgroup\$ – 12Me21 Jun 17 '17 at 15:28
2
\$\begingroup\$

QBasic, 139 bytes

-1 c/o DLosc

SCREEN 13
FOR i=0TO 199
FOR j=0TO 199
x=0
y=0
FOR c=0TO 255
t=y*y
c=c-255*(x*x+t>4)
y=2*x*y+j/50-2
x=x*x-t+i/50-2
NEXT
PSET(i,j),c
NEXT j,i

Output:

It may be necessary to append a INPUT$(1) to prevent the window from closing until a key is pressed.


FreeBASIC, 139 bytes

Using FreeBASIC's SCREEN 16, we can generate a more detailed image at the same code length:

SCREEN 16
FOR i=0TO 383
FOR j=0TO 383
x=0
y=0
FOR c=0TO 255
t=y*y
c=c-255*(x*x+t>4)
y=2*x*y+j/96-2
x=x*x-t+i/96-2
NEXT
PSET(i,j),c
NEXT j,i

Compile as fbc -lang qb mandel.bas.

Higher resolutions are also available.

\$\endgroup\$
4
  • \$\begingroup\$ Please count newlines as a byte too \$\endgroup\$ – Mark Jeronimus Sep 27 '17 at 14:32
  • \$\begingroup\$ @MarkJeronimus my mistake, I though I had. \$\endgroup\$ – primo Sep 28 '17 at 4:31
  • \$\begingroup\$ Modifying c to exit the FOR loop is really clever! You can save 2 bytes by using y*y directly instead of assigning to t, and one more byte by writing NEXT j,i instead of NEXT twice. (Not sure if that second one works in FreeBASIC.) \$\endgroup\$ – DLosc Jun 3 at 19:59
  • \$\begingroup\$ The assignment to t is necessary, because the old value of y is used in the computation of x. Thanks for the multi-NEXT tip ;) \$\endgroup\$ – primo Jun 4 at 11:49
1
\$\begingroup\$

Julia

Well, better late than never:

function mandelbrot(x0,y0,side,N=800,L=55,R=3.)
    m = [0 for i=1:N,j=1:N]
    delta = side/N
    for i=1:N, j=1:N
        c = x0+delta*i+(y0+delta*j)*im
        z, h = 0+0*im, 0
        while (h<L) && (abs(z)<R)
            z = z^2+c
            h+=1
        end
        m[j,i]=h
    end
    return m
end
n=2.6
m = mandelbrot(-n/1.3,-n/2, n)
using Winston, Color
imagesc(m)
title("Mandelbrot Set")

Colormap Mod. :

function RGB_cm()
    colormap = [RGB(0,0,0) for t=1:255*5]
    rgb = [255,0,0]
    for t in 0:(255*5-1)
    c = [0, 0, 0]
    i = ifloor(t/255)
    c[(i+3)%3!=0?(i+3)%3:3] = (-1)^i
    rgb+=c
    colormap[t+1] = RGB(rgb[1],rgb[2],rgb[3])
    end
    colormap[(end-25):end] = RGB(0,0,0)
    return colormap
end
c = RGB_cm()
Winston.colormap(c)

Output:

Mandelbrot Set

\$\endgroup\$
3
  • \$\begingroup\$ Should I byte-count only the first program or both? \$\endgroup\$ – Mark Jeronimus Mar 29 '14 at 10:10
  • \$\begingroup\$ I think both, because without the color map mod the image would not satisfy the rules. \$\endgroup\$ – CCP Mar 29 '14 at 15:35
  • 2
    \$\begingroup\$ I'm sure you can save much on whitespace. \$\endgroup\$ – Erik the Outgolfer Sep 25 '17 at 17:15
1
\$\begingroup\$

Python 3, 290 Bytes

from PIL import Image
import numpy as n
s=640;d=n.zeros((s,s,3),dtype=n.uint8)
for k in range(s*s):
    r=4/s*(k%s)-2;i=2-4/s*(k//s);z=c=complex(r,i)
    for i in range(50,9950,100):
        if abs(z)>2:
            d[k//s,k%s]=[i*5,i*9,i*7];break
        z=z*z+c
Image.fromarray(d).show()

mandelbrot

\$\endgroup\$
1
2

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.