Tell me more ×
Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

The challenge is to generate an image similar to the StackOverflow logo:

The output must contain:

  • Image size 64*64 or greater
  • A gray |__| shaped base
  • A curved segmented stack coming up from the base. The segments will fade from gray to orange, and make a ~90 degree right turn. The number of segments should be between 5 and 7, with 6 being preferred.

Note: For ascii displays that lack color, use a '0' character to represent gray, and '9' for orange. '1' to '8' would represent the shades in-between.

Restrictions:

  • You must generate the image. Loading images or storing them in the code/binary is not allowed.

Additional rules/information:

  • The image is not required to be identical to the logo, however it must be recognizable as it.
  • The method of display is up to you. Saving it to an image file or displaying on the screen are both acceptable.

Judging/winning criteria:

  • Accuracy of the image is the primary condition
  • Elegance of generation is the secondary condition
share|improve this question
1  
The official 16x16 px version of the logo actually has only 4 bars in the stack. – Ilmari Karonen Jan 8 '12 at 12:06

13 Answers

up vote 35 down vote accepted

Mathematica

Graphics[{
   Gray, Rectangle[{0, 0}, {78, 50}],
   White, Rectangle[{9, 9}, {69, 50}]}
  ~Join~
  Table[{
    Blend[{Gray, Orange}, x/5],
    Rotate[
     Translate[
      Rectangle[{16, 16}, {61, 25}],
      {0.25x^3 + 0.6x^2 - 0.4x, -0.53x^3 + 3.26x^2 + 12x}],
     -0.05x^2 - 0.04x]},
   {x, 0, 5}]]

I decided to prettify my answer after realizing this isn't code golf. Whoops!

Screenshot:

Stack Overflow logo

In related news, I also created what I think the Stack Overflow logo might look like in... THE FUTURE:

THE FUTURE IS NOW

Here's the code if anyone wants to play around with it (sorry for the mess):

Graphics3D[{EdgeForm[],
   Opacity[1],
   RGBColor[0.2, 0.2, 0.2], Cuboid[{0, 0, 0}, {78, 4, 50}],
   Cuboid[{0, 4, 0}, {4, 45, 50}],
    Cuboid[{74, 4, 0}, {78, 45, 50}],
   Opacity[1]}
  ~Join~
  Fold[Join, {},
   Table[{Hue[0.15 - i/5/12, i/3, 1],
     Translate[
      Rotate[
       Scale[Cuboid[{16, 16, 16}, {61, 25, 25}], {1, .3, .3}],
       (-.05 ((i*2 - 1.5)*1.25)^2 - .04 ((i*2)*1.2)), {0.3, 
        0.8, -1}, {(16 + 61)/2, (16 + 25)/2, (16 + 25)/2}],
      {-((i*2)^2 - (i*2)*4)/2, (i*2)^2*3/2, 0}]},
    {i, 0, 4.5, 0.05}]], Lighting -> "Neutral", Axes -> False, 
 Background -> White, Boxed -> False]
share|improve this answer
Awesome, but the proportion sheet - box would look better, imho, with a smaller box with less thick border. – user unknown Jan 10 '12 at 6:28
Very nice! This community could use your skills ;-) mathematica.stackexchange.com – Vitaliy Kaurov Jul 31 '12 at 2:30

Javascript (650)

I wrote a quine that reads the characters in the function, and replaces non-space characters with a number from 0-9.

(function a(){
l=[
                   1,
                    1,
            11,      1,
             11,     1,
               11,    1,
       11,      11,   1,
         11,      11,
           11,
   11,       1111,
     1111,
0,       11111111, 0,
0, 11,             0,
0,   111111111111, 0,
0,                 0,
0, 11111111111111, 0,
0,                 0,
000000000000000000000]

b=a.toString().split("[")[1].split("]")[0].split(""),i=-1
document.getElementById("output").innerHTML=
b.map(function(c){
++i
if(c==" "||c=="\n")return c
if(c!=0)c=9-Math.floor((i/b.length)*10)
if(b[i-1]=="0")c=0
return"<span class='c"+c+"'>"+c+"</span>"
}).join("")
})()

