title: Generate Realistic Maps

text:
# Question
Title: Generate Realistic Maps
I drew this map of the regions of an imaginary word in a few minutes in MS Paint:

I think that being able to generate maps like this programmatically would be really cool.

# Challenge

Write a program that takes in positive integers `W` and `H`, and a non-empty set of positive integers `S`.

Generate a standard true color image that is `W` pixels wide by `H` pixels tall.

For each integer `i` in `S`, draw a planar region in the image whose area in pixels is proportional to `i`, using a color different from any neighboring regions. Specifically, the number of pixels in the region should be `W * H * i / sum(S)`, rounded either up or down to **ensure that every pixel in the image belongs to a region**.

A planar region is a set of pixels with the property that any pixel in the region can be reached from any other by staying within the region and only moving orthogonally (and not diagonally). My map above has 10 planar regions.

All the pixels in a planar region must be the same color, which must be different than the color of any neighboring regions. Regions may be the same color if they are not neighbors.

Otherwise, there are no limitations on how you shape, position, or color your regions. This is a popularity-contest. The goal is to create a program that makes realistic maps of imaginary worlds, physical or political, with any geography, at any scale.

Naturally, please show off your best output images, not just your code.

# Details

* Take input from file, command line, stdin, or similar. Save the image in any standard format or display it to the screen.
* Your program should be deterministic for identical inputs. That is, the output image should always be the same for some particular `H`, `W`, and `S`. (Note that **`S` is a set**, not a list, so its ordering doesn't matter.) Otherwise you may employ randomness where desired, though you are not required to (but I highly suggest it).
* The output image geography does not need to "scale" for different values of `W` or `H` (though it could). It may be completely different.
* You may randomly assign colors, disregarding the neighbor-color rule, as long as there at least 32 random color possibilities, since it would be unlikely for two neighbors to get colored the same.
* The regions stop at the image boundaries. There is no wrap around.
* Regions may contain zero pixels (and thus be nonexistent), as would be the case when there are more regions than pixels.

# Example Input

A valid submission might have generated my map above with the parameters:

```
W = 380
H = 260
S = {233, 420, 1300, 3511, 4772, 5089, 9507, 22107, 25117, 26744}

```

These `S` values are the exact same as the number of pixels in each region but that need not be the case. Remember that `S` is a set, so it is not necessarily always sorted.

# Answer
I agree with the others, This was a surprisingly difficult challenge. Partially due to the requirement to have adjacently connected pixels of the same region type, but also due to the aesthetic challenge to make the regions look like a map of countries.

Here is my attempt... it is horribly inefficient but seems to produce reasonable output. Continuing the trend of using common input for comparison purposes:

**Parameters : 380 260 233 420 1300 3511 4772 5089 9507 22107 25117 26744**

**Parameters : 380 260 8 5 6 7 8 4 5 6 7 9 4 6 9 5 8 7 5**

**Dark Age of Camelot 213 307 1 1 1**

**My larger example: (640 480 6 1 7 2 9 3 4 5 6 1 9 8 7 44 3 1 9 4 5 6 7 2 3 4 9 3 4 5 9 8 7 5 6 1 2 1 2 1 2 6 7 8 9 63 3)**

**An example with more countries: 640 480 6 1 7 2 9 3 4 5 6 1 9 8 7 44 3 1 9 4 5 6 7 2 3 4 9 3 4 5 9 8 7 5 6 1 2 1 2 1 2 6 7 8 9 63 5 33 11 88 2 7 9 5 6 2 5 7**

```
package GenerateRealisticMaps;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import javax.imageio.ImageIO;

public class GenerateRealisticMaps
{
    private static final Random rand = new Random(3);
    private static final Color[] paletteizedColours = new Color[100];

    // create colour palette
    static
    {
        paletteizedColours[0] = new Color(0xFF000000);
        for (int i = 1; i < paletteizedColours.length; i++)
        {
            paletteizedColours[i] = Color.getHSBColor(rand.nextFloat(), rand.nextFloat(), 0.5f + rand.nextFloat() * 0.4f);
        }
    }

    /**
     * Represents a pixel that is the boundary of a region
     * @author default
     *
     */
    public static class BoundaryPixel
    {
        public BoundaryPixel(int x, int y, int otherRegionId)
        {
            super();
            this.x = x;
            this.y = y;
            this.otherRegionId = otherRegionId;
        }

        int x;
        int y;
        int otherRegionId;
    }

    /**
     * Group of adjacent pixels that represent a region (i.e. a country in the map)
     * @author default
     *
     */
    public static class Region
    {
        static private int masterId = 0;

        Region(int desiredSize)
        {
            this.desiredSize = desiredSize;
            id = ++masterId;
        }

        int desiredSize;
        int size = 0;
        int id;
        List<BoundaryPixel> boundary = new ArrayList<GenerateRealisticMaps.BoundaryPixel>();

    }

    /**
     * Container of regions
     * @author default
     *
     */
    public static class Regions
    {
        List<Region> regionList = new ArrayList<GenerateRealisticMaps.Region>();
        Map<Integer, Region> regionMap = new HashMap<Integer, GenerateRealisticMaps.Region>();
    }

    public static void main(String[] args) throws IOException
    {
        int width = Integer.parseInt(args[0]);
        int height = Integer.parseInt(args[1]);
        int[] s = new int[args.length - 2];

        // read in the region weights
        int sum = 0;
        for (int i = 0; i < args.length - 2; i++)
        {
            sum += s[i] = Integer.parseInt(args[i + 2]);
        }

        int totalPixels = width * height;

        double multiplier = ((double) totalPixels) / sum;

        // convert region weights to pixel counts
        int runningCount = 0;
        for (int i = 0; i < s.length - 1; i++)
        {
            runningCount += s[i] = (int) (multiplier * s[i]);
        }
        s[s.length - 1] = totalPixels - runningCount;

        Regions regions = new Regions();
        int[][] map = new int[width][height];

        // initialise region starting pixels
        for (int v : s)
        {
            Region region = new Region(v);
            regions.regionList.add(region);
            regions.regionMap.put(region.id, region);

            int x;
            int y;
            do
            {
                x = rand.nextInt(width);
                y = rand.nextInt(height);
            } while (map[x][y] != 0);

            map[x][y] = region.id;
            region.size++;

        }

        // initialise a "height" map that provides cost to claim a unclaimed region. This allows for more natural shaped countries
        int[][] heightMap = new int[width][height];
        for (int i = 0; i < width; i++)
        {
            for (int j = 0; j < height; j++)
            {
                heightMap[i][j] = rand.nextInt(50);
            }
        }

        boolean equal = false;

        // main loop
        do
        {
            growRegions(map, heightMap, width, height, regions);

            // determine whether regions have reached their desired size
            equal = true;
            for (Region region : regions.regionList)
            {
                equal = equal && region.size == region.desiredSize;
            }

            if (equal)
            {
                HashMap<Integer, Set<Integer>> commonIsolatedRegions = new HashMap<Integer, Set<Integer>>();
                int isolatedRegionId = 0;
                int[][] isolatedRegions = new int[width][height];
                List<Integer> isolatedRegionSize = new ArrayList<Integer>();
                isolatedRegionSize.add(-1); // add dummy entry at index 0 since region ids start at 1

                // go though each pixel and attempt to identify an isolated region from that point if it as not
                // yet been identified... i.e. an enclosed area.
                for (int i = 0; i < width; i++)
                {
                    for (int j = 0; j < height; j++)
                    {
                        if (isolatedRegions[i][j] == 0)
                        {
                            isolatedRegionId++;

                            Point point = new Point(i, j);
                            int size = identifyEnclosedArea(map, isolatedRegions, width, height, point, isolatedRegionId);

                            // add this isolated region id to the group of isolated regions associated with the region at this pixel
                            Set<Integer> isolatedRegionSet = commonIsolatedRegions.get(map[i][j]);
                            if (isolatedRegionSet == null)
                            {
                                isolatedRegionSet = new HashSet<Integer>();
                                commonIsolatedRegions.put(map[i][j], isolatedRegionSet);
                            }
                            isolatedRegionSet.add(isolatedRegionId);
                            isolatedRegionSize.add(size);
                        }
                    }
                }

                // only keep the largest isolated region in each group. Mark the other members in the group areas as unclaimed.
                for (Region region : regions.regionList)
                {
                    Set<Integer> isolatedRegionSet = commonIsolatedRegions.get(region.id);

                    // find the largest isolatedRegion mapped to this region
                    int largestIsolatedRegionId = -1;
                    int largestIsolatedRegionSize = -1;
                    for (Integer isolatedRegionIdentifier : isolatedRegionSet)
                    {
                        if (isolatedRegionSize.get(isolatedRegionIdentifier) > largestIsolatedRegionSize)
                        {
                            largestIsolatedRegionSize = isolatedRegionSize.get(isolatedRegionIdentifier);
                            largestIsolatedRegionId = isolatedRegionIdentifier;
                        }
                    }
                    // remove the largest isolated region (i.e. retain those pixels)
                    isolatedRegionSet.remove(largestIsolatedRegionId);

                    if (isolatedRegionSet.size() > 0)
                    {
                        equal = false;

                        // for all remaining isolated regions mapped to this region, convert to unclaimed areas.
                        for (Integer isolatedRegionIdentifier : isolatedRegionSet)
                        {
                            for (int i = 0; i < width; i++)
                            {
                                for (int j = 0; j < height; j++)
                                {
                                    if (isolatedRegions[i][j] == isolatedRegionIdentifier)
                                        map[i][j] = 0;
                                }
                            }
                        }
                    }
                }
            }

        } while (!equal);

        saveOutputImage("out.final.png", map);
    }

    /**
     * Renders and saves the output image
     *
     * @param filename
     * @param map
     * @throws IOException
     */
    public static void saveOutputImage(String filename, int[][] map) throws IOException
    {

        final int scale = 1;
        final int width = map.length;
        final int height = map[0].length;
        BufferedImage image = new BufferedImage(width * scale, height * scale, BufferedImage.TYPE_INT_RGB);

        Graphics2D g = (Graphics2D) image.getGraphics();

        for (int j = 0; j < height; j++)
        {
            for (int i = 0; i < width; i++)
            {
                g.setColor(paletteizedColours[map[i][j]]);
                g.fillRect(i * scale, j * scale, scale, scale);
            }
        }

        ImageIO.write(image, "png", new File(filename));
    }

    /**
     * Grows the regions of the world. Firstly by unclaimed cells and then by distributing cells amongst the regions.
     *
     * @param map
     *            cell to region map
     * @param heightMap
     *            the "height" cost of unclaimed cells. Used to give more natural shapes.
     * @param width
     * @param height
     * @param regions
     */
    public static void growRegions(int[][] map, int[][] heightMap, int width, int height, Regions regions)
    {
        // reset region sizes
        for (Region region : regions.regionList)
        {
            region.size = 0;
            region.boundary.clear();
        }

        // populate corners with adjacent pixel region id... these pixels cannot ever be "grown" into.
        map[0][0] = map[1][0];
        map[width - 1][0] = map[width - 1][5];
        map[width - 1][height - 1] = map[width - 2][height - 1];
        map[0][height - 1] = map[1][height - 1];

        int i, x, y, dx = 0, dy = 0, currHeight, currentId = -1, pixelRegionId;
        Region currRegion = null;
        ;

        // calculate initial region sizes
        for (y = 0; y < height; y++)
        {
            for (x = 0; x < width; x++)
            {
                if (map[x][y] > 0)
                    regions.regionMap.get(map[x][y]).size++;
            }
        }

        // expand regions into surrounding unclaimed pixels.
        // construct a list of region boundary pixels in the process.
        for (y = 1; y < height - 1; y++)
        {
            for (x = 1; x < width - 1; x++)
            {
                int cellId = map[x][y];
                if (cellId > 0)
                {
                    if (cellId != currentId)
                    {

                        currRegion = regions.regionMap.get(map[x][y]);
                        currentId = currRegion.id;
                    }

                    currHeight = heightMap[x][y]++;

                    for (i = 0; i < 4; i++)
                    {
                        switch (i)
                        {
                        case 0:
                            dx = x - 1;
                            dy = y;
                            break;
                        case 1:
                            dx = x + 1;
                            dy = y;
                            break;
                        case 2:
                            dx = x;
                            dy = y - 1;
                            break;
                        case 3:
                            dx = x;
                            dy = y + 1;
                            break;
                        }
                        pixelRegionId = map[dx][dy];
                        switch (pixelRegionId)
                        {
                        // unclaimed cell...
                        case 0:
                            if (heightMap[dx][dy] < currHeight)
                            {
                                map[dx][dy] = currRegion.id;
                                currRegion.size++;
                            }
                            break;
                        // claimed cell...
                        default:
                            if (pixelRegionId != currRegion.id)
                            {
                                currRegion.boundary.add(new BoundaryPixel(dx, dy, pixelRegionId));
                            }
                            break;
                        }
                    }
                }
            }
        }

        HashMap<Integer, List<BoundaryPixel>> neighbourBorders = new HashMap<Integer, List<BoundaryPixel>>();

        // for all regions...
        for (Region region : regions.regionList)
        {
            // that are less than the desired size...
            if (region.size < region.desiredSize)
            {
                neighbourBorders.clear();

                // identify the boundary segment per neighbour of the region
                for (BoundaryPixel boundaryPixel : region.boundary)
                {
                    List<BoundaryPixel> neighbourBorderSegment = neighbourBorders.get(boundaryPixel.otherRegionId);
                    if (neighbourBorderSegment == null)
                    {
                        neighbourBorderSegment = new ArrayList<GenerateRealisticMaps.BoundaryPixel>();
                        neighbourBorders.put(boundaryPixel.otherRegionId, neighbourBorderSegment);
                    }
                    neighbourBorderSegment.add(boundaryPixel);
                }

                out:
                // for each neighbour...
                for (int id : neighbourBorders.keySet())
                {
                    Region neighbourRegion = regions.regionMap.get(id);
                    int surplusPixelCount = neighbourRegion.size - neighbourRegion.desiredSize;
                    // that has surplus pixels...
                    if (surplusPixelCount > 0)
                    {
                        // and convert the border segment pixels to the current region...
                        List<BoundaryPixel> neighbourBorderSegment = neighbourBorders.get(id);
                        int index = 0;
                        while (surplusPixelCount-- > 0 && index < neighbourBorderSegment.size())
                        {
                            BoundaryPixel boundaryPixel = neighbourBorderSegment.get(index++);
                            map[boundaryPixel.x][boundaryPixel.y] = region.id;
                            region.size++;
                            regions.regionMap.get(boundaryPixel.otherRegionId).size--;
                            // until we reach the desired size...
                            if (region.size == region.desiredSize)
                                break out;
                        }
                    }
                }
            }

            // if region contains more pixels than desired...
            else if (region.size > region.desiredSize)
            {
                // and the region has neighbours
                if (region.boundary.size() > 0)
                {
                    // choose a neighbour to off load extra pixels to
                    Region neighbour = regions.regionMap.get(region.boundary.remove(rand.nextInt(region.boundary.size())).otherRegionId);

                    ArrayList<BoundaryPixel> adjustedBoundary = new ArrayList<>();
                    // iterate over the boundary neighbour's boundary pixels...
                    for (BoundaryPixel boundaryPixel : neighbour.boundary)
                    {
                        // and then for those pixels which are of the current region, convert to the neighbour region
                        if (boundaryPixel.otherRegionId == region.id)
                        {
                            map[boundaryPixel.x][boundaryPixel.y] = neighbour.id;
                            neighbour.size++;
                            region.size--;
                            // stop when we reach the region's desired size.
                            if (region.size == region.desiredSize)
                                break;
                        }
                        else
                        {
                            adjustedBoundary.add(boundaryPixel);
                        }
                    }
                    neighbour.boundary = adjustedBoundary;
                }
            }
        }

    }

    /**
     * identifies the area, starting at the given point, in which adjacent pixels are of the same region id.
     *
     * @param map
     * @param isolatedRegionMap
     *            cells identifying which area that the corresponding map cell belongs
     * @param width
     * @param height
     * @param point
     *            the starting point of the area to be identified
     * @param isolatedRegionId
     *            the id of the region to assign cells with
     * @return the size of the identified area
     */
    private static int identifyEnclosedArea(int[][] map, int[][] isolatedRegionMap, int width, int height, Point point, final int isolatedRegionId)
    {
        ArrayList<Point> stack = new ArrayList<Point>();
        final int EXPECTED_REGION_ID = map[point.x][point.y];
        stack.add(point);
        int size = 0;

        while (stack.size() > 0)
        {
            Point p = stack.remove(stack.size() - 1);
            int x = p.x;
            int y = p.y;
            if (y < 0 || y > height - 1 || x < 0 || x > width - 1 || isolatedRegionMap[x][y] > 0)
                continue;
            int val = map[x][y];
            if (val == EXPECTED_REGION_ID)
            {
                isolatedRegionMap[x][y] = isolatedRegionId;
                size++;
                stack.add(new Point(x + 1, y));
                stack.add(new Point(x - 1, y));
                stack.add(new Point(x, y + 1));
                stack.add(new Point(x, y - 1));
            }
        }

        return size;
    }

}

```

# Explanation (from comments)

The algorithm is pretty simple: Firstly initialise the map with random weights, choose random seed pixels for each of the country regions. Secondly "grow" each region by attempting to claim unclaimed adjacent pixels. This occurs when the weight of the current pixel exceeds the unclaimed weight.

Each pixel in a region increases its weight each growth cycle. Additionally if a region has neighbours then if the current region being considered has less pixels than desired, then it will steal pixels from its neighbour if the neighbour has more pixels than desired. If the current region has more pixels than its neighbour then it randomly chooses a neighbour and then give all the surplus pixels to that neighbour. When all regions are of the correct size, then the third phase occurs to identify and convert any regions that have been split and are no longer continuous.

Only the largest split of the region is kept and the other splits are converted into unclaimed pixels and the second phase starts again. This repeats until all pixels in a region are adjacent and all regions are of the correct size.
> 16 votes

# Answer
This challenge is surprisingly difficult. I wrote a map generator in Python using Pygame. The program grows the color area into free space, and results in an image that might look like a map (if you squint).

My algorithm does not always complete the countries as the remaining area may not have enough space, but I thought it resulted in an interesting effect, and I will not be spending anymore time on it. The odd blue patches left can be considered large lakes, and the speckled blue features between countries are the rivers that mark the border (it is a feature, not a bug!).

In order to compare with the Super Chafouin, I used their parameter examples.

**Parameters : 380 260 233 420 1300 3511 4772 5089 9507 22107 25117 26744**

**Parameters : 380 260 8 5 6 7 8 4 5 6 7 9 4 6 9 5 8 7 5**

**Dark Age of Camelot (213 307 1 1 1)**

**My larger example: (640 480 6 1 7 2 9 3 4 5 6 1 9 8 7 44 3 1 9 4 5 6 7 2 3 4 9 3 4 5 9 8 7 5 6 1 2 1 2 1 2 6 7 8 9 63 3)**

This example looks a little like East Europe?

**An example with more countries: 640 480 6 1 7 2 9 3 4 5 6 1 9 8 7 44 3 1 9 4 5 6 7 2 3 4 9 3 4 5 9 8 7 5 6 1 2 1 2 1 2 6 7 8 9 63 5 33 11 88 2 7 9 5 6 2 5 7**

I changed the color generator with this example to `colors = [(80+ri(100), 80+ri(100), 80+ri(100)) for c in counts]` so as to get a more mellow (and map-like) range.

Python Code:

```
from pygame.locals import *
import pygame, sys, random

BACK = (0,0,200)
ORTH = [(-1,0), (1,0), (0,-1), (0,1)]
PI = 3.141592

random.seed(9999)
def ri(n):
    return int(random.random() * n)

args = [int(v) for v in sys.argv[1:]]
W, H = args[:2]
shares = sorted(args[2:])
ratio = float(W*H) / sum(shares)
counts = [int(s*ratio) for s in shares]
for i in range(W*H - sum(counts)):
    counts[i] += 1

colors = [(2+ri(250), 2+ri(250), 2+ri(250)) for c in counts]
countries = range(len(counts))
random.shuffle(countries)

border = ( set((x,y) for x in (0,W-1) for y in range(H)) |
            set((x,y) for x in range(W) for y in (0,H-1)) )

screen = pygame.display.set_mode((W,H))
screen.fill(BACK)
pix = screen.set_at
def look(p):
    if 0 <= p[0] < W and 0 <= p[1] < H:
        return screen.get_at(p)
    else:
        return None

clock = pygame.time.Clock()

while True:
    dt = clock.tick(300)
    pygame.display.flip()

    if countries:
        country = countries.pop()
        color = colors[country]
        if not countries:
            color = (20,20,200)  # last fill color to be water
        count = counts[country]
        frontier = set()
        plotted = 0
        loc = border.pop()
        while plotted < count:
            pix(loc, color)
            if plotted % 50 == 0:
                pygame.display.flip()
            plotted += 1
            direc = [(loc[0]+dx, loc[1]+dy) for dx,dy in ORTH]
            for dloc in direc:
                if look(dloc) == BACK:
                    frontier.add(dloc)
            border |= frontier
            if frontier:
                loc = frontier.pop()
                border.discard(loc)
            else:
                print 'Country %s cover %u of %u' % (
                    shares[country], plotted, count)
                break
        if not countries:
            fn = 'mapper%u.png' % ri(1000)
            pygame.image.save(screen, fn)

    for event in pygame.event.get():
        if event.type == QUIT: sys.exit(0)
        if not hasattr(event, 'key'): continue
        if event.key == K_ESCAPE: sys.exit(0)

```
> 13 votes

# Answer
Let's be lazy and adapt my answer from this question !

1. The algorithm computes a "snake path" starting from upper left corner that fills the whole rectangle. The snake can go only up, down, left, right.
2. The snake path is followed and is filled with the first color, then the second color, etc... taking in account the color percentages
3. This algorithm produces a lots of straight lines; to improve it, I detect them and replace them with "waves" that keep the same amount of pixels.

**Parameters : 380 260 233 420 1300 3511 4772 5089 9507 22107 25117 26744**

**Parameters : 380 260 8 5 6 7 8 4 5 6 7 9 4 6 9 5 8 7 5**

**Dark Age of Camelot (213 307 1 1 1)**

The code:

```
package map;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;

public class GenMap2 {

    private enum State { NO, YES, SHIFT };
    public final static int TOP = 1, BOTTOM = 2, LEFT = 4, RIGHT = 8;
    enum Action { ADD_LINE_TOP, ADD_LINE_LEFT, DOUBLE_SIZE, CREATE};

    public static void main(String[] args) throws IOException {

        int w = Integer.parseInt(args[0]), h = Integer.parseInt(args[1]);
        List<Integer> areas = new ArrayList<Integer>();
        int total = 0;
        for (int i = 2; i < args.length; i++) {
            int area = Integer.parseInt(args[i]);
            areas.add(area);
            total += area;
        }
        Collections.sort(areas);
        Collections.reverse(areas);
        int [][] tab = build(w, h);

        BufferedImage dest = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        int [] black = {0, 0, 0};
        for (int j = 0; j < dest.getHeight(); j++) {
            for (int i = 0; i < dest.getWidth(); i++) {
                dest.getRaster().setPixel(i, j, black);
            }
        }

        int x = 0, y = -1;
        int go = BOTTOM, previous = BOTTOM;

        List<Color> colors = new ArrayList<Color>();
        Random rand = new Random(0); // prog must be deterministic
        while (colors.size() < areas.size()) {
            Color c = new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256));
            boolean ok = true;
            for (Color existing : colors) {
                if (existing.equals(c)) {
                    ok = false;
                    break;
                }
            }
            if (ok) {
                colors.add(c);
            }
        }

        int [][] map = new int[w][h];
        int cpt = 0;
        while (true) {
            if (go == BOTTOM) y++;
            if (go == TOP) y--;
            if (go == LEFT) x--;
            if (go == RIGHT) x++;

            int tmp = (int)(((long)cpt) * total / (w * h));
            int i = 0;
            for (i = 0; i < areas.size(); i++) {
                int area = areas.get(i);
                if (tmp < area) {
                    break;
                }
                tmp -= area;
            }

            map[x][y] = i;

            previous = go;

            go = -1;
            if ((tab[x][y] & TOP) != 0 && previous != BOTTOM) go = TOP;
            if ((tab[x][y] & BOTTOM) != 0 && previous != TOP) go = BOTTOM;
            if ((tab[x][y] & LEFT) != 0 && previous != RIGHT) go = LEFT;
            if ((tab[x][y] & RIGHT) != 0 && previous != LEFT) go = RIGHT;
            if (go == -1) break;
            cpt++;
        }

        String [] src0 = srcPattern(16);
        String [] repl0 = destPattern(16);
        while (findPattern(map, src0, Arrays.asList(repl0, flip(repl0)))){}
        while (findPattern(map, rotate(src0), Arrays.asList(rotate(repl0), rotate(flip(repl0))))){}
        String [] src1 = srcPattern(8);
        String [] repl1 = destPattern(8);
        while (findPattern(map, src1, Arrays.asList(repl1, flip(repl1)))){}
        while (findPattern(map, rotate(src1), Arrays.asList(rotate(repl1), rotate(flip(repl1))))){}
        String [] src2 = srcPattern(4);
        String [] repl2 = destPattern(4);
        while (findPattern(map, src2, Arrays.asList(repl2, flip(repl2)))){}
        while (findPattern(map, rotate(src2), Arrays.asList(rotate(repl2), rotate(flip(repl2))))){}

        for (y = 0; y < h; y++) {
            for (x = 0; x < w; x++) {
                Color c = colors.get(map[x][y]);
                dest.getRaster().setPixel(x, y, new int[] {c.getRed(), c.getGreen(), c.getBlue()});
            }
        }

        ImageIO.write(dest, "png", new FileOutputStream("map.png"));
    }

    private static Random randPat = new Random(0);

    private static String [] srcPattern(int size) {
        String [] ret = new String[size*2];
        for (int i = 0; i < size*2; i++) {
            ret[i] = "";
            for (int j = 0; j < size*4; j++) {
                ret[i] += i < size ? "1" : "2";
            }
        }
        return ret;
    }

    private static String [] destPattern(int size) {
        String [] ret = new String[size*2];
        for (int i = 0; i < size*2; i++) {
            ret[i] = "";
            for (int j = 0; j < size*2; j++) {
                //int target = (int)((1 + Math.sin(j * Math.PI * .5/ size) * .4) * size);
                int target = (int)((1 + (Math.cos(j * Math.PI/ size) - 1) * .2) * size);
                ret[i] += (i < target)  ? '1' : '2';
            }
        }

        for (int i = 0; i < size*2; i++) {
            for (int j = 0; j < size*2; j++) {
                ret[i] += ret[size*2 - 1 - i].charAt(size*2 - 1 - j) == '1' ? '2' : '1';
            }
        }
        return ret;
    }
    private static String [] flip(String [] pat) {
        String [] ret = new String[pat.length];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = new StringBuilder(pat[i]).reverse().toString();

        }
        return ret;
    }
    private static String [] rotate(String [] pat) {
        String [] ret = new String[pat[0].length()];
        for (int i = 0; i < ret.length; i++) {
            ret[i] = "";
            for (int j = 0; j < pat.length; j++) {
                ret[i] += pat[j].charAt(i);
            }
        }
        return ret;
    }

    private static boolean findPattern(int [][] map, String [] src, List<String []> dest) {
        for (int y = 0; y < map[0].length - src.length; y++) {
            for (int x = 0; x < map.length - src[0].length(); x++) {
                int c1 = -1, c2 = -1;
                boolean wrong = false;
                for (int y1 = 0; y1 < src.length; y1++) {
                    for (int x1 = 0; x1 < src[0].length(); x1++) {
                        if (src[y1].charAt(x1) == '1') {
                            if (c1 == -1) {
                                c1 = map[x+x1][y+y1];
                            } else {
                                if (c1 != map[x+x1][y+y1]) {
                                    wrong = true;
                                }
                            }
                        }
                        if (src[y1].charAt(x1) == '2') {
                            if (c2 == -1) {
                                c2 = map[x+x1][y+y1];
                            } else {
                                if (c2 != map[x+x1][y+y1]) {
                                    wrong = true;
                                }
                            }
                        }
                        if (c1 != -1 && c1 == c2) wrong = true;
                        if (wrong) break;
                    }
                    if (wrong) break;
                }
                if (!wrong) {
                    System.out.println("Found match at " + x + " " + y);
                    String [] repl = dest.get(randPat.nextInt(dest.size()));
                    for (int y1 = 0; y1 < src.length; y1++) {
                        for (int x1 = 0; x1 < src[0].length(); x1++) {
                            map[x+x1][y+y1] = repl[y1].charAt(x1) == '1' ? c1 : c2;

                        }
                    }
                    return true;
                }
            }
        }
        return false;
    }

    public static int [][] build(int width, int height) {
        List<Action> actions = new ArrayList<Action>();
        while (height>1 && width>1) {
            if (height % 2 == 1) {
                height--;
                actions.add(Action.ADD_LINE_TOP);
            }
            if (width % 2 == 1) {
                width--;
                actions.add(Action.ADD_LINE_LEFT);
            }
            if (height%2 == 0 && width%2 == 0) {
                actions.add(Action.DOUBLE_SIZE);
                height /= 2;
                width /= 2;
            }
        }
        actions.add(Action.CREATE);
        Collections.reverse(actions);
        int [][] tab = null;
        for (Action action : actions) {
            if (action == Action.CREATE) {
                tab = new int[width][height];
                if (height >= width) {
                    for (int i = 0; i < height-1; i++) {
                        tab[0][i] = TOP|BOTTOM;
                    }
                    tab[0][height-1] = TOP;
                } else {
                    tab[0][0] = TOP|RIGHT;
                    for (int i = 1; i < width-1; i++) {
                        tab[i][0] = RIGHT|LEFT;
                    }
                    tab[width-1][0] = LEFT;

                }
            }
            if (action == Action.DOUBLE_SIZE) {
                tab = doubleTab(tab);
            }
            if (action == Action.ADD_LINE_TOP) {
                int [][] tab2 = new int[tab.length][tab[0].length+1];
                for (int i = 0; i < tab.length; i++) {
                    for (int j = 0; j < tab[0].length; j++) {
                        tab2[i][j+1] = tab[i][j];
                    }
                }
                tab2[0][0] = BOTTOM|RIGHT;
                for (int i = 1; i < tab.length-1; i++) {
                    tab2[i][0] = RIGHT|LEFT;
                }
                tab2[tab.length-1][0] = TOP|LEFT;
                mirror(tab2);
                tab = tab2;
            }
            if (action == Action.ADD_LINE_LEFT) {
                int [][] tab2 = new int[tab.length+1][tab[0].length];
                for (int i = 0; i < tab.length; i++) {
                    for (int j = 0; j < tab[0].length; j++) {
                        tab2[i+1][j] = tab[i][j];
                    }
                }
                tab2[0][0] = BOTTOM|RIGHT;
                tab2[1][0] |= LEFT;
                tab2[1][0] -= TOP;
                for (int i = 1; i < tab[0].length-1; i++) {
                    tab2[0][i] = TOP|BOTTOM;
                }
                tab2[0][tab[0].length-1] = TOP|BOTTOM;
                flip(tab2);
                tab = tab2;
            }

        }

        return tab;
    }

    private static void mirror(int [][] tab) {
        for (int i = 0; i < tab.length/2; i++) {
            for (int j = 0; j < tab[0].length; j++) {
                int tmp = tab[tab.length - 1 - i][j];
                tab[tab.length - 1 - i][j] = tab[i][j];
                tab[i][j] = tmp;
            }
        }
        for (int i = 0; i < tab.length; i++) {
            for (int j = 0; j < tab[0].length; j++) {
                if ((tab[i][j] & LEFT)!=0 && (tab[i][j] & RIGHT)==0) {
                    tab[i][j] -= LEFT; tab[i][j] |= RIGHT;
                } else if ((tab[i][j] & RIGHT)!=0 && (tab[i][j] & LEFT)==0) {
                    tab[i][j] -= RIGHT; tab[i][j] |= LEFT;
                }
            }
        }
    }

    private static void flip(int [][] tab) {
        for (int i = 0; i < tab.length; i++) {
            for (int j = 0; j < tab[0].length/2; j++) {
                int tmp = tab[i][tab[0].length - 1 - j];
                tab[i][tab[0].length - 1 - j] = tab[i][j];
                tab[i][j] = tmp;
            }
        }
        for (int i = 0; i < tab.length; i++) {
            for (int j = 0; j < tab[0].length; j++) {
                if ((tab[i][j] & TOP)!=0 && (tab[i][j] & BOTTOM)==0) {
                    tab[i][j] -= TOP; tab[i][j] |= BOTTOM;
                } else if ((tab[i][j] & BOTTOM)!=0 && (tab[i][j] & TOP)==0) {
                    tab[i][j] -= BOTTOM; tab[i][j] |= TOP;
                }
            }
        }
    }

    public static int [][] doubleTab(int [][] tab) {
        boolean [][] shiftTop = new boolean[tab.length][],
                shiftLeft = new boolean[tab.length][],
                shiftBottom = new boolean[tab.length][],
                shiftRight = new boolean[tab.length][];
        for (int i = 0; i < tab.length; i++) {
            shiftTop[i] = new boolean[tab[i].length];
            shiftLeft[i] = new boolean[tab[i].length];
            shiftBottom[i] = new boolean[tab[i].length];
            shiftRight[i] = new boolean[tab[i].length];
        }

        int x = 0, y = -1;
        for (int i = 0; i < tab.length; i++) {
            if ((tab[i][0] & TOP) != 0) {
                x = i;
            }
        }
        int go = BOTTOM, previous = BOTTOM;
        boolean init = false;
        while (true) {
            if (go == BOTTOM) y++;
            if (go == TOP) y--;
            if (go == LEFT) x--;
            if (go == RIGHT) x++;

            previous = go;

            go = -1;
            if ((tab[x][y] & TOP) != 0 && previous != BOTTOM) go = TOP;
            if ((tab[x][y] & BOTTOM) != 0 && previous != TOP) go = BOTTOM;
            if ((tab[x][y] & LEFT) != 0 && previous != RIGHT) go = LEFT;
            if ((tab[x][y] & RIGHT) != 0 && previous != LEFT) go = RIGHT;
            if (previous == BOTTOM) {
                shiftTop[x][y] = y==0 ? init : shiftBottom[x][y-1];
            }
            if (previous == TOP) {
                shiftBottom[x][y] = shiftTop[x][y+1];
            }
            if (previous == RIGHT) {
                shiftLeft[x][y] = shiftRight[x-1][y];
            }
            if (previous == LEFT) {
                shiftRight[x][y] = shiftLeft[x+1][y];
            }
            if (go == -1) break;

            if (previous == BOTTOM && go == LEFT) {
                shiftLeft[x][y] = !shiftTop[x][y];
            }
            if (previous == BOTTOM && go == RIGHT) {
                shiftRight[x][y] = shiftTop[x][y];
            }
            if (previous == BOTTOM && go == BOTTOM) {
                shiftBottom[x][y] = shiftTop[x][y];
            }

            if (previous == TOP && go == LEFT) {
                shiftLeft[x][y] = shiftBottom[x][y];
            }
            if (previous == TOP && go == RIGHT) {
                shiftRight[x][y] = !shiftBottom[x][y];
            }
            if (previous == TOP && go == TOP) {
                shiftTop[x][y] = shiftBottom[x][y];
            }

            if (previous == RIGHT && go == TOP) {
                shiftTop[x][y] = !shiftLeft[x][y];
            }
            if (previous == RIGHT && go == BOTTOM) {
                shiftBottom[x][y] = shiftLeft[x][y];
            }
            if (previous == RIGHT && go == RIGHT) {
                shiftRight[x][y] = shiftLeft[x][y];
            }

            if (previous == LEFT && go == TOP) {
                shiftTop[x][y] = shiftRight[x][y];
            }
            if (previous == LEFT && go == BOTTOM) {
                shiftBottom[x][y] = !shiftRight[x][y];
            }
            if (previous == LEFT && go == LEFT) {
                shiftLeft[x][y] = shiftRight[x][y];
            }
        }
        int [][] tab2 = new int[tab.length * 2][];
        for (int i = 0; i < tab2.length; i++) {
            tab2[i] = new int[tab[0].length * 2];
        }

        for (int i = 0; i < tab.length; i++) {
            for (int j = 0; j < tab[0].length; j++) {
                State left = State.NO, right = State.NO, top = State.NO, bottom = State.NO;
                if ((tab[i][j] & LEFT) != 0) {
                    left = shiftLeft[i][j] ? State.SHIFT : State.YES;
                }
                if ((tab[i][j] & TOP) != 0) {
                    top = shiftTop[i][j] ? State.SHIFT : State.YES;
                }
                if ((tab[i][j] & RIGHT) != 0) {
                    right = shiftRight[i][j] ? State.SHIFT : State.YES;
                }
                if ((tab[i][j] & BOTTOM) != 0) {
                    bottom = shiftBottom[i][j] ? State.SHIFT : State.YES;
                }

                int [] comp = compute(left, top, right, bottom);
                tab2[i*2][j*2] = comp[0];
                tab2[i*2+1][j*2] = comp[1];
                tab2[i*2][j*2+1] = comp[2];
                tab2[i*2+1][j*2+1] = comp[3];
            }
        }
        return tab2;
    }

    private static int [] compute(State left, State top, State right, State bottom) {
        //   |
        // --+
        //
        if (left == State.YES && top == State.SHIFT) {
            return new int[] {LEFT|BOTTOM, TOP|BOTTOM, TOP|RIGHT, TOP|LEFT};// "v^>^";
        }
        if (left == State.SHIFT && top == State.YES) {
            return new int[] {TOP|RIGHT, LEFT|BOTTOM, LEFT|RIGHT, LEFT|TOP}; //"^<>^";
        }
        //
        // --+
        //   |
        if (left == State.YES && bottom == State.YES) {
            return new int[] {LEFT|RIGHT, LEFT|BOTTOM, RIGHT|BOTTOM, LEFT|TOP}; //">vv<";
        }
        if (left == State.SHIFT && bottom == State.SHIFT) {
            return new int[] {RIGHT|BOTTOM, LEFT|BOTTOM, LEFT|TOP, TOP|BOTTOM}; //">v^v";
        }
        //   |
        //   +--
        //
        if (right == State.SHIFT && top == State.SHIFT) {
            return new int [] {RIGHT|BOTTOM,LEFT|TOP,TOP|RIGHT, LEFT|RIGHT}; //" v<>>";
        }
        if (right == State.YES && top == State.YES) {
            return new int [] {TOP|BOTTOM,RIGHT|BOTTOM,TOP|RIGHT,TOP|LEFT}; //"v>>^";
        }
        //
        //   +--
        //   |
        if (right == State.YES && bottom == State.SHIFT) {
            return new int [] {RIGHT|BOTTOM, LEFT|RIGHT, TOP|RIGHT, LEFT|BOTTOM}; //"v<>v";
        }
        if (right == State.SHIFT && bottom == State.YES) {
            return new int [] {RIGHT|BOTTOM, LEFT|BOTTOM, TOP|BOTTOM, RIGHT|TOP}; //"v<v^";
        }
        //
        // --+--
        //
        if (right == State.YES && left == State.YES) {
            return new int [] {LEFT|BOTTOM, RIGHT|BOTTOM, TOP|RIGHT, LEFT|TOP};
        }
        if (right == State.SHIFT && left == State.SHIFT) {
            return new int [] {RIGHT|BOTTOM, LEFT|BOTTOM, LEFT|TOP, RIGHT|TOP};
        }
        //   |
        //   +
        //   |
        if (top == State.YES && bottom == State.YES) {
            return new int [] {TOP|RIGHT, LEFT|BOTTOM, BOTTOM|RIGHT, LEFT|TOP};
        }
        if (top == State.SHIFT && bottom == State.SHIFT) {
            return new int [] {RIGHT|BOTTOM, LEFT|TOP, RIGHT|TOP, LEFT|BOTTOM};
        }
        //
        //   +--
        //
        if (right == State.YES && bottom == State.NO && left == State.NO && top == State.NO) {
            return new int [] {BOTTOM, RIGHT|BOTTOM, TOP|RIGHT, LEFT|TOP};
        }
        if (right == State.SHIFT && bottom == State.NO && left == State.NO && top == State.NO) {
            return new int [] {RIGHT|BOTTOM, LEFT|BOTTOM, TOP, RIGHT|TOP};
        }

        //   |
        //   +
        //
        if (top == State.YES && bottom == State.NO && left == State.NO && right == State.NO) {
            return new int [] {TOP|RIGHT, LEFT|BOTTOM, RIGHT, LEFT|TOP};
        }
        if (top == State.SHIFT && bottom == State.NO && left == State.NO && right == State.NO) {
            return new int [] {BOTTOM|RIGHT, LEFT|TOP, TOP|RIGHT, LEFT};
        }
        //
        //   +
        //   |
        if (bottom == State.YES && top == State.NO && left == State.NO && right == State.NO) {
            return new int [] {RIGHT, LEFT|BOTTOM, BOTTOM|RIGHT, LEFT|TOP};
        }
        if (bottom == State.SHIFT && top == State.NO && left == State.NO && right == State.NO) {
            return new int [] {BOTTOM|RIGHT, LEFT, TOP|RIGHT, LEFT|BOTTOM};
        }
        //
        // --+
        //
        if (left == State.YES && bottom == State.NO && right == State.NO && top == State.NO) {
            return new int [] {LEFT|BOTTOM, BOTTOM, TOP|RIGHT, LEFT|TOP};
        }
        if (left == State.SHIFT && bottom == State.NO && right == State.NO && top == State.NO) {
            return new int [] {BOTTOM|RIGHT, LEFT|BOTTOM, LEFT|TOP, TOP};
        }
        return null;
    }
}

```
> 8 votes

---
Tags: popularity-contest, graphical-output
---


# Question
Title: Decompose a number into a sum of repdigits
Repdigits are numbers of the form `a * (10^n - 1)/9` with `a in [-9,9]\{0}` (in other words 111, -3333, 66, numbers which are made by repeating only one digit)

**Goal:** Write a program or function which takes a single positive integer `N` and prints `N = s_1 + s_2 + ... + s_k`. There should be one number per line and the numbers need to be right-aligned. No two summands should have the same number of digits and adding zeros is not allowed. The output should be ordered in ascending or descending order (by number of digits)

**Examples:**

```
in:
24192
out:
24192 =
22222 +
 2222 -
  222 -
   33 +
    3

in:
24192
out:
    -7
   -22
  +888
 +1111
+22222
=24192

in:
113
out:
113=    NOT  111+  no empty lines  111+
111+          00+
  2            2                     2

```

As you can see there can be multiple solutions and some artistic freedom is allowed. Leading and trailing whitespace in each line is allowed

Shortest byte count wins

# Answer
# perl 5 - 97 92 93 86

```
$x=$_=pop;{printf"%15s
",$_;$_=$x,s!\d!//,$&!eg,$x-=$_,$i++?s/^\b/+/:s/^/=/;/0/||redo}

```

Input given as a parameter:

```
$perl a.pl 2224192
     2224192
    =2222222
       +1111
        +888
         -22
          -7

```
> 6 votes

# Answer
## CJam, ~~55~~ 50 bytes

```
'=l:L+Li{_W>"-+"=1$zs(\,)*+:Ii-L,_S*I+\~>\}h;]W%N*

```

Test it here.

Uses the output format

```
      -7
     -22
    +888
   +1111
+2222222
=2224192

```

I might golf this more once I'm beaten.

Explanation:

```
'=l:L+Li{_W>"-+"=1$zs(\,)*+:Ii-L,_S*I+\~>\}h;]W%N*
'=                                                 "Push = character.";
  l:L                                              "Read STDIN and store in L.";
     +L                                            "Concatenate, push new copy of L.";
       i                                           "Convert to integer.";
        {                                 }h       "Do-while loop. Leaves the condition on the
                                                    stack. I will use the remainder for that.";
         _W>                                       "Duplicate remainder, compare with -1.";
            "-+"=                                  "Select appropriate sign character.";
                 1$                                "Copy remainder again.";
                   zs                              "Take abs() and convert to string.";
                     (                             "Shift off first digit.";
                      \                            "Swap with string.";
                       ,                           "Get length.";
                        )                          "Increment.";
                         *                         "Repeat digit that often.";
                          +                        "Concatenate with sign.";
                           :I                      "Store in I.";
                             i-                    "Convert to integer. Subtract from remainder.";
                                                   "Now we'll right-justify I.";
                               L,                  "Load input, get length.";
                                 _                 "Duplicate.";
                                  S*               "Repeat space that often.";
                                    I+             "Load string and concatenate.";
                                      \~           "Swap with length. Bitwise complement.";
                                        >          "Take that many characters from the right.";
                                         \         "Swap with remainder.";
                                            ;      "Discard final remainder (0).";
                                             ]     "Wrap in array.";
                                              W%   "Reverse.";
                                                N* "Join with line feeds.";

```

The resulting array is printed automatically at the end of the program.
> 2 votes

# Answer
# JavaScript ES6 - 145

```
i=0;f=n=>{return g=n<0,n=Math.abs(n)+'',l=n.length,r=l-1?n[0].repeat(l):n,(i>0?g?'-':'+':n+'=')+'\n'+' '.repeat(i++)+(l-1?r+f((+n-r)*(g?-1:1)):r)}

```

Paste into Firefox console. Run as `f(24192)`.

Output for `f(24192)`:

```
24192=
22222+
 1111+
  888-
   22-
    7

```
> 0 votes

# Answer
## GolfScript 77

```
~.[{..0>2*(.@*`.,\[0=]*''+~*.@\-.}do;]-1%{[.0>' +'=\`n].1=,2$`,\-' '*\+}%'='@

```

Online demo links:

A slightly more readable version (if GolfScript can be called readable) with unit tests version is available here.
> 0 votes

---
Tags: code-golf, ascii-art, number
---


title: Underground geek rock band names

text:
# Question
Title: Underground geek rock band names
We have a group of stealthy computer-savvy geeks who are also musicians with a very subversive element to their songs that the authorities in their totalitarian country just can't stand, and are itching to show up at one of the concerts, fire off rubber bullets and tear gas at the audience, and arrest the band members and as may other fans as their paddy vans can carry and "disappear" them.

However, the authorities are a bit slow to act, and will only show up to the *second* concert held under the same band name (case, accent and whitespace-length insensitive). They are also not very tech-savvy, so can't reverse-engineer the decoder (see later). Since they are working from memory, they'll forget a name after five years, so a repeat after that time won't attract their attention.

One of these tech-savvy band members comes up with an algorithm that - given the date of a concert - generates a (hopefully) unique cool-sounding and pronounceable band name using the latin alphabet (A-Z) plus Space. They also create a *decoder* that they distribute to fans, which, given a band name and a date, returns some output indicating that this is indeed a code-generated name of our subversive band, or some other output indicating that the band name entered is that of some other band (or a sting set up by the authorities to catch fans they want to arrest).

The decoder does not output any valid names, as the authorities are just tech-savvy enough themselves to obtain a copy and use that to generate possible names if it can output them, but don't have time to check all the names of the hundreds of other bands that appear and disappear (sometimes with their assistance) from time to time against it.

**Your Task:**

Produce these two complementary pieces of code - the name generator and the name checker.

As this is a popularity contest, we're looking for cool-sounding, pronounceable band names for the English-speaking world, not random unpronounceable text. Any programming language is OK, as the fans are all very tech-savvy like us. Please provide a sample of the cool names your generator generates.

If it can be shown that an algorithm produces a duplicate for any two dates in a 5-calendar-year period, then that will be considered a disqualification. (Disqualification is a far better fate than what the authorities would do to them).

# Answer
> 6 votes
# Pyth

Encoder:

```
Jf-\'T'jdm@JdjswlJ

```

Takes two arguments: a dictionary on one line, and the date, in DDMMYYYY form on the next.

Filters out words with apostrophes from the dictionary, then converts the current date into a number with base equal to the dictionary length, and then chooses words from the filtered dictionary with indexes of the digits, and prints them out, space separated.

Today's result:

```
$ pyth -c "Jf-\'T'jdm@JdjswlJ" <<< '/usr/share/dict/words
30102014'
Annam pals

```

Future results:

```
31102014
Antarctica economical

01112014
Abernathy carousels

02112014
Acadia unsnarled

03112014
Actaeon oversimplifying

04112014
Adela dugouts

0511204
Adolph Maude

```

To decode, run the date through the program and see if the output matches the name given. I'm not going to list any more band names, but from how the program works it should be clear there are no repeats.

# Answer
> 3 votes
### Encoder

```
{18+65}%

```

Expects input in the form `YYYYMMDD`. Online demo

### Decoder

```
n/~{18+65}%=

```

Expects input in the form

```
BANDNAME
YYYYMMDD

```

Online demo

I'm not going to post a list of 260 names because a) that would be a complete waste of space; b) it's easy to convince yourself that the encoder is an injection.

# Answer
> 1 votes
# Python 3

## Generator

This generates shorter names so they seem a little less obscure.

```
import string

date = input()
vowels = 'aeiou'
name = ''
consonants = ''.join(i for i in string.ascii_lowercase if not i in vowels)
for i in range(0,len(date),2):
    name += vowels[int(date[i])%len(vowels)]+consonants[int(date[i])%len(consonants)]
print(name)

```

### Example

```
Input:  30102014
Output: ofecidec

```

## Validator

Just performs the above and compares the result with the supplied name.

```
import string

date, name = input().split(',')
vowels = 'aeiou'
tname = ''
consonants = ''.join(i for i in string.ascii_lowercase if not i in vowels)
for i in range(0,len(date),2):
    tname += vowels[int(date[i])%len(vowels)]+consonants[int(date[i])%len(consonants)]
print(tname == name)

```

### Examples

```
Input:  30102014,ofecidec
Output: True

Input:  30102014,ofocidoc
Output: False

```

Input should be in the format:

```
DDMMYYYY,NAME

```

# Answer
> 0 votes
# Javascript

Since the authorities forget names after 5 years, we can leave the millennium, century, and decade digits out of the year. We can also use day of year (DoY). This program accepts input in the form of YDoY

## Encoder

The encoder converts the base 10 date to a base 26 string, then shifts it over 10 characters to remove any numbers. Then we add vowels, spaces, and capitalization to make the words look like english.

```
function encodeName(date){
    var alphabet = '0123456789abcdefghijklmnopqrstuvwxyz';
    var vowels = 'aeiou';
    var rebased = date.toString(26);
    var shifted = '';
    var name = '';
    for(var c in rebased){
        var i = alphabet.indexOf(rebased[c]);
        shifted += alphabet.substring(i+10, i+11)
    }
    for(var a in shifted)
            name += a%2 == 0 ? shifted[a].toUpperCase() + vowels[a%vowels.length] : shifted[a] + ' ';

    return name.trim();
}

```

## Decoder

```
function decodeName(name){
    var alphabet = '0123456789abcdefghijklmnopqrstuvwxyz';
    var vowels = 'aeiou';
    var stripped = '';
    var shifted = '';

    for(var n in name)
        stripped += vowels.indexOf(name[n]) >= 0 || name[n] == ' ' ? '' : name[n].toLowerCase();

    for(var n in stripped)
        shifted += alphabet[alphabet.indexOf(stripped[n])-10];

    return parseInt(shifted, 26);
}

```

## Examples

```
function encodeName(b){b=b.toString(26);var a="",d="",c;for(c in b)var f="0123456789abcdefghijklmnopqrstuvwxyz".indexOf(b[c]),a=a+"0123456789abcdefghijklmnopqrstuvwxyz".substring(f+10,f+11);for(var e in a)d+=0==e%2?a[e].toUpperCase()+"aeiou"[e%5]:a[e]+" ";return d.trim()}
function decodeName(b){var a="",d="",c;for(c in b)a+=0<="aeiou".indexOf(b[c])||" "==b[c]?"":b[c].toLowerCase();for(c in a)d+="0123456789abcdefghijklmnopqrstuvwxyz"["0123456789abcdefghijklmnopqrstuvwxyz".indexOf(a[c])-10];return parseInt(d,26)};

var date = 1003;
alert(encodeName(date) + ' -- ' + decodeName(encodeName(date)));
var date = 9123;
alert(encodeName(date) + ' -- ' + decodeName(encodeName(date)));
var date = 3333;
alert(encodeName(date) + ' -- ' + decodeName(encodeName(date)));
var date = 2321;
alert(encodeName(date) + ' -- ' + decodeName(encodeName(date)));
var date = 0345;
alert(encodeName(date) + ' -- ' + decodeName(encodeName(date)));
```

---
Tags: popularity-contest, encoding
---


title: The Mirror Maze Mania

text:
# Question
Title: The Mirror Maze Mania
# Puzzle

There are some mirrors located throughout a grid. A ray of light enters the grid from some position. It travels through the grid in a straight line trying to escape. On encountering with a mirror it changes its course by 90 degrees. This continues to happen until it breaks free from the maze. The challenge is simply this: **Guide the light ray to an exit.**

---

# Elements

* **Grid** \- The grid is a square composed of *n x n* blocks. A block is either empty or contains a mirror.
* **Mirror** \- Both faces of the mirror are reflective. They have two orientations - 45o left or right(see figure).
* **Light ray** \- It always travels straight and reflects from the mirror surface upon incidence (i=r=45o).

---

# Code

* **Input** \- The user will input 3 values - *n*, *m* and *s*.

*n* represents the value of grid's length (no of blocks). You are free to choose the type of this value; It could be a string, integer, float or any other data type. This cannot be zero/empty.

*m* is a sequence of two values indicating where the mirrors are and what their orientations will be. You are free to choose the sequence type. For example, if *0* and *1* are the two orientations of the mirror and each block in the grid is marked from 1 to n2, you may input a sequence such as *{(5,0), (3,1), (6,0),...}*. Since you're free to choose this type, you may even squeeze them in to a string and decode it properly. In other words, it only needs to be legible to your code. This can be zero for no mirrors.

*s* represents the starting position of the light ray. Again, you may choose this type based on the rest of your code. Any form of data is valid.

*NOTE* The user is responsible for inputing the correct values. If they enter an invalid value such as placing a mirror out of the grid or not providing a starting position, your code doesn't have to deal with it.
* **Process** \- Calculate the position from which the light ray will emerge out of the grid. You are free to mark your grid (or not) in any way you like. The same goes with start and exit positions. Include these details in your answer below. How you represent these data will influence the output. See scoring rubrics for details.
* **Output** \- Display the emerging position of the light ray. Detailed output can score more. See scoring rubrics for details.

You are free to use any libraries or extensions to implement *any part* of the maze, but not the *entire* maze. The only restriction here is this: if the library is for GUI, or implementing the Grid or anything like that it's fine. If it already contain a preset grid with mirrors (highly unlikely), you *can't* use it.

# Scoring

* **+64** for keeping your code less than 10 kilobytes (10240 bytes).
* **-2** for every byte after the 10240th byte
* **+16** for including the path of the ray in the output. Any representation is OK, but explain it in the answer. You may mark your grid with numbers, alphabets or in any other way you like.
* **+64** for drawing the grid with the solution (see figure). It could be a GUI or CLI! The drawing must *at least* include the grid and the ray of light from start to exit. Numbers, markings and everything else are optional. If you do this, you shouldn't add the +16 points above.
* **+128** for inventing partially reflective mirrors. These mirrors will guide the light in to two locations. One that is perpendicular to the original ray and one that passes straight through them. You may of course combine multiple mirrors like these with the normal ones for added effect. There may be 2 exit rays for this type of mirrors which you *must* display in your solution. If you choose to do this, change the user input *m* to suit the code accordingly (it must be a sequence of 3 elements rather than 2, the third value being the type of mirror). See figure below.
* **+128** for inventing the absorber mirror. Absorber mirror absorbs the light ray and stops it from exiting the grid. The solution to this case should be something like 'LIGHT RAY ABSORBED!' (you can show anything as long you explain it in the answer below.) Everything else is same as the partially reflective mirror shown above.
* **+128** for inventing the laser mirror. A laser mirror's reflection will destroy any other mirror that is in it's way. So, if the light strikes a laser mirror(m1) and then falls on another mirror (m2), it (m2) will be destroyed. The ray now travels straight as if that block is empty. Everything else is same as the partially reflective mirror shown above.
* **+128** for inventing a new kind of mirror and explaining its action. Make it really cool. ;)

TIE BREAKER: In case of a tie, the shortest code shall win. If by some strange coincidence, that happens to be the same, the winner shall be decided based on how many numbers there are in the code (every single digit of integers, floats and even numbers in variables) - the least one wins!

# Example

The first one is a typical solution with a GUI output. It marks the positions as integers from 1 to 12 and shows the path of the ray along with 2 mirrors. The second one shows the partially reflective mirror (bonus points) that has 2 exit rays. The third example is a CLI output model (this one is tough!). It shows the same thing as our GUI. The normal output without any diagrams (no bonus) could be as short as a single number or any value (eg: 7 or G) indicating from where the ray has emerged. The way you chose to name the positions must be included in your answer.

```
       ^
     __:___ ______ ______ ______ ______
    |  :   |      |      |      |      |
<...|..\\..|.<....|..\   |      |      |
    |______|______|__:__ |______|______|
    |      |      |  :   |      |      |
    |      |      |  ^   |      |      |
    |______|______|__:___|______|______|
    |      |      |  :   |      |      |
....|..>...|......|../   |      |      |
    |______|______|______|______|______|
    |      |      |      |      |      |
    |      |      |      |      |      |
    |______|______|______|______|______|

/  = normal mirror
// = partially reflecting mirror

```

# Answer
## T-SQL(2012+) Score ~~512~~ 640

I hope this fits in the rules. I implemented the 3 mirrors + a super absorber. I didn't count the super absorber as a cool extra.

The input is three variables.
One int and two tables for mirror and start. The mirror table has columns for X, Y, Orientation(-1/1) and Type (1-4) -1 is Left and 1 is Right Type 0 is standard, 1 is laser, 2 is partial, 3 is absorber and 4 is super absorber **EDIT:** 5 is laser splitter and 6 is a splitter. These will split the beam in both directions.

The start table has columns for start X and Y, Direction(1-4) and Laser Flag(0/1) Direction 1 is north, 2 is east, 3 is south and 4 is west. It will handle more than one start point.

A function to handle mirrors. Run once.

```
DROP FUNCTION M;
GO
CREATE FUNCTION M(@d INT,@O INT,@t INT,@L INT) RETURNS TABLE AS RETURN
    SELECT IIF(d=0,4,d)d, l FROM (
    SELECT (@d+(@o*(IIF(@d%2=0,-1,1)))+4)%4d,isnull(@t,0)%2l WHERE @L=0 AND @o is not null and isnull(@t,0)not in(3,4)
    UNION ALL
    SELECT @d, @l WHERE isnull(@t,2)=2 OR (@l=1 AND @t<>4)
    UNION ALL
    SELECT (@d+(-@o*(IIF(@d%2=0,-1,1)))+4)%4,isnull(@t,0)%2 WHERE @L=0 and @t in(5,6)
    )m

```

The grid setup and query

```
-- Set up Maze
DECLARE @n INT = 5
DECLARE @m TABLE (X INT, Y INT, O INT, T INT)
DECLARE @s TABLE (X INT, Y INT, D INT, L INT)
INSERT INTO @m VALUES (1,5,-1,0),(1,1,-1,0),(2,1,1,2),(3,1,1,2),(4,1,1,1),(2,3,-1,5),(4,3,-1,3),(4,5,-1,4),(4,2,1,0),(3,4,1,6);
INSERT INTO @s VALUES (0,5,2,0);
-- Solve Maze
WITH S AS (
    SELECT x,y,d,l,Geometry::Parse(CONCAT('LINESTRING (',px,' ',py,',',x,' ',y,')')).STBuffer((l+1)/30.)g
    FROM(
        SELECT x+(d.d+1)%2*-SIGN(d.d-3)x,y+d.d%2*-SIGN(d.d-2)y,d.d,d.l,x px,y py
        FROM @s s OUTER APPLY(SELECT O, T FROM @m m WHERE s.x=m.x and s.y=m.y)x CROSS APPLY(SELECT d,l FROM M(s.d,x.o,x.t,s.l))d
        )g
    UNION ALL
    SELECT x,y,d,l,Geometry::Parse(CONCAT('LINESTRING (',px,' ',py,',',x,' ',y,')')).STBuffer((l+1)/30.)g
    FROM(
        SELECT x+(d.d+1)%2*-SIGN(d.d-3)x,y+d.d%2*-SIGN(d.d-2)y,d.d,d.l,x px,y py
        FROM S OUTER APPLY(SELECT O, T FROM @m m WHERE s.x=m.x and s.y=m.y)x CROSS APPLY(SELECT d,l FROM M(s.d,x.o,x.t,s.l))d
    WHERE s.X>0 AND s.X<=@n AND s.Y>0 AND s.y<=@n
        )g
    )
    ,E AS (SELECT *FROM(VALUES(\),(\),(\),(\),(\),(\),(\),(\),(\),(\))E(N))
    ,N AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT\)) N FROM E e1,E e2,E e3)
