title: Down the drain it goes

text:
# Question
Title: Down the drain it goes
I once encountered this (mini) game where you had 4 or more vertical pipes that were connected by a number of horizontal pipes and you have to drop a ball or water into the vertical pipes.
There are 2 kinds I know of:

* Get the object into a bucket/basket under one of the exits (guess what pipe to throw it in)
* Guess what pipe the object will come from.

### Sample pipes:

```
|       |       |-------|
|-------|       |-------|
|       |-------|       |
|-------|-------|-------|
|       |-------|       |
|-------|       |-------|
|-------|       |-------|
|       |-------|       |

```

### Basic rules:

* When moving through a horizontal pipe the object will go down when possible
* When moving through a vertical pipe the object will turn into a horizontal pipe when possible.

### Your job

* Write a program that will create a random grid of pipes(see sample pipes).
* There should be at least 4 vertical pipes and a fair amount of horizontal pipes at least 10.
* The length of the vertical pipes is up to you.
* Show the path that the object took to reach the bottom and show how many turns it took to get there.
* (Optional) input to deterimine starting point, pipes numbered 1..N from left to right.

### Display:

```
 | vertical pipe
 - horizontal pipe
 : vertical pipe used by the object
 = horizontal pipe used by the object
 V Object starting point
 ^ Object ending point

```

### Example:

```
V
:       |       |-------|
:=======:       |-------|
|       :=======:       |
|-----!-:=======:       |
|       :=======:-------|
|-------|       :=======:
|-------|       :=======:
|       :=======:       |
        ^
14 turns were taken to get to the end.

```

**Detail**
The object enters pipe 1 and starts moving down, goes left into the first horizontal pipe.
Back down and into the second pipe followed by a U-turn into the third pipe.
At the end of the third pipe you see an exclamation mark,
shouldnt be in your result but I used this to show you the object could have gone straight ahead.
However rule number 1 prevents that.

Winner will be determined by votes in 3 weeks from now 24-02-2014 (dd-mm).

Happy coding ^.^

# Answer
> 24 votes
# Mathematica

The 2D code generates a graph showing the path of the water. I displayed the vertex numbers for convenient cross-checking with the 3D display. Normally the vertex numbers would be hidden.

Input:

```
r=10;c=7;
result=flow2D[{r,c},3]

```

Actually, the result contains multiple objects. The first object, `result[[1]]`, is the 2D graph shown here.

---

The 3 dimensional pipes are `Tube`'s (3D lines) plotted in 3 space. The coordinates computed based on the vertices of the 2D graph along a 3rd coordinate that was randomly generated (This allows the pipes to assume different positions along y each time the code is run.)

The axes are displayed to help the reader convince herself that the 3D rendering is indeed based on the 2D rendering.

The 3D input of interest here is:

```
Graphics3D[{CapForm[None],verticalPipes,allRungs,Darker@Red,connections},
ImageSize->600,Axes-> True,Ticks->{Range[1,2 r,2],Range[c],Range[10]},ViewPoint->{0,-2,1.5}]

```

The number or rows, columns and entry column are taken from the 2D code. They do not have to be re-entered.

## 2D Code

In the coming days I will document and tidy up the code for 2D and 3D.

```
flow2D[{rows_,columns_},startColumn_]:=
Module[{r=rows,c=columns,g,j,h,ends,middle,midcuts,direction="down",turns=0,path,rungs},

   (*complete gridgraph*)
g=GridGraph[{r,c},VertexSize-> Medium,GraphStyle->"Prototype",EdgeStyle->"Thick",
  VertexLabels->"Name",ImagePadding-> 30,ImageSize->470];

(*horizontal pipes that must be removed*)
ends=Table[r(c1-1)+r1\[UndirectedEdge] r(c1)+r1,{c1,1,c-1},{r1,{1,r}}];

(*horizontal pipes to consider removing *)
middle=Table[r(c1-1)+r1\[UndirectedEdge] r(c1)+r1,{c1,1,c-1},{r1,2,r-1}];
midcuts=RandomSample[#,RandomInteger[Round[{r/15,2r/5}]]]&/@middle;

rungs=Flatten[midcuts(*Join[ends,midcuts]*)];

j=EdgeDelete[g,Flatten[Join[ends,midcuts]]];

h[path_]:= Module[{start=path[[-1]],right,left,up,down,newnodes},
     {v=NeighborhoodGraph[j,start,1,(*VertexLabels\[Rule]"Name",*)ImagePadding->25],
     VertexList[v]};newnodes=Complement[VertexList[v],path];
     If[newnodes=={},path,
     h[Append[path,
  Switch[direction,
   "down",Which[
     MemberQ[newnodes,start+r],(turns++;direction="right";start+r),
     MemberQ[newnodes,start-r],(turns++;direction="left";start-r),
     MemberQ[newnodes,start-1],start-1],
   "right",Which[
     MemberQ[newnodes,start-1],(turns++;direction="down";start-1),
     MemberQ[newnodes,start+r],start+r],
   "left",Which[
     MemberQ[newnodes,start-1],(turns++;direction="down";start-1),
     MemberQ[newnodes,start-r],start-r]
    ]]]]];
{HighlightGraph[j,path=h[{r*startColumn}],ImageSize->300],path,rungs,ends,midcuts}]

convert[node_,r_,c_]:=Append[footing[[Quotient[node-1,r]+1]],Mod[node-1,r]+1(*Mod[node,r]*)]
connect[a_\[UndirectedEdge]b_,r_,c_]:=Tube[Line[{convert[a,r,c],convert[b,r,c]}],0.2]

```

# 3D Code and results

```
r=10;c=7;
result=flow2D[{r,c},3];
g2D=result[[1]];
path2D=result[[2]];
\[AliasDelimiter]
xScale=2;
footing = {#, RandomInteger[{1, 6}]} & /@ Range[1,xScale c, xScale];
verticalPipes=Tube[Line[{Append[#,1],Append[#,r]}],.19]&/@footing;
Graphics3D[{CapForm[None],verticalPipes},ImageSize->600,Axes->True,AxesEdge->Automatic,ViewPoint->{0,-2,1.5},
Ticks->{Range[1,2 r,2],Range[c],Range[10]}];

path3D=UndirectedEdge@@@Partition[Riffle[stops=path2D,Rest@stops],2];
allRungs=connect[#,r,c]&/@rungs;
connections=connect[#,r,c]&/@path3D;

path2D;
g2D
Graphics3D[{CapForm[None],verticalPipes,allRungs,Darker@Red,connections},
ImageSize->600,Axes-> True,Ticks->{Range[1,2 r,2],Range[c],Range[10]},ViewPoint->{0,-2,1.5}]

```

# Answer
> 12 votes
# C#

*(via LINQPad, in "C# Program" mode; )*

Going to have to apply Equitable Stroke Control, as far as any golfing might go, but this is my approach in C# *(well, LINQPad, but who wants all the boilerplate that goes into making a full C# app work?)*.

Grid definitions are variable, with a number of vertical pipes and height of overall structure, and are repeatably-random by passing a seed (see the `PipeGrid` constructor).

In the absence of a definitive answer as to which way the object would flow if either direction was possible, I have allowed you to specify a behaviour from a number of options (see `SolveBehavior` enumeration / `PipeSolver` constructor).

Starting vertical is definable (see `PipeSolver.Solve`).

I have assumed that the horizontal pipes are always between two *adjacent* vertical pipes, i.e. no horizontal can bypass a horizontal pipe.