This outputs this ASCII art:

                   99
                    88
            888      88
             777     77
               766    66
       666      666   66
         555      555
           555
   444       44444
     44444
00       333333333 00
00 333             00
00   2222222222222 00
00                 00
00 111111111111111 00
00                 00
000000000000000000000

which can be colored with a css stylesheet if you like

  span{
    font-weight: bold;
  }
  .c0, .c1{
    color: #222;
  }
  .c2{
    color: #765;
  }
  .c3{
    color: #976;
  }
  .c4{
    color: #A64;
  }
  .c6, .c5{
    color: #D51;
  }
  .c8, .c9, .c7{
    color: #F60;
  }

You can see it in action on jsBin.

Here is a screenshot, in case the link dies:

enter image description here

share|improve this answer

Haskell w/Gloss

import Graphics.Gloss

picture = translate 0 (-50) $ pictures [stack, base 150 60 20]

stack = translate 0 30 $ pictures [item n | n <- [0..5]]

item n = bend 200 (-10*n) $ color (fade grey orange (n/5)) box
  where box = rectangleSolid 110 20

base width height thickness = color grey $ pictures [left, right, bottom]
  where bottom = rectangleSolid width thickness
        left = translate (width / 2) (height / 2) side
        right = translate (-width / 2) (height / 2) side

        side = rectangleSolid thickness (height + thickness)

bend radius angle = translate radius 0 . rotate angle . translate (-radius) 0

fade from to alpha = mixColors (1-alpha) alpha from to

grey = greyN 0.5

Screenshot

Paste the code here to see it in action, or add the following line to compile it (requires Gloss).

main = display (InWindow "Stack Overflow" (512, 512) (10, 10)) white picture
share|improve this answer

SVG (316 characters)

Based on Sir_Lagsalot's version, with strokes instead of fills. Besides shaving off a few chars, the code is simpler and the output looks better scaled up.

<svg xmlns="http://www.w3.org/2000/svg">
<g stroke-width="6" fill="none">
<path stroke="grey" d="m3,51v31h47V53M10,70h33"/>
<path stroke="#a86" d="m10,57 33,3"/>
<path stroke="#b95" d="m13,42 31,9"/>
<path stroke="#c82" d="m20,25 28,17"/>
<path stroke="#e80" d="m34,9 19,27"/>
<path stroke="#f71" d="m56,1 4,32"/>
</g>
</svg>

Link to SVG image.

Rendered to PNG (at natural size and scaled up x2 and x3):

Natural size     Scaled up x2     Scaled up x3

share|improve this answer

SVG (333 characters)

I've created a SVG image that generates a 67x68 version of the logo in 333 characters:

<svg xmlns="http://www.w3.org/2000/svg">
<path fill="grey" d="m0,53v34h53V53h-5v29H5V53M9,69h33v6H11v-6"/>
<path fill="#a86" d="m12,56 31,3-1,6-31-3"/>
<path fill="#b95" d="m15,41 31,9-2,6-31-8"/>
<path fill="#c82" d="m22,25 28,17-3,5-28-17"/>
<path fill="#e80" d="m38,8 19,27-5,4-19-27"/>
<path fill="#f71" d="m62,0 5,32-6,1-5-32"/>
</svg>

Link for small SVG image
Link for large SVG image

Example

share|improve this answer
I wonder if using stroked paths wouldn't be even shorter. – Ilmari Karonen Jan 17 '12 at 1:30

Javascript (a lot of 814 characters)