SELECT CONCAT('Exits into ',x,', ',y,' from the ',CASE d WHEN 1THEN'south'WHEN 2THEN'west'WHEN 3THEN'north'WHEN 4THEN'east'END),null
FROM S
WHERE s.X=0 OR s.X>@n OR s.Y=0 OR s.y>@n
UNION ALL
SELECT 'Beam'O,Geometry::UnionAggregate(g)G FROM S --Draw Line
UNION ALL
SELECT CONCAT('Mirror Type ',T),Geometry::Parse(CONCAT('LINESTRING (',x+(ABS(o)/3.),' ',y+(o/3.),',',x-(ABS(o)/3.),' ',y-(o/3.),')')).STBuffer(.06) FROM @m WHERE T NOT IN(3,4,5,6) --Draw Mirrors
UNION ALL
SELECT 'Blocker',Geometry::Parse(CONCAT('LINESTRING (',x+(ABS(o)/(-T+8.)),' ',y+(o/(-T+8.)),',',x-(ABS(o)/(-T+9.)),' ',y-(o/(-T+9.)),')')).STEnvelope() FROM @m WHERE T IN(3,4) --Draw Blockers
UNION ALL
SELECT CONCAT('Mirror Type ',T),Geometry::Parse(CONCAT('MULTILINESTRING ((',x+.33,' ',y+.33,',',x-.33,' ',y-.33,'),(',x+.33,' ',y-.33,',',x-.33,' ',y+.33,'))')).STBuffer(.06) FROM @m WHERE T IN(5,6) --Draw Splitters
UNION ALL
SELECT 'Grid',Geometry::UnionAggregate(g) FROM (
    SELECT Geometry::Parse(CONCAT('LINESTRING (',x1,' ',y1,',',x2,' ',y1,',',x2,' ',y2,',',x1,' ',y2,',',x1,' ',y1,')'))g -- Draw Grid
    FROM (SELECT TOP(@n) N-.5x1,N+.5x2 FROM N)x,(SELECT TOP(@n) N-.5y1,N+.5y2 FROM N)y
)g
OPTION (MAXRECURSION 10000)