```
///Entry point
void Main()
{
    var grid = new PipeGrid(vertical:10, height:10, seed:5);
    var solver = new PipeSolver(grid, SolveBehavior.FlipFlop);
    solver.Solve(start:2);
}

///Represents the direction the object is travelling
enum Direction
{
    Down = 0,
    Left = 1,
    Right = 2
}

///Determines the route to take if a junction yields both horizontal directions
enum SolveBehavior
{
    ///Throws an <see cref="InvalidOperationException" />
    Fail = 0,

    ///Prefers the left-most direction (screen-relative)
    FavorLeft = 1,

    ///Prefers the right-most direction (screen-relative)
    FavorRight = 2,

    ///Alternates preferred direction, based on the number of turns
    FlipFlop = 3,

    ///Prefers the same direction the object travelled, on its last horizontal movement
    SameDirection = 4,

    ///Prefers the opposite direction the object travelled, on its last horizontal movement
    Uturn = 5
}

///Provides the logic for solving a <see cref="PipeGrid" /></summmary>
class PipeSolver
{
    ///Creates a new <see cref="PipeSolver" /> for the supplied <paramref name="grid" />,
    ///with the given <paramref name="behavior" /> used to resolve junctions with both horizontal
    ///paths
    public PipeSolver(PipeGrid grid, SolveBehavior behavior = SolveBehavior.FlipFlop)
    {
        if (grid == null) throw new ArgumentNullException("grid");
        _grid = grid;
        _behavior = behavior;
    }

    private readonly PipeGrid _grid;
    private readonly SolveBehavior _behavior;

    ///Simulate the dropping of an object to run through the grid, at the top of a
    ///given <paramref name="start" /> vertical pipe
    public void Solve(int start = 1, bool dumpFrames = false, string tag = "Result")
    {
        if (start < 1) start = 1;
        if (start > _grid.Verticals) start = _grid.Verticals;

        int x, y;

        Direction?[,] path = new Direction?[_grid.Width, _grid.Height];

        x = (start - 1) * 2;
        y = 0;
        Direction dir = Direction.Down, lastDir = Direction.Down;

        int turns = 0;
        do
        {
            path[x, y] = dir;       // we moved through this pipe

            // rule 1: when moving through horizontal pipe, object will go down when possible
            if ((dir == Direction.Left || dir == Direction.Right) && (x % 2 == 0))
            {
                lastDir = dir;
                dir = Direction.Down;
                ++turns;
            }
            // rule 2: when moving through start pipe, object will turn into horizontal pipe when possible
            else if (dir == Direction.Down)
            {
                bool hasLeft  = (x > 0 && _grid[x - 1, y]);
                bool hasRight = (x < _grid.Width - 1 && _grid[x + 1, y]);

                if (hasLeft && hasRight)
                {
                    switch (_behavior)
                    {
                        case SolveBehavior.FavorLeft:
                            hasRight = false;       // "forget" about right pipe
                            break;
                        case SolveBehavior.FavorRight:
                            hasLeft = false;        // "forget" about left pipe
                            break;
                        case SolveBehavior.FlipFlop:
                            if (turns % 2 == 0) hasLeft = false;
                            else hasRight = false;  // "forget" about left on the even moves, or right on the odd moves
                            break;
                        case SolveBehavior.SameDirection:   // force staying in the same direction
                            if (lastDir == Direction.Left)       hasRight = false;
                            else if (lastDir == Direction.Right) hasLeft = false;
                            else goto case SolveBehavior.FlipFlop;  // use the flip-flop behaviour to determine first turn
                            break;
                        case SolveBehavior.Uturn:   // force turning back on itself
                            if (lastDir == Direction.Left)       hasLeft = false;
                            else if (lastDir == Direction.Right) hasRight = false;
                            else goto case SolveBehavior.FlipFlop;  // use the flip-flop behaviour to determine first turn
                            break;
                        default: throw new InvalidOperationException(
                            "Failed to find distinct path, with no resolving behavior defined"
                        );
                    }
                }

                if (hasLeft)        dir = Direction.Left;
                else if (hasRight)  dir = Direction.Right;

                if (hasLeft || hasRight) ++turns;
            }

            switch (dir)    // update position, based on current direction
            {
                case Direction.Left:  if (x > 0) --x; break;
                case Direction.Right: if (x < _grid.Width - 1) ++x; break;
                default: ++y; break;
            }
            if (dumpFrames)
            {
                DumpFrame(path, start, tag:string.Concat("Frame #", turns, " (", _grid.Seed, ")"));
                DrawFrame(path, start, tag:string.Concat("Frame #", turns));
            }
        }
        while (y < _grid.Height);

        int end = (x / 2) + 1;
        DumpFrame(path, start, end, turns, tag);
        DrawFrame(path, start, end, turns, tag);
    }

    ///Internal method for drawing a given frame
    private void DumpFrame(Direction?[,] path, int start, int? end = null, int? turns = null, string tag = null)
    {
        var builder = new StringBuilder();

        builder.Append(' ', --start * 5).AppendLine("v");
        for (int y = 0; y < _grid.Height; y++)
        {
            for (int x = 0; x < _grid.Width; x++)
            {
                builder.Append(
                    (x % 2 == 0)
                        ? path[x, y].HasValue ? ":"    : _grid[x, y] ? "|"    : " "
                        : path[x, y].HasValue ? "====" : _grid[x, y] ? "----" : "    "
                );
            }
            builder.AppendLine();
        }
        if (end.HasValue)   builder.Append(' ', (end.Value - 1) * 5).AppendLine("^");

        if (turns.HasValue) builder.Append(turns.Value)
                                   .Append(" turns were taken to get to ")
                                   .AppendLine(end.HasValue ? "the end." : "this point.");

        builder.ToString().Dump(string.IsNullOrWhiteSpace(tag) ? "Frame" : tag);
    }

    ///Internal method for rendering a frame as a bitmap
    private void DrawFrame(Direction?[,] path, int start, int? end = null, int? turns = null, string tag = null)
    {
        using (var sprites = new Sprites())
        using (var canvas = new Bitmap(16 * _grid.Width, 16 * (_grid.Height + 3)))
        using (var graphics = Graphics.FromImage(canvas))
        {
            graphics.FillRectangle(Brushes.Green, 0, 16, 16 * _grid.Width, 16 * _grid.Height);
            _grid.Draw(graphics, sprites, offsetX:0, offsetY:16);

            // draw the start position
            start = (start - 1) * 32;
            graphics.DrawImageUnscaled(sprites.RoadVertical, start, 0);
            graphics.DrawImageUnscaled(sprites.CarVertical,  start, 0);
            graphics.DrawImageUnscaled(sprites.StartFlag,    start, 0);

            // draw the path
            for (int y = 0; y < _grid.Height; y++)
            for (int x = 0; x < _grid.Width;  x++)
            {
                if (path[x, y].HasValue)
                {
                    Image car;

                    switch (path[x, y])
                    {
                        case Direction.Left:
                            // if even, then on a vertical, so turning left; otherwise travelling left
                            car = (x % 2 == 0) ? sprites.CarTurnLeft : sprites.CarLeft;
                            break;
                        case Direction.Right:
                            // if even, then on a vertical, so turning right; otherwise travelling right
                            car = (x % 2 == 0) ? sprites.CarTurnRight: sprites.CarRight;
                            break;
                        default:
                            car = sprites.CarVertical;
                            if (x == 0 && path[x + 1, y].HasValue)                            // far-left and will move right = turn-right
                                car = sprites.CarTurnRight;
                            else if (x == _grid.Width - 1 && path[x - 1, y].HasValue)         // far-right and will move left = turn-left
                                car = sprites.CarTurnLeft;
                            else if (x > 0 && x < _grid.Width - 1)
                            {
                                car = sprites.CarVertical;                                    // if not right or left, then down
                                if (path[x + 1, y].HasValue && !path[x - 1, y].HasValue)      // if came from the left, then turn right
                                    car = sprites.CarTurnRight;
                                else if (path[x - 1, y].HasValue && !path[x + 1, y].HasValue) // if came from the right, then turn left
                                    car = sprites.CarTurnLeft;
                            }
                            break;
                    }

                    graphics.DrawImageUnscaled(car, 16 * x, 16 * (y + 1));
                }
            }

            // draw the end position, if we are at the end
            if (end.HasValue)
            {
                end = (end - 1) * 32;
                graphics.DrawImageUnscaled(sprites.RoadVertical, end.Value, 16 * (_grid.Height + 1));
                graphics.DrawImageUnscaled(sprites.CarVertical,  end.Value, 16 * (_grid.Height + 1));
                graphics.DrawImageUnscaled(sprites.EndFlag,      end.Value, 16 * (_grid.Height + 1));
            }

            if (turns.HasValue)
            {
                string s = string.Concat(turns.Value, " turns were taken to get to ",
                                         end.HasValue ? "the end." : "this point.");

                graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
                graphics.DrawString(s, SystemFonts.DefaultFont, Brushes.Black, 0, 16 * (_grid.Height + 2));
            }

            canvas.Dump(tag ?? "Bonus");
        }
    }
}

///Represents a configuration of pipes
class PipeGrid
{
    ///Creates a new <see cref="PipeGrid" />, of a given <paramref name="height" />
    ///with the given number of <paramref name="vertical" /> pipes, and randomly distributes
    ///horizontal pipes between them, based on a repeatable <paramref name="seed" />.
    public PipeGrid(int vertical = 4, int height = 8, int? seed = null)
    {
        if (vertical < 2) vertical = 2;
        if (height < 2) height = 2;

        Width = (2 * vertical) - 1;
        Height = height;
        Verticals = vertical;

        Seed = seed ?? Environment.TickCount;
        var rnd = new Random(Seed);

        _nodes = new bool[Width,Height];
        for (int x = 0, xw = Width; x < xw; x++)
        for (int y = 0; y < height; y++)
        {
            // place verticals in every even column, and randomly place horizontals in odd columns
            if (x % 2 == 0 || rnd.Next(0, 2) == 1)
                _nodes[x, y] = true;
        }
    }

    private readonly bool[,] _nodes;

    public int Width { get; private set; }
    public int Height { get; private set; }
    public int Verticals { get; private set; }
    public int Seed { get; private set; }

    public bool this[int x, int y] { get { return _nodes[x, y]; } }

    ///Renders the grid to the LINQPad results pane, for inspection
    public PipeGrid Dump(string tag = null)
    {
        var builder = new StringBuilder();

        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                builder.Append(
                    (x % 2 == 0)
                        ? _nodes[x, y] ? "|"    : " "
                        : _nodes[x, y] ? "----" : "    "
                );
            }
            builder.AppendLine();
        }

        builder.ToString().Dump(string.IsNullOrWhiteSpace(tag) ? "Grid" : tag);
        return this;
    }

    ///Render the grid as a bitmap image
    public void Draw(Graphics g, Sprites s, int offsetX = 0, int offsetY = 0)
    {
        for (int y = 0; y < Height; y++)
        {
            for (int x = 0; x < Width; x++)
            {
                if (_nodes[x, y])
                {
                    Image sprite = sprite = s.RoadVertical;

                    if (x % 2 != 0)
                        sprite = s.RoadHorizontal;
                    else if (x == 0 && _nodes[1, y])
                        sprite = s.JunctionTeeRight;
                    else if (x == Width - 1 && _nodes[x - 1, y])
                        sprite = s.JunctionTeeLeft;
                    else if (x > 0 && x < Width - 1)
                    {
                        if (_nodes[x - 1, y] && _nodes[x + 1, y])
                            sprite = s.JunctionCross;
                        else if (_nodes[x + 1, y] && !_nodes[x - 1, y])
                            sprite = s.JunctionTeeRight;
                        else if (_nodes[x - 1, y] && !_nodes[x + 1, y])
                            sprite = s.JunctionTeeLeft;
                    }

                    g.DrawImageUnscaled(sprite,
                                        x:(16 * x) + offsetX,
                                        y:(16 * y) + offsetY);
                }
            }
        }
    }

    ///Creates a <see cref="PipeGrid" /> with horizontal pipes at all possible positions
    public static PipeGrid CreateAllOpen(int verticals = 4, int height = 8)
    {
        var grid = new PipeGrid(verticals, height, 0);
        for (int y = 0; y < height; y++)
        for (int x = 0, xw = grid.Width; x < xw; x++)
            grid._nodes[x, y] = true;

        return grid;
    }
}

///Store tile sprites, to be used in the graphical rendering of the result
class Sprites : IDisposable
{
    public Sprites()
    {
        byte[,] car = new byte[,] {
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0 },
            { 0, 0, 0, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0, 0, 0 },
            { 0, 0, 0, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 0, 0, 0 },
            { 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0 },
            { 0, 0, 0, 1, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0, 0, 0 },
            { 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0 },
            { 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        };
        byte[,] road = new byte[,] {
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 6, 6, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
        };
        byte[,] roadNESW = new byte[,] {
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
            { 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6 },
            { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
            { 2, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 2, 2, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 2, 2, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 2, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 2, 2, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 2, 2, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 2, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 2, 2, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 2, 2, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 2, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
            { 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
        };
        byte[,] roadNES = new byte[,] {
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
            { 0, 6, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 0, 6, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 0, 6, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 0, 6, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 0, 6, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 0, 6, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 0, 6, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 0, 6, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 0, 6, 2, 2, 5, 5, 2, 5, 5, 2, 5, 5, 2, 2, 2, 2 },
            { 0, 6, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 5, 2, 2, 2 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 6 },
            { 0, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 0 },
        };
        byte[,] start = new byte[,] {
            { 0, 0, 1, 1, 1, 0, 4, 4, 4, 0, 0, 0, 4, 0, 0, 0 },
            { 0, 0, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0 },
            { 0, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0 },
            { 0, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0 },
            { 0, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0 },
            { 0, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0 },
            { 0, 0, 1, 4, 4, 4, 0, 0, 0, 4, 4, 4, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        };
        byte[,] end = new byte[,] {
            { 0, 0, 1, 1, 1, 0, 1, 1, 6, 0, 0, 0, 6, 0, 0, 0 },
            { 0, 0, 1, 6, 6, 6, 1, 1, 6, 6, 1, 1, 6, 0, 0, 0 },
            { 0, 0, 1, 1, 6, 6, 6, 6, 1, 6, 1, 1, 1, 0, 0, 0 },
            { 0, 0, 1, 1, 1, 1, 6, 6, 1, 1, 6, 6, 1, 0, 0, 0 },
            { 0, 0, 1, 1, 1, 1, 1, 1, 6, 1, 6, 6, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 6, 6, 1, 1, 6, 6, 1, 1, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 6, 6, 6, 6, 1, 6, 1, 1, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 1, 1, 6, 6, 1, 1, 6, 6, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 6, 6, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
            { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
        };

        RoadVertical     = Sprite(road);
        RoadHorizontal   = RotateSprite(RoadVertical, 90);
        JunctionCross    = Sprite(roadNESW);
        JunctionTeeRight = Sprite(roadNES);
        JunctionTeeLeft  = FlipSprite(JunctionTeeRight, horizontal:true);
        CarVertical      = Sprite(car);
        CarLeft          = RotateSprite(CarVertical,  90);
        CarRight         = FlipSprite(CarLeft, horizontal:true);
        CarTurnLeft      = RotateSprite(CarVertical,  45);
        CarTurnRight     = FlipSprite(CarTurnLeft, horizontal:true);
        StartFlag        = Sprite(start);
        EndFlag          = Sprite(end);
    }

    public Image RoadVertical     { get; private set; }
    public Image RoadHorizontal   { get; private set; }
    public Image JunctionCross    { get; private set; }
    public Image JunctionTeeLeft  { get; private set; }
    public Image JunctionTeeRight { get; private set; }
    public Image CarVertical      { get; private set; }
    public Image CarLeft          { get; private set; }
    public Image CarRight         { get; private set; }
    public Image CarTurnLeft      { get; private set; }
    public Image CarTurnRight     { get; private set; }
    public Image StartFlag        { get; private set; }
    public Image EndFlag          { get; private set; }

    ///Create a sprite from the byte data
    private Image Sprite(byte[,] data)
    {
        int width = data.GetLength(0);
        int height = data.GetLength(1);

        var image = new Bitmap(width, height);

        for (int y = 0; y < height; y++)
        for (int x = 0; x < width; x++)
        {
            Color c;
            switch (data[y,x])
            {
                case 1: c = Color.Black; break;
                case 2: c = Color.DarkGray; break;
                case 3: c = Color.Red; break;
                case 4: c = Color.LimeGreen; break;
                case 5: c = Color.Yellow; break;
                case 6: c = Color.White; break;
                default: continue;
            }

            image.SetPixel(x, y, c);
        }

        return image;
    }

    ///Rotate an image by a number of <paramref name="degrees" /> around the centre
    private Image RotateSprite(Image source, float deg)
    {
        var b = new Bitmap(source.Width, source.Height);

        using (var g = Graphics.FromImage(b))
        {
            float tx = (float)source.Width / 2.0f;
            float ty = (float)source.Height / 2.0f;

            g.TranslateTransform(tx, ty);
            g.RotateTransform(deg);
            g.TranslateTransform(-tx, -ty);
            g.DrawImageUnscaled(source, 0, 0);
        }

        return b;
    }

    ///Flip an image about its centre
    private Image FlipSprite(Image source, bool horizontal = false, bool vertical = false)
    {
        var b = new Bitmap(source);

        RotateFlipType rft = ( horizontal &&  vertical) ? RotateFlipType.RotateNoneFlipXY
                           : ( horizontal && !vertical) ? RotateFlipType.RotateNoneFlipX
                           : (!horizontal &&  vertical) ? RotateFlipType.RotateNoneFlipY
                           : RotateFlipType.RotateNoneFlipNone;

        b.RotateFlip(rft);
        return b;
    }

    #region IDisposable implementation
    public void Dispose() { Dispose(true); }
    ~Sprites() { Dispose(false); }
    protected void Dispose(bool disposing)
    {
        if (disposing)
        {
            GC.SuppressFinalize(this);
            using (RoadVertical) { }
            using (RoadHorizontal) { }
            using (JunctionCross) { }
            using (JunctionTeeLeft) { }
            using (JunctionTeeRight) { }
            using (CarVertical) { }
            using (CarLeft) { }
            using (CarRight) { }
            using (CarTurnLeft) { }
            using (CarTurnRight) { }
            using (StartFlag) { }
            using (EndFlag) { };
        }
        RoadVertical = null;
        RoadHorizontal = null;
        JunctionCross = null;
        JunctionTeeLeft = null;
        JunctionTeeRight = null;
        CarVertical = null;
        CarLeft = null;
        CarRight = null;
        CarTurnLeft = null;
        CarTurnRight = null;
        StartFlag = null;
        EndFlag = null;
    }
    #endregion
}

```