window.onload = function() {
                var canvas = document.getElementById("cgCanvas");
                var context = canvas.getContext("2d");
                context.moveTo(60,140);
                context.lineTo(60,190);
                context.moveTo(57.5,190);
                context.lineTo(137.5,190);
                context.moveTo(135,140);
                context.lineTo(135,190);
                context.lineWidth = 5;
                context.strokeStyle = "rgb(94,94,94)";
                context.stroke();
                for(i=0;i<6;i++) {
                    context.beginPath();
                    var b=1;
                    var a=1;
                    if(i==5) {
                        a=3;
                        b=1.3;
                    }
                    else if(i==4)
                        a==2;
                    x=94+i*9;
                    y=94-i*5;
                    z=95-i*19;
                    context.moveTo(122.5+i*i,180-i*15);
                    context.lineTo(72.5+i*i+i*i*b,180-i*15-i*i*i+i*i*a);
                    context.lineWidth = 8;
                    context.strokeStyle = 'rgb('+ x +','+ y +','+ z +')';
                    context.stroke();
                }
            };

It ain't pretty but looks a bit like the SO logo. Test fiddle here - http://jsfiddle.net/elssar/jcYtg/2/

share|improve this answer
That can be golfed down quite a bit if you change the name of context to something more simple. – MrZander Jan 9 '12 at 19:25
Hey there, I golfed it down a little bit for you, it now is on 749 chars: jsfiddle.net/jcYtg/5 -- I liked this approach! Very nice. – Alpha Jan 9 '12 at 21:13
706 now: jsfiddle.net/jcYtg/12 -- wanted to change the repetition of i's or the rgb but only messed it up, so didn't change that part. – Alpha Jan 9 '12 at 21:28
3  
(Sorry for the spam, this is the last one, I promise). Minimized: jsfiddle.net/jcYtg/13 501 chars. – Alpha Jan 9 '12 at 21:30
1  
Thanks @Alpha It's going to take some time getting used to golfing the code, most times looking at golfed code makes me want to kill the person who wrote it(sorry). About the approach was basically trial & error as I was too lazy to do the math. Would've been better to use concentric circles or even better concentric ellipses to get the positions of the stacks. – elssar Jan 10 '12 at 7:05

LaTeX

Using the TikZ and PGF packages.

\documentclass{minimal}
\usepackage{tikz}
\pagestyle{empty}
\begin{document}
\xdefinecolor{col1}{RGB}{167, 149, 116}
\xdefinecolor{col2}{RGB}{189, 153, 87}
\xdefinecolor{col3}{RGB}{211, 157, 57}
\xdefinecolor{col4}{RGB}{233, 161, 28}
\xdefinecolor{col5}{RGB}{255, 165, 0}
\begin{tikzpicture}
\draw[gray, fill=gray] (-1,0.5) -- (-1,0) -- (0,0) -- (0,0.5) -- (-0.1,0.5) -- (-0.1,0.1) -- (-0.9,0.1) -- (-0.9,0.5) -- (-1,0.5);
\draw[gray, fill=gray] (-0.8,0.3) rectangle(-0.2,0.2); 
\draw[col1, fill=col1, xshift=0.3pt, yshift=3pt,  rotate around={-15:(0.2,0.2)}] (-0.8,0.3) rectangle(-0.2,0.2); 
\draw[col2, fill=col2, xshift=0.5pt, yshift=6pt,  rotate around={-30:(0.2,0.2)}] (-0.8,0.3) rectangle(-0.2,0.2); 
\draw[col3, fill=col3, xshift=0.8pt, yshift=9pt,  rotate around={-45:(0.2,0.2)}] (-0.8,0.3) rectangle(-0.2,0.2); 
\draw[col4, fill=col4, xshift=1.3pt, yshift=12pt, rotate around={-60:(0.2,0.2)}] (-0.8,0.3) rectangle(-0.2,0.2); 
\draw[col5, fill=col5, xshift=2.1pt, yshift=14pt, rotate around={-75:(0.2,0.2)}] (-0.8,0.3) rectangle(-0.2,0.2); 
\end{tikzpicture}
\end{document}

LaTeX Logo

share|improve this answer

PHP w/ GD