```

The output Query Results tab SSMS

Spatial Results tab SSMS
> 5 votes

# Answer
C# 1669 chars, i implemented everything i think except msges(like laser has escpaed, laser got absorberbed etc...). ITS ALSO ANIMATED!

So its works like this, create a project called mirror and copy all of this into Form.cs. When you press the form with your mouse it takes the variables entered into the textbox to start everything , so dont click before you enter them. The variables are as follow:

```
20 2 0 0 5 0 8

```

The first number is the grid size, the second number is the direction the laser will be going 0 is left, 1 is up, 2 is right and 3 is down. Then come the X Y starting position of the laser and after that you got 3 numbers for every object, first two being the X and Y position of the object and the third being the type of the object:

```
2 = /
3 = \
4 = //
5 = \\
6 = O (absorber)
7 = X (laser mirror)
8 = T (random teleport)

```

I dont consider my special object as worthy of the extra points since it isnt very cool. Also side note the thread doesnt finish properly so you need to kill the process (gotta save dat space). Here is a cool one to test it out

```
40 2 0 0 10 0 3 10 10 2 5 10 4 4 10 5 0 10 6 4 5 2 15 5 5 15 20 2 10 20 7 8 20 3 6 20 2 4 20 4 2 20 5 35 5 8 25 5 5 25 25 2 18 25 6