## Update:

Fearing my plain old text output might be a little drab for this popularity context, I offer up an extended version that *also* draws the path taken as an image. I've modelled it as car, driving through a horrible road network, trying to get to the bottom, but with the world's-worst GPS that forces you to make a turn at every junction.

As a bonus, this also makes it clearer to see the 'turns'.

Enjoy -- *vroom vroom!!*

## Example results:

*(verticals: 10, height: 10, random seed:5, start pipe: 2, solve behaviour: FlipFlop})*

# Answer
> 8 votes
## C#

Fun times! :-)

This code ensures there is at least some straight pipe at either end of each pipe. It also ensures there are no ambiguous turns.

```
using System;

namespace Experiment.DownTheDrain
{
    class Program
    {
        static void Main(string[] args)
        {
            var program = new Program();
            program.Width = 19;
            program.Height = 17;
            program.SpanCount = program.Width * program.Height / 4;
            program.Spacing = 3;
            program.Run();
        }

        public int Width { get; set; }
        public int Height { get; set; }
        public int SpanCount { get; set; }
        public int Spacing { get; set; }
        public bool[,] Spans { get; private set; }

        public void Run()
        {
            GenerateSpans();
            DrawPipes();
            var pipe = ReadStartPipe();
            var turns = DrawPath(pipe);
            WriteTurns(turns);
            Console.ReadLine();
        }

        private void GenerateSpans()
        {
            Random random = new Random();
            Spans = new bool[Width, Height];

            int x, y;
            for (int i = 0; i < SpanCount; i++)
            {
                do
                {
                    x = random.Next(Width);
                    y = random.Next(Height);
                }
                while (SpanAt(x - 1, y) || SpanAt(x, y) || SpanAt(x + 1, y));
                Spans[x, y] = true;
            }
        }

        private void DrawPipes()
        {
            const string Junction = "│┤├┼";

            Console.CursorLeft = 0;
            Console.CursorTop = 0;
            DrawLabels();
            for (int y = -1; y <= Height; y++)
            {
                for (int x = 0; x <= Width; x++)
                {
                    Console.Write(Junction[(SpanAt(x-1,y) ? 1 : 0) + (SpanAt(x,y) ? 2 : 0)]);
                    Console.Write(x == Width ? Environment.NewLine : new string(SpanAt(x, y) ? '─' : ' ', Spacing));
                }
            }
            DrawLabels();
        }

        private void DrawLabels()
        {
            for (int x = 0; x <= Width; x++)
                Console.Write("{0}{1}",
                    (char)(x + 65),
                    x == Width ? Environment.NewLine : new string(' ', Spacing)
                );
        }

        private int ReadStartPipe()
        {
            Console.WriteLine();
            Console.Write("Please select a start pipe: ");
            int pipe;
            do
            {
                var key = Console.ReadKey(true);
                pipe = (int)char.ToUpper(key.KeyChar) - 65;
            }
            while (pipe < 0 || pipe > Width);
            Console.WriteLine((char)(pipe + 65));
            return pipe;
        }

        private int DrawPath(int x)
        {
            int turns = 0;
            Console.CursorTop = 1;
            for (int y = -1; y <= Height; y++)
            {
                if (SpanAt(x - 1, y))
                {
                    x--;
                    Console.CursorLeft = x * (Spacing + 1);
                    Console.WriteLine("╔{0}╝", new string('═', Spacing));
                    turns += 2;
                }
                else if (SpanAt(x, y))
                {
                    Console.CursorLeft = x * (Spacing + 1);
                    Console.WriteLine("╚{0}╗", new string('═', Spacing));
                    x++;
                    turns += 2;
                }
                else
                {
                    Console.CursorLeft = x * (Spacing + 1);
                    Console.WriteLine("║");
                }
            }

            return turns;
        }

        private void WriteTurns(int turns)
        {
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("{0} turns taken to reach the bottom.", turns);
        }

        private bool SpanAt(int x, int y)
        {
            return x >= 0
                && x < Width
                && y >= 0
                && y < Height
                && Spans[x, y];
        }
    }
}

```

Output:

# Answer
> 8 votes
# Funciton

As if Funciton wasn’t already among the most pointless languages in the world, this is certainly the most useless program I’ve written in it so far.

Since this looks ugly in StackExchange due to the extra line spacing, consider running the following in your browser’s JavaScript console to fix that:

> `$('pre').each(function(){$(this).css('line-height',1)})`

Since Funciton doesn’t have a random number generator, I decided to let you enter the pipe pattern. Since the pattern encoding is unobvious, banging the digit keys on your keyboard randomly is as good as a random number generator.

The input is expected to be three decimal numbers separated by spaces. The first number is the width (one less than the number of vertical pipes); the second is the index of the starting pipe, and the last is any number that encodes the horizontal pipe pattern; you can make it as large as you want. If the width is negative or the pipe index is out of range, the output is `Impossiburu.`

The program automatically ensures that there are never two horizontal pipes next to each other, which could cause ambiguous turns.