<?php
$img = imagecreatetruecolor(67,68);
$white = imagecolorallocate($img,0xff,0xff,0xff);
$grey = imagecolorallocate($img,0x80,0x81,0x85);
$orng1 = imagecolorallocate($img,0xa6,0x8a,0x6e);
$orng2 = imagecolorallocate($img,0xc0,0x95,0x53);
$orng3 = imagecolorallocate($img,0xd3,0x8b,0x28);
$orng4 = imagecolorallocate($img,0xfd,0x88,0x08);
$orng5 = imagecolorallocate($img,0xfe,0x7a,0x15);
imagefilledrectangle($img,0,0,67,68,$white);

//container
imagefilledrectangle($img,7,41,10,65,$grey);
imagefilledrectangle($img,10,61,44,65,$grey);
imagefilledrectangle($img,41,61,44,41,$grey);

// stack levels
imagefilledrectangle($img,14,52,37,56,$grey); //1st level
imagefilledpolygon($img,array(14,42,14,47,37,49,37,44),4,$orng1);
imagefilledpolygon($img,array(16,32,15,36,37,42,38,38),4,$orng2);
imagefilledpolygon($img,array(22,21,20,24,39,35,41,32),4,$orng3);
imagefilledpolygon($img,array(33,10,31,12,43,30,45,28),4,$orng4);
imagefilledpolygon($img,array(45,5,48,5,51,27,48,27),4,$orng5);
header("Content-type: image/png");
imagepng($img);
?>

Example: StackOverflow logo drawn in PHP

share|improve this answer
1  
Use variable functions: $a = 'imagecolorallocate';$r = 'imagefilledrectangle'; $p = 'imagefilledpolygon'; which allows you to reduce the code substantially: $p(...);$p(...);.... – Xeoncross Aug 29 '12 at 18:41
1  
Here is a 700 character gist down from the 1000+ characters here. – Xeoncross Aug 29 '12 at 18:49

C#/GDI+

I was surprised when I noticed there's no C# answer here. So here's one. This is not an ingenious way of drawing the logo, and is not a short solution either. But gets the required output.

Generated logo and the original StackOverflow logo

You can check my blog post out to download the full working solution → http://guganeshan.com/blog/stackoverflow-logo-using-csharp-and-gdi.html

public class SOLogo
{
    private float _rotateValue;
    private float _xValueForTransformation;
    private float _yValueForTransformation;

    int _containerWidth;
    int _containerHeight;
    float _lineThickness;
    int _paddingWithinContainer;
    int _elementStartY;

    public SOLogo(float rotateValue, float xValueForTransformation, float yValueForTransformation)
    {
        // Values used to position and rotate the overflowing elements.
        _rotateValue = rotateValue;
        _xValueForTransformation  = xValueForTransformation;
        _yValueForTransformation = yValueForTransformation;
    }

