title: Scrappers v0.1: Mercenary Programmers

text:
# Question
Title: Scrappers v0.1: Mercenary Programmers
In a desolate, war-torn world, where cities have been overrun by thugs and thieves, civilization has reinvented itself in the form of small, isolated, industrial cooperatives, scattered throughout the previously uninhabited landscape. The existence of these communities is reliant on teams of mercenary workers called "scrappers", who search the untamed territory for valuable materials to sell to the coops. As these materials have grown more scarce, scrapping has become an ever more difficult and dangerous profession. Fragile human workers have mostly been replaced with remote robotic stand-ins, called “bots”, and a typical mercenary is more likely to be a skilled programmer than an armed welder. As the human presence in scrapping has declined, so too has the respect between mercenary groups for one another. Bots are equipped not only to collect scrap, but to defend it, and in some cases take it by force. Bot programmers work tirelessly devising new strategies to outsmart rival scrappers, resulting in increasingly aggressive bots, and yet another danger for humans who venture outside the walls of their communities.

*(yeah, the logo gets cropped hilariously)*

# Welcome to Scrappers!

*This is an early version of Scrappers in which scrap collection and factories have not been implemented. It’s basically a “shoot ‘em up”.*

You are a mercenary programmer tasked with creating a program to remotely conduct your bots to victory over rival scrapper groups. Your bots are spider-like machines consisting of power and shield generators at their core, surrounded by many appendages equipped with gripping, cutting, and attacking implements. The power generator is capable of producing 12 power units (pu) per tick (a scrapper's unit of time). You are in control of how this power is distributed amongst a bot's three primary needs: movement, shields, and firepower.

Scrapper bots are exceptionally agile machines, and can easily move over, under, and around any obstacles they encounter. Thus, collision is not something that your program needs take into consideration. You are free to allocate all, some, or none of the 12pu available to your bot for movement, as long as you deal in whole numbers. Allocating 0pu to a bot's movement functions would render it immobile. Allocating 2pu would enable a bot to move 2 distance units (du) per tick, 5pu would result in 5du/tick, 11pu would result in 11du/tick, and so on.

Your bots’ shield generators project a bubble of deflective energy around their body. A shield can deflect up to 1 damage before popping, thus leaving your bot exposed until it's shield generator builds enough power to snap the shield back into place. You are free to allocate all, some, or none of the 12pu available to your bot towards it’s shield. Allocating 0pu to a bot's shield means that it will never generate a shield. Allocating 2pu would allow a bot to generate a new shield 2 out of 12 ticks, or once every 6 ticks. 5pu would result in shield regeneration 5 out of every 12 ticks, and so on.

By building up a charge in their welding lasers, your bots can fire damaging beams over short distances with fair accuracy. Like shield generation, your bots’ rate of fire depends on the power allocated to their lasers. Allocating 0pu to a bot's lasers means that it will never fire. Allocating 2pu would allow a bot to fire 2 out of every 12 ticks, and so on. A bot’s laser will travel until it encounters an object or disperses into uselessness, so be mindful of friendly fire. Although your bots are quite accurate, they aren’t perfect. You should expect +/- 2.5 degrees of variance in accuracy. As the laser beam travels, its particles are incrementally deflected by the atmosphere until the beam becomes effectively harmless with enough distance. A laser does 1 damage at point blank range, and 2.5% less damage every bot-length it travels. In other words, the closer you are to your target, the more likely you are to hit it, and the more damage you will cause.

Scrapper bots are autonomous enough to handle basic functions, but rely on you, their programmer, to make them useful as a group. As a programmer, you may issue the following commands for each individual bot:

* MOVE: Specify coordinates towards which a bot will move.
* TARGET: Identify a bot to aim at and fire at when power allocation allows.
* POWER: Redistribute power between movement, shields, and firepower.

# Technical Game Details

There are three programs that you'll need to be familiar with. The Game Engine is the heavy lifter and provides a TCP API that the player programs connect to. The player program is what you'll write, and I've provided some examples with binaries here. Finally, the Renderer processes the output from the Game Engine to produce a GIF of the battle.

## The Game Engine

You can download the game engine from here. When the game is launched, it will begin listening on port 50000 (currently not configurable) for player connections. Once it receives two player connections, it sends the READY message to the players and begins the game. Player programs send commands to the game via the TCP API. When the game is over, a JSON file named scrappers.json (also, currently not configurable) is created. This is what the renderer uses to create a GIF of the game.

## The TCP API

Player programs and the game engine communicate by passing newline-terminated JSON strings back and fourth over a TCP connection. There are just five different JSON messages that can be sent or received.

### Ready Message

The READY message is sent from the game to the player programs and is only sent once. This message tells the player program what its player ID (PID) is and provides a list of all the bots in the game. The PID is the only way to determine which Bots are friendly vs enemy. More info on the bot fields below.

```
{
    "Type":"READY",  // Message type
    "PID":1,         // Player ID
    "Bots":[         // Array of bots
        {
            "Type":"BOT",
            "PID":1,
            "BID":1,
            "X":-592,
            ...
        },
        ...
    ]
}

```

### Bot Message

The BOT message is sent from the game to the player programs and is sent when a bot's attributes change. For instance, when shields are projected, or health changes, a BOT message is sent. The Bot ID (BID) is only unique within a particular player.

```
{
    "Type":"BOT",   // Message type
    "PID":1,        // Player ID
    "BID":1,        // Bot ID
    "X":-592,       // Current X position
    "Y":-706,       // Current Y position
    "Health":12,    // Current health out of 12
    "Fired":false,  // If the Bot fired this tick
    "HitX":0,       // X position of where the shot landed
    "HitY":0,       // Y position of where the shot landed
    "Scrap":0,      // Future use. Ignore.
    "Shield":false  // If the Bot is currently shielded.
}

```

### Move Message

The MOVE message is a command from the player program to the game (but think of it as a command to a bot). Simply identify the bot you want to move, and the coordinates. It's assumed that you are commanding your own bot, so no PID is necessary.

```
{
    "Cmd":"MOVE",
    "BID":1,        // Bot ID
    "X":-592,       // Destination X coordinate
    "Y":-706,       // Destination Y coordinate
}

```

### Target Message

The TARGET message tells one of your bots to target some other bot.

```
{
    "Cmd":"TARGET",
    "BID":1,        // Bot ID
    "TPID":0,       // The PID of the bot being targeted
    "TBID":0,       // The BID of the bot being targeted
}

```

### Power Message

The POWER message reallocates the 12pu available to your bot between movement, firepower, and shields.

```
{
    "Cmd":"POWER",
    "BID":1,        // Bot ID
    "FPow":4,       // Set fire power
    "MPow":4,       // Set move power
    "SPow":4,       // Set shield power
}

```

# The Competition

If you're brave enough to explore the untamed lands, you'll be entered into a double-elimination tournament against your mercenary peers. Please create an answer for your submission and either paste your code or provide a link to a git repo, gist, etc. Any language is acceptable, but you should assume I know nothing about the language and include instructions for running your program. Create as many submissions as you like, and be sure to give them names!

The sample player programs will be included in the tournament, so I highly recommend testing your bot against them. The tournament will commence roughly two weeks after we get four unique program submissions. Good luck!

```
--- Winner's Bracket ---

** Contestants will be randomly seeded **
__________________
                  |___________
__________________|           |
                              |___________
__________________            |           |
                  |___________|           |
__________________|                       |
                                          |________________
__________________                        |                |
                  |___________            |                |
__________________|           |           |                |
                              |___________|                |
__________________            |                            |
                  |___________|                            |
__________________|                                        |
                                                           |
--- Loser's Bracket ---                                    |___________
                                                           |
___________                                                |
           |___________                                    |
___________|           |___________                        |
                       |           |                       |
            ___________|           |                       |
                                   |___________            |
___________                        |           |           |
           |___________            |           |___________|
___________|           |___________|           |
                       |                       |
            ___________|            ___________|

```

# Other Important Info

* The game runs at 12 ticks/second, so you will not receive messages more frequently than every 83 milliseconds or so.
* Each bot is 60du in diameter. The shield takes up no additional space. With the +/- 2.5% accuracy, the odds of hitting a bot at a certain distance are represented by this graph:

* The decay of laser damage over distance is represented by this graph:

* A bot's accuracy and laser decay combine to calculate its average damage per shot. That is, the average damage a bot will cause when it fires from a certain distance. Damage per shot is represented by this graph:

* A bot's laser originates half way between the bot's center and its edge. Thus, stacking your bots will result in friendly fire.
* Enemy bots spawn roughly 1440du apart.
* The game ends if 120 ticks (10 seconds) pass without any damage dealt.
* The winner is the player with the most bots, then the most health when the game ends.

# Understanding the Rendered Image

* Player 1 is represented by circles and player 2 by hexagons.
* The color of a bot represents its power allocation. More red means more power has been allocated to firing. More blue means more shield. More green means more movement.
* The "hole" in a bot's body represents damage. The larger the hole, the more damage has been taken.
* The white circles surrounding a bot are it's shield. If a bot has a shield at the end of the turn, it is shown. If the shield was popped by taking damage, it is not shown.
* The red lines between bots represent shots taken.
* When a bot is killed, a large red "explosion" is shown.

# Answer
# Extremist (Python 3)

This bot will always devote all of its power to one thing: shielding if it isn't shielded, moving if it is out of position, and firing otherwise. Beats all of the sample bots except death-dish.

```
import socket, sys, json
from types import SimpleNamespace
s=socket.socket()
s.connect(("localhost",50000))
f=s.makefile()
bots={1:{},2:{}}
def hook(obj):
    if "BID" in obj:
        try:
            bot = bots[obj["PID"]][obj["BID"]]
        except KeyError:
            bot = SimpleNamespace(**obj)
            bots[bot.PID][bot.BID] = bot
        else:
            bot.__dict__.update(obj)
        return bot
    return SimpleNamespace(**obj)
decoder = json.JSONDecoder(object_hook=hook)
PID = decoder.decode(f.readline()).PID
#side effect: .decode fills bots dictionary
def turtle(bot):
    send({"Cmd":"POWER","BID":bot.BID,"FPow":0,"MPow":0,"SPow":12})
    bot.firing = bot.moving = False
def send(msg):
    s.send(json.dumps(msg).encode("ascii")+b"\n")
for bot in bots[PID].values():
    turtle(bot)
target_bot = None
def calc_target_bot():
    ok_bots = []
    for bot2 in bots[(2-PID)+1].values():
        if bot2.Health < 12:
            ok_bots.append(bot2)
    best_bot = (None,2147483647)
    for bot2 in (ok_bots or bots[(2-PID)+1].values()):
        dist = bot_dist(bot, bot2)
        if dist < best_bot[1]:
            best_bot = bot2, dist
    return best_bot[0]
def bot_dist(bot, bot2):
    if isinstance(bot, tuple):
        bot=SimpleNamespace(X=bot[0],Y=bot[1])
    if isinstance(bot2, tuple):
        bot=SimpleNamespace(X=bot[0],Y=bot[1])
    distx = bot2.X - bot.X
    disty = bot2.Y - bot.Y
    return (distx**2+disty**2)**.5
LENGTH_Y = -80
LENGTH_X = 80
line = None
def move(bot, pos):
    bot.firing = False
    bot.moving = True
    send({"Cmd":"POWER","BID":bot.BID,"FPow":0,"MPow":12,"SPow":0})
    send({"Cmd":"MOVE","BID": bot.BID,"X":pos[0],"Y":pos[1]})
def go(bot, line):
    if line != None:
        position = (line[0]+LENGTH_X*(bot.BID-6),line[1]+LENGTH_Y*(bot.BID-6))
        if not close_pos(bot, position, 1.5):
            return True, position
    return False, None
def close_pos(bot, pos, f):
    if abs(bot.X - pos[0]) <= abs(LENGTH_X*f) or \
        abs(bot.Y - pos[1]) <= abs(LENGTH_Y*f):
        return True
def set_line(bot):
    global line
    newline = bot.X - LENGTH_X*(bot.BID - 6), bot.Y - LENGTH_Y*(bot.BID - 6)
    if line == None or bot_dist(line, target_bot) < (bot_dist(newline, target_bot) - 100):
        line = newline
def move_or_fire(bot):
    global target_bot, line
    if not target_bot:
        target_bot = calc_target_bot()
    followline, place = go(bot, line)
    if not target_bot:
        #Game should be over, but just in case ...
        return turtle(bot)
    elif bot_dist(bot, target_bot) > 2000:
        line = None
        position = (target_bot.X, target_bot.Y)
        position = (position[0]+LENGTH_X*(bot.BID-6),position[1]+LENGTH_Y*(bot.BID-6))
        move(bot, position)
    elif followline:
        set_line(bot)
        move(bot, place)
    elif any(close_pos(bot, (bot2.X, bot2.Y), .6) for bot2 in bots[PID].values() if bot != bot2):
        try:
            move(bot, place)
        except TypeError:
            turtle(bot)
        set_line(bot)
        #Let the conflicting bots resolve
    else:
        set_line(bot)
        bot.firing = True
        bot.moving = False
        send({"Cmd":"POWER","BID":bot.BID,"FPow":12,"MPow":0,"SPow":0})
        send({"Cmd":"TARGET","BID": bot.BID,
              "TPID":target_bot.PID,"TBID":target_bot.BID})
def dead(bot):
    del bots[bot.PID][bot.BID]
def parse_message():
    global target_bot
    line = f.readline()
    if not line:
        return False
    bot = decoder.decode(line)
    assert bot.Type == "BOT"
    del bot.Type
    if bot.PID == PID:
        if bot.Health <= 0:
            dead(bot)
        elif not bot.Shield:
            turtle(bot)
        else:
            move_or_fire(bot)
    elif target_bot and (bot.BID == target_bot.BID):
        target_bot = bot
        if target_bot.Health <= 0:
            target_bot = None
            dead(bot)
            for bot in bots[PID].values():
                if bot.firing or bot.moving:
                    move_or_fire(bot)
    elif bot.Health <= 0:
        dead(bot)
    assert bot.Health > 0 or bot.BID not in bots[bot.PID]
    return True
while parse_message():
    pass

```
> 4 votes

# Answer
# Less Reckless (Go)

```
go run main.go

```

Originally, I planned to slightly modify the Reckless Abandon sample program so that bots would not fire if a friendly bot was in the way. I ended up with bots that pick new targets when a friend is in the way, which I guess is better. It'll beat the first two programs.

The code isn't perfect. The logic to determine if a shot is clear uses some pretty random guesswork.

There doesn't seem to be a mechanism to target "nobody". That might be a good feature to add.

The TCP API is nice in that any language can play, but it also means a lot of boilerplate code. If I wasn't familiar with the language the sample bots were written in, I probably wouldn't have been motivated to play around with this. A collection of boilerplate samples in various languages would be a great addition to your other git repos.

( most of the following code is copy/paste from one of the sample bots )

```
package main

import (
    "bufio"
    "encoding/json"
    "flag"
    "io"
    "log"
    "math"
    "math/rand"
    "net"
    "time"
)

const (
    MaxHealth int = 12
    BotSize float64 = 60
)

var (
    // TCP connection to game.
    gameConn net.Conn
    // Queue of incoming messages
    msgQueue chan MsgQueueItem
)

// MsgQueueItem is a simple vehicle for TCP
// data on the incoming message queue.
type MsgQueueItem struct {
    Msg string
    Err error
}

// Command contains all the fields that a player might
// pass as part of a command. Fill in the fields that
// matter, then marshal into JSON and send.
type Command struct {
    Cmd  string
    BID  int
    X    int
    Y    int
    TPID int
    TBID int
    FPow int
    MPow int
    SPow int
}

// Msg is used to unmarshal every message in order
// to check what type of message it is.
type Msg struct {
    Type string
}

// BotMsg is used to unmarshal a BOT representation
// sent from the game.
type BotMsg struct {
    PID, BID   int
    X, Y       int
    Health     int
    Fired      bool
    HitX, HitY int
    Scrap      int
    Shield     bool
}

// ReadyMsg is used to unmarshal the READY
// message sent from the game.
type ReadyMsg struct {
    PID  int
    Bots []BotMsg
}

// Create our game data storage location
var gdb GameDatabase

func main() {

    var err error
    gdb = GameDatabase{}
    msgQueue = make(chan MsgQueueItem, 1200)

    // What port should we connect to?
    var port string
    flag.StringVar(&port, "port", "50000", "Port that Scrappers game is listening on.")
    flag.Parse()

    // Connect to the game
    gameConn, err = net.Dial("tcp", ":"+port)
    if err != nil {
        log.Fatalf("Failed to connect to game: %v\n", err)
    }
    defer gameConn.Close()

    // Process messages off the incoming message queue
    go processMsgs()

    // Listen for message from the game, exit if connection
    // closes, add message to message queue.
    reader := bufio.NewReader(gameConn)
    for {
        msg, err := reader.ReadString('\n')
        if err == io.EOF {
            log.Println("Game over (connection closed).")
            return
        }
        msgQueue <- MsgQueueItem{msg, err}
    }
}

func runStrategy() {

    // LESS RECKLESS ABANDON
    // - For three seconds, all bots move as fast as possible in a random direction.
    // - After three seconds, split power between speed and firepower.
    // - Loop...
    //     - Identify the enemy bot with the lowest health.
    //     - If a friendly bot is in the way, pick someone else.
    //     - If there's a tie, pick the one closest to the group.
    //     - Everybody moves towards and targets the bot.

    var myBots []*GDBBot

    // Move quickly in random direction.
    // Also, might as well get a shield.
    myBots = gdb.MyBots()
    for _, bot := range myBots {
        send(bot.Power(0, 11, 1))
        radians := 2.0 * math.Pi * rand.Float64()
        x := bot.X + int(math.Cos(radians)*999)
        y := bot.Y + int(math.Sin(radians)*999)
        send(bot.Move(x, y))
    }

    // Wait three seconds
    time.Sleep(3 * time.Second)

    // Split power between speed and fire
    for _, bot := range myBots {
        send(bot.Power(6, 6, 0))
    }

    for { // Loop indefinitely

        // Find a target

        candidates := gdb.TheirBots()

        // Order by health
        reordered := true
        for reordered {
            reordered = false
            for n:=1; n<len(candidates); n++ {
                if candidates[n].Health < candidates[n-1].Health {
                    temp := candidates[n-1]
                    candidates[n-1] = candidates[n]
                    candidates[n] = temp
                    reordered = true
                }
            }
        }

        // Order by closeness

        // My swarm position is...
        ttlX, ttlY := 0, 0
        myBots = gdb.MyBots() // Refresh friendly bot list
        for _, bot := range myBots {
            ttlX += bot.X
            ttlY += bot.Y
        }
        avgX := ttlX / len(myBots)
        avgY := ttlY / len(myBots)

        // Sort
        reordered = true
        for reordered {
            reordered = false
            for n:=1; n<len(candidates); n++ {
                thisDist := distance(avgX, avgY, candidates[n].X, candidates[n].Y)
                lastDist := distance(avgX, avgY, candidates[n-1].X, candidates[n-1].Y)
                if thisDist < lastDist {
                    temp := candidates[n-1]
                    candidates[n-1] = candidates[n]
                    candidates[n] = temp
                    reordered = true
                }
            }
        }

        // For all my bots, try to find the weakest enemy that my bot has a clear shot at
        myBots = gdb.MyBots()
        for _, bot := range myBots {
            for _, enemy := range candidates {

                clear := clearShot(bot, enemy)
                if clear {

                    // Target and move towards
                    send(bot.Target(enemy))
                    send(bot.Follow(enemy))
                    break
                }
                log.Println("NO CLEAR SHOT")
            }
        }

        time.Sleep(time.Second / 24)
    }
}

func clearShot(bot, enemy *GDBBot) bool {

    deg45rad := math.Pi*45/180
    deg30rad := math.Pi*30/180
    deg15rad := math.Pi*15/180
    deg5rad := math.Pi*5/180

    myBots := gdb.MyBots()
    enmyAngle := math.Atan2(float64(enemy.Y-bot.Y), float64(enemy.X-bot.X))

    for _, friend := range myBots {

        dist := distance(bot.X, bot.Y, friend.X, friend.Y)
        angle := math.Atan2(float64(friend.Y-bot.Y), float64(friend.X-bot.X))
        safeAngle := angle

        if dist < BotSize*3 {
            safeAngle = deg45rad/2
        } else if dist < BotSize*6 {
            safeAngle = deg30rad/2
        } else if dist < BotSize*9 {
            safeAngle = deg15rad/2
        } else {
            safeAngle = deg5rad/2
        }

        if angle <= enmyAngle+safeAngle &&  angle >= enmyAngle-safeAngle {
            return false
        }
    }

    return true
}

func processMsgs() {

    for {
        queueItem := <-msgQueue
        jsonmsg := queueItem.Msg
        err := queueItem.Err

        if err != nil {
            log.Printf("Unknown error reading from connection: %v", err)
            continue
        }

        // Determine the type of message first
        var msg Msg
        err = json.Unmarshal([]byte(jsonmsg), &msg)
        if err != nil {
            log.Printf("Failed to marshal json message %v: %v\n", jsonmsg, err)
            return
        }

        // Handle the message type

        // The READY message should be the first we get. We
        // process all the data, then kick off our strategy.
        if msg.Type == "READY" {

            // Unmarshal the data
            var ready ReadyMsg
            err = json.Unmarshal([]byte(jsonmsg), &ready)
            if err != nil {
                log.Printf("Failed to marshal json message %v: %v\n", jsonmsg, err)
            }

            // Save our player ID
            gdb.PID = ready.PID
            log.Printf("My player ID is %v.\n", gdb.PID)

            // Save the bots
            for _, bot := range ready.Bots {
                gdb.InsertUpdateBot(bot)
            }

            // Kick off our strategy
            go runStrategy()

            continue
        }

        // The BOT message is sent when something about a bot changes.
        if msg.Type == "BOT" {

            // Unmarshal the data
            var bot BotMsg
            err = json.Unmarshal([]byte(jsonmsg), &bot)
            if err != nil {
                log.Printf("Failed to marshal json message %v: %v\n", jsonmsg, err)
            }

            // Update or add the bot
            gdb.InsertUpdateBot(bot)

            continue
        }

        // If we've gotten to this point, then we
        // were sent a message we don't understand.
        log.Printf("Recieved unknown message type \"%v\".", msg.Type)
    }
}

///////////////////
// GAME DATABASE //
///////////////////

// GameDatabase stores all the data
// sent to us by the game.
type GameDatabase struct {
    Bots []GDBBot
    PID  int
}

// GDBBot is the Bot struct for the Game Database.
type GDBBot struct {
    BID, PID int
    X, Y     int
    Health   int
}

// InserUpdateBot either updates a bot's info,
// deletes a dead bot, or adds a new bot.
func (gdb *GameDatabase) InsertUpdateBot(b BotMsg) {

    // If this is a dead bot, remove and ignore
    if b.Health <= 0 {

        for i := 0; i < len(gdb.Bots); i++ {
            if gdb.Bots[i].BID == b.BID && gdb.Bots[i].PID == b.PID {
                gdb.Bots = append(gdb.Bots[:i], gdb.Bots[i+1:]...)
                return
            }
        }
        return
    }

    // Otherwise, update...
    for i, bot := range gdb.Bots {
        if b.BID == bot.BID && b.PID == bot.PID {
            gdb.Bots[i].X = b.X
            gdb.Bots[i].Y = b.Y
            gdb.Bots[i].Health = b.Health
            return
        }
    }

    // ... or Add
    bot := GDBBot{}
    bot.PID = b.PID
    bot.BID = b.BID
    bot.X = b.X
    bot.Y = b.Y
    bot.Health = b.Health
    gdb.Bots = append(gdb.Bots, bot)
}

// MyBots returns a pointer array of GDBBots owned by us.
func (gdb *GameDatabase) MyBots() []*GDBBot {
    bots := make([]*GDBBot, 0)
    for i, bot := range gdb.Bots {
        if bot.PID == gdb.PID {
            bots = append(bots, &gdb.Bots[i])
        }
    }
    return bots
}

// TheirBots returns a pointer array of GDBBots NOT owned by us.
func (gdb *GameDatabase) TheirBots() []*GDBBot {
    bots := make([]*GDBBot, 0)
    for i, bot := range gdb.Bots {
        if bot.PID != gdb.PID {
            bots = append(bots, &gdb.Bots[i])
        }
    }
    return bots
}

// Move returns a command struct for movement.
func (b *GDBBot) Move(x, y int) Command {
    cmd := Command{}
    cmd.Cmd = "MOVE"
    cmd.BID = b.BID
    cmd.X = x
    cmd.Y = y
    return cmd
}

// Follow is a convenience function which returns a
// command stuct for movement using a bot as a destination.
func (b *GDBBot) Follow(bot *GDBBot) Command {
    cmd := Command{}
    cmd.Cmd = "MOVE"
    cmd.BID = b.BID
    cmd.X = bot.X
    cmd.Y = bot.Y
    return cmd
}

// Target returns a command struct for targeting a bot.
func (b *GDBBot) Target(bot *GDBBot) Command {
    cmd := Command{}
    cmd.Cmd = "TARGET"
    cmd.BID = b.BID
    cmd.TPID = bot.PID
    cmd.TBID = bot.BID
    return cmd
}

// Power returns a command struct for seting the power of a bot.
func (b *GDBBot) Power(fire, move, shield int) Command {
    cmd := Command{}
    cmd.Cmd = "POWER"
    cmd.BID = b.BID
    cmd.FPow = fire
    cmd.MPow = move
    cmd.SPow = shield
    return cmd
}

////////////////////
// MISC FUNCTIONS //
////////////////////

// Send marshals a command to JSON and sends to the game.
func send(cmd Command) {
    bytes, err := json.Marshal(cmd)
    if err != nil {
        log.Fatalf("Failed to mashal command into JSON: %v\n", err)
    }
    bytes = append(bytes, []byte("\n")...)
    gameConn.Write(bytes)
}

// Distance calculates the distance between two points.
func distance(xa, ya, xb, yb int) float64 {
    xdist := float64(xb - xa)
    ydist := float64(yb - ya)
    return math.Sqrt(math.Pow(xdist, 2) + math.Pow(ydist, 2))
}

```
> 2 votes

# Answer
**Trigger Happy - Java 8**

Trigger Happy is a simple evolution of my original, but no longer viable, Bombard bot. It is a very simple bot that will simply fire on the currently targeted enemy if there is a clear shot, otherwise performs a random walk to try to get into a better position. All the time attempting to have a shield.

However, for all its simplicity it is very effective. And will readily destroy the sample bots.

Note, there are multiple bugs with the bot such as will sometimes fire even when not a clear shot and may not maintain a shield... but it is still effective so will just submit this entry as-is

Death-dish vs Trigger Happy

Code as follows:

```
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

//import visual.Viewer;

public class TriggerHappy {

  static final int BOT_RADIUS = 30;
private static final double WALK_MAX_DIRECTION_CHANGE = Math.PI/3;
  static Bot targetedBot;

  enum BotState
  {
    INIT,
    RANDOM_WALK,
    FIRING,
    SHIELDING,
    DEAD,
    END
  }

  enum Power
  {
    MOVE,
    FIRE,
    SHIELD
  }

  private static PrintStream out;
private static List<Bot> enemyBots;
private static List<Bot> myBots;
//private static Viewer viewer;

  public static void main(String[] args) throws Exception
  {
    InetAddress localhost = Inet4Address.getLocalHost();
    Socket socket = new Socket(localhost, 50000);
    InputStream is = socket.getInputStream();
    out = new PrintStream(socket.getOutputStream());

    // read in the game configuration
    String line = readLine(is);
    Configuration config = new Configuration(line);
  //  viewer = new Viewer(line);

    myBots = config.bots.values().stream().filter(b->b.playerId==config.playerId).collect(Collectors.toList());
    enemyBots = config.bots.values().stream().filter(b->b.playerId!=config.playerId).collect(Collectors.toList());

    // set initial target
    targetedBot = enemyBots.get(enemyBots.size()/2);
    myBots.forEach(bot->target(bot,targetedBot));

    for (line = readLine(is);line!=null;line = readLine(is))
    {
//      viewer.update(line);
      // read in next bot update message from server
      Bot updatedBot = new Bot(line);
      Bot currentBot = config.bots.get(updatedBot.uniqueId);
      currentBot.update(updatedBot);

      // check for bot health
      if (currentBot.health<1)
      {
        // remove dead bots from lists
        currentBot.state=BotState.DEAD;
        if (currentBot.playerId == config.playerId)
        {
          myBots.remove(currentBot);
        }
        else
        {
          enemyBots.remove(currentBot);

          // change target if the targetted bot is dead
          if (currentBot == targetedBot)
          {
            if (enemyBots.size()>0)
            {
              targetedBot = enemyBots.get(enemyBots.size()/2);
              myBots.forEach(bot->target(bot,targetedBot));
            }
            // no more enemies... set bots to end state
            else
            {
              myBots.forEach(bot->bot.state = BotState.END);
            }
          }
        }
      }
      else
      {
          // ensure our first priority is shielding
          if (!currentBot.shield && currentBot.state!=BotState.SHIELDING)
          {
              currentBot.state=BotState.SHIELDING;
              shield(currentBot);
          }
          else
          {
              // not game end...
              if (currentBot.state != BotState.END)
              {
                // command to fire if we have a clear shot
                if (clearShot(currentBot))
                {
                    currentBot.state=BotState.FIRING;
                    fire(currentBot);
                }
                // randomly walk to try and get into a better position to fire
                else
                {
                    currentBot.state=BotState.RANDOM_WALK;
                    currentBot.dir+=Math.random()*WALK_MAX_DIRECTION_CHANGE - WALK_MAX_DIRECTION_CHANGE/2;
                    move(currentBot, (int)(currentBot.x+Math.cos(currentBot.dir)*100), (int) (currentBot.y+Math.sin(currentBot.dir)*100));
                }

              }
          }
      }
    }
    is.close();
    socket.close();
  }

// returns true if there are no friendly bots in firing line... mostly
private static boolean clearShot(Bot originBot)
{

    double originToTargetDistance = originBot.distanceFrom(targetedBot);
    for (Bot bot : myBots)
    {
        if (bot != originBot)
        {
            double x1 = originBot.x - bot.x;
            double x2 = targetedBot.x - bot.x;
            double y1 = originBot.y - bot.y;
            double y2 = targetedBot.y - bot.y;
            double dx = x2-x1;
            double dy = y2-y1;
            double dsquared = dx*dx + dy*dy;
            double D = x1*y2 - x2*y1;
            if (1.5*BOT_RADIUS * 1.5*BOT_RADIUS * dsquared > D * D && bot.distanceFrom(targetedBot) < originToTargetDistance)
            {
                return false;
            }
        }
    }

    return true;

}

  static class Bot
  {
    int playerId;
    int botId;
    int x;
    int y;
    int health;
    boolean fired;
    int hitX;
    int hitY;
    double dir = Math.PI*2*Math.random();
    boolean shield;
    int uniqueId;
    BotState state = BotState.INIT;
    Power power = Power.SHIELD;

    Bot(String line)
    {
      String[] tokens = line.split(",");
      playerId = extractInt(tokens[1]);
      botId = extractInt(tokens[2]);
      x = extractInt(tokens[3]);
      y = extractInt(tokens[4]);
      health = extractInt(tokens[5]);
      fired = extractBoolean(tokens[6]);
      hitX = extractInt(tokens[7]);
      hitY = extractInt(tokens[8]);
      shield = extractBoolean(tokens[10]);
      uniqueId = playerId*10000+botId;
    }

    Bot()
    {
    }

    double distanceFrom(Bot other)
    {
        return distanceFrom(new Point(other.x,other.y));
    }

    double distanceFrom(Point other)
    {
        double deltaX = x - other.x;
        double deltaY = y - other.y;
        return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
    }

    void update(Bot other)
    {
      x = other.x;
      y = other.y;
      health = other.health;
      fired = other.fired;
      hitX = other.hitX;
      hitY = other.hitY;
      shield = other.shield;
    }
  }

  static class Configuration
  {
    BotState groupState = BotState.INIT;
    HashMap<Integer,Bot> bots = new HashMap<>();
    boolean isOpponentInitiated;
    int playerId;

    Configuration(String line) throws Exception
    {
      String[] tokens = line.split("\\[");
      playerId = extractInt(tokens[0].split(",")[1]);

      for (String token : tokens[1].split("\\|"))
      {
        Bot bot = new Bot(token);
        bots.put(bot.uniqueId,bot);
      }
    }
  }

  /**
   * Reads a line of text from the input stream. Blocks until a new line character is read.
   * NOTE: This method should be used in favor of BufferedReader.readLine(...) as BufferedReader buffers data before performing
   * text line tokenization. This means that BufferedReader.readLine() will block until many game frames have been received.
   * @param in a InputStream, nominally System.in
   * @return a line of text or null if end of stream.
   * @throws IOException
   */
  static String readLine(InputStream in) throws IOException
  {
     StringBuilder sb = new StringBuilder();
     int readByte = in.read();
     while (readByte>-1 && readByte!= '\n')
     {
        sb.append((char) readByte);
        readByte = in.read();
     }
     return readByte==-1?null:sb.toString().replace(",{", "|").replaceAll("}", "");

  }

  final static class Point
  {
    public Point(int x2, int y2) {
        x=x2;
        y=y2;
    }
    int x;
    int y;
  }

  public static int extractInt(String token)
  {
    return Integer.parseInt(token.split(":")[1]);
  }

  public static boolean extractBoolean(String token)
  {
    return Boolean.parseBoolean(token.split(":")[1]);
  }

  static void distributePower(Bot bot, int fire, int move, int shield)
  {
    out.println("{\"Cmd\":\"POWER\",\"BID\":"+bot.botId+",\"FPow\":"+fire+",\"MPow\":"+move+",\"SPow\":"+shield+"}");
//  viewer.distributePower(bot.botId, fire, move, shield);
  }

  static void shield(Bot bot)
  {
    distributePower(bot,0,0,12);
    bot.power=Power.SHIELD;
  }

  static void move(Bot bot, int x, int y)
  {
    distributePower(bot,0,12,0);
    out.println("{\"Cmd\":\"MOVE\",\"BID\":"+bot.botId+",\"X\":"+x+",\"Y\":"+y+"}");
  }
  static void target(Bot bot, Bot target)
  {
    out.println("{\"Cmd\":\"TARGET\",\"BID\":"+bot.botId+",\"TPID\":"+target.playerId+",\"TBID\":"+target.botId+"}");
  }

  static void fire(Bot bot)
  {
    distributePower(bot,12,0,0);
    bot.power=Power.FIRE;
  }
}

```

To compile: javac TriggerHappy.java

To run: java TriggerHappy
> 2 votes

---
Tags: king-of-the-hill
---


title: Let's play POKE!

text:
# Question
Title: Let's play POKE!
Poke is a really simple incomplete-information game. It's like "Poker", but simpler. At the start of every round, each player is dealt a hand. To simplify things, a hand is a uniformly distributed random number between 0 and 1. Each player only knows their own hand. The player that wins the round is the one whose hand has the greatest value.

Every turn, all the players who are still in the round make a bet that they're the player with the best hand. Each player has to decide whether or not to match the largest bet. If they match it, that amount is added to the pot from their account. If they choose not to match it, they drop out of the round. Even if they had the best hand, they can't win once they drop out, and they lose everything they had in the pot. At the end of the round, the player with the best hand out of those that haven't dropped wins. (Each player knows how many turns are gonna be in the round since the start of the round).

The winner is the one that makes the most money after a large number of rounds (hundreds, or thousands). In order to compete, write a struct that inherits from this "player" class:

```
class player
{
private:
    double _hand;
    game* _owner = 0;
public:
    //You must provide
    bool set_new_owner(game* current, game* new_owner) {
    if(current == _owner) { _owner = new_owner; return true; }
    return false;
    }
    bool set_new_hand(game* current, double new_hand) {
    if(current == _owner) { _hand = new_hand; return true; }
    return false;
    }
    double hand() const { return _hand; }
    virtual double bet(const round_info&) = 0;
    virtual bool take_bet(const round_info&) = 0;
    virtual std::string name() { return typeid(*this).name(); }
    virtual ~player() {}
};

```

All you need to do is specialize the "bet" function (which determines how much your player bets each turn), and the "take\_bet" function (which determines whether or not to take the bet. Here are some examples:

```
struct grog : player
{
    //Always bets the minimum amount
    double bet(const round_info&) { return 1.0; }
    //Takes any bet
    bool take_bet(const round_info&) { return true; }
    string name() { return "Grog"; }
};
struct bob : player
{
    //Bet the minimum amount
    double bet(const round_info&) { return 1.0; }
    //Only take bets when you have a good hand
    bool take_bet(const round_info&) { return hand() > 0.95; }
    string name() { return "Bob"; }
};
struct james : player
{
    //Raise the bet a lot if you have a *really* good hand
    double bet(const round_info&) {
        if(hand() > 0.99) return 1000.0;
        else return 1.0;
    }
    //Only take bets when you have a *really* good hand
    bool take_bet(const round_info&) { return hand() > 0.99; }
    string name() { return "James"; }
};
struct rainman : player
{
    //Play it safe
    double bet(const round_info&) { return 1.0; }
    bool take_bet(const round_info& r)
    {
        double cost = r.current_max_bet();
        double winnings = r.winnings() + r.current_max_bet() * r.n_active_players();
        int players = r.n_players();
        double hand = this->hand();
        double p_win = pow(hand,players - 1);
        double p_loss = 1 - p_win;
        double gain = -(cost * p_loss) + p_win * winnings;
        if(gain > 0) return true;
        return false;
    }
    string name() { return "Rainman"; }
};

```

If all four people are playing, then over a few thousand games, James will be the winner and Rainman will do worse than anyone but Grog. But if only Bob, Grog, and Rainman are playing, Rainman will clean the floor with the other players (and win tons of money).

**Edit:** Here is the code for `round_info` and for the class that will manage the game. https://github.com/Artifexian/PokeGame

**Edit 2:** If you submit something not in C++, I can try to translate it into C++ for you. If you want me to, I will edit your answer and append my translated version.

**Edit 3:** I will work to write a wrapper for non-c++ languages. Your solution must include 2 functions: something to determine how much to bet (which should return a floating point value), and something to determine whether or not to stay in the round (which should return true or false). Contact me about your preferring input format. I will write something to translate "round\_info" into text. The data provided as text will be the same data provided to everyone else. It will include:

1. The current turn number
2. The maximum number of turns (when the round ends)
3. The number of players
4. The number of players who haven't dropped out
5. The history of what each player has bet
6. A list of which players haven't dropped out
7. The size of the pot
8. The current maximum bet amount (what you have to put down to stay in the game)
9. Your hand

**Edit 4:** Any bets made by players will be clipped to be between 1 and 10^6

# Answer
## Frequent Folder

The more players there are, the lower the odds of winning. Thus, this player only takes bets when he thinks his hand is high, using the starting number of players as a guideline.

```
struct frequent_folder : player
{
    //Bets fairly heavily under same conditions a bet is taken
    //Bet varies based on how good hand is
    double bet(const round_info& r) {
        double numer = hand() - (1 - (1/r.n_players)), denom = 1 - (1 - (1/r.n_players));
        double qty = 250 * (numer/denom);
        return qty > 1 ? qty : 1.0;
    }

    //Take bet only if likely to have highest hand
    //e.g. 2 players -> 0.5+, 3 players -> 0.67+, 4 players -> 0.75+
    bool take_bet(const round_info& r) { return(hand() >= 1 - (1/r.n_players())); }

    string name() { return "Frequent Folder"; }
};

```

---

## Bluffer

Where the Frequent Folder plays a very conservative strategy, the Bluffer lives on the edge. He bets heavily with a hand he thinks can win... or a hand he *knows* will lose. He takes favorable bets more often than he bluffs, hoping this will mean net gain, but the probability of a bluff is high enough that strategies analyzing previous bets may be thrown off by the Bluffer's erratic behavior.

```
struct bluffer : player
{
    //Bets hard with an excellent hand... or a very poor one!  Small bet otherwise
    double bet(const round_info&) { (return hand() > 0.9 || hand() < 0.05) ? 500.0 : 1.0; }

    //Take bet with an excellent hand... or a very poor one!
    bool take_bet(const round_info& r) { return(hand() > 0.9 || hand() < 0.05; }

    string name() { return "Bluffer"; }
};

```

These are my first entries on KotH as well as SE as a whole. I hope everyone finds them up to snuff.
> 5 votes

# Answer
# Gambling Russian

Simulates a person who is also playing Russian Roulette. There is a 1 in 6 chance he dies playing Russian Roulette, thus he will stop making bets once he has died. Every time he survives he gets so excited he bets as much as he possibly can because he believes he is on a good luck streak. If there is something smelly about my code let me know.

```
struct gambling_russian : player
{
  bool alive = true;

  double bet(const round_info&) { return DBL_MAX; };

  bool take_bet(const round_info&)
  {
    if(hand < (1.0/6.0)){
      alive = false;
    }
    return alive;
  }

  string name() { return "Gambling Russian"; }
}

```
> 3 votes

# Answer
I'll get this started with a simple player, who will randomly take bets based on the quality of his hand.

```
struct ronald : player
{
  double bet(const round_info&) { return fmax( 1.0, hand()*2 ); };

  bool take_bet(const round_info&)
  {
    double p = (double)rand() / RAND_MAX;
    return hand()>p;
  }

  string name() { return "Ronald"; }
}

```
> 1 votes

# Answer
# The Thinker

```
struct theThinker: player
{
    //Raise the bet depending on hand value, but less if the pot has a lot already
    double bet(const round_info&) {
        double b = hand() * hand() * 1000.0 - round_info.winnings() / 10.0;
        return b > 1.0 ? b : 1.0;
    }
    //Take bets when the pot and hand look better than the amount you may loose
    bool take_bet(const round_info&) {
        return hand() * (round_info.winnings() + 1000.0) > current_max_bet();
    }
    string name() { return "The Thinker"; }
};

```
> 1 votes

---
Tags: king-of-the-hill, c++, statistics
---


title: Tips for golfing in Processing

text:
# Question
Title: Tips for golfing in Processing
Does anyone have any tips for golfing in Processing? It is a graphical extension of java, and is somewhat difficult to golf.

# Answer
> 8 votes
* If no animation is required, you can skip the `void draw()` and put everything into `void setup()`.
* Initialising the size of the canvas is sometimes not necessary - it will be initialised to `(100, 100)` by default.
* If you need to use `height` and `width` in your code, it is usually shorter to use their numeric values instead. For example, with a canvas of size `(100, 100)`, using `99` to replace `height` and `width` can save you 7 bytes.

# Answer
> 3 votes
If you only run code in the setup method then you don't need write the method outline. For example you can write:

```
rect(10,10,90,90);

```

instead of

```
void setup {
    rect(10,10,90,90);
}

```

And as long as you don't use any other methods then everything will be put in the setup method before running

# Answer
> 3 votes
# White `#FFFFFF`

Related: Colour Notation

Instead of using this for white:

```
color(255)     //10 bytes

```

you can do this:

```
color(-1)      //9 bytes

```

and save 1 byte.

# Answer
> 2 votes
# Colours `(R, G, B)` notation

### Hexadecimal colours

Processing is very flexible in colour format.

```
fill(255,255,0); //16 bytes

```

can be written using hexadecimal notation as

```
fill(#ffff00);   //14 bytes (2 bytes saved)

```

### Grayscale

Here is a special usage for colours if all the Red, Green and the Blue values are the same (white):

```
fill(255,255,255); //18 bytes
fill(#ffffff);     //14 bytes
fill(255);         //10 bytes

```

All the three parameters can be shortened into one parameter containing the grayscale value: from `0` black to `255` white.

This can be extended for alpha as well:

```
fill(175,175,175,50); //translucent gray
fill(175,50);         //8 bytes shorter

```

Both mean the same colour, but the latter way is shorter by 8 bytes.

### Alpha

Although obvious, it should be stated that the alpha parameter in specifying colours is optional since colours are defaulted to an alpha value of `255` (100% opaque).

# Summary: Color formats

Use the shortest colour format to express your colour (remember to leave out unnecessary bits -depending on the context of the program- for example: alpha or grayscale)

`R`: Red `G`: green `B`: blue `A`: alpha `g`: grayscale

```
RRR,GGG,BBB
#RRGGBB
ggg
RRR,GGG,BBB,AAA
ggg,AAA

```

# Answer
> 2 votes
## Abbreviate constants

If you're ever using one of the all-caps keywords in Processing (such as `DIFFERENCE` or `TRIANGLE_FAN`), see if the number they correspond to is shorter.

For example, `DIFFERENCE` is just an `int` that's equal to 32. Instead of using `DIFFERENCE` here, I could write `32`, saving 8 characters.

# Answer
> 2 votes
# Shorter alternative to `void keyPressed(){}`

```
void draw(){}void keyPressed(){foo;} //36 bytes
void draw(){if(key>0)foo;}           //26 bytes

```

The `void draw(){}` is needed by default in order for `key` to be updated. If the user hasn't pressed a key since the start of the program, `key` is given a value of `0`. By checking if it is more than `0` (ie the user has pressed a key), we have golfier code and save 10 bytes.

# Answer
> 1 votes
# Setting and committing pixels using set()

It's more efficient to set pixels via pixels\[\]:

```
pixels[0] = color(255)
updatePixels();

```

However, that requires `updatePixels()` and also using an index which depending on the scenario will require converting an x,y position to a pixel index. To keep things short, even though it's less CPU efficient (as each call updates the whole buffer), set() allows a pixel to set and committed to buffer straight away in one call.

```
set(0,0,color(255));

```

---
Tags: code-golf, tips
---


title: Who owes who money?

text:
# Question
Title: Who owes who money?
The Dank Memes Casino is one of the best casinos of the world. They have a rule that if you win or lose money, you will be paid at the beginning of the next month.

But, catastrophe struck and there was an earthquake, which demolished the casino.

Now, all the poker players have gathered and realised that the casino is not the person that owes them money or they do not owe the casino money, but as a matter of fact, they owe each other!

Your mission, should you choose to accept, will be to find out who owes who money.

Also, do keep in mind that the shortest code wins.

## Input

The first line contains the names of the people separated by spaces (Let there be n names).

The second line contains n integers, the ith of which denotes the ith person's winnings or losings at poker. A positive number means that he is owed money from someone, whereas a negative number entails that he owes someone money.

Flexible input methods are accepted.

## Output

Print out as many lines as required. Each line should contain the name of the person who owes the money, the name of the person who is owed money, the amount of money that is owed separated by a space.

## Input Constraints

2 \<= n \<= 6

-100000 \<= amount of money \<= 100000

## Guaranteed Constraints

Sum of all integers in the array = 0

# Sample Test Cases

## Test Case 1

Sample Input

```
Messi Ronaldo Hazard Ibrahimovich
1000 1000 -2000 0

```

Sample Output

```
Hazard Messi 1000
Hazard Ronaldo 1000

```

## Test Case 2

Sample Input

```
Maradona Pele
20000 -20000

```

Sample Output

```
Pele Maradona 20000

```

## Test Case 3

Sample Input

```
A B C D E
1 1 1 1 -4

```

Sample Output

```
E A 1
E B 1
E C 1
E D 1

```

## Test Case 4

Sample Input

```
A B C D E F
3 3 1 2 -4 -5

```

Sample Output

```
F D 2
F C 1
F B 2
E B 3
E B 1
E A 3

```

## Clarification

There may be multiple answers, anyone of them will be accepted. For example:

```
A B C
1 1 -2

```

can yield both of the following:

```
C A 1
C B 1

```

or

```
C B 1
C A 1

```

both are correct.

# Answer
# Python 2, 146 bytes

```
def f(p,b):
	a=sorted(zip(b,p))
	while a:
		d,D,c,C=a[0]+a[-1];t=d+c;a[0]=(t,D);a[-1]=(t,C);a=a[t>=0:[len(a),-1][t<=0]]
		if d:print D,C,min(-d,c)

```

Try it online!
> 1 votes

# Answer
# Python 3, 173 bytes

```
a=lambda:input().split()
m={x:int(y)for x,y in zip(a(),a())}
l=lambda k:m[k]
while any(map(l,m)):d=min(m,key=l);s=max(m,key=l);t=min(m[s],-m[d]);m[d]+=t;m[s]-=t;print(d,s,t)

```

Try it online!

-6 bytes thanks to ppperry using dictcomps instead of `dict` of a listcomp
> 4 votes

---
Tags: code-golf
---


title: Shuffle a deck without local variables

text:
# Question
Title: Shuffle a deck without local variables
The object of this puzzle is to take a deck of 52 cards and shuffle it so that each card is in a random position.

## Given:

* An array, `deck`, of 52 distinct integers representing the cards. When you start, `deck` contains exactly one of each card in some unknown order.
* A function, `int rand(min, max)`, that returns a random integer between ints `min` and `max`, inclusive. You can assume that this function is truly random.
* A function, `void swap(x, y)` that swaps two cards in the deck. If you call `swap(x, y)`, the cards at positions `x` and `y` will switch places.

## When:

* The program calls `shuffle()` (or `shuffle(deck)` or `deck.shuffle()` or however your implementation likes to run),

## Then:

* `deck` should contain exactly one of each card in perfectly random order.

## The Catch:

**You can't declare any variables.** Call `swap` and `rand` as much as you like, but you can't declare any variables of your own. This includes `for` loop counters--even implicit ones like in a `foreach`.

## Clarifications:

* You can change minor details to suit your chosen language. For example, you can write `swap` to switch two integers by reference. Changes should be to make this work with your language, not to make the puzzle easier.
* `deck` can be a global variable, or you can take it in as a parameter.
* You can do anything you want to the contents of `deck`, but you can't change its length.
* Your cards can be numbered 0-51, 1-52, or anything you like.
* You can write this in any language, but no cheating with your language's built-in `shuffle` function.
* Yes, you could write the same line 52 times. No one will be impressed.
* Execution time doesn't matter, but true randomness does.
* This isn't really code golf, but feel free to minimize/obfuscate your code.

---

## Edit: Boilerplate code and visualizer

If you used .NET or JavaScript, here's some test code you may find useful:

### JavaScript:

### C#:

This code sorts and shuffles the deck several thousand times and performs some basic sanity testing: For each shuffle, it verifies that there are exactly 52 cards in the deck with no repeats. Then the visualizer plots the frequency of each card ending up at each place in the deck, displaying a grayscale heat map.

The visualizer's output should look like snow with no apparent pattern. Obviously it can't prove true randomness, but it's a quick and easy way to spot-check. I recommend using it or something like it, because certain mistakes in the shuffling algorithm lead to very recognizable patterns in the output. Here's an example of the output from two implementations, one with a common flaw:

The flawed version does partially shuffle the deck, so might look fine if you examined the array by hand. The visualizer makes it easier to notice a pattern.

# Answer
# JavaScript

I believe this is the intended form of solution, I use the card in position 0 to keep track of progress, only shuffling the cards that have already been used as counter, this achieves the standard 52! permutations with a perfect equal distribution. The procedure is complicated by XOR swap not allowing that an element is swapped by itself.

Edit: I built in a sorting that sorts each element into place just before it is used, thus allowing this to work with an unsorted array. I also dropped recursive calling in favour of a while loop.

```
deck=[]
for(a=0;a<52;a++){
    deck[a]=a
}
function swap(a,b){
    deck[a]=deck[b]^deck[a]
    deck[b]=deck[b]^deck[a]
    deck[a]=deck[b]^deck[a]
}
function rand(a,b){
    return Math.floor(Math.random()*(1+b-a))+a
}
function shuffle(){
    while(deck[0]!=0){ //Sort 0 into element 0
        swap(0,deck[0])
    }
    while(deck[0]<51){ //Run 51 times
        while(deck[deck[0]+1]!=deck[0]+1){ //Sort element deck[0]+1 into position deck[0]+1
            swap(deck[deck[0]+1],deck[0]+1)
        }
        swap(0,deck[0]+1) //Swap element deck[0]+1 into position 0, thus increasing the value of deck[0] by 1
        if(rand(0,deck[0]-1)){ //Swap the element at position deck[0] to a random position in the range 1 to deck[0]
            swap(deck[0],rand(1,deck[0]-1))
        }
    }
    if(rand(0,51)){ //Swap the element at position 0 to a random position
        swap(0,rand(1,51))
    }
}
for(c=0;c<100;c++){
    shuffle()
    document.write(deck+"<br>")
}

```
> 8 votes

# Answer
## Haskell

Here is a point-free implementation. No variables, formal parameters, or explicit recursion. I used lambdabot's `@pl` ("pointless") refactoring feature quite a bit.

```
import Data.List
import Control.Applicative
import Control.Monad
import System.Random

shuffle :: [a] -> IO [a]
shuffle = liftM2 (<$>) ((fst .) . foldl' (uncurry ((. flip splitAt) . (.) .
          (`ap` snd) . (. fst) . flip flip tail . (ap .) . flip flip head .
          ((.) .) . (. (++)) . flip . (((.) . (,)) .) . flip (:))) . (,) [])
          (sequence . map (randomRIO . (,) 0 . subtract 1) . reverse .
          enumFromTo 1 . length)

main = print =<< shuffle [1..52]

```

Here's my test procedure to make sure the numbers were uniformly distributed:

```
main = print . foldl' (zipWith (+)) (replicate 52 0)
       =<< replicateM 1000 (shuffle [1..52])

```

Here is the original algorithm:

```
shuffle :: [a] -> IO [a]
shuffle xs = shuffleWith xs <$>
             sequence [randomRIO (0, i - 1) | i <- reverse [1..length xs]]

shuffleWith :: [a] -> [Int] -> [a]
shuffleWith xs ns = fst $ foldl' f ([], xs) ns where
    f (a,b) n = (x:a, xs++ys) where
        (xs, x:ys) = splitAt n b

```
> 14 votes

# Answer
# J

Ignoring that deck is a variable, there's the obvious...

```
52 ? 52

```

Of course, if you really want a function, there's this, which will work even if you forget to remove the jokers (or try to shuffle something other than cards).

```
{~ (# ? #)

```

So that...

```
shuffle =: {~ (# ? #)
deck =: i. 52
shuffle deck

```

This is probably outside the intent of the question, which would be to implement the shuffle yourself from rand (`?`). I might do that later when I'm not supposed to be working.

# Explanation

Explanation of `52 ? 52`:

* `x ? y` is x random unique items from y.

Explanation of `{~ (# ? #)` is harder because of forks and hooks. Basically, it is the same as `shuffle =: 3 : '((# y) ? (# y)) { y'`, which has one implicit argument (`y`).

* `# y` gives the length of y
* This gives 52 ? 52 like before, which is a random permutation of 0..51
* `x { y` is the item of y in index x, or (in this case) items in the indexes in x.
* This lets you shuffle whatever is passed in, not just integers.

See J Vocabulary for details of operators, though the syntax and semantics are quite a bit tricky because of rank and tacit programming.
> 5 votes

# Answer
## Python

```
import random
def rand(x, y):
 return random.randrange(x, y+1)

def swap(deck, x, y):
 deck[x] ^= deck[y]
 deck[y] ^= deck[x]
 deck[x] ^= deck[y]

def shuffle(deck):
 if len(deck)>1:
  deck[1:]=shuffle(deck[1:])
  if rand(0,len(deck)-1)>0:swap(deck, 0, rand(1, len(deck)-1))
 return deck

print shuffle(range(52))

```
> 3 votes

# Answer
### Using factoradic representation

In the factoradic representation of a permutation an element i takes values from 0 to N-i. So a random permutation is just `rand(0,i)` for every N-i.

In J:

```
? |.>:i.52
2 39 20 26 ... 2 0 1 0 0 0

```

where `? x` is `rand(0,x-1)` and `|.>:i.52` is `52 51 ... 1`

Then, if `a` is the value of ith factoradic, we do the swap: `swap(deck[i], deck[i+a])`. The list of pairs to swap are:

```
(,. i.52) ,. (,. ((?|.>:i.52)+i.52))
0 33
1 20
2  3
...
49 50
50 50
51 51

```

The swap we'll be using works like this:

```
deck
24 51 14 18 ...
deck =: 0 1 swap deck
51 24 14 18 ...

```

It's not really "by reference" but there are no real functions in J.

We'll use deck's length (`#deck`) to avoid using a constant.

### Complete program in J:

```
deck =: 52 ? 52                           NB. Initial random deck
swap =: 4 : 'deck =: (x { y) (|.x) } y'   NB. Given swap "function"
f =: 3 : 0                                NB. function that calls the swap for a pair
({.y) swap deck
}.y
)
f^:(#deck) (,.,.[:,.]+[:?[:|.>:) i.#deck

```
> 3 votes

# Answer
# C#

Here's my own answer based on the Fisher-Yates algorithm. Should give you a perfect shuffle if your random number generator is good enough.

English version:

1. Repeatedly swap the card at `deck[0]` with the one at `deck[v]`, where `v` is the face value of the card at `deck[0]`. Repeat until `v == 0`. This will partially sort the deck, but that doesn't matter. You now know Card 0 is at the front of the deck, which means you can steal that space in the array and use it as a loop counter. This is the key "cheat" for the problem of local variables.
2. Starting at position 1 (the second card in the deck), swap the card at `i` with the one at `rand(i, 51)`. Note that you need `rand(i, 51)`, **NOT** `rand(1, 51)`. That won't ensure that each card is randomized.
3. Set `deck[0]` back to 0. Now the whole deck is shuffled except for the first card, so swap `deck[0]` with `deck[rand(0, 51)]` and you're done.

C# version:

```
public static void shuffle(int[] deck)
{
    while (deck[0] > 0)
        swap(ref deck[0], ref deck[deck[0]]);

    for (deck[0] = 1; deck[0] < 52; deck[0]++)
        swap(ref deck[deck[0]], ref deck[rand(deck[0], 51)]);

    deck[0] = 0;
    swap(ref deck[0], ref deck[rand(0, 51)]);
}

```

Javascript version:

```
while (deck[0] > 0)
    swap(0, deck[0]);

for (deck[0] = 1; deck[0] < 52; deck[0]++)
    swap(deck[0], rand(deck[0], 52));

deck[0] = 0;
swap(0, rand(0, 52));

```

...where `swap(a, b)` swaps `deck[a]` with `deck[b]`.
> 3 votes

# Answer
# Ruby, one line

Is this considered cheating? It should be as random as it gets.

```
deck=(0..51).to_a # fill the deck
deck[0..51] = (0..51).map{deck.delete_at(rand deck.length)}

```

(Ruby's `rand` method only takes one argument and then generates a number n such that 0 \<= number \< argument.)

Additionally - similar to sogart's Perl solution, but as far as I know it doesn't suffer from the problem:

```
deck = deck.sort_by{rand}

```

Ruby's sort\_by is different than sort - it first generates the list of values to sort the array by, and only then sorts it by them. It's faster when it's expensive to find out the property we're sorting by, somewhat slower in all other cases. It's also useful in code golf :P
> 2 votes

# Answer
## JavaScript

**NOTE: This solution is technically not correct because it uses a second parameter, `i`, in the call to `shuffle`, which counts as an external variable.**

```
function shuffle(deck, i) {
    if (i <= 0)
        return;
    else {
        swap(deck[rand(0,i-1)], deck[i-1]);
        shuffle(deck, i - 1);
    }
}

```

Call with `shuffle(deck,52)`

A complete working example (had to modify `swap` slightly because there is no pass-by-reference of ints in JavaScript):

```
function rand(min, max) { return Math.floor(Math.random()*(max-min+1)+min); }
function swap(deck, i, j) {
    var t=deck[i];
    deck[i] = deck[j];
    deck[j] = t;
}

function shuffle(deck, i) {
    if (i <= 0)
        return;
    else {
        swap(deck, rand(0,i-1), i-1);
        shuffle(deck, i - 1);
    }
}

// create deck
var deck=[];
for(i=0;i<52;i++)deck[i]=i;
document.writeln(deck);
shuffle(deck,52);
document.writeln(deck);

```
> 1 votes

# Answer
## C++

```
#include <cstdlib>
#include <ctime>
#include <iostream>

int deck[52];

void swap(int a, int b) {
    deck[a] ^= deck[b];
    deck[b] ^= deck[a];
    deck[a] ^= deck[b];
}

int r(int a, int b) {
    return a + (rand() % (b - a + 1));
}

void s(int *deck) {
    swap(1, r(2, 51));
    deck[0] *= 100;

    for(deck[0] += 2; (deck[0] % 100) < 51; deck[0]++) {
        swap(deck[0] % 100,
          r(0, 1) ? r(1, (deck[0] % 100) - 1) : r((deck[0] % 100) + 1, 51));
    }
    swap(51, r(1, 50));

    deck[0] = (deck[0] - 51) / 100;
    swap(r(1, 51), 0);
}

int main(int a, char** c)
{
    srand(time(0));

    for (int i = 0; i < 52; i++)
        deck[i] = i;

    s(deck);
    s(deck);

    for (int i = 0; i < 52; i++)
        std::cout << deck[i] << " ";
}

```

Avoids swapping elements with themselves, so has to call twice to be random.
> 1 votes

# Answer
## D

```
shuffle(int[] d){
    while(d.length){
        if([rand(0,d.length-1)!=0)swap(d[0],d[rand(1,d.length-1)]);
        d=d[1..$];
    }
}

```
> 1 votes

# Answer
Another Perl solution, which actually produces uniformly distributed output:

```
sub shuffle_integers {
    map int, sort {$a-int $a <=> $b-int $b} map $_+rand, @_;
}

say join " ", shuffle_integers 1 .. 52;

```

This solution uses Perl's `rand`, which returns a random number *x* in the range 0 ≤ *x* \< 1. It adds such a random number to each integer in the input, sorts the numbers according to their fractional parts, and finally strips those fractional parts away again.

(I believe the use of the special variables `$_`, `$a` and `$b` falls within the spirit of the challenge, since those are how perl passes the input to `map` and `sort`, and they're not used for any other purpose in the code. In any case, I believe they're actually aliases to the input values, not independent copies. This is not actually an in-place shuffle, though; both `map` and `sort` create copies of the input on the stack.)
> 1 votes

# Answer
## Java

I am surprised nobody stated the obvious: (I'll assume swap(x,x) does nothing.

```
    static void shuffle(){
        swap(1,rand(0,1));
        swap(2,rand(0,2));
        swap(3,rand(0,3));
        swap(4,rand(0,4));
        swap(5,rand(0,5));
        swap(6,rand(0,6));
        swap(7,rand(0,7));
        swap(8,rand(0,8));
        swap(9,rand(0,9));
        swap(10,rand(0,10));
        swap(11,rand(0,11));
        swap(12,rand(0,12));
        swap(13,rand(0,13));
        swap(14,rand(0,14));
        swap(15,rand(0,15));
        swap(16,rand(0,16));
        swap(17,rand(0,17));
        swap(18,rand(0,18));
        swap(19,rand(0,19));
        swap(20,rand(0,20));
        swap(21,rand(0,21));
        swap(22,rand(0,22));
        swap(23,rand(0,23));
        swap(24,rand(0,24));
        swap(25,rand(0,25));
        swap(26,rand(0,26));
        swap(27,rand(0,27));
        swap(28,rand(0,28));
        swap(29,rand(0,29));
        swap(30,rand(0,30));
        swap(31,rand(0,31));
        swap(32,rand(0,32));
        swap(33,rand(0,33));
        swap(34,rand(0,34));
        swap(35,rand(0,35));
        swap(36,rand(0,36));
        swap(37,rand(0,37));
        swap(38,rand(0,38));
        swap(39,rand(0,39));
        swap(40,rand(0,40));
        swap(41,rand(0,41));
        swap(42,rand(0,42));
        swap(43,rand(0,43));
        swap(44,rand(0,44));
        swap(45,rand(0,45));
        swap(46,rand(0,46));
        swap(47,rand(0,47));
        swap(48,rand(0,48));
        swap(49,rand(0,49));
        swap(50,rand(0,50));
        swap(51,rand(0,51));
    }

```

OK, ok, it can be shorter:

```
package stackexchange;

import java.util.Arrays;

public class ShuffleDry1
{
    static int[] deck = new int[52];

    static void swap(int i, int j){
        if( deck[i]!=deck[j] ){
            deck[i] ^= deck[j];
            deck[j] ^= deck[i];
            deck[i] ^= deck[j];
        }
    }

    static int rand(int min, int max){
        return (int)Math.floor(Math.random()*(max-min+1))+min;
    }

    static void initialize(){
        for( int i=0 ; i<deck.length ; i++ ){
            deck[i] = i;
            swap(i,rand(0,i));
        }
    }

    static void shuffle(){
        while( deck[0]!=0 ) swap(0,deck[0]);
        for( deck[0]=52; deck[0]-->1 ; ) swap(deck[0],rand(deck[0],51));
        swap(0,rand(0,51));
    }

    public static void main(String[] args) {
        initialize();
        System.out.println("init: " + Arrays.toString(deck));
        shuffle();
        System.out.println("rand: " + Arrays.toString(deck));
    }

}

```
> 1 votes

# Answer
## Burlesque

What you are actually asking for is a random permutation of a list of integers? `r@` will give us all permutations, and we just select a random one.

```
blsq ) {1 2 3}r@sp
1 2 3
2 1 3
3 2 1
2 3 1
3 1 2
1 3 2
blsq ) {1 2 3}r@3!!BS
2 3 1

```

Since we need true randomness, something Burlesque isn't capable of doing because Burlesque has no I/O functionality you'd need to provide some source of randomness through STDIN.

That's probably something I'll fix in later version (i.e. generate a random seed at startup and push it to the secondary stack or something like that, but the Burlesque Interpreter itself has no I/O).
> 1 votes

# Answer
## Javascript

I'm not sure if it's "cheating" but my solution uses the native local array of a function's arguments. I included my self-made functions of `rand()` `swap()` and `filldeck()`. Of interesting note, this should work with a deck of any size.

```
    var deck = [];

    function shuffle(){
        main(deck.length);
    }

    function main(){
        arguments[0] && swap( arguments[0]-=1, rand(0, deck.length-1) ), main(arguments[0]);
    }

        function rand(min, max){
            return Math.floor( Math.random()*(max-min+1) )+min;
        }

        function swap(x, y){
            var _x = deck[x], _y = deck[y];
            deck[x] = _y, deck[y] = _x;
        }

        function filldeck(dL){
            for(var i=0; i<dL; i++){
                var ran = rand(1,dL);
                while( deck.indexOf(ran) >= 0 ){
                    ran = rand(1,dL);
                }
                deck[i] = ran;
            }
        }

    filldeck(52);
    shuffle();

```
> 0 votes

# Answer
# Tcl, 32 bytes

Abusing `time` function which serves to measure how much time is spent a script is running, but also can serve as a looping mechanism without declaring any variables.

```
time {lswap $D [rand] [rand]} 52

```

Try it online!
> 0 votes

# Answer
**perl - this is not a proper shuffle as explained in comments!**

```
my @deck = (0..51);
@deck = sort {rand() <=> rand()} @deck;
print join("\n",@deck);

```

I think I didn't use anything as a swap etc. was that needed as part of the problem?
> -1 votes

# Answer
# JavaScript 4 lines

```
function shuffle() {
  while(deck[0]!=0)swap(deck[0],rand(1,51))
  while(deck[0]++!=104)swap(deck[0]%51+1,rand(1,51))
  deck[0]=0
  swap(0,rand(0,51))
}

```

Original answer that wasn't random enough. The swap wasn't guaranteed to touch each item in the deck.

```
// shuffle without locals
function shuffle() {
  deck.map(function(){swap(deck[rand(0,51)],deck[rand(0,51)])});
}

```
> -1 votes

---
Tags: code-challenge, restricted-source, random, array
---


title: Frankenstein Words

text:
# Question
Title: Frankenstein Words
For this challenge you need to make a given word by concatenating "pieces" (a.k.a contiguous substrings) from other words. Given a word and a list of words as input, output the fewest number of pieces needed to create the first word.

# Rules

* Words consist of characters in the ASCII range 33 to 126.
* The word list may have repeats.
* Construction of words is case sensitive (you can not use the piece "Head" as part of the word "forehead".)
* Once you have used a piece in a construction, you can not use any part of that piece again (e.g if I use "lo" from "lone" as part of constructing "lolo", I cannot use "lo" from that "lone" again. However, if I had two "lone" in my word list, I could use one "lo" from each.)
* Once you use a piece, you can still make pieces out of unused substrings in the word. (E.g. If I used "tt" in "butter", I still have "bu" and "er" left over to use. However, I can't combine them into one "buer" piece.)
* If it is impossible to construct the input word using the word list given, output nothing, or something other than a positive integer.

# Examples

(you only need to output the number)

* `"snack" ["food","Shoe","snack"]` =\> 1 (`snack`)
* `"Snack" ["food","Shoe","snack"]` =\> 2 (`S` \+ `nack`)
* `"frog" ["cat","dog","log"]` =\> 0
* `"~~Frank~~" ["Frog~","~~Love","Hank~"]` =\> 4 (`~~` \+ `Fr` \+ `ank~` \+ `~`)
* `"loop-de-loop" ["loop", "frien-d","-elk","pool"]` =\> 7 (`loop` \+ `-d` \+ `e` \+ `-` \+ `l` \+ `oo` \+ `p`)
* `"banana" ["can","can","boa"]` =\> 4 (`b`+`an`+`an`+`a`)
* `"banana" ["can","boa"]` =\> 0
* `"13frnd" ["fr13nd"]` =\> 3 (`13` \+ `fr` \+ `nd`)

Let me know if you think of more useful test cases.

# Answer
> 2 votes
# JavaScript, ~~209~~ 206 bytes

```
f=(a,b,F)=>a?[...a].map((_,i)=>[...Array(i+1)].map((_,j)=>F||b.forEach((q,k)=>!F&&~(I=q.indexOf(a[S='substring'](j,r=a.length-i+j)))&&(F=b[k]=q[S](0,I)+' '+q[S](I+r+j),a=a[S](0,j)+a[S](r)))))&&F&&1+f(a,b):0

```

Try it online

Returns `NaN` if the combination is not found.

---
Tags: code-golf, string
---


title: Make a Minecraft Crafting Table

text:
# Question
Title: Make a Minecraft Crafting Table
Don't you hate it when you can't remember how to craft something in Minecraft? Well, time to remedy that!

# Task

Your task is to take an input, either as a 1D or 2D list and output what item is a result of the crafting table!

# Input

You may take input as either a string or a list of length `9` or a 2D nested array.

If you take input as a...

## String

Each item in the table is 1 char in the printable ASCII character (`0x20` to `0x7E`). To represent an empty space, you use a `-` e.g. `WWW-W-WWW` would be the same as a crafting table like

```
+------+------+------+
| Wood | Wood | Wood |
+------+------+------+
|      | Wood |      |
+------+------+------+
| Wood | Wood | Wood |
+------+------+------+

```

You may also take input as a multiline string as long as all spaces are preserved e.g.

```
WWW
 W
WWW

```

## 1D array

You would take the input as a char array where empty spaces on the crafting table would be an empty char e.g. the above table would be `['W','W','W','','W','','W','W','W']`

## 2D array

This time, each list represents a line on the crafting table, where an empty space is an empty char e.g. `[['W','W','W'],['','W',''],['W','W','W']]`

You can assume that the input will always correspond to an item that can be crafted, and if using array input, you may replace the empty char with any character not used as an abbreviated name.

# Output

Output will be the item crafted from the input, in any form you want, as long as it is obvious what it means. (Personally, I would use my 1 letter abbreviations of the items)

# Ingredients

For this challenge, `wood` means wooden planks, not wooden logs.

You only have to handle the most common items when crafting. These are the ingredients for crafting but may also be products of crafting. The crafting recipe follows the format `xxxxxxxxx` like the string input above. If an item cannot be crafted, `---------` is placed instead.

Some recipes are **shapeless**, meaning that just so long as all items are there, the item will be made. These are denoted be a `*`. An example of this would be `pumpkin pie` (not one in this challenge) that only needs `pumpkin`, `sugar` and `egg` to be made.

```
   item name    | abb. name | crafting recipe
----------------+-----------+------------------
wood            |     W     | ---------
cobblestone     |     C     | ---------
sticks          |     S     | ----W--W-
iron            |     I     | ---------
gold            |     G     | ---------
diamond         |     D     | ---------
redstone        |     R     | ---------
string          |     N     | ---------
coal            |     Y     | ---------
sugar cane      |     U     | ---------
redstone torch  |     E     | -R--S----
paper           |     P     | ---------
book            |     B     | ---PL-PP-
wool            |     M     | ---NN-NN-
obsidian        |     O     | ---------
gunpowder       |     X     | ---------
sand            |     A     | ---------
glass           |     H     | ---------
feather         |     F     | ---------
flint           |     K     | ---------
torch           |     T     | ---------
leather         |     L     | ---------
material blocks |     Z     | QQQQQQQQQ (here Q represents any in `[G, I, R, D, Y]`
compass         |     V     | -I-IRI-I-

```

# Products

This is a list of all the products that you could handle for crafting. if the item is also an ingredient, it will not be included here **but you must still be able to handle it**. Each one can be crafted using only the ingredients above and is designated a unique, lowercase letter to identify it. Armour (`+`) can use any ingredient in `[G, I, L, D]`. Weapons (`$`) can be made from `[W, C, I, G, D]`. As this is a site, however, we need to make these lists shorter. `[G, I, L, D]` is denoted by a `Q` and `[W, C, I, G, D]` is denoted by a `J`.

```
   item name    | abb. name | crafting recipe
----------------+-----------+------------------
crafting table  |     a     | -----WWWW
boots +         |     b     | ---Q-QQ-Q
pants +         |     c     | QQQQ-QQ-Q
chestplate +    |     d     | Q-QQQQQQQ
helmet +        |     e     | QQQQ-Q---
bed             |     f     | ---MMMWWW
chest           |     g     | WWWW-WWWW
wood door       |     h     | WW-WW-WW-
iron door       |     i     | II-II-II-
furnace         |     j     | CCCC-CCCC
trap door       |     k     | ---WW-WW-
TNT             |     l     | XAXAXAXAX
anvil           |     m     | ZZZ-I-III
axe $           |     n     | -JJ-SJ-S-
sword $         |     o     | -J--J--S-
pickaxe $       |     p     | JJJ-S--S-
hoe $           |     q     | JJ--S--S-
shovel $        |     r     | -J--S--S-
arrow           |     s     | -K--S--F-
bow             |     t     | SN-S-NSN-
bowl            |     u     | ---W-W-W-
gold nugget *   |     v     | ----G----
bucket          |     w     | ---I-I-I-
clock           |     y     | -G-GRG-G-
map             |     z     | PPPPVPPPP
fishing rod     |     1     | --S-SNS-N
flint and steel |     2     | ----I---K
shears          |     3     | ---I---I-
wood button *   |     4     | ----W----
dropper         |     5     | CCCC-CCRC
stone button *  |     6     | ----C----
jukebox         |     7     | WWWWDWWWW
lever           |     8     | ----S--C-
noteblock       |     9     | WWWWRWWWW
piston          |     0     | WWWCICCRC
pressure plate  |     !     | ------WW- (W can also be replaced with C/I/G)
repeater        |     @     | ---ERECCC
tripwire hook   |     #     | -I--S--W-
activator rail  |     (     | ISIIEIISI
boat            |     %     | ---W-WWWW
minecart        |     ^     | ---I-IIII
powered rail    |     &     | G-GGSGGRG
rail            |     )     | I-IISII-I
stone wall      |     {     | ---CCCCCC
fence gate      |     }     | ---SWSSWS
fence panel     |     [     | ---SSSSSS
glass pane      |     ]     | ---HHHHHH
iron bars       |     ;     | ---IIIIII
item frame      |     :     | SSSSLSSSS
ladder          |     '     | S-SSSSS-S
sandstone       |     "     | -----AAAA
slabs           |     |     | ---CCC---
stairs          |     <     | W--WW-WWW
bookshelves     |     >     | WWWBBBWWW
carpet          |     .     | -------MM
painting        |     ,     | SSSSMSSSS
sign            |     ?     | WWWWWW-S-
cauldron        |     /     | I-II-IIII
enchant. table  |     `     | -B-DODOOO
glass bottle    |     ~     | ---H-H-H-
rocket *        |     _     | -----PXXX

```

## Scoring

As it would be unreasonable to ask you to do all of these recipes, you only have to do the ones that you want! But of course, the more that you do, the better your score.

Score is defined as

```
score = length of program in bytes / number of working recipes squared

```

For example, this could be a submission.

```
input()
print('S')

```

As you can assume that the input passed will be one that it can handle (`----W--W-`), it will always output `S`, which is equivalent to `sticks`. This would score **18 / 1 = 18**.

**You must take input** to be a valid program and you must be able to handle at least 5 **different** inputs.

The person with the lowest score wins.

# Rules

* Lowest score wins
* You may take input using any accepted method (function parameters, STDIN etc)
* You can only take input in one of the above forms. It isn't too restrictive and should be workable
* Standard loopholes are disallowed
* You must take input
* You must output at least `5` correct results to qualify as competing.
* For recipes that are shapeless, e.g. gold nuggets, different combinations *do not* count as different recipes. `----W----` is the same (recipe-wise) as `--W------` and is only 1 recipe.
* On the flip side of this, for recipes that use more than one material, such as material blocks, each different material counts as a different recipe, meaning that `IIIIIIIII` is not the same (recipe-wise) as `RRRRRRRRR`.

Good luck, Minecrafters!

# Answer
# Python 2, Score: 0.0636347

**715 bytes, all 106 recipes**

```
import zlib,base64
i=input()
x=`sorted(i)`[2::5]
W=zlib.decompress(base64.b64decode('eNpVUglywyAMfJEeEUPqaoKPQTPFzf8fUq0O6iyyLJsFLUhERMOM6Gx0ngj2HWYYijXBiZ6oid8EM7nZYhhW0orvTiS2qxK6PhHCmO+B527UYK3dA5+qVGG13gOf0lyr5YyAUjxN+SZDKPZsLXawXXxKsW3bcNB8wYrC3PWI8X6/7RiMaRlYrhQpCPSnMAIVIisCzSEVgV87yGYgm4FsBrKZJFOSKcmUZEoy1V7mv5KjaxeqRz2Og+i/rE7GaSyAfgtwcxbgOvI2DOB+/gH39ue8rkt2/drF+mfY8CpbVYVk19lT8QOHavXoDo7H/QsSa1Rg9HgXLqWXKEEvRHknIW4ebyqOgHkqhn/2p/JZmJ+s3qV6ledxvGHQP7KqyI9GlejS4lqIvm1AzhCYopmn8OAYTIx3oeKh0KzLsnjy2W1RIMe2YRNzSGH4AwHh7JI='))
d={W[l:l+9]:'SBMaZZZZZikeEVbcebcebcebcddqddqfghjlmnnnnnooooorrrrrs#`4ppppp6qvq_tuw1zy3279058|!!!!@(%q^&/){~}:\'];"><?.,['[l/9]for l in range(0,len(W),9)}
if i in d:x=i
print d[x]

```

Try it online!

Handles all the specified recipes, including material variations.

Creates a dictionary of all working recipes (with length 9).

The shapeless recipes are included by sorting the input string, and checking those against the dictionary.

Edit: Switched to string compression, and saved 7 bytes in the code thanks to notjagan
> 6 votes

# Answer
# Mathematica, score: 0.0482378 ~~0.0540228~~ ~~0.0543788~~

542 ~~607~~ ~~611~~ bytes, all 106 recipes

-4 bytes for rearranging compressed data

-65 bytes for losing the ability to deal with invalid inputs

```
"4/a[:chwpb?_oqjB%',>!6aM7^s<S@1|dfi~g38y&.nz}25#0r;]`mVe{v)b\"l9(tZE"~StringTake~{#&@@Join@@StringPosition[Uncompress@"1:eJw9UVuOgzAMrHoS9yglsGnUJkAsLYj92wv0/n+dsU3HZoAwfnL7f3f9u14uEtiKFDrIXgHc9IsXaQWEjo/uQDHjFxU6gt0MfiKy7Psuq9CVKVycACcoXrIsEQ6oF3euJBwOw+CNAUwSSNZx9NManSnGmCLmelrRH+R38ebFxO5Tn6wNFGwqjUmtK85rwHOtFVElNsWoh5mV+dbyy2ohQZbcs5hlzXx21MoBlEtbgF8SgzbMqRJJnrGfnviqsZpU7OTcIbUlftzDIIOM8zjP83EcPjy5x29aJRaXUmzekClUk/rUIbsD+2kcspOonKjXhhYaeD0hPbr6AOvmjtk=",#<>""&/@{v=#/.""->" ",Sort@v,v/.(#|##2&@@Characters@"GLIDWCYR"->"Q")}]/9+8/9}&

```

Take input as 1D-list `{"W", "W", "", "", ...}`

Expanded & clear version:

```
TableOfNames~StringTake~{# & @@
      Join @@ StringPosition[
        Uncompress@CompressedRecipeTable,
        # <> "" & /@ {v = # /. "" -> " ", Sort@v,
          v /. (# | ##2 & @@ Characters@"GLIDWCYR" -> "Q")}]/9 + 8/9}
 &

```

The big `Uncompress` is a string table of all combinations, joined together.

```
"        WI II IIII     WWWW   SSSSSSSSSSLSSSSQQQQ QQ QWW WW WW    I \
I I QQQ S  S    W W W WWWWWW S      PXXX Q  Q  S QQ  S  S CCCC CCCC   \
PL PP    W WWWWS SSSSS SSSSSMSSSSWWWBBBWWW      QQ         C   WW WW  \
  NN NN WWWWDWWWW   I IIII K  S  F W  WW WWW    W  W    ERECCC  S SNS \
N   CCC   Q QQQQQQQ   MMMWWWII II II    H H H WWWW WWWW   I   I     S \
 C  G GRG G G GGSGGRG       MM QQ SQ S PPPPVPPPP   SWSSWS    I   \
KCCCC CCRC I  S  W WWWCICCRC Q  S  S    IIIIII   HHHHHH B DODOOOZZZ I \
III I IRI I QQQQ Q      CCCCCC        GI IISII I   Q QQ Q     \
AAAAXAXAXAXAXWWWWRWWWWISIIEIISISN S NSN QQQQQQQQQ R  S    "

```

`StringPosition` looks for matching in a order of: input itself, sorted input (for shapeless recipe), armour, weapon, pressure plate.

`# & @@ Join @@` returns the position of first occurence.

`/9+8/9` calculates the index in result table and `StringTake` takes the character at that position.
> 3 votes

# Answer
# SOGL V0.12, ~~325~~ ~~322~~ ~~317~~ 316 bytes / 106^2 = score 0.0281238875

```
3∫HA"-?%mΛe*▓╔Υι§ā⅜β¬kēōΠ»t ‰CV↓ZΟΚΨpΝ∫3υ≤↕‰č⅛c╚≤Æ⁷/←;[piυ¦╗⌠⁄⁸qη╔@O;┐√)cR█9ιZ׀l»░(■DΛQ-╥76PT─ō4ο3ū^╝/9»¾κλCβ׀+!'▼vw-№█⁷$▒d`Σ⅟Ιž⁴n≡,`!m≤Σ═╥∫Κ‽∆Q>+g=¼⁾⁽D┐?─D○≠6τ╝ZTΞķ⅜∑²V=]4Æ⁴℮lT$¡sψī1 ◄δ)⅞/Σ/Δō»ņe#≥ζz⅛yB÷B⅞⁵Kβn┘g⁵ķ»<§└≡↓θ○‼¼ņΔε⁄z‼Ζ∙Φ6β⅜c≈Νycm!=V○Jεκ~  :I)ΩS‘U9ndW:? ~Δ" $*+-=\x”Z+čøŗ"SEBMZV”+W←,a‽"9╚πw⁽νQσ_‘č┌ŗD}a?□D

```

Explanation:

```
3∫                    3 times repeat (on each it'll try something else)
  HA                    save 1-indexed iteration - 1 on variable A
    "..‘                push a string of the recipes
        U               uppercase it (as lowercase was ~7 bytes shorter)
         9n             split into and array of strings of length 9
           d            load the variable D (by default string input)
            W           get the variables 1-based index in that array, 0 if not found
:?                  ←   if [it isn't 0], leaves the input on the stack
   ~Δ                     get the ascii characters from space to ~ (inclusive)
     "..”                 push " $*+-=\x", the characters that are in the ASCII but not used
         Z+               add the uppercase alphabet to that (as most of it can't be outputted)
           čøŗ            filter those out
              "..”+       append to it the uppercase characters that are used - "SEBMZV"
                   W      get in the finished string the character at the index gotten before the if
                    ←     exit, outputting that
       ,                push the input
        a‽        }     if the 0-based index is not [0] (aka if this is the 1st time in the loop)
          "..‘            push "RDYWCDCIGL" - characters that are either of the groups of Q, J or the pressure plate
              č┌ŗ         replace [in the pushed input, each of those characters, with a dash]
                 D        save on variable D - used in the IF above
                   a?   if the 0-based index [is == 0] (aka if this is the 2st time in the loop, soon-to-be 3rd/last)
                     □    sort [the previously pushed input]
                      D   save on the variable D

```

Try it Here! or test by running the following (which will say what's wrong):

```
var arr = `      WW  !\n      CC  !\n      II  !\n      GG  !\n     AAAA "\n I  S  W  #\n   W WWWW %\nG GGSGGRG &\nS SSSSS S '\nISIIEIISI (\nI IISII I )\nSSSSMSSSS ,\n       MM .\nI II IIII /\nWWWCICCRC 0\n  S SNS N 1\n    I   K 2\n   I   I  3\n        W 4\nW         4\n    W     4\n      W   4\nCCCC CCRC 5\n        C 6\n     C    6\nC         6\nWWWWDWWWW 7\n    S  C  8\nWWWWRWWWW 9\nSSSSLSSSS :\n   IIIIII ;\nW  WW WWW <\nWWWBBBWWW >\nWWWWWW S  ?\n   ERECCC @\n   SSSSSS [\n   HHHHHH ]\n   I IIII ^\n     PXXX _\n XP    XX _\nX   XP  X _\nXXXP      _\n B DODOOO \`\n   G GG G b\nGGGG GG G c\nG GGGGGGG d\nGGGG G    e\n   I II I b\nIIII II I c\nI IIIIIII d\nIIII I    e\n   L LL L b\nLLLL LL L c\nL LLLLLLL d\nLLLL L    e\n   D DD D b\nDDDD DD D c\nD DDDDDDD d\nDDDD D    e\n   MMMWWW f\nWWWW WWWW g\nWW WW WW  h\nII II II  i\nCCCC CCCC j\n   WW WW  k\nXAXAXAXAX l\nZZZ I III m\n WW SW S  n\n W  W  S  o\nWWW S  S  p\nWW  S  S  q\n W  S  S  r\n CC SC S  n\n C  C  S  o\nCCC S  S  p\nCC  S  S  q\n C  S  S  r\n II SI S  n\n I  I  S  o\nIII S  S  p\nII  S  S  q\n I  S  S  r\n GG SG S  n\n G  G  S  o\nGGG S  S  p\nGG  S  S  q\n G  S  S  r\n DD SD S  n\n D  D  S  o\nDDD S  S  p\nDD  S  S  q\n D  S  S  r\n K  S  F  s\nSN S NSN  t\n   W W W  u\n        G v\n      G   v\n   G      v\nG         v\n   I I I  w\n G GRG G  y\nPPPPVPPPP z\n   CCCCCC {\n   CCC    |\n   SWSSWS }\n   H H H  ~\n    W  W  S\n R  S     E\n   PL PP  B\n   NN NN  M\nGGGGGGGGG Z\nIIIIIIIII Z\nLLLLLLLLL Z\nDDDDDDDDD Z\n I IRI I  V`.split("\n");
toLog = "";
arr.forEach(f=>{
  inputs.value = f.substring(0,9);
  runClicked();
  correct = f.charAt(10);
  got = output.value;
  if (got != correct)
    toLog+= "\""+ inputs.value +"\": expected \""+ correct +"\", got \""+ got +"\".";
})
console.log(toLog);

```
> 2 votes

# Answer
# Jelly, score 0.00173611111

4/(48^2) = 0.00173611111 score

```
OṢḄỌ

```

Takes input as string with hyphens for empty space, e.g. `-----WWWW`.

I think this is valid because the challenge says

> Output will be the item crafted from the input, **in any form you want**, as long as it is obvious what it means. (Personally, I would use my 1 letter abbreviations of the items)

The 1 letter abbreviations are about as confusing as what this outputs, so this output is obvious enough what it means.

This assumes the input can be one the program can handle as specified by

> you can assume that the input passed will be one that it can handle

Try it online!

Test Suite (Header and footer prettify the output) This does all 48 recipes and gives their names.

**How it Works**

This is really just a really poor hash function.

```
OṢḄỌ - main link, input e.g. ZZZ-I-III
O      - character codes e.g. [90, 90, 90, 45, 73, 45, 73, 73, 73]
 Ṣ     - sort. This helps shapeless recipes and keeps recipes such as TNT in CJK
           e.g. [45, 45, 73, 73, 73, 73, 90, 90, 90]
  Ḅ    - convert from binary to integer e.g. 26670
   Ọ   - chr: convert from integer to character e.g.栮

```
> 1 votes

---
Tags: string, code-challenge, game
---


title: Golf me a memory array

text:
# Question
Title: Golf me a memory array
This challenge is pretty simple: Your task is to draw a schematic of a (simplified) memory array. You will be given two (positive) integers `n,m` and the task is to draw the `n:2^n` decoder connected to the memory array with `d` data lines.

The addressing will be in the order of gray codes, to check if the sequence is correct, see A014550. For simplicity there are no input ports, write ports etc. On the top of the decoder you need to specify its type (e.g. `2:4`) and you will label the data lines with `d:[d-1],...,d:1,d:0`. If the cray code wouldn't fit the decoder width, you'll need to expand the width, see the last two examples.

## Rules

* Leading whitespaces are not allowed
* Trailing whitespaces are allowed
* At the end of the output there may be one or several newlines
* You can assume the following constraints on the input `0 < n` and `0 < d <= 1e4`
* The output is either printed to the console or you write a function that returns a newline-separated string
* For invalid input the behaviour of your program/function is left undefined

## Test cases

```
n = 1, d = 1

.-----.
| 1:2 |
|     |
|    0|---+
|     |   |
|     |  .+.
|     |  | +-+
|     |  `-' |
|    1|---+  |
|     |   |  |
|     |  .+. |
|     |  | +-+
|     |  `-' |
`-----'      |
            d:0

```

---

```
n = 1, d = 10

.-----.
| 1:2 |
|     |
|    0|---+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|     |   |     |     |     |     |     |     |     |     |     |
|     |  .+.   .+.   .+.   .+.   .+.   .+.   .+.   .+.   .+.   .+.
|     |  | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+
|     |  `-' | `-' | `-' | `-' | `-' | `-' | `-' | `-' | `-' | `-' |
|    1|---+--(--+--(--+--(--+--(--+--(--+--(--+--(--+--(--+--(--+  |
|     |   |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
|     |  .+. | .+. | .+. | .+. | .+. | .+. | .+. | .+. | .+. | .+. |
|     |  | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+ | +-+
|     |  `-' | `-' | `-' | `-' | `-' | `-' | `-' | `-' | `-' | `-' |
`-----'      |     |     |     |     |     |     |     |     |     |
            d:9   d:8   d:7   d:6   d:5   d:4   d:3   d:2   d:1   d:0

```

---

```
n = 2, d = 3

.-----.
| 2:4 |
|     |
|   00|---+-----+-----+
|     |   |     |     |
|     |  .+.   .+.   .+.
|     |  | +-+ | +-+ | +-+
|     |  `-' | `-' | `-' |
|   01|---+--(--+--(--+  |
|     |   |  |  |  |  |  |
|     |  .+. | .+. | .+. |
|     |  | +-+ | +-+ | +-+
|     |  `-' | `-' | `-' |
|   11|---+--(--+--(--+  |
|     |   |  |  |  |  |  |
|     |  .+. | .+. | .+. |
|     |  | +-+ | +-+ | +-+
|     |  `-' | `-' | `-' |
|   10|---+--(--+--(--+  |
|     |   |  |  |  |  |  |
|     |  .+. | .+. | .+. |
|     |  | +-+ | +-+ | +-+
|     |  `-' | `-' | `-' |
`-----'      |     |     |
            d:2   d:1   d:0

```

---

```
n = 4, d = 5

.------.
| 4:16 |
|      |
|  0000|---+-----+-----+-----+-----+
|      |   |     |     |     |     |
|      |  .+.   .+.   .+.   .+.   .+.
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  0001|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  0011|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  0010|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  0110|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  0111|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  0101|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  0100|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1100|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1101|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1111|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1110|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1010|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1011|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1001|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
|  1000|---+--(--+--(--+--(--+--(--+  |
|      |   |  |  |  |  |  |  |  |  |  |
|      |  .+. | .+. | .+. | .+. | .+. |
|      |  | +-+ | +-+ | +-+ | +-+ | +-+
|      |  `-' | `-' | `-' | `-' | `-' |
`------'      |     |     |     |     |
             d:4   d:3   d:2   d:1   d:0

```

---

```
n = 1, d = 1024    (output truncated!)

.-----.
| 1:2 |
|     |
|    1|---+-----+----...
|     |   |     |    ...
|     |  .+.   .+.   ...
|     |  | +-+ | +-+ ...
|     |  `-' | `-' | ...
|    0|---+--(--+--(-...
|     |   |  |  |  | ...
|     |  .+. | .+. | ...
|     |  | +-+ | +-+ ...
|     |  `-' | `-' | ...
`-----'      |     | ...
            d:1023d:1022d:1021...

```

---

```
n = 10, d = 1    (output truncated!)

.-----------.
| 10:1024   |
|           |
| 0000000000|---+
|           |   |
|           |  .+.
|           |  | +-+
|           |  `-' |
...        ...    ...

```

---

```
n = 12, d = 5    (output truncated!)

.-------------.
| 12:4096     |
|             |
| 000000000000|---+-----+-----+-----+-----+
|             |   |     |     |     |     |
|             |  .+.   .+.   .+.   .+.   .+.
|             |  | +-+ | +-+ | +-+ | +-+ | +-+
|             |  `-' | `-' | `-' | `-' | `-' |
...          ...    ...   ...   ...   ...   ...

```

# Answer
# SOGL V0.12, 185 bytes

```
b :2b^:D⁰∑l2+bIΧCc┌*:A .1ΟO@c*┐1Οd5*2+∙ `a '+++;31žƧ01bH{╬⁰1w⁄»Ƨ01*□+}I{∑4⌡@}¹cb-2+3žKOKOād0C{āe{"h}‼Τ─īsgQ⅛&šε╬»‘6n┌eF-¡3**41ž┐c3*∙ceF-*¡³ (*ž61ž┼}+1C}@5*┐+e*+d┌@4*Ο;┼øe∫eκƧd:ΚF6*1ž}+┼

```

Try it Here!

Way too long...
> 6 votes

# Answer
# Charcoal, ~~170~~ 157 bytes

```
ＮνＮδＡＸ²νηＡ⪫⟦θ:Ｉη ⟧ωθＡ⌈⟦νＬθ⟧ζ←“ E*lÿxγ∨P3ζgRＵ#@˜R2$⁴⟧”Ｆ⁻δ¹Ｃ±⁶¦⁰↓←|  Ｆ⁻η¹Ｃ⁰¦⁵Ｐ←×⁺+×-⁵δ⸿Ｐ|  ←Ｍ×⁵η↓Ｆδ«Ｐ⁺d:ιＭ⁶←»↑←'-←ζ↑`↑²↑×⁵η.-Ｐ⁺¶θζ↓.↓²Ｐ↓×⁵η←Ｆη«Ｆν←§0110÷ιＸ²κＭν⁵

```

Try it online! Verbose approximation. Explanation:

```
ＮνＮδＡＸ²νηＡ⪫⟦θ:Ｉη ⟧ωθＡ⌈⟦νＬθ⟧ζ

```

Sets up the variables used in the rest of the code. `ν` and `δ` are the inputs, `η` is `2`<sup>`ν`</sup>, `θ` is the label at the top of the box, while `ζ` is one less than the width of the box.

```
←“ E*lÿxγ∨P3ζgRＵ#@˜R2$⁴⟧”

```

This compressed string represents the bottom left decoder. This is the one that's most representative, although ironically it first gets printed in the top right and then copied left and down.

```
Ｆ⁻δ¹Ｃ±⁶¦⁰↓←|

```

The decoder is repeated horizontally, and the `--(` at the top right of the last decoder is changed to a `|`.

```
Ｆ⁻η¹Ｃ⁰¦⁵Ｐ←×⁺+×-⁵δ⸿Ｐ|  ←Ｍ×⁵η↓

```

The decoder is then repeated vertically, and the `(`s in the top row are changed to `-`s (if you look carefully you'll see that too many `-`s are printed but fortunately the last one gets overwritten by the `0` of the address), after which the `|`s for the top right decoder are removed.

```
Ｆδ«Ｐ⁺d:ιＭ⁶←»

```

The decoders are numbered right-to-left.

```
↑←'-←ζ↑`↑²↑×⁵η.-Ｐ⁺¶θζ↓.↓²Ｐ↓×⁵η←

```

The box is printed, including the label.

```
Ｆη«Ｆν←§0110÷ιＸ²κＭν⁵

```

The Gray codes are printed.
> 6 votes

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