```
                            ┌───╖
               ┌────────────┤ ♯ ╟───────────┬───────────────┐
     ╔════╗  ┌─┴─╖  ┌────╖  ╘═══╝  ╔═══╗  ┌─┴─╖  ╔════╗     │
     ║ 21 ║  │ × ╟──┤ >> ╟─────────╢   ╟──┤ ʘ ╟──╢ 32 ║     │
     ╚═╤══╝  ╘═╤═╝  ╘═╤══╝         ╚═══╝  ╘═══╝  ╚════╝     │
       └───────┘  ┌───┴───┐                                 │
   ╔════╗  ┌───╖  │   ┌───┴──────────────────┐              │
   ║ 32 ╟──┤ ʘ ╟──┘   │          ╔═══╗       │              │
   ╚════╝  ╘═╤═╝    ┌─┴─╖        ║ 0 ╟───┐   │              │
     ┌───────┴──────┤ · ╟────┐   ╚═══╝ ┌─┴─╖ │              │
     │              ╘═╤═╝    └─────────┤ ʃ ╟─┘              │
     │     ┌──────────┘                ╘═╤═╝                │
   ┌─┴─╖ ┌─┴──╖  ┌─────────╖        ┌────┴────╖             │
   │ ♯ ║ │ >> ╟──┤ str→int ╟────┐   │ str→int ║             │
   ╘═╤═╝ ╘═╤══╝  ╘═════════╝  ┌─┴─╖ ╘════╤════╝           ┌─┴─╖
     │   ┌─┴─╖ ╔════╗         │ ░ ║   ┌──┴────────────────┤ · ╟────────────┐
     └───┤ × ╟─╢ 21 ║         ╘═╤═╝ ┌─┴─╖                 ╘═╤═╝            │
         ╘═══╝ ╚════╝┌─────┐    └───┤ ▒ ╟───┐ ┌─────────╖ ┌─┴─╖            │
      ┌─────────╖  ┌─┴─╖   │        ╘═╤═╝   ├─┤ str→int ╟─┤ ʃ ╟─┐          │
   ┌──┤ int→str ╟──┤ · ╟─┐ └──────────┘     │ ╘═════════╝ ╘═╤═╝ │          │
   │  ╘═════════╝  ╘═╤═╝ │ ╔══════════════╗ │ ╔═══╗  ┌──────┘   │          │
   │ ╔══════════╗  ┌─┴─╖ │ ║ 158740358500 ║ │ ║   ╟──┘ ┌───╖  ╔═╧═╗  ┌───╖ │
   │ ║ 20971533 ╟──┤   ╟─┘ ║ 305622435610 ║ │ ╚═══╝  ┌─┤ ≤ ╟──╢ 0 ╟──┤ ≥ ╟─┴─┐
   │ ╚════╤═════╝  └─┬─╜   ║ 491689778976 ║ └────────┤ ╘═╤═╝  ╚═══╝  ╘═╤═╝   │
   │    ┌─┴─╖  ┌───╖ │     ║ 886507240727 ║          │   └──────┬──────┘     │
   │    │ ‼ ╟──┤ ‼ ╟─┘     ║ 896192890374 ║          │         ┌┴┐           │
   │    ╘═╤═╝  ╘═╤═╝       ║ 899130957897 ╟───┐      │         └┬┘           │
   └──────┘    ┌─┴─╖       ╚══════════════╝ ┌─┴─╖  ┌─┴─╖        │            │
               │ ‼ ╟────────────────────────┤ ? ╟──┤ · ╟────────┤            │
               ╘═╤═╝                        ╘═╤═╝  ╘═╤═╝      ┌─┴─╖          │
 ╔═══════════════╧════════════════════════╗   │      └────────┤ ≥ ╟──────────┘
 ║ 83139057126481738391428729850811584337 ║       ┌────╖      ╘═══╝
 ║ 75842912478026089564602018574355013746 ║  ┌────┤ >> ╟──┐
 ║ 85373033606532129933858395805642598753 ║  │    ╘══╤═╝  │
 ║ 19381927245726769973108298347355345088 ║  │     ┌─┴─╖  │       ╓───╖
 ║ 84932603219463911206052446527634696060 ║  │     │ ░ ║  │       ║ ░ ║
 ║ 230797436494578049782495796264992      ║  │     ╘═╤═╝  │       ╙─┬─╜
 ╚════════════════════════════════════════╝  │    ┌──┴──┐ └─────────┴────────┐
                                             │    │   ┌─┴──╖ ┌┐   ┌┐         │
                                             │    │   │ << ╟─┤├─┬─┤├─────┐   │
   ┌────╖  ╔═══╗                             │    │   ╘═╤══╝ └┘ │ └┘   ╔═╧═╗ │
 ┌─┤ << ╟──╢ 1 ║                             │    │   ╔═╧═╗     │      ║ 1 ║ │
 │ ╘═╤══╝  ╚═══╝      ┌───────────────────┐  │    │   ║ 2 ║     │      ╚═╤═╝ │
 │   └─────┬──────────┴─────────┐         │  │ ┌──┴─╖ ╚═══╝   ┌─┴─╖ ┌┐   │   │
 │         │           ┌───┐  ┌─┴─╖       │  │ │ << ╟─────────┤ ? ╟─┤├───┤   │
 │         │           │   ├──┤ · ╟─┐     │  │ ╘══╤═╝         ╘═╤═╝ └┘   ├───┘
 │ ┌───┐ ┌─┴─╖ ┌───╖   └─┬─┘  ╘═╤═╝ ├───┐ │  │  ╔═╧═╗  ╔═══╗  ┌─┴─╖      │
 ├─┤   ├─┤ · ╟─┤ ♯ ╟─────┘    ┌─┴─╖ │   │ │  └──╢ 1 ║  ║ 0 ╟──┤ ? ╟──────┘
 │ └───┘ ╘═╤═╝ ╘═══╝  ┌───────┤ · ╟─┴─┐ │ │     ╚═══╝  ╚═══╝  ╘═╤═╝
 │       ┌─┴─╖      ┌─┴─╖     ╘═╤═╝   │ │ └─────────────────┐   │
 │  ┌────┤ · ╟──────┤ · ╟──┐    │     │ └────────┐          │
 │  │    ╘═╤═╝      ╘═╤═╝  │    │     └────┐     │          │
 │  └───┬──┴──┐       │    │    │        ┌─┴──╖  │          │
 │      │    ┌┴┐      │    │    └─────┬──┤ << ║  │          │
 │      │    └┬┘      │    │         ┌┴┐ ╘═╤══╝  │          │
 │    ┌─┴─╖ ┌─┴─╖   ┌─┴─╖  │         └┬┘ ╔═╧═╗   │          │
 └────┤ · ╟─┤ ? ╟─┐ │ ♯ ║  ├──────────┤  ║ 1 ║   │          │
      ╘═╤═╝ ╘═╤═╝ │ ╘═╤═╝ ┌┴┐         │  ╚═══╝   │          │
        │     │   │ ┌─┴─╖ └┬┘         │          │          │
        │     │   └─┤ ? ╟──┘        ┌─┴─╖        │          │
        │     │     ╘═╤═╝     ┌─────┤ > ╟─────┬──┘          │
        │     │     ┌─┴─╖   ┌─┴─╖   ╘═══╝     ├─────────┐   │
      ┌─┴─╖   └─────┤ · ╟───┤ · ╟─────────────┘         │   │
    ┌─┤ · ╟─────┐   ╘═╤═╝   ╘═╤═╝                       │   │
    │ ╘═╤═╝  ┌──┴─╖ ┌─┴─╖     │                         │   │
    │   │    │ >> ╟─┤ ▒ ╟──┐  ├─────────────┐         ┌─┴─╖ │
    │   │    ╘══╤═╝ ╘═╤═╝  ├──┘             │ ╓───╖ ┌─┤ · ╟─┤
    │   │       │   ┌─┴─╖  │                ├─╢ ▒ ╟─┤ ╘═╤═╝ │
    │   │       └───┤ · ╟──┘                │ ╙─┬─╜ │   │   │
    │   │           ╘═╤═╝                   │   │ ┌─┴─╖ │   │
    │   │           ┌─┴─╖                   │   └─┤ · ╟─┤   │
    │   │        ┌──┤   ╟────────────┐      │     ╘═╤═╝ │   │
    │   │        │  └─┬─╜  ┌───╖   ┌─┴─╖  ┌─┴─╖   ┌─┴─╖ │   │
    │   └──────┐ │    └────┤ ‼ ╟───┤ · ╟──┤ · ╟───┤ ▓ ╟─┘   │
    │          │ │         ╘═╤═╝   ╘═╤═╝  ╘═╤═╝   ╘═╤═╝     │
    │          │ │  ╔═══╗  ┌─┴─╖     │      └───────┘       │
    │          │ └──╢ 0 ╟──┤ ? ╟─┐   │                      │
    │          │    ╚═══╝  ╘═╤═╝ │ ┌─┴─╖                    │
    │ ╔═══╗    │           ┌─┴─╖ ├─┤ · ╟─┐                  │
    │ ║ 2 ║    │      ┌────┤ · ╟─┘ ╘═╤═╝ ├──────────────────┘
    │ ╚═╤═╝    │      │    ╘═╤═╝     │   │
    │ ┌─┴─╖  ┌─┴─╖  ┌─┴─╖  ╔═╧═╕ ┌─┐ │   │
    │ │ + ╟──┤ ? ╟──┤ ? ╟──╢   ├─┴─┘ │   │
    │ ╘═╤═╝  ╘═╤═╝  ╘═╤═╝  ╚═╤═╛     │   │
    │   └──┬───┘    ╔═╧═╗    │       │   │
    │      │        ║ 0 ║            │   │
    │      │        ╚═══╝            │   │
    │      └─────────────────────────┘   │
    └────────────────────────────────────┘        ╓┬──╖
 ┌────────────────────────────────────────────────╫┘▓ ╟────────────┐
 │ ╔═══════════╗        ╔════════════════════╗    ╙─┬─╜            │
 │ ║ 387759291 ║        ║ 385690484238253342 ║      │              │
 │ ║ 565251600 ║    ┌───╢ 839653020379129116 ║      │    ┌────┐    │
 │ ║ 199735775 ║  ┌─┴─╖ ╚════════════════════╝      │    │   ┌┴┐   │
 │ ║ 904933210 ╟──┤ ? ╟────────────────┐            │    │   └┬┘   │
 │ ╚═══════════╝  ╘═╤═╝    ┌──────┐    ├────────────┴────┘  ┌─┴─╖  │
 │ ╔═══════════╗  ┌─┴─╖  ┌─┴─╖  ╔═╧═╗  │  ╔════╗    ╔═══╗   │ ♯ ║  │
 │ ║ 388002680 ╟──┤ ? ╟──┤ ≠ ║  ║ 1 ║  │  ║ 21 ║  ┌─╢ 1 ║   ╘═╤═╝  │
 │ ║ 480495420 ║  ╘═╤═╝  ╘═╤═╝  ╚═══╝  │  ╚═╤══╝  │ ╚═══╝    ┌┴┐   │
 │ ║ 244823142 ║    │      ├───────────┘    │     │          └┬┘   │
 │ ║ 920365396 ║    │    ┌─┴─╖  ┌───╖     ┌─┴──╖  │ ┌────╖  ┌─┴─╖  │
 │ ╚═══════════╝    └────┤ · ╟──┤ ‡ ╟─────┤ >> ║  └─┤ >> ╟──┤ · ╟──┴─┐
 │ ╔═══════════╗ ┌───┐   ╘═╤═╝  ╘═╤═╝     ╘═╤══╝    ╘═╤══╝  ╘═╤═╝    │
 │ ║ 618970314 ╟─┘ ┌─┴─╖ ┌─┘      │         │       ┌─┴─╖     │      │
 │ ║ 790736054 ║ ┌─┤ ? ╟─┴─┐      │         ├───────┤ ▓ ╟─────┘      │
 │ ║ 357861634 ║ │ ╘═╤═╝   │      │     ┌───┘       ╘═╤═╝            │
 │ ╚═══════════╝ │ ┌─┴─╖ ┌─┴─╖  ┌─┴─╖ ┌─┴─╖         ┌─┴─╖     ╔═══╗  │
 │ ╔═══════════╗ │ │ ‼ ╟─┤ · ╟──┤ ? ╟─┤ · ╟─────────┤ · ╟──┐  ║ 1 ║  │
 │ ║ 618970314 ╟─┘ ╘═╤═╝ ╘═╤═╝  ╘═╤═╝ ╘═╤═╝         ╘═╤═╝  │  ╚═╤═╝  │
 │ ║ 790736054 ║     │   ┌─┴─╖  ┌─┴─╖   │   ╓┬──╖    ┌┴┐  ┌┴┐   │    │
 │ ║ 357861713 ║     └───┤ · ╟──┤ · ╟───┘ ┌─╫┘‡ ╟─┐  └┬┘  └┬┘   │    │
 │ ╚═══════════╝         ╘═╤═╝  ╘═╤═╝     │ ╙───╜ │ ┌─┴─╖  └────┤    │
 │ ╔════════════════╗    ┌─┴─╖  ┌─┴─╖     │ ┌───╖ │ │ ♯ ║       └────┘
 │ ║ 43980492383490 ╟────┤ ? ╟──┤ ? ╟───┐ └─┤ ‼ ╟─┘ ╘═╤═╝
 │ ╚════════════════╝    ╘═╤═╝  ╘═╤═╝   │   ╘═╤═╝    ┌┴┐
 │ ╔════════════════╗      │      │     │     │      └┬┘
 │ ║ 43980492383569 ╟──────┘            └──────┬──────┘
 │ ╚════════════════╝                          │
 └─────────────────────────────────────────────┘

```

## Explanation

* The main program finds the first two spaces and splits out the numbers. It runs the third (the pipe pattern) through  and then calls  with the result, which returns the output as well as the number of turns taken. It then adds the text `n turns were taken to get to the end.`, where `n` is the number of turns calculated by .
* takes a number and inserts a `0`-bit after every `1`-bit, thus ensuring there are never two horizontal pipes in succession.
* generates the output by successively calling  and then shifting out the right number of bits from the pipe pattern until it is zero. It also increments or decrements the “current pipe” appropriately.
* generates one line of the output. In each iteration, it shifts out one bit from the pipe pattern and then decides whether to output  (+ 4 spaces),  (+ 4 spaces), `├────┤`, `╔════╝` or `╚════╗`; in the latter three cases, it removes the first character from the next iteration. The last iteration generates `│\r\n` or `║\r\n` as appropriate.

## Example output

Input:

> `6 3 73497529294753`

Output:

```
├────┤    │    ║    │    │    │
├────┤    │    ╚════╗    ├────┤
│    ├────┤    ╔════╝    ├────┤
│    ├────┤    ║    │    │    │
│    │    │    ║    │    ├────┤
│    │    │    ║    ├────┤    │
│    ├────┤    ╚════╗    ├────┤
│    ├────┤    │    ║    │    │
│    ├────┤    ╔════╝    │    │
├────┤    ╔════╝    │    ├────┤
│    │    ║    │    │    ├────┤

10 turns were taken to get to the end.

```

Input:

> `3 0 65536`

Output:

```
║    │    │    │
║    │    │    │
║    │    ├────┤

0 turns were taken to get to the end.

```

Input:

> `3 7 75203587360867` (pipe index out of range)

Output:

```
Impossiburu.

```

# Answer
> 3 votes
# Groovy, 311