    public void DrawLogo(Graphics g, int startX, int startY)
    {
        // Backup the current smoothing mode to apply later.
        var SmoothingMoodBackup = g.SmoothingMode;
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

        // Values for the container box.
        _containerWidth = 94;
        _containerHeight = 61;
        _lineThickness = 11f;
        _paddingWithinContainer = 15;

        // Y value of the position where the 1st overflowing element starts.
        _elementStartY = 0;

        // Starting point of the 'container' - Top point of the line on the left-> |_|
        Point pointContainerLineStart = new Point(startX, startY);

        Point pointContainer1stLineEnd = new Point(pointContainerLineStart.X, pointContainerLineStart.Y); // Start with the previous
        pointContainer1stLineEnd.Offset(0, _containerHeight); // Offset "Y"

        Point pointContainer2ndLineEnd = new Point(pointContainer1stLineEnd.X, pointContainer1stLineEnd.Y); // Start with the previous
        pointContainer2ndLineEnd.Offset(_containerWidth, 0); // Offset "X"

        Point pointContainer3rdLineEnd = new Point(pointContainer2ndLineEnd.X, pointContainer2ndLineEnd.Y); // Start with the previous
        pointContainer3rdLineEnd.Offset(0, 0 - _containerHeight); // Offset "Y" (negative)

        GraphicsPath pathOfBox = new GraphicsPath();
        pathOfBox.AddLine(pointContainerLineStart, pointContainer1stLineEnd); // Left line. Top to bottom
        pathOfBox.AddLine(pointContainer1stLineEnd, pointContainer2ndLineEnd); // Bottom line. Left to right
        pathOfBox.AddLine(pointContainer2ndLineEnd, pointContainer3rdLineEnd); // Right line. Bottom to top

        Pen thickPen = new Pen(Brushes.Gray, _lineThickness);
        Color elementColor = Color.FromKnownColor(KnownColor.Gray);

        // Draw the 'container'
        g.DrawPath(thickPen, pathOfBox);

        // Increase the size of the pen to draw the elements inside the container
        thickPen.Width = _lineThickness += 3;
        // "Y" - position of the 1st element
        _elementStartY = startY + 38;

        // The following section draws the overflowing elements

        Point pointElement1Left = new Point(startX + _paddingWithinContainer, _elementStartY);
        Point pointElement1Right = new Point((startX + _containerWidth) - _paddingWithinContainer, _elementStartY);

        // Six colors of the overflowing elements
        var colors = new Color[] {
            Color.Gray,                 Color.FromArgb(-6911615),   Color.FromArgb(-4417693),
            Color.FromArgb(-2848227),   Color.FromArgb(-554957),    Color.FromArgb(-688847)
        };

        for (int x = 0; x < 6; x++)
        {
            thickPen.Color = colors[x];
            pointElement1Left = new Point(startX + _paddingWithinContainer, _elementStartY);
            pointElement1Right = new Point((startX + _containerWidth) - _paddingWithinContainer, _elementStartY);
            g.DrawLine(thickPen, pointElement1Left, pointElement1Right);
            g.RotateTransform(_rotateValue);
            g.TranslateTransform(_xValueForTransformation, _yValueForTransformation);
        }

        pathOfBox.Dispose();
        thickPen.Dispose();

        // Restore the smoothing mood that was backed up before we started this method.
        g.SmoothingMode = SmoothingMoodBackup;
    }
}
share|improve this answer

Scala

object LogoCanvas extends javax.swing.JPanel {

  import java.awt._

    def viereck (g: Graphics, points: scala.List[(Int, Int)]) = {
      val polygon = new Polygon ()
      points.foreach (p => polygon.addPoint (10 * p._1, 400 - 10 * p._2))
      g.fillPolygon (polygon)           
    }

  override def paint (g: Graphics) = {
    g.setColor (Color.GRAY);
    // ablage
    viereck (g, scala.List ((2, 1), (2, 11), (3, 11), (3, 1)))
    viereck (g, scala.List ((2, 1), (2, 2), (23, 2), (23, 1)))
    viereck (g, scala.List ((23, 1), (23, 11), (24, 11), (24, 1)))
    // blaetter flach
    viereck (g, scala.List ((5, 5), (5, 6), (21, 6), (21, 5)))
    viereck (g, scala.List ((5, 9), (5, 10), (21, 10), (21, 9)))
    // blaetter schraeg
    g.setColor (Color.LIGHT_GRAY);
    viereck (g, scala.List ((7, 22), (8, 23), (21, 13), (21, 12)))
    viereck (g, scala.List ((12, 28), (13, 29), (22, 15), (21, 14)))
    // blaetter steil
    g.setColor (Color.ORANGE);
    viereck (g, scala.List ((18, 34), (19, 34), (23, 17), (22, 16)))
    viereck (g, scala.List ((24, 36), (25, 36), (25, 17), (24, 17)))
  }

  import javax.swing._

  def main (args: Array [String]) : Unit = {
    val jf = new JFrame ("Stackoverflow!")  
    jf.setSize (350, 520)
    jf.setLocationRelativeTo (null)
    jf.setBackground (Color.BLACK)
    jf.add (LogoCanvas)
    jf.setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE) 
    jf.setVisible (true)            
  }
}

Stackoverflow logo on black background

share|improve this answer

CSS+JavaScript (HTML div based)