```

CODE

```
    using System;using System.Collections.Generic;using System.Drawing;using System.Windows.Forms;using System.Threading;namespace mirror{partial class Form1:Form{public Form1(){InitializeComponent();this.Load+=l;}int[,]g=new int[1,1];int i;List<int[]>d=new List<int[]>();void l(object ss,EventArgs k){SetStyle(ControlStyles.AllPaintingInWmPaint,true);SetStyle(ControlStyles.OptimizedDoubleBuffer,true);this.Width=this.Height=800;TextBox t=new TextBox();this.Controls.Add(t);this.Click+=(p,e)=>{t.Hide();string[]s=t.Text.Split(' ');i=o(s[0]);g=new int[i,i];d.Add(new int[]{o(s[1]),o(s[2]),o(s[3]),0});g[d[0][1],d[0][2]]=1;for(int j=4;j<s.Length;)g[o(s[j++]),o(s[j++])]=o(s[j++]);Thread x=new Thread(r=>{while(true){for(int c=0;c<d.Count;c++){try{got:if(d[c][0]==0)d[c][1]--;if(d[c][0]==1)d[c][2]--;if(d[c][0]==2)d[c][1]++;if(d[c][0]==3)d[c][2]++;if(d[c][3]==0){int l=d[c][0];int z=g[d[c][1],d[c][2]];if(z==2)d[c][0]=l==0?3:l==1?2:l==2?1:0;if(z==3)d[c][0]=l==0?1:l==1?0:l==2?3:2;if(z==4)d.Add(new int[]{l==0?3:l==1?2:l==2?1:0,d[c][1],d[c][2],0});if(z==5)d.Add(new int[]{l==0?1:l==1?0:l==2?3:2,d[c][1],d[c][2],0});if(z==6){d.RemoveAt(c);continue;}if(z==7)d[c][3]=1;if(z==8){Random rr=new Random();d[c][1]=rr.Next(i);d[c][2]=rr.Next(i);}if(z>1)goto got;}g[d[c][1],d[c][2]]=1;}catch(Exception){}}this.Invalidate();Thread.Sleep(100);}});x.Start();};string[]ar=new string[]{" ","*","/",@"\","//",@"\\","O","X","T"};this.Paint+=(h,v)=>{Graphics z=v.Graphics;for(int q=0;q<i;q++)for (int w=0;w<i;w++){z.DrawRectangle(Pens.Black,new Rectangle(q*20,w*20,20,20));z.DrawString(ar[g[q,w]],this.Font,Brushes.Black,new Point(q*20+8,w*20+8));}};}int o(string s){return int.Parse(s);}}}

```

non golfed: http://pastebin.com/sNa0aK7f , http://horobox.co.uk/u/vajura\_1414782718.rar exe

Also hope you like it was fun to make! :)
> 2 votes

---
Tags: code-challenge, graphical-output
---


title: Underhanded Bank Account

text:
# Question
Title: Underhanded Bank Account
You are working as a programmer for a bank.
Your task is to write a program that handles the transactions from one bank account to another.

**The program should do the following:**

* Run in an infinite loop waiting for input.
The input consists of 3 numbers:
Accountnumber1, Accountnumber2 and x the amount of money.
e.g. 999222 777333 500
* Check if the account numbers and x are valid.
The input is valid if the account numbers are not the same and exist in your database and if x is greater than zero,
* Transfer the money from account1 to account2, but only if account1 has enough money.
Accounts are not allowed to go into the negative.
* If everything goes well print something like "Transferred x$ from number1 to number2"
* if something goes wrong, for example because the account numbers are invalid, print an error message.
* Stop if the input is 0

---

**The database contains the following bank accounts:**

* `999222: 10000.56$`
* `888333: 335.13$`
* `555222: 56.0$`
* `222111: 123.55$`
* `123456: 0.0$`

---

**Simple Python 2 example:**

```
account_numbers = ["999222", "888333", "555222", "222111", "123456"]
account_money   = [10000.56,   335.13,     56.0,   123.55,      0.0]

while True:
    #input in the form of: 999222 777333 500
    input = raw_input()

    if input == "0": break

    number1, number2, x = input.split()

    x = float(x)
    if x <= 0:
        print "Invalid request!"
        continue

    if number1 in account_numbers and number2 in account_numbers and number1 != number2:
        index1 = account_numbers.index(number1)
        index2 = account_numbers.index(number2)

        if account_money[index1] >= x:
            account_money[index1] -= x
            account_money[index2] += x
            print "Transferred %.2f$ from %s to %s" % (x, number1, number2)
        else:
            print "Not enough money in account %s!" % (number1)

    else:
        print "Invalid account number(s)!"

```

**TWIST:**
Your bank account number is 123456.
You have exactly 0.0$ in your account.
You want to change that by manipulating your program:
The program should do exactly what it is supposed to do, but should also transfer some free money to your account.

You have to be careful though. Your supervisor will look at your code and he won't be pleased if he sees anything suspicious. He knows about the Standard Loop Holes, so don't even try.
Also, the money you give to yourself shouldn't be too much. It would be suspicious if your money increases too quickly. Don't be greedy.

Your code should be as simple and clear as possible, try to avoid heavy obfuscation.

This is a popularity contest, the answer with the most upvotes wins.

**Note:** Please output the balance of each account at the end of your program, so that we can see how much money you earned with your hard work (simply to show that your program actually did something).

**EDIT: To clarify**
The challenge is not to write a program that can handle a large database and a lot of transactions. The challenge is to make the program look like it only does what it is supposed to do, but in reality doesn't.

For example if the input is `999222 777333 500`:
Then add, if possible, 500 to account 777333 and subtract 500 from account 999222. You don't have to "steal" the money from those accounts. You can "generate" the money for your account by simply increasing it somehow in your code.
How much is up to you, but you can assume that you want to earn at least 0.1$ and max. 10$ for each given input. It would be suspicious if you would suddenly have millions on your account. You don't have to worry about floating point imprecision, but you can use it to increase your money.

Every user plays the role of the supervisor.
If the trick is hard to spot upvote the answer.

# Answer
> 3 votes
I've tried to emulate features of real-world large systems here. I use encapsulation and abstraction to handle the different operations to the database, like getting an account balance and transferring money. The code also has a basic test suite for those functions. However, one programmer has taken advantage of recent changes in the project requirements to add $1 to their account with every input. There's even plausible deniability.

```
# {account number: balance in USD}
ndb = {
    999222: 10000.56,
    888333: 335.13,
    555222: 56.0,
    222111: 123.55,
    123456: 0.0
}

# {hashed account ID: balance in USD}
# (hash the IDs because integer-based hash tables are fast, and a
# bunch of strcmp's would be slow)
# 2014-10-20: phased out alphabetic account IDs for numeric ones
# keeping the old data here because Murphy's Law guarantees we'll
# need it right after it's deleted. -- RJO
odb = {
#   hash('mEYjxG'): 42.0,
#   hash('lDCIqp'): 1337.0,
#   hash('QDxkwD'): 123456.0,
#   hash('jSWlMM'): 0.0,
#   hash('siYWKC'): 20.14
}

def balance(a, db):
    try:
        return db[hash(a)]
    except:
        raise ValueError('no such account:', a)

def credit(a, n, db):
    if n <= 0:
        raise ValueError('invalid amount: ' + str(n))
    try:
        db[hash(a)] += n
    except:
        raise ValueError('no such account:', a)

# 2012-10-20: parameterizing the database ops to handle both
# old and new databases is a pain in the neck. -- RJO

def debit(a, n, db):
    if n <= 0:
        raise ValueError('invalid amount: ' + str(n))
    if balance(a, db) < n:
        raise ValueError('insufficient funds: below ' + str(n))
    try:
        db[hash(a)] -= n
    except:
        raise ValueError('no such account', a)

def transfer(a, b, n, db):
    if a == b:
        raise ValueError('same account', a)
    debit(a, n, db)
    credit(b, n, db)

# 2014-10-20: tests need to be updated with new account IDs, but
# it's Friday afternoon. -- RJO
def test(db):
    # back up database prior to changes
    bdb = db.copy()
    # test database functions
    try:
        # test 'balance'
        account = 'does not exist'
        try:
            bal = balance(account, db)
            assert(db[hash(account)] == bal)
        except ValueError:
            assert(hash(account) not in db)
        # test 'credit'
        account = 'jSWlMM'
        start = balance(account, db)
        delta = 1
        credit(account, delta, db)
        assert(balance(account, db) == start + delta)
        # test 'debit'
        account = 'lDCIqp'
        start = balance(account, db)
        delta = 1337
        try:
            debit(account, delta, db)
            assert(balance(account, db) == start - delta)
        except ValueError:
            assert(balance(account, db) < delta)
        # test 'transfer'
        account1 = 'mEYjxG'
        account2 = 'siYWKC'
        start1 = balance(account1, db)
        start2 = balance(account2, db)
        delta = 123
        try:
            transfer(account1, account2, delta, db)
            assert(balance(account1, db) == start - delta)
            assert(balance(account2, db) == start + delta)
        except ValueError:
            assert(balance(account1, db) < delta)
    except Exception as ex:
        # log errors
        print ex.message
    finally:
        # roll back all changes
        odb.update(bdb)

# interactive transfers
while True:
    # test everything
    test(ndb)
    # get input
    print 'Transfer $N from A to B:'
    line = raw_input('Enter "A B N" or 0: ')
    # check for exit
    if line == '0':
        print 'Exit'
        # print account balances
        for a in ndb:
            print 'Account', a, 'has', balance(a, ndb), '$'
        break
    # parse input
    try:
        a, b, n = line.split()
        a = int(a)
        b = int(b)
        n = float(n)
    except:
        print 'Bad input!'
        continue
    # make transfer
    try:
        transfer(a, b, n, ndb)
        print 'Transferred', n, '$ from account', a, 'to', b
    except ValueError as e:
        print e

```

And here's a sample run:

```
Transfer $N from A to B:
Enter "A B N" or 0: 999222 222111 500
Transferred 500.0 $ from account 999222 to 222111

Transfer $N from A to B:
Enter "A B N" or 0: 555222 888333 12
Transferred 12.0 $ from account 555222 to 888333

Transfer $N from A to B:
Enter "A B N" or 0: 222111 555222 14
Transferred 14.0 $ from account 222111 to 555222

Transfer $N from A to B:
Enter "A B N" or 0: 0
Exit
Account 555222 has 58.0 $
Account 123456 has 4.0 $
Account 888333 has 347.13 $
Account 999222 has 9500.56 $
Account 222111 has 609.55 $

```

# Answer
> 1 votes
What about this ?

```
account_numbers = ["999222", "888333", "555222", "222111", "123456"]
account_money   = [10000.56,   335.13,     56.0,   123.55,      0.0]

counting=locals()[locals().keys()[2]]

while True:
    #input in the form of: 999222 777333 500
    input = raw_input()

    if input == "0": break

    counting[-1]+=1
    number1, number2, x = input.split()

    x = float(x)
    if x <= 0:
        print "Invalid request!"
        continue

    if number1 in account_numbers and number2 in account_numbers and number1 != number2:
        index1 = account_numbers.index(number1)
        index2 = account_numbers.index(number2)

        if account_money[index1] >= x:
            account_money[index1] -= x
            account_money[index2] += x
            print "Transferred %.2f$ from %s to %s" % (x, number1, number2)
        else:
            print "Not enough money in account %s!" % (number1)

    else:
        print "Invalid account number(s)!"

for i in range(len(account_numbers)):
    print "Money in account '%s' is %s" % (account_numbers[i], account_money[i])

```

Test:

```
999222 222111 500
Transferred 500.00$ from 999222 to 222111
555222 888333 12
Transferred 12.00$ from 555222 to 888333
222111 555222 14
Transferred 14.00$ from 222111 to 555222
0
Money in account '999222' is 9500.56
Money in account '888333' is 347.13
Money in account '555222' is 58.0
Money in account '222111' is 609.55
Money in account '123456' is 3.0

```

---
Tags: popularity-contest, underhanded
---


title: Leave your mark!

text:
# Question
Title: Leave your mark!
In this challenge, you'll need to edit a grid of characters to make a program that does a task, while ensuring that you leave a lasting mark on the grid.

# Task

The task to perform is determined by when you answer. Specifically, for the `n`th answer, divide `n` by 5, and if the remainder is...

* 0. Read a positive integer from STDIN (or closest alternative) and print its square.
* 1. Print the value of n9-n8+n7-...-n2+n-1.
* 2. Read a string from STDIN (or closest alternative) and print it, reversed.
* 3. Print the name of the language being used.
* 4. Print the first 99 Fibonacci numbers, with some delimiter.

In all cases, "print" means to STDOUT or closest alternative. Leading or trailing whitespace is okay. A full program is required, not just a function.

# Answering (please read before posting)

> This is a "sequential answering" challenge. Answers have a specific order. If the previous answer, chronologically, was titled **Answer `n`**, your answer should be titled **Answer `n+1`**.

All answers are 100 characters (in printable ASCII) long, divided into ten rows. Each row is separated by a newline. I have already posted the first answer.

Once an answer has been verified by another user (in a comment), any user, except for the one who gave the previous answer, can submit the next answer, pursuant to the following rules:

For each answer after the first, change at least one character (but not newlines) in the previous answer to another printable ASCII character achieve the correct task. You may not add, remove, or move any characters. You may use any language with a readily available compiler or interpreter.

Furthermore, you must specify one character you changed to be your "mark". You want to maximize the longevity of your mark. If your mark is first changed by the answer five after yours, its lifespan is 4 (four other answers left it untouched). If no one ever removes your mark, then the lifespan is the total number of other answers after it.

If you answer multiple times, you may have multiple existing marks at once.

If your answer is found incorrect, please delete it if there are no subsequent valid answers. Otherwise, do not delete or change your answers.

# Scoring

Your score is the sum of your marks' longevities, divided by the total number of characters you changed. Subtract 5% from your score for each answer past the first.

For example, suppose I answer three times. First with 5 changes and a mark longevity of 3, then 4 changes and 20, then 1 change and a longevity of 7. My score is now ((3 + 20 + 7) / (5 + 4 + 1)) * (100% - 10%) = 2.7.

# Answer
> 4 votes
# Answer 2, CJam, 6 changed

```
"lass Fun{
 public
  static
void main(
 String[]
args) {
System.out
.print(0);
  }
}";lW%

```

The mark is the `;` in the last line.

Test it here.

# Answer
> 3 votes
# Answer 5, Deadfish, changes 4

Deadfish has no input, thus the *closest alternative to STDIN* is that the number is already stored in the counter. Note that the language can't handle numbers over 255, so the "input" must be between 0 and 15 inclusive.

The `j` in `statjc` is the mark.

```
 var  Fun,
 publjc,
  statjc,
v=2;  f3r(
 S =[1,1];
v<99;){
S[v]=S[v-1
]+S[v++-2]
  o
alert(S)

```

# Answer
> 2 votes
# Answer 3, CJam, 8 changed

```
"lass Fun{
 public
  static
void main(
 String[]
args) {
System.out
.print(0);
  }
";"CJam"

```

Changed the mark (`;`) from Answer 2.

My mark is the second `"` on the last line.

Test it here.

# Answer
> 2 votes
# Answer 6, CJam, changes 13

```
"var  Fun,
 publjc,
";8638UY5"
v=2;  f3r(
 S =[1,1];
v<99;){
S[v]=S[v-1
]+S[v++-2]
  o
alert(S)";

```

Try it online here

My mark is the last `;`

# Answer
> 1 votes
# Answer 4, JavaScript, 56 changed

```
 var  Fun,
 public,
  static,
v=2;  for(
 S =[1,1];
v<99;){
S[v]=S[v-1
]+S[v++-2]
  }
alert(S)
```

Removed the previous mark. My mark is the `}` in the second-to-last line. Unfortunately, JavaScript rounds the really big FIbonacci numbers, but I think it works. (Note that there should be a leading space and 2 trailing spaces that are automatically removed.)

# Answer
> 1 votes
# Answer 7, \>\<\>, changes 14

```
i:0(  !#?^
 publjc,
";8638UY5o
v=2;  f3r:
 S =[1,1];
v<99;){  !
S[v]=S[v-?
]+S[v++-2l
  o
alert(S)"~

```

My mark is the `#` on the first line.

# Answer
> 0 votes
## Answer 1, Java

```
class Fun{
 public
  static
void main(
 String[]
args) {
System.out
.print(0);
  }
}

```

---
Tags: code-challenge, printable-ascii
---