```
t=System.in.text.collect{it.collect{it}};s=t.size();d=0;c=0;y=0;x=t[0].indexOf('|');println' '*x+'V'
while(y<s){t[y][x]=t[y][x]=='|'?':':'='
if(d){x+=d}else y++
if(y<s)if(d){if(t[y][x]=='|'){d=0;c++}}else if(t[y][x+1]=='-'){d=1;c++} else if(t[y][x-1]=='-'){d=-1;c++}}
t.each{println it.join()}println' '*x+'^'+c

```
* line 1: setup and find first |
* line 2: swap out replacement : or =
* line 3: move x/y to next pos (d=0=down,d=-1=left,d=1=right)
* line 4: find next direction
* line 5: print out results

Here it is formatted:

```
t=System.in.text.split('\n').collect{it.collect{it}}; s=t.size()
d=0; c=0; y=0; x=t[0].indexOf('|')
println ' '*x + 'V'
while (y<s) {
    t[y][x] = t[y][x] == '|' ? ':' : '='
    if (d) {x += d} else y++
    if (y<s)
        if (d) {if (t[y][x]=='|') {d = 0; c++}}
        else if(t[y][x+1]=='-') {d = 1; c++}
        else if(t[y][x-1]=='-') {d = -1; c++}
}
t.each {println it.join()}
println ' '*x + '^'+c

```

Output from the sample:

```
V
:       |       |-------|
:=======:       |-------|
|       :=======:       |
|-------|-------:=======:
|       |-------|       :
|-------|       :=======:
|-------|       :=======:
|       |-------|       :
                        ^10

```

Other output:

```
V
:       |       |-------|       |
:=======:       |-------|       |
|       :=======:       |-------|
|-------|-------:=======:       |
|       |-------|       :=======:
|-------|       |-------|       :
|-------|       |-------|       :
|       |-------|       :=======:
|       |-------|       :       |
|       |       :=======:       |
|-------|       :       |       |
|       :=======:       |       |
|       :       |-------|       |
|       :=======:       |       |
                ^16

```

(I know I did code-golf instead of popularity, but that's just my style)

# Answer
> 2 votes
**JavaScript**

The HTML canvas listens for click events and finds the nearest row of pipes and uses that for the starting point. Output is drawn on the canvas and there is also a textarea containing the ASCII output defined by the OP.

The algorithm will ensure that there are never two connecting horizontal pipes. Other than that restriction, a probability is defined in the initial variables and that is used to randomly determine whether a horizontal pipe should occur or not.

JSFIDDLE

```

Click on a row to show the path

<canvas id="canvas" width="450" height="350"></canvas>
<textarea id="output" style="width:100%; height:24em;"></textarea>

```

**Output**

---
Tags: popularity-contest
---


# Question
Title: Make a PNG image with "Hello World!" with programming APIs, in the shortest code possible
So, I want you to make a PNG image that says "Hello world!" and nothing else on a distinguishable background using only an image making API (eg ImageMagick) and return the image. Fewest characters win, as usual. Oh, and you can use any color text.

# Answer
# Sage notebook, 22

```
text("Hello world",0j)

```
> 8 votes

# Answer
# Bash + ImageMagick: ~~35~~ 33

Default font, default text size, default colours:

```
convert label:Hello\ world! a.png

```

and here's the result:

Thanks to DigitalTrauma and sch for the help :-D
> 58 votes

# Answer
# Mathematica ~~28~~ 27

This creates and exports the sentence, "Hello world!", as a PNG image. 1 char saved by Mechanical snail.

```
".png"~Export~"Hello world!"

```

---

**Testing**

This imports the PNG image. The image was enlarged by dragging the image box handles.
> 45 votes

# Answer
# HTML, 1494

I know this won't win, but I didn't see this here before.

```
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEIAAAANEAYAAABNymQSAAAABmJLR0T///////8JWPfcAAAACXBIWXMAAABIAAAASABGyWs+AAAACXZwQWcAAABCAAAADQDi7GgjAAADvElEQVRYw+1YPa9pTRReRIJKEPHdiEJBoVVIRCenpCJBfCQEDeI3qAh/QCIRUchp0KCUaISgROO7QMRHSGS9xX73u+85592Xe47uepqJZ9bMrFnzrJm1MfBfwAsvAADzM8HhcDgczv2Bj9r9KRgMBoPBeJz/2/DdODwaV+bjU77wN+AliBc+4OmCmE6n0+kUwGKxWCwWAKFQKBQKAfR6vV6vBygWi8Vi8efr7Ha73W4H4HK5XC4XgFQqlUqlADKZTCaTAbjdbrfbTdndg8FgMBgMANVqtVqtUnwikUgkEgBisVgsFgOQFRfZkny/3+/3+z/3i7zC8/l8Pp8HkEgkEomE3u/tdrvdbgEcDofD4aDirVar1Wo1QCaTyWQyj8f1iyAul8vlcqEco2tJu88IBoPBYBDA7/f7/X6A5XK5XC4ByuVyuVwGSCaTyWQSYDAYDAaD7wsiHo/H43EAFovFYrEAxuPxeDwGGI1Go9GI4skDvYe3t7e3tzeAer1er9cpvtlsNptNAC6Xy+VyAYbD4XA4pPwnea1Wq9Vqn+dXu91ut9sAjUaj0WjQ28VisVgsRgl0MplMJhOAXq/X6/UAOp1Op9OhH8/j8Xg83i8EfgKbzWaz2XgXdHYCgUAgEJBfLfQtkQFfx/+/V195uVwul8sRV6vVarX6ak8IEVGpVCqVyvv7IQKISBwsIpHBiBqNRqPRIBIHiJhOp9PpNGIqlUqlUoihUCgUCj3PL3Kf6/V6vV7fjwNxAyEuFovFYvHVnuTp4moymUwmE/Wb9f0c/b3iut1ut9sFIDZO9c9ms9lsBsDn8/l8/s/Xu1c932632+12fx6dTqfT6QD2+/1+vwcolUqlUgnAaDQajUYAs9lsNpsBstlsNpulMjISiUQikef7JRKJRCLRfb+ZTCaT+ZuH/95XCflU/odHM/9Ru3A4HA6HEaPRaDQaRbxer9frFbHVarVaLURCMFSm3MsAOt7j8Xg8HkSfz+fz+RDP5/P5fEY8nU6n0wnR6/V6vV6qfRSBQCAQCFAZXCgUCoUC4vF4PB6PiMRBISoUCoVCgUg8nc/zi27/dP3kPHa73W63IxKCRjwcDofDAZGoWejnrdVqtVrtl/mfLQiiyEG02Ww2m416QogiB/H9/f39/f3xDdPx5DpOp9PpdCISxRfVkjxp9ygqlUqlUqHWm8/n8/mc6ievWKvVarVa6ff/Xb/+VBCbzWaz2VCCIOOtUqlUKhViLpfL5XKPx5XxseOFvx2v/yFe+ICXIF74gH8A5ia8gOmPT18AAAASdEVYdGxhYmVsAEhlbGxvIHdvcmxkIbl+3UEAAAAASUVORK5CYII=

```

Well apparently StackExchange will not allow data links so you must copy & paste it into your browser's address bar.

---

@squeamish ossifrage got it down to 176:

```
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAHAQAAAAC0VvlnAAAAOklEQVR4nGLIv/57/+9rDGDqAkPOterN0YIM3KG712pdZcgI3bW26gZD9lUwlRNWW1wtAAAAAP//AwCcyhjs3+7tWQAAAABJRU5ErkJggg

```

---

114

```
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACUAAAAEAQAAAAAhFcs9AAAAIElEQVQIHWOJit1f7szy58v9DAWWPaEMP7hZHHgi1aMB

```

---

@primo got it down to 112:

```
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACYAAAAEAQAAAADKInA+AAAAH0lEQVR4nGOIj///7wVDZOBdoQ4G4dCrYWuA7JNiHQ

```
> 31 votes

# Answer
# C# - 168 chars

C# is better! ;)

```
using System.Drawing;class a{static void Main(){var s=new Bitmap(99,9);Graphics.FromImage(s).DrawString("Hello world!",new Font("",5),Brushes.Red,0,0);s.Save(".png");}}

```

Saves as .png in the current directory.

Rule abuse:

* Minimum font/image size has not been specified, so I settled for the minimum readable ;)
* Filename is empty (only extension!), but it works flawlessly.

To mirror the Java answer, here is the indented code:

```
using System.Drawing;
class a
{
    static void Main()
    {
        var s = new Bitmap(99, 9);
        Graphics.FromImage(s).DrawString("Hello world!", new Font("", 5), Brushes.Red, 0, 0);
        s.Save(".png");
    }
}

```

.net's API is a lot cleaner.
> 28 votes

# Answer
## Linux shell + various utilities: 48 bytes

My first thought was to print `Hello World!` in the console, and then take a screenshot (after a small delay to avoid the race condition) using `scrot`:

```
echo Hello World\!;scrot -d1

```

(28 bytes). Unfortunately, this fails the "and nothing else" requirement: it will generally show other things like window decorations.

So instead, do it inside a full-screen `xterm`. This covers up any other windows and hides window decorations. It also satisfies the background-color requirement, since `xterm` defaults to a white background.

Because `xterm` displays a black cursor, we also need to tell it to hide the cursor. That can be accomplished using a terminal escape sequence: ESC `[` `?` `2` `5` `l`.

The option to make it full-screen is `-fullscreen`. However, it seems to work if you abbreviate the option to the shortest unambiguous possibility, `-fu`, saving 8 bytes.

The final code (48 bytes) is:

```
xterm -fu -e 'echo \x1b[?25lHello World!;scrot -d1'

```

(where `\x1b` denotes a literal ESC character, which takes 1 byte). By default, `scrot` writes the screenshot to a timestamped PNG file in the current directory.

It works on my system:
> 25 votes

# Answer
## Processing, 38 37

This might be considered cheating, but:

```
text("HeΠo World!",9,8);save(".png");

```

---

38 char solution:

```
text("Hello World!",9,9);save(".png");

```

Saves this image as `.png`:
> 19 votes

# Answer
# Java - ~~340~~ ~~339~~ ~~292~~ ~~261~~ ~~239~~ ~~236~~ 233 chars

This outputs a file just called `p` with a transparent background and white text:

```
import java.awt.image.*;class R{public static void main(String[]y)throws Exception{BufferedImage b=new BufferedImage(80,9,2);b.getGraphics().drawString("Hello World!",5,9);javax.imageio.ImageIO.write(b,"png",new java.io.File("p"));}}

```

Here a properly-indented version. Should be pretty clear what is going on:

```
import java.awt.image.*;

class R {
    public static void main(String[] y) throws Exception {
        // 2 = BufferedImage.TYPE_INT_ARGB
        BufferedImage b = new BufferedImage(80, 9, 2);
        b.getGraphics().drawString("Hello world!", 5, 9);
        javax.imageio.ImageIO.write(b, "png", new java.io.File("p"));
    }
}

```

You might argue that white text in a transparent background is awful for reading and the file being called just `p` without the `.png` extension is awful too. So this longer variant version with 290 chars use red text and outputs a file called `p.png`:

```
import java.awt.image.*;import java.awt.*;class R{public static void main(String[]y)throws Exception{BufferedImage b=new BufferedImage(80,9,2);Graphics g=b.getGraphics();g.setColor(Color.RED);g.drawString("Hello world!",5,9);javax.imageio.ImageIO.write(b,"png",new java.io.File("p.png"));}}

```

That properly-indented:

```
import java.awt.image.*;
import java.awt.*;

class R {
    public static void main(String[] y) throws Exception {
        // 2 = BufferedImage.TYPE_INT_ARGB
        BufferedImage b = new BufferedImage(80, 9, 2);
        Graphics g = b.getGraphics();
        g.setColor(Color.RED);
        g.drawString("Hello world!", 5, 9);
        javax.imageio.ImageIO.write(b, "png", new java.io.File("p.png"));
    }
}

```
> 14 votes

# Answer
# Fortran 90, 104 94 bytes:

Aight, game on. Fortran 90, using the g2 graphics library and implict typing, so "d" is a real:

```
d=g2_open_gd('h',80.,12.,g2_gd_png)
call g2_string(d,1,1,'Hello world!')
call g2_close(d)
end

```

Needs to have the g2 library installed, then just compile with

```
gfortran -lg2 -fsecond-underscore p.f90

```

Thanks Kyle Kanos for suggesting to drop "program p"!

I'm pretty satisfied that I beat C#, C + Cairo, Java, Javascript, Python and Ruby! And now also Perl!

Example output:
> 14 votes

# Answer
# R, 52 39 chars

```
png()
frame()
text(.5,1,"Hello World!")

```

Saves as Rplot001.png in current directory. To be run as a script in non-interactive (batch) mode.

Thanks to Sven Hohenstein and Michael Hoffman for updates!
> 11 votes

# Answer
## PHP + gd2 - 86 bytes

```
<?imagestring($i=imagecreatetruecolor(97,16),4,2,0,'Hello world!',65535);imagepng($i);

```

`imagecreatetruecolor` is used instead of the shorter `imagecreate`, because colors can used directly without having to allocate them with `imagecolorallocate`. `65535` corresponds to hex color `#00FFFF`, a.k.a. cyan. I could have used `255` for blue, but it's fairly hard to see on a black canvas.

If the requirement that the background must be white or transparent is to be strictly enforced, I think the best that can be done is **98 bytes**:

```
<?imagestring($i=imagecreatetruecolor(97,16),4,2,0,'Hello world!',imagefilter($i,0));imagepng($i);

```

The `0` sent to `imagefilter` is the value of the constant `IMG_FILTER_NEGATE`, which of course negates the image. The result, `1`, is then used as the paint color (`#000001`):

Another option at **108 bytes**:

```
<?imagestring($i=imagecreatetruecolor(97,16),4,2,imagecolortransparent($i,0),'Hello world!',1);imagepng($i);

```

Setting black to be transparent, and drawing with `#000001` instead.

---

## PHP + *No Library* \- 790+ bytes

```
<?
echo pack('CA3N2',137,'PNG',218765834,13);
echo $ihdr = pack('A4N2C5','IHDR',45,7,1,0,0,0,0);
echo hash('crc32b',$ihdr,true);
$data =
  '--------0  0      0 0                        0    0 0---'.
  '--------0  0      0 0                        0    0 0---'.
  '--------0  0  00  0 0  00    0   0  00  0 0  0  000 0---'.
  '--------0000 0  0 0 0 0  0   0   0 0  0 00 0 0 0  0 0---'.
  '--------0  0 0000 0 0 0  0   0 0 0 0  0 0    0 0  0 0---'.
  '--------0  0 0    0 0 0  0   0 0 0 0  0 0    0 0  0  ---'.
  '--------0  0  000 0 0  00     0 0   00  0    0  000 0---';
$bytes = join(array_map(chr,array_map(bindec,str_split(strtr($data,' -',10),8))));
$cmp = gzcompress($bytes);
echo pack('N',strlen($cmp));
echo $idat = 'IDAT'.$cmp;
echo hash('crc32b',$idat,true);
echo pack('NA4N',0,'IEND',2923585666);

```

Ahh, that's better. No bloat; exactly as much as required, and not a chunk more.
The result is this **109 byte** png:

Or, URI encoded (which seems to be trending...) at **168 bytes**:

`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAHAQAAAAC0VvlnAAAANElEQVR4nGPIv/7//+8LDFAq51r15mgBBu7Q3Wu1LjBkhO5aW3WBIfsqkLrBkBNWW1wtAACw2RlgLInRogAAAABJRU5ErkJggg`

Supposing we wanted to cut that down a bit more, let's say we replace the data string with this:

```
$data =
  '--------0  0      0 0                    0   0 0'.
  '--------0  0  00  0 0 000   0   0 000 00 0 000 0'.
  '--------0000 0 00 0 0 0 0   0 0 0 0 0 0  0 0 0 0'.
  '--------0  0 00   0 0 0 0   0 0 0 0 0 0  0 0 0  '.
  '--------0  0  000 0 0 000   00 00 000 0  0 000 0';

```

(and update the header to the new dimensions, 40x5), the output would be this **96 byte** png:

Which URI encodes to **150 bytes**:

`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAFAQAAAAAft5MoAAAAJ0lEQVR4nGPIv/7//y6GnCvlLosYuEJLQ1cxZF4tDV3NkBNS5LoIANqBDTt5Av0NAAAAAElFTkSuQmCC`

I think that's about as small as you're going to be able to get, and still be considered "human readable".

### Further Analysis

You may have noticed that we've been toting along an extra byte at the beginning of each scanline (denoted by `--------`). This isn't solely for decoration. Each byte specifies the filtering used by each scanline. According to the PNG specification, *"Filtering transforms the PNG image with the goal of improving compression."* So let's try that.

The are five different filtering operations which can be applied independently to each scanline. The PHP implementation that I used for each can be seen here: http://codepad.org/xCQpBPC3 where `$bytes` represents the raw bytes for the current scanline, and `$prior` represents the raw, unfiltered bytes for the scanline above the current.

Let's start with the first 45x7 image. Seven scanlines each with 5 different filterings makes 78125 different possibilities to grind through. The initial encoding of the data block was 52 bytes in length, and after a bit of grinding zlib found a one byte improvement using filtering pattern \[1, 1, 1, 1, 0, 0, 0\] (that is, the first four scanlines with Sub filtering, and the last three unfiltered). The result is this **108 byte** png:

Which of course looks identical to the last. But I'm not convinced that zlib is producing the best possible encoding, and I think i have good reason to be skeptical. I decided to try AdvanceComp (which uses the same DEFLATE engine used for 7-zip), and Zopfli, an implementation which claims to *"find a low bit cost path through the graph of all possible deflate representations."* Sure enough, Zopfli mananged to compress the same data data pattern \[1, 1, 1, 1, 0, 0, 0\] down to 50 bytes, producing this **107 byte** png:

Once again, visually identical. (As a point of interest, it should probably be mentioned at this point that AdvanceComp with the setting `-z3` (compress-extra (7z)) didn't manage to find anything shorter than 60 bytes - the data was left uncompressed. It seems it refuses to compress anything this short). The above URI encodes to **165 bytes**:

`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC0AAAAHAQAAAAC0VvlnAAAAMklEQVR4AWPMz9Bg+HMVRuVkLbVYsZWR2yvtU+0yhozQXWurLjBkXwVSNxhywmqLqwUA+IMVKa7QjrYAAAAASUVORK5CYII`

Fully 11 bytes shorter than squeamish ossifrage's attempt at more or less an identical image.

Onwards to the 40x5 image. Five lines with 5 filterings each means we only have 3125 possibilities this time. The original encoding was 39 bytes in length, and with a bit of grinding, zlib found quite a few 38s. The one I've chosen is \[1, 0, 0, 2, 0\], which contains the largest number of unfiltered lines, and Sub and Up filters on lines 0 and 4, which are the simplest. Zopfli wasn't able to improve this result any further. The result is this **95 byte** png:

Which URI encodes to **149 bytes**:

`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAFAQAAAAAft5MoAAAAJklEQVR4nGPMz9Bg2M2Qc6XcZREDV2hp6Cqm+AYGBkaGnJAi10UAju4JJ/1zkEIAAAAASUVORK5CYII`

You might be tempted to think that the last 18 or so bytes of this aren't necessary. After all, this **121 byte** URI will still display correctly, at least in Chromium:

`data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAFAQAAAAAft5MoAAAAIUlEQVR4nGPMz9Bg2M2Qc6XcZREDV2hp6Cqm+AYGBkaGnJAi10U`

But if you save it to a file, it will break in very many image viewers. In fact, any compliant decoder is required to report an error. So what have we chopped off?

From end towards beginning:

* 4 bytes - CRC32 for `IEND` chunk (always `0xAE426082`)
* 4 bytes - `IEND` chunk marker (always `IEND`)
* 4 bytes - `IEND` chunk length (always `0x00000000`)
* 4 bytes - CRC32 for `IDAT` chunk
* 4 bytes - Adler32 for zlib data
* 1 byte - Stop marker for zlib data

Additionally adjusting the `IDAT` length marker down by 5 (to compensate for the bytes we deleted) seems to "fix" the image in Windows Previewer.
> 10 votes

# Answer
# Octave, 47

```
axis('off')
title("Hello World!")
print -dpng x.png

```
> 9 votes

# Answer
# C + Cairo: ~~238~~ ~~221~~ 202 bytes

```
#include <cairo/cairo.h>
main(){cairo_surface_t*s=cairo_image_surface_create(0,99,50);cairo_t*c=cairo_create(s);cairo_move_to(c,0,9);cairo_show_text(c,"Hello world!");cairo_surface_write_to_png(s,"o");}

```

$ cc \`pkg-config cairo --libs --cflags\` mini.c && ./a.out && display o

Here is the un-minified version:

```
#include <cairo/cairo.h>
void main (int argc, char* argv[])
{
    cairo_t *cr;
    cairo_surface_t *surf;
    surf = cairo_image_surface_create (0, 99, 50);
    cr = cairo_create (surf);
    cairo_move_to (cr, 0, 9);
    cairo_show_text (cr, "Hello world!");
    cairo_surface_write_to_png (surf, "out.png");
}

```

Best enjoyed while listening to this song :)
> 9 votes

# Answer
# Javascript! ~~105~~ ~~104~~ 101

```
c=document.createElement('canvas');open(c.toDataURL(c.getContext('2d').fillText('Hello world!',0,9)))

```

Outputs this size-optimized and pretty image:
> 9 votes

# Answer
> make a PNG image that ***says*** "Hello world!" …

You'll hopefully excuse my very loose interpretation of the above requirement. :)

### OSX bash:

```
printf '"Hello world!" and nothing else on a distinguishable background using only an image making API (eg ImageMagick) and return the image.' > hello.png
say -f hello.png

```
> 9 votes

# Answer
## TI-BASIC, 22

```
Text(0,0,"HELLO WORLD!

```

White background. Use TI-Connect if you wish to retrieve it from the calculator. Resulting PNG:
> 8 votes

# Answer
## Ruby, 138

I'm golfing this hole with just my putter. (I chose a PNG library without fonts or a string draw method.)

```
require'chunky_png';i=ChunkyPNG::Image.new 34,4
136.times{|v|i[*(v.divmod(4))]=9*(0xb0fae0f02e0eae0ece00eae0f0f0bf0f2f&1<<v)>>v};i.save ?h

```

Actual output is 34x4 pixels. (Enlarged below.) This plots very, *very* small and *nearly* transparent hand-drawn chars onto a very small transparent background. Image is saved to a PNG file named `h`.
> 8 votes

# Answer
# BASH + RST + ImageMagick = 43 chars

Just for fun, here's another (quite ugly) one:

```
echo 'Hello World!'|rst2pdf|convert - a.png

```

Output:
> 8 votes

# Answer
**Gnuplot**

Not really a true competitor, just for fun. (homepage)

```
#!/usr/bin/gnuplot
set terminal pngcairo
set output "hw.png"
set label "Hello\nWorld!"
unset xtics
unset ytics
set yrange [-1:+1]
plot -1 notitle

```

or, as a oneliner (thanks to Phil H): 74 characters

```
se te pngc;se ou "q.png";se la "Hello world!";se yr[-1:1];uns ti;pl -1 not

```
> 6 votes

# Answer
## **Perl, 95:**

The whole command incantation:

```
perl -MGD::Simple -e'$i=new GD::Simple;moveTo$i 9,50;string$i "Hello world!";print$i->png'>.png

```

Because of (reasonable) module defaults, it's **95** characters (or **92** if single letter file name allowed).

On Windows we need to `binmode STDOUT`, the shortest way I think can be `-M-encoding`\+ get rid of double colons:

```
perl -MGD'Simple -M-encoding -e"$i=new GD'Simple;moveTo$i 9,50;string$i 'Hello world!';print$i->png">.png

```

i.e. **105**
> 5 votes

# Answer
## Data URI: 446

Following Chloe's idea, applied some basic optimisation to the image.

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEEAAAALCAAAAAAFX7+TAAABBUlEQVQoz2P4Tylg+M8IohiRRUCIkC6E0sFlwhFBJo5kmPAdWSYmuTsgGa6y/3pMf/8yLYEJMcQwARXckmZi8YCawAAG//8L537ZxbEMaoKCwuvXCkogE2y0/nMyL1vC/BcmxKC6AqhAXurBc1kGkNUINzCBDIqFmsB84f//c8wgmcVs91j13d3U4EIMl0AKmM78/38GqJQXyQSWQ///H3sJMwGo7ALYhL/MQUq1wkK1cCEGsE+ZgSacAzKNkUxQ1/kygfEczBeKb18rKICDS4U58SUT8ye4EMQEBelHz+WAzEokE+6IM7HkI4ekLDgk/5cxnPrPK/4fLgQxARSSUdCQpBQAAFZKE8rQG60FAAAAAElFTkSuQmCC

Might be able to hack it further, but then would not be a perfectly conformant PNG and some viewers may not display it correctly.
> 5 votes

# Answer
## Python and Matplotlib - 66 65 chars

```
from pylab import*;title('Hello world!');axis('off');savefig('X')

```

Bit of whitespace, but it has the text and nothing else. File is saved as `X.png`:
> 5 votes

# Answer
# Python with PIL 122 Chars

```
from PIL import Image,ImageDraw;d=Image.new("RGB",(70,9));i=ImageDraw.Draw(d);i.text((0,0),"Hello World!");d.save("a.png")

```

It could probably be much smaller but I haven't worked with PIL extensively and made this in 5 minutes.

Output:
> 4 votes

# Answer
## Ghostscript command line incantation, 84 (i.e. Postscript) :

```
 gs -sDEVICE=png16 -oa.png -c '/ 72 selectfont 9 9 moveto(Hello world!)show showpage'

```

Missing font message is intentional ;-). And proper (i.e. not hidden) name for our PNG file, too :-)
> 4 votes

# Answer
# Python, with ~~118~~ ~~115~~ ~~117~~ ~~116~~ 114 chars

Here's a full criteria passing with white text on alpha background at ~~116~~ 114 chars!:

```
from PIL import Image,ImageDraw as D
m=Image.new("LA",(99,9))
D.Draw(m).text((9,0),'Hello World!')
m.save('r.png')

```

(You can replace newlines with semicolons - count is the same regardless.)
> 3 votes

# Answer
# Bash + DOT, ~~46~~ 41

```
dot -Tpng<<<'graph{label="Hello World!"}'

```

This outputs a png into the standard output. It is saving a file, but I don't think that was a requirement.

Outout:
> 3 votes

# Answer
# PureBasic - 128 chars

```
UsePNGImageEncoder()
CreateImage(0,99,24)
StartDrawing(ImageOutput(0))
DrawText(0,0,"Hello World!")
SaveImage(0,"a.png",4673104)

```

Not the shortest here, but I have to support my favorite Basic language :)

edit: just in case there is a complain about the black background, at 133 chars:

```
UsePNGImageEncoder()
CreateImage(0,80,16)
StartDrawing(ImageOutput(0))
DrawText(0,0,"Hello World!",0,-1)
SaveImage(0,"a.png",4673104)

```
> 2 votes

# Answer
# Rebol/View 45

```
save/png %i to-image layout[h1"Hello World!"]

```

writes a png image file named i into current directory
> 2 votes

# Answer
## bash + netpbm: 31 chars

```
pbmtext "Hello world!"|pnmtopng

```

Will make:
> 2 votes

# Answer
# Internet 11

Internet is an API!

ow.ly/thgUJ -\> http://dummyimage.com/99x9/f/0.png&text=Hello+world!
> 2 votes

# Answer
## Matlab: 47 characters

I'm not sure what exactly an Image making API is. This uses a figure/graph making API, which is arguably an image.

```
text(1,1,'Hello World!');axis off;print -dpng f
```
> 1 votes

# Answer
## EPL, 28

```
0,0,0,1,1,1,N,"Hello World!"

```
> 1 votes

# Answer
Chloe used a Base64 encoded approach with 1494 characters, however you can easily reduce the size:

# Anchor link - 166 chars

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD8AAAAFAQAAAADaxQm5AAAAM0lEQVQIW2Mo0a+w3iKQz8NQ+r56r+71/BIGlnwg40J+GUhkz9lr78sYShQ57O6IKfIAAJypEkNzAX3zAAAAAElFTkSuQmCC

Paste this into your browser
> 1 votes

# Answer
## Bash, using Google's chart API: 92 characters

```
curl http://chart.googleapis.com/chart?chst=d_text_outline&chld=|9|h|||Hello+world! > h.png

```

## Further optimization: 33 characters

```
curl http://goo.gl/a8ntA4 > h.png

```
> 1 votes

# Answer
# MATLAB, 41 chars

@gerrit posted a MATLAB solution as well, but since I don't have enough rep to comment, I'll post mine too. (The output is the same as his, so I don't want to take up more space with the resulting PNG).

```
axis off,title 'Hello world!',print -dpng

```
> 1 votes

# Answer
# Groovy, 133

Not going to win any points for size here as it's just an abbreviated Java.

No color setting:

```
i=new java.awt.image.BufferedImage(75,30,2);i.graphics.drawString('Hello World',5,20);javax.imageio.ImageIO.write(i,'PNG',System.out)

```

With setting color (164):

```
i=new java.awt.image.BufferedImage(75,30,2);g=i.graphics;g.color=java.awt.Color.RED;g.drawString('Hello World',5,20);javax.imageio.ImageIO.write(i,'PNG',System.out)

```

### Formatted:

```
i = new java.awt.image.BufferedImage(75,30,2)
g = i.graphics
g.color = java.awt.Color.RED
g.drawString('Hello World',5,20)
javax.imageio.ImageIO.write(i,'PNG',System.out)

```
> 1 votes

# Answer
Here is a cool trick, only 37 chars: placehold.it/png/99&text=Hello+world! (+7 chars for the protocol).

This generates a 239 bytes long png image with 99px of width and height.

I know it's not programming, but this is a website that generates placeholder images.

You should visit http://placehold.it.
> 1 votes

# Answer
**Groovy, 151 (or 202 with a black text)**

a rewrite of the proposed Java version. Resulting image is with white text on a transparent background. Add 50 chars to have black text !

```
import java.awt.image.BufferedImage as B
B b=new B(80,9,2)
b.graphics.drawString("Hello world!",5,9)
javax.imageio.ImageIO.write(b,"png",new File("p"))

```

The version with black text:

```
import java.awt.*
import java.awt.image.BufferedImage as B
B b=new B(80,9,2)
b.graphics.with {setColor(new Color(0)); drawString("Hello world!",5,9); }
javax.imageio.ImageIO.write(b,"png",new File("p"))

```
> 0 votes

# Answer
# Ruby 192 chars:

I use `RMagick` `RVG (Ruby Vector Graphics)`.

```
require 'rvg/rvg';include Magick;RVG::dpi = 72;RVG.new(1.5.in, 1.5.in){|canvas|canvas.background_fill = '#C0C0C0';canvas.text(10, 100){|title|;title.tspan("Hello World!")}}.draw.write('hw.png')

```

output:
> 0 votes

# Answer
# Shell + Graphviz (55)

```
echo 'graph{a[label="Hello World!"]}'|dot -Tpng>h.png

```
> 0 votes

# Answer
# Mouse: 0 chars

"right click" \> "save image as"

Result:
> -1 votes

---
Tags: code-golf, graphical-output, hello-world
---


title: Animated sound waveform

text:
# Question
Title: Animated sound waveform
Make an animated sound waveform using any programming language your prefer, the squares of the spectrum can be of a single color (no rainbow effect).
The animation must be infinite and not a loop sequence (must be a random animation).

You can use any kind of external library you prefer.

This is a code-golf so the shortest code will win.

Example of waveform:

(a screenshot of the result is appreciated)

Edit: I thought was obvious,but the waveform must be horizontal.

# Answer
## APL (61)

```
{∇n⊣⎕DL.1⊣⎕SM←1 1,⍨⊂' '⍪⊖⍉↑⍴∘'▇'¨,0,⍪n←24⌊0⌈⍵+3-?5/⍨⍴⍵}?24/40

```

It starts with random-sized bars, and changes the height of each of the bars by a random number between -2 and 2 each frame.

Screenshot:
> 3 votes

# Answer
# Ruby 96

The program takes two arguments which are the height and width of the "graphics", so to make it fill a 80x24 terminal, run it with `ruby spectrum.rb 80 24`

```
w,h=$*.map &:to_i
loop{o=(1..w).map{rand h}
h.times{|i|puts o.map{|j|j>i ?" ":?#}*''}
sleep 0.1}

```

Displays something like this in the terminal:

```
       #
       #
     ###  #
  #  ###  #
  ## ###  ##
  ## #### ##
 ######## ##
######### ##       #
######### ##      ##
######### ##      ##
######### ##   #####
#############  #####
#############  #####
####################

```

# Ruby 22

With horizontal bars and fixed width (heigh = height of terminal)

```
loop{puts ?#*rand(24)}

```
> 1 votes

# Answer
# Bash and Linux utils, 79

The question specifications are a little imprecise, so here is my vertically-scrolling ascii-art interpretation that uses real sound input samples (much more interesting than random data)

```
arecord -q|xxd -g1 -c1|while read _ s _;do printf "%$[0x$s-88]s
"|tr " " =;done

```

Output for a few milliseconds of Rachmaninov's Piano Concerto #2:

```
=========================================
======================================
=======================================
===========================================
========================================
======================================
========================================
=========================================
========================================
======================================
========================================
==========================================
========================================
======================================
=========================================
=========================================

```
> 1 votes

# Answer
## Batch - 193

```
@echo off&setLocal enableDelayedExpansion
:s
set/ar=%RANDOM%*17/32768+4&for /l %%a in (20,-1,1)do (if %%a GEQ %r% (set l%%a= !l%%a!) else set l%%a=Û!l%%a!)&echo !l%%a!
ping 1>nul&cls&@goto s

```

Un-golfed -

```
@echo off
setLocal enableDelayedExpansion
:s
set /a r=%RANDOM%*17/32768+4
for /l %%a in (20,-1,1) do (
    if %%a GEQ %r% (set l%%a= !l%%a!) else set l%%a=Û!l%%a!
) & echo !l%%a!
ping 1>nul
cls
goto s

```

This will work assuming you have an infinitely wide terminal window - I'll work on the text wrapping...

Not the prettiest - but it does the trick - **295 bytes**

```
@echo off&setLocal enableDelayedExpansion
for /f "tokens=2" %%w in ('mode con^|findstr Col')do set w=%%w
:s
mode con:cols=%w% lines=20
set/ar=%RANDOM%*17/32768+4&for /l %%a in (20,-1,1)do (if %%a GEQ %r% (set l%%a= !l%%a!) else set l%%a=Û!l%%a!)&echo !l%%a!
set/aw+=1&ping 1>nul&cls&@goto s

```
> 0 votes

# Answer
# Mathematica 105

This animates continually, at approximately 24 frames per second, as if it were capturing sound in real-time. However, it is not processing sound at all. (That would would require considerably more code.)

```
data1@n_ := NormalDistribution[0, 1]~RandomVariate~150;
Animate[Histogram[data1@a, Axes -> False], {a, 0, Infinity}]

```
> 0 votes

# Answer
# Matlab (43 / 37)

```
while(1)hist(randn(100,1));pause(1/24);end

```

Inspired by the Mathematica approach, this is just a histogram of 100 random, normally distributed numbers. the plot regenerates at 1/24 second per frame (24 fps).

Shorter, Stranger version (37):

```
while(1)bar(randn(9,1));pause(.1);end

```

This version includes negative numbers, so it doesn't exactly fit the requirements.
> 0 votes

---
Tags: code-golf
---


title: Stopwatch for Alphabets

text:
# Question
Title: Stopwatch for Alphabets
Implement Stopwatch for typing Alphabets

**Alphabets** = "a b c d e f g h i j k l m n o p q r s t u v w x y z".

**Note**

* The program should run infinitely and should stop only when **Esc** button is pressed.
* The stopwatch starts with keystroke "a" and ends with keystroke "z"
* Output is the time taken to type the **Alphabets** correctly (ie. time take for **51 keystrokes**)
* If an illegal character occurs then stopwatch should stop and print **"Failed"**
* If a new record is set then print "**!!New record!!," TimeTaken**

where, **TimeTaken** = time taken to print alphabets correctly.

**Winner:** One with the shortest code.

# Answer
Mathematica, 303

Here with white-space and expanded symbols. Everything happens in the `Switch` statement of the `EventHandler` where I pattern match `{pressed key, next letter}`.

Might want to replace the `Quit` with something less sinister before hitting escape:

```
z := AbsoluteTime[];
f = "a"; y = Dynamic;
DynamicModule[{
  a = f~CharacterRange~"z", c = 1, d = f, r = \[Infinity]},
 EventHandler[
  y@d~InputField~String,
  "KeyDown" :> Switch[
    {CurrentValue@"EventKey", a[[c]]},
    {f ..},
      t = z; c++; d = y@a[[c]],
    {"z" ..},
      t = z - t;
      d = If[t < r,
         r = t; "!!New record!!,",
         ""] ~~ ToString@t;
      c = 1,
    {a_, a_},
      c++,
    {"\[RawEscape]", _}, Quit[],
    _, d = "Failed"; c = 1]]]

```
> 4 votes

# Answer
## C, 181

Note that in order for this to work, your terminal must be setup to not buffer characters. One possible linux solution is here. Should this be considered part of my code?

```
double t,c,r=2<<29;main(l){for(;l<27&&96+l++==(c=getchar());)l==2&&time(&t);if(c==27)return;t=difftime(time(),t);l-27?puts("Failed"):t<r&&printf("!!New record!! %f\n",r=t);main(1);}

```
> 4 votes

# Answer
## Perl, 182

```
use Term::ReadKey;ReadMode 3;@a=a..z;while(1){$c=getc;$s=time if!$i;last if$c eq"\e";if($c ne$a[$i++]){print"Failed";last}if($i==@a){print"!!New record!!,",(time-$s);last}}ReadMode 0

```

There's probably room for improvement. I could also remove the `ReadMode 0` from the end, saving 10 chars. In addition, it's not clear to me if the use of `Term::ReadKey` is OK or not for the Code Golf. If it's not, then I don't think that this particular golf can be solved with Perl.

Same program written properly and in a readable fashion:

```
use warnings;
use strict;
use Term::ReadKey;
use Time::HiRes qw(time);
ReadMode 3;
my @a=('a'..'z');
my $i=0;
my $s;
while (1) {
    my $c=ReadKey(0);
    $s=time if !$i;
    last if $c eq "\e";
    if ($c ne $a[$i++]) {
        print "Failed";
        last;
    }
    if ($i==@a) {
        print "!!New record!!,",(time-$s);
        last;
    }
}
ReadMode 0;

```
> 2 votes

---
Tags: code-golf, game
---


title: Partition of Array

text:
# Question
Title: Partition of Array
Given an integer array. You have to check whether it is possible to divide the array in two parts such that the sum of elements of one part is equal to the sum of the element of the other part.If it is possible print "YES" otherwise "NO".

**Sample Input**

```
4 3 5 5 3

```

**Sample Output**

```
YES

```

**Explanation**

```
Array can be divided in two parts {4,3,3} and {5,5}

```

**Sample Input**

```
1 3

```

**Sample Output**

```
NO

```

**Sample Input**

```
5 5

```

**Sample Output**

```
YES

```

# Answer
> 4 votes
# Ruby 98

```
f=->a{s=a.inject :+;(1..a.count).any?{|i|a.combination(i).any?{|r|r.inject(:+)*2==s}}?'Yes':'No'}

```

# Answer
> 4 votes
# Prolog

Without proper output (**92** chars)

```
s(A):-s(A,0,0).
s([],B,B).
s([H|T],B,C):-D is B+H,s(T,D,C).
s([H|T],B,C):-D is C+H,s(T,B,D).

```

With proper output (**121** chars)

```
s(A):-(s(A,0,0),print('YES'),!;print('NO')).
s([],B,B).
s([H|T],B,C):-D is B+H,s(T,D,C).
s([H|T],B,C):-D is C+H,s(T,B,D).

```

To query the rules:

```
s([4,3,5,5,3])
s([1,3])

```

# Answer
> 3 votes
# Ruby with ActiveSupport 74

```
p (1..a.size).any?{|b|a.combination(b).any?{|c|c.sum*2==a.sum}}?'YES':'NO'

```

# Ruby 88

```
p (1..a.size).any?{|b|a.combination(b).any?{|c|c.reduce(:+)*2==a.reduce(:+)}}?'YES':'NO'

```

# Answer
> 2 votes
# Mathematica 59

With spaces for readability,

```
f@a_ := If[Select[Subsets@a, Tr@# == Tr@a/2 &] == {}, "NO\n", "YES\n"]

```

**The Logic**

If there exists no subset of the input integer array, `a`, having, as its total, one-half of the total of `a`, then NO. Else, YES.

---

**Examples**

```
f[{4, 3, 5, 5, 3}]

```

> YES

---

```
f[{4, 3, 5}]

```

> NO

# Answer
> 2 votes
# Haskell - 113 (30 chars for imports)

```
import Control.Monad(filterM)
f x|t="YES"
 |1>0="NO"where t=or$map(==(sum x)/2)$map(sum)$filterM(\_->[0>1,1>0])x

```

Query by calling f on a list:

```
*Main> f [4,3,5,5,3]
"YES"
*Main> f [1,3]
"NO"
*Main> f [5,5]
"YES"

```

This is my first attempt at golfing in Haskell, if anyone has any tips for shortening my code they are welcomed.

# Answer
> 1 votes
## MATLAB ~~75~~ 64

Quite happy with this. Too bad the function names are so much characters.

```
@(x)['NO '+[11,-10,51]*ismember(sum(x)/2,cumsum(perms(x),2)) '']

```

# Answer
> 1 votes
# Javascript

Only works in browsers with ECMAScript 6 support (Firefox works). Defines a function that can be called with a list of integers, the target sum value, and the length of the list.

## 53 characters (sans formatting and specific criteria)

```
q=(l,s,i)=>--i>=0&&(q(l,s,i)||l[i]==s||q(l,s-l[i],i))

```

This will work with both positive and negative floating point numbers as well, not just integers. It can also find whether the list at any point can sum to any arbitrary sum, which is much more general than the problem requires.

## 106 Characters (with formatting and starting criteria)

```
q=(l,i,s)=>--i>=0&&(q(l,i,s)||l[i]==s||q(l,i,s-l[i]));f=l=>q(l,l.length,l.reduce((a,b)=>a+b)/2)?'YES':'NO'

```

Fully half of the code here is just boilerplate required to limit the solution to this specific case, and format the output according to the criteria.

A non recursive solution that builds the table from the bottom is more efficient but also takes more characters.

# Answer
> 1 votes
## GolfScript ~~64~~ 47

```
~:x[[]]{{+}+1$%+}@/(;{{+}*2*x{+}*=},'YES''NO'if

```

Explanation: Find a subset (using this subset method) whose sum is exactly half of the total sum of the input.

Previous solution:

```
~].,.))2?,{2base}%\{\,=}+,\`{]zip{~\2*(*}%}+%{{+}*!},'YES''NO'if

```

Explanation: This uses `base` to count and find every possible array of length `n` comprised of only `1`s and `0`s. Then it uses this array to negate or do nothing to elements of the initial array. For example, for input `[1 2 3]`, we would have `[1 2 3][1 2 -3][1 -2 3][1 -2 -3][-1 2 3][-1 2 -3][-1 -2 3][-1 -2 -3]`. The program then returns 'YES' if and only if the sum of the elements of any of these arrays is 0. Negating some subset of the array, then adding all the elements and checking if it equals 0 is clearly equivalent to checking for a 2-part partition.

I'm sure this implementation can be improved upon, but I think the idea is there.

# Answer
> 1 votes
### GolfScript, 34 characters

```
~]1,\{2*{1$+}+%}/)2/?)!"YES
NO"n/=

```

The code basically calculates the totals of all possible subsets and then searches for (half of) the overall total in this list. (Actualy the code calculates doubles all the subset sums and searches for the list's total in order to not conflict with integer division.) You can see the example running online.

```
> 4 3 5 5 3
YES

> 4 5 5 5 3
NO

```

# Answer
> 0 votes
# C++ — ~~294~~ 275

Not very compact, but you don't often see C++ in code challenges!

### Features

* can get NO result in O(1) time for many inputs
* uses no external algorithms for generating subsets, all in code
* C++ was used for easy vector creation

### Code

```
#include <iostream>
#include <vector>
using namespace std;int main(){vector<int>v;int s,e,w,g,t;for(s=0;cin>>e;s+=e)v.push_back(e);if(!(s&1)){s/=2;w=v.size();for(e=0;e<1<<w;e++){for(g=0,t=0;g<w;g++)if(e&1<<g)t+=v[g];if(t==s){cout<<"YES\n";return 0;}}}cout<<"NO\n";return 1;}

```

### To compile

```
g++ -o partition partition.cpp

```

### Examples

```
$ echo 4 3 5 5 3 | ./partition
YES

$ echo {1..28} | ./partition
YES # after a slight delay

$ echo 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 29 | ./partition
NO # after a long delay

$ echo {1..29} | ./partition
NO # immediately

```

### Limitations

* upper limit is 29 elements, could use `unsigned long long int` to extend to 61 or 62 elements, but the basic idea is the same

# Answer
> 0 votes
## C#, 169 bytes

It enumerates through a series of arrays of the same length as the input. Each array contains a list of +1 and -1 values which are multiplied against each corresponding input value. If the sum of the multiplied arrays is zero, then some numbers sum to the same as the rest of the numbers.

For the sake of golfing the +1/-1 array is actually +2/0 and 1 subtracted from it when used.

Example:

```
input    = n = {  4,  3,  5,  5,  3 }
polarity = p = { +1, +1, -1, -1, +1 }
n*p      =     { +4, +3, -5, -5, +3 }
result   = x = Sum(n*p) == 0

```

Code:

```
bool S(int[]n){
    int i=0,l=n.Length,s;
    var x=false;
    var p=new int[l+1];
    while(i>=0){
        s=0;
        for(i=l;i-->0;)
            s+=n[i]*(p[i]-1);
        x|=s==0;
        for(i=l;p[i]<1&&i-->0;)
            p[i]=2-p[i];
    }
    return x;
}

```

Test:

```
Console.WriteLine(S(new[]{4,3,5,5,3}));
True

Console.WriteLine(S(new[]{1,3}));
False

Console.WriteLine(S(new[]{2}));
False

Console.WriteLine(S(new[]{0}));
True
// Presuming Sum{0} == Sum{}

```

---
Tags: code-golf
---