* { padding: 0; margin: 0; }

div { position: absolute; width: 100px; height: 20px; background-color: red; }
.s { background-color: gray; }
#d0,#d2 { width: 20px; height: 70px; }
#d0 { left: 20px; top: 160px; }
#d1 { left: 20px; top: 230px; width: 160px; }
#d2 { left: 160px; top: 160px; }

.e { -moz-transform-origin: 200% center; -ms-transform-origin: 200% center; -o-transform-origin: 200% center; -webkit-transform-origin: 200% center; transform-origin: 200% center; }
$(document).ready(function() {
    for (var i = 0; i < 9; i++)
        $('body').append($('<div/>').attr('id', 'd' + i).attr('class', i < 3 ? 's' : 'e'))

    $('.e').each(function(i) {
        $(this).css({
            left: (50 - i * 3) + 'px',
            top: '200px',
            backgroundColor: '#' + (i + 10).toString(16) + 'a' + (10 - i * 2).toString(16),
            '-moz-transform': 'rotate(' + (i * 15) + 'deg)',
            '-ms-transform': 'rotate(' + (i * 15) + 'deg)',
            '-o-transform': 'rotate(' + (i * 15) + 'deg)',
            '-webkit-transform': 'rotate(' + (i * 15) + 'deg)',
            transform: 'rotate(' + (i * 15) + 'deg)'
        });
    });
});

Sample run: http://jsfiddle.net/ryzBx/

Sample rendering (Firefox 14):
StackExchange Logo

share|improve this answer

JavaScript + jQuery & SVG - 250

$('body').html('<svg><g stroke-width="6" fill="none"$grey" d="m3,51v31h47V53M10,70h33"/$#a86" d="m10,57 33,3"/$#b95" d="m13,42 31,9"/$#c82" d="m20,25 28,17"/$#e80" d="m34,9 19,27"/$#f71" d="m56,1 4,32"/></g></svg>'.replace(/\$/g, '><path stroke="'))​

I took Ilmari Karonen's SVG and used JavaScript to replace $s with ><path stroke=" effectively shortening it even with the overhead of JavaScript.

share|improve this answer

R

Not the prettiest solution but it returns the requested output.

library(grid)
my.palette <- colorRampPalette(c("grey57","orange"))(6)
png("StackOverflow_Logo.png", width=300, height=300)
pushViewport(viewport(x=0.5, y=0.5, w=unit(100, "points"), h=unit(100, "points")))
grid.polygon(x=unit(c(10, 0, 0, 100, 100, 90, 90, 10),"points"), 
             y=unit(c(50, 50, 0, 0, 50, 50, 10, 10),"points"),
             default.units="points", gp=gpar(col = "grey57", fill="grey57"))
grid.rect(vp=viewport(x=0.5, y=0.3, w=unit(70, "points"), h=unit(10, "points")), 
          gp=gpar(col = "grey57", fill="grey57"))

grid.rect(vp=viewport(x=0.52, y=0.52, w=unit(70, "points"), h=unit(10, "points"), angle=-10), 
          gp=gpar(col = my.palette[2], fill=my.palette[2]))

grid.rect(vp=viewport(x=0.58, y=0.78, w=unit(70, "points"), h=unit(10, "points"), angle=-20), 
          gp=gpar(col = my.palette[3], fill=my.palette[3]))

grid.rect(vp=viewport(x=0.70, y=1.05, w=unit(70, "points"), h=unit(10, "points"), angle=-35), 
          gp=gpar(col = my.palette[4], fill=my.palette[4]))

grid.rect(vp=viewport(x=0.90, y=1.25, w=unit(70, "points"), h=unit(10, "points"), angle=-55), 
          gp=gpar(col = my.palette[5], fill=my.palette[5]))

grid.rect(vp=viewport(x=1.15, y=1.38, w=unit(70, "points"), h=unit(10, "points"), angle=-70), 
          gp=gpar(col = my.palette[6], fill=my.palette[6]))
dev.off() 

logo

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.