title: Codémon, I choose you!

text:
# Question
Title: Codémon, I choose you!
> Your kindly neighbour, Doctor Tree, just gave you three magical creatures called Codémon. There's a battle tournament in the nearby town of Colorville. Are you the very best, like no one ever was?

## Overview

This is a battle tournament. Each player controls a team of three monsters, and the objective is to knock out (kill) the other team. There are 100 rounds, with points being awarded for wins and ties. The team with the most points wins!

## Monsters

A Codémon is a complicated little creature. There are five types (elements) to choose from, three stats, and three move slots on each.

### Types

Each Codémon is assigned *one* type. The five types are Normal, Psychic, Fire, Water, and Grass. Each has its strengths and weaknesses. Damage is based on the following chart:

The numbers are damage multipliers. For instance, Fire attacking Water has a 0.5 modifier (half damage), whereas Fire attacking Grass is doubled (2).

### Stats

Each monster has three stats that determine its battle abilities. Attack raises the damage it does. Defense lowers the damage it takes. Speed allows it to move before those with lower Speed.

Each monster has a starting value of 50 for each stat, and a maximum of 100. When you create your monsters, you will be able to assign **80** additional stat points (each). Remember that no individual stat can go over 100. So, you could have a 100/80/50, 90/80/60, or 65/65/100 distribution, but 120/50/60 is illegal. Any team with illegal stats is disqualified. You are not *required* to use all 80 points, but you probably shouldn't go with the minimum 50/50/50.

You could also consider HP a stat, but each Codémon has a non-modifiable 100 HP. When HP drops to zero, they are unable to continue fighting. HP is refilled to 100 before each battle.

### Moves

Each monster knows three battle moves. The three chosen must be distinct, so no Punch/Punch/Punch.

There are 15 moves, three of each type. Each type has a direct attack, a weaker attack with an effect, and a sole effect move.

```
id  name        type    power   uses    usable  effect

0   Punch       N       20      -       NFWG
1   Heal        N        0      3       NFWG    Heals 50 HP
2   Slow        N       10      5       NFWG    Enemy speed x0.8
3   Pain        P       20      -       PFWG
4   Sleep       P        0      3       PFWG    No enemy action until wake
5   Weaken      P       10      5       PFWG    Enemy Atk x0.8
6   Fireball    F       20      -       NPFW
7   Burn        F        0      3       NPFW    Enemy -10 HP each turn
8   Sharpen     F       10      5       NPFW    Own Atk x1.25
9   Watergun    W       20      -       NPWG
10  Confuse     W        0      3       NPWG    Enemy may strike itself (10 power)
11  Shield      W       10      5       NPWG    Own Def x1.25
12  Vine        G       20      -       NPFG
13  Poison      G        0      3       NPFG    Enemy -5xTurns HP each turn
14  Sap         G       10      5       NPFG    Enemy Def x0.8

```

`type` refers to the type of the move. `power` is its striking power. `uses` indicates how many times it can be used per battle (`-` is unlimited). `usable` shows what types it can be used by (for example, Punch cannot be given to a Psychic type, as there is no `P`). `effect` shows what effects the moves have. There is a 75% chance of each effect working, except Heal, which always works.

For effects that change a monster's stats, **effects may be stacked**. For example, using Weaken twice may lower your opponent's attack to 0.64 effectiveness. Effects that do not change a monster's stats (Sleep, Burn, etc) **do not stack**.

**Sleep** puts the opponent to sleep, with a 60% chance of waking at the start of each turn. No action will be taken by sleeping monsters.

**Burn** damages the opponent 10 HP at the end of each turn *when active*. **Poison** works similarly, but takes an increasing amount each turn. On the first turn, it's 5, and it gains 5 each turn thereafter. So, by the fourth turn, it will be damaging for 20. These are flat damages, not affected by the monster's type or subject to bonuses.

**Confusion** may make a monster attack itself instead of doing what it was told to do. This attack has power 10, and has a 30% chance of happening on a given turn.

To be clear, effects last until end of battle (except Sleep, as noted above).

Moves also receive a 20% boost in power if used by a monster of the corresponding type. For example, a Grass monster using Vine is boosted, while using Punch he is not.

### Secret Stats

The stats and type (but *not* moves) of each monster is public knowledge. Your opponents will be able to see what they're fighting, in order to choose the best action. However, there are also bonuses available that are hidden.

Specifically, after every **two** battles, you will be given one "bonus" stat point for each monster on your team. Points are given to *all* monsters, dead or alive, winner or loser. You can assign this to whichever of the three stats you choose. You cannot stack them on a single monster; each monster gets *one* each time. **These points are immune to the 100 limit.** Since there will be 100 battle rounds, this means you can get a single stat up to 149 if you allot all your bonuses to it. Again, the opponent will only see your "base" stats, so the farther into the tournament you are, the further their knowledge diverges from the truth.

## Battle

Battle takes place between teams of three, with one active on each team at a time. At the start, you will be shown the opponent's team and asked to choose which monster will be your first "active" player.

After that, turns take place with the following steps:

* Switch : *Mandatory* monster switches take place (if any)
* Choose battle action
* Switch : Any *optional* monster switches (chosen as battle action) take place
* Sleep Check : Chance to wake from sleep
* Attack 1 : If able, the speedier monster uses its selected move
* Attack 2 : If able, the other monster uses its selected move
* Effect damage : Apply burn/poison damage to living monsters

"Speedier" means the monster with the higher speed. If both speed stats are the same, it is chosen by PRNG coin flip each turn.

At the end of any turn where your active monster dies, you will be asked to choose a new active. You may *also* choose to switch active monsters *as your move* for any turn (provided you have more than one alive). Again, if you switch as your move, you will not make a battle move that turn.

Monsters are not "processed" when inactive. This means they take no burn/poison damage, poison counters won't accumulate, no wake from sleep, etc. **No effects are removed or changed when switching**. This isn't that *other* monster battling game. If you switch out with attack raised and burned, they'll still be there when you switch back in.

Effect damage takes place whether you kill your active opponent or not. In this way, members of both teams may die on a single turn.

When one team runs out of usable monsters, they lose. If both teams run out on the same turn, it's a tie. If the battle lasts for 1000 turns, it's a tie.

The formula to determine damage is:

```
floor((effAttack / effDefense) * movePower * typeMultiplier * moveBoost)

```

`effAttack` and `effDefense` are the *effective* stats for the monsters. Effective attack is obtained by adding Attack and Bonus Attack, then multiplying (by 0.8 or 1.25) if any effects alter it. Remember that these effects can stack.

Damage can only be 0 when the type modifier is 0 (Normal \<--\> Psychic) or the move's Power is 0 (Heal, Burn, etc). Otherwise the minimum is enforced at 1.

## Tournament

Tournaments last for 100 rounds. In each round, the teams are shuffled and paired against each other randomly. If there are an odd number of teams, the leftover receives a bye (scores as a tie). Winning a battle earns the team **2** points, ties are worth **1**, and losses nothing. The team with the most points at the end wins!

If teams are tied, a tournament with only the teams tied for first place will take place to determine tiebreaker order.

# Protocol

The controller will send your program one of four commands. The first character determines the command type, with data following if necessary.

Your program will accept the command as an argument, and will respond on STDOUT within **one second**. Do not stay alive listening to STDIN, it won't be there. Each command will spawn a new process.

You may write data/state to disk. Place any files in a subfolder with the same name as your team. Do not write more than 32 kilobytes of data, or you will be disqualified. Data will persist between rounds, but will be cleared between tournaments.

## Commands

### Team Data

This is sent once at the start of the tournament to register your team. Your reply should be *constant*, not different for each tournament.

**Query:**

```
T

```

**Response:**

```
name|member0|member1|member2

```

`name` is a string with your team name. Please use alphanumeric only, for ease of parsing. `memberN` is a member string, giving the details of each monster:

Member string:

```
name:typeid:attack:defense:speed:moveid0:moveid1:moveid2

```

Again, 'name' is a string, this time with this monster's name. `typeid` is its type. Type ids are in the order shown in the chart above, with Normal=0 and Grass=4.

The next three fields are your base stats. Keep in mind the limits described in the stats section above.

The last three are your monster's moves. IDs are shown in the move chart above.

An example team data reply may look like this:

```
DummyTeam|DummyA:0:50:60:70:0:1:2|DummyB:0:50:60:70:0:1:2|DummyC:0:50:60:70:0:1:2

```

Any team that sends back garbage, ill-formatted, or illegal data here will not participate until it is fixed.

### Choose Active

This is sent at the start of each battle, and when a monster dies and needs to be switched.

**Query:**

```
C#battleState

```

`battleState` shows the state of the current battle. Bear with me here, it's ugly:

```
yourTeamState#theirTeamState

```

Where `XteamState` looks like:

```
name:activeSlot|member0state|member1state|member2state

```

`activeSlot` shows which monster is currently active (0-2). The member states come in two flavors. If it's *your* team, it gives extra information. So,

*Your* memberXstate:

```
name:id:attack:defense:speed:hp:typeid:poisonedturns:moveCount0:moveCount1:moveCount2:bonusAttack:bonusDefense:bonusSpeed:effectid:effectid:effectid

```

*Their* memberXstate:

```
name:id:attack:defense:speed:hp:typeid:poisonedturns:effectid:effectid:effectid

```

`id` is simply an integer identifier you can use to keep track of monsters if you don't like using `name`.

`attack:defense:speed` are your **base** stats.

`poisonedturns` tells you how many turns you've been poisoned for.

`moveCountX` tells how many uses you have left for each move. If 0, it cannot be used. For unlimited moves, this will be negative.

`bonus(stat)` is the amount of bonus points you have assigned to each stat.

`effectid` is a variable-sized list of effects that have been applied to your monster. There will *not* be a trailing `:` on the string, whether there are active effects present or not. If there are stacked effects, they will show up as multiple effects in the list.

The effect ids are:

```
0  NONE           (should not appear, internal use)
1  POISON
2  CONFUSION
3  BURN
4  SLEEP
5  HEAL           (should not appear, internal use)
6  ATTACK_UP
7  ATTACK_DOWN
8  DEFENSE_UP
9  DEFENSE_DOWN
10 SPEED_DOWN

```

**Response:**

```
memberSlot

```

The only response required is a single number 0,1,2, telling which member you want to be active. *This must be a member who is able to fight.* Don't send back `1` if member 1 is dead.

### Battle Action

Each turn, you need to decide what to do.

**Query:**

```
A#battleState

```

The `battleState` here is exactly as described above.

**Response:**

To use a move, send back the slot the move is in. For example, if I assigned Punch to slot 0, sending `0` performs Punch.

To switch to another member, send the member's slot *plus ten*. So to switch to member 2, send `12`.

Anything not in \[0,1,2,10,11,12\] is considered invalid and will result in no action taken this turn.

### Bonus Stats

After every two battles, you receive a secret bonus point for each team member.

**Query:**

```
B#yourTeamState

```

Your team state is the same as shown above, don't make me repeat it.

**Response:**

```
stat0:stat1:stat2

```

Your response will represent what stat to increase for each team member. Attack is 0, Defense is 1, Speed is 2.

So to raise member one's speed, member two's attack, and member three's defense, you would respond with:

```
2:0:1

```

# Controller

The controller can be found on BitBucket: https://Geobits@bitbucket.org/Geobits/codemon.git

Just toss all of the compiled class files, submissions, and players.conf in a folder and run.

The controller's main class is called `Tournament`. Usage is:

```
java Tournament [LOG_LEVEL]

```

Log levels from 0-4 give increasing information. Level 0 runs the tournament silently and just gives the results, where level 3 gives turn-by-turn commentary. Level 4 is debug output.

You can add submissions to the tournament in `players.conf` Simply add the command line string needed to run the program, one per line. Lines starting with `#` are comments.

In your post, include the command I will need to add to my `players.conf`, and any compilation steps (if required).

Included is a dummy team comprised of all Normal members with the three Normal moves. They choose moves randomly and have terrible stats. Have fun beating up on them.

# Misc Rules

* You may not read or write to any external resources (except in your own subfolder, up to 32 kB as noted above).
* Your team needs to go into the tournament "blind". That means you can't analyze other people's source to figure out what a specific team/monster will do in a given situation. You **can** analyze your opponent's moves/stats and keep track as the tournament progresses, but no hardcoding this information in.
* Do not interfere with other processes/submissions. No invoking them, using reflection to get at their data, etc. Do not mess with my computer. Just don't try it. This is at my discretion. Violators may be barred from future entry.
* Contestants are limited to a maximum of **two** entries. If you submit more, I will only score the first two submitted. If you want to revoke one, delete it.
* Entries may not exist solely to prop up other entries. Also, you may not try to indirectly disqualify other contestants (for example, using a 27M character team name to DQ players that try to write this to disk). Each submission should play to win on its own merit.
* Your program may spawn a maximum of one child process at a time (total descendants, not direct). Both the main and any child processes must terminate directly after giving output. Either way, ensure you don't go over the timeout.
* The tournament will be held on my computer running Ubuntu with an Intel i7 3770K processor.

# Results

These are the results of the current players. It's *very* close between the top contenders, and I'm thinking about bumping the number of rounds up to 500 (and adjusting the spacing of bonus points to match). Any objections, comments?

```
------- Final Results -------

158     Happy3Campers
157     LittleKid
71      InsideYourHead
68      HardenedTrio
46      BitterRivals

```

Full play-by-play results on Google Drive

# Answer
# Happy 3 campers - PHP

*A bunch of cowards who like to pelt the opposition with debilitating spells and watch them rot away.*

**EDIT**: Mr. Lumpy has been severely chastised and won't say no bad words anymore

---

## **Handy**`Grass - atk:50 def:99 spd:81 Confuse Poison Heal`

A venomous armless beaver who likes to confuse people with problematic handshakes

---

## **Flippy**`Water - atk:50 def:99 spd:81 Confuse Burn Heal`

A bulletin board veteran with a soft spot for bore-me-silly talks and flame wars.

---

## **Nutty**`Fire - atk:50 def:99 spd:81 Burn Poison Heal`

Weapons of mass destruction are his favourite candies.

---

## **Lumpy**`Php - lines:500 clarity:05 spd:01 Gather Guess Store`

Thanks to his nearly 2 digits IQ and phenomenal memory, Lumpy can guess enemy moves. Well, mostly.

---

## Strategy

The strategy is to have adversaries poisoned, burned and confused as soon as possible.
Sleep was not used since it seemed less powerful than the 3 spells above.
Confusion is deadly in the long run, since it reduces attacks by 30% (both damage dealing and spell casting), prevents healers from healing themselves and harms heavy hitters badly (a 50 def / 100 atk monster will inflict 20 points of damage upon itself).

Once a foe is thoroughly pasted, my campers simply watch him sizzle, rot and punch himself to death.

High defense and healing are used to mitigate incoming damage during the agony.

While my 3 campers are fighting, Lumpy the magic deer watches the enemies every move, and sometimes manages to identify them. The information is fed back to our fighters, who do their best to take advantage of it.

After defense, speed is the most important stat to boost.
Initiative is crucial for applying healing before the next blow comes.

Attack is not used at all.

## Are spells the ultimate weapon?

Spells like poison, burn and confuse escape the overall rock/paper/scissor logic of other attacks.

Once a monster is affected, it will continue losing HPs even after the spellcaster is dead. It is as if the ghost of the caster kept attacking him.
Besides, poison becomes quickly more powerful than a fully buffed-up massive attack (above 50 points after 5 turns).

A poisoned and burnt monster's life expectancy does not go beyond 8 turns, even with 3 healings.

As Martin's bots seem to indicate, the game balance is pretty good.
It's basically initiative that will tip the balance between pure spellcasters and pure attackers.

## The code

**Invoke with** `php campers.php`

It's an ugly mess, but frankly the interface does not help either.

Now that a suitably agressive competition appeared, I implemented my long planned enemy moves guessing.
Analyzing attacks requires various aerobatic deductions and persistent storage of last turn state, which means full-scale war with the paranoid controller interface.
It ain't no pretty stuff and no six-legged jackrabbit either, but it does an adequate job.

```
<?php

// ============================================================================
// Game
// ============================================================================
class G {
    static $code_type = array ("Normal", "Psychic", "Fire", "Water", "Grass", "?", "self");
    static $code_move = array    ("Punch", "Heal", "Slow", "Pain", "Sleep", "Weaken", "Fireball", "Burn", "Sharpen", "Watergun", "Confuse", "Shield", "Vine", "Poison", "Sap", "?", "self", "pass");
    static $move_uses = array (1000,3,5,1000,3,5,1000,3,5,1000,3,5,1000,3,5,   2000,2000);
    static $move_type      = array (0,0,0,1,1,1,2,2,2,3,3,3,4,4,4, 5,5,5);
    static $move_dmg       = array (20,0,10,20,0,10,20,0,10,20,0,10,20,0,10,  20,10,0);
    static $move_forbidden = array (1,1,1,0,0,0,4,4,4,2,2,2,3,3,3);
    static $code_effect = array ("N", "Poison", "Confuse", "Burn", "Sleep", "H", "Sharpen", "Weaken", "Shield", "Sap", "Slow");
    static $decode_type, $decode_move, $decode_effect;
    static $damage_multiplier = array (
        array (2, 0, 1, 1, 1, 0),
        array (0, 2, 1, 1, 1, 0),
        array (1, 1,.5, 2,.5, 0),
        array (1, 1,.5,.5, 2, 0),
        array (1, 1, 2,.5,.5, 0),
        array (2, 2, 2, 2, 2,-1),
        array (9, 9, 9, 9, 9, 9, 1));
    static $atk_score = array ("Poison"=> 1002, "Confuse"=>1001, "Burn"=>1000);
    static $status_field = "atk:def:spd:hp:type:Pturns";
    static $all_moves, $strong_moves, $medium_moves, $effect_moves, $possible_moves;

    function init()
    {
        self::$status_field = explode (":", self::$status_field);
        foreach (array ("type", "move", "effect") as $table) self::${"decode_$table"} = array_flip (self::${"code_$table"});
        foreach (self::$code_move as $c=>$m)
        {
            if ($m == "?") break;
            self::$all_moves[] = new Move($m);
            if (self::$move_uses[$c] >  5) self::$strong_moves[] = $m;
            if (self::$move_uses[$c] == 5) self::$medium_moves[] = $m;
            if (self::$move_uses[$c] == 3) self::$effect_moves[] = $m;
            for ($type = 0 ; $type != 5 ; $type++) if ((self::$move_uses[$c] >  5) && (self::$move_forbidden[$c] != $type)) self::$possible_moves[$type][] = $m;
        }
    }

    function __construct ($name, $team)
    {
        $this->turn = 0;
        $this->name = $name;
        $this->team = $team;
        $this->results_pending = false;
    }

    function parse_team ($tpack, $own_team)
    {
        $pack = explode ("|", $tpack);
        list ($name,$active) = explode (":", array_shift($pack));
        if ($own_team)
        {
            $team = $this->team;
        }
        else
        {
            if (!isset($this->enemies[$name])) $this->enemies[$name] = new Team(array (new Monster (), new Monster (), new Monster ()));
            $team = $this->foes = $this->enemies[$name];
        }
        $team->active = $active;
        foreach ($pack as $i=>$mpack) $team->monster[$i]->parse_monster ($own_team, $mpack);
    }

    function choose_active ()
    {
        // detect start of round
        $team = $this->team;
        $foes = $this->foes;
        foreach ($team->monster as $i=>$m) if ($m->hp > 0) $candidate[$i] = $m;
        if (count ($candidate) == 3)
        {
            $this->results_pending = false;
            $this->round++;

            // reinitialize all monsters
            foreach (array($team, $foes) as $t)
            foreach ($t->monster as $m)
                $m->start_round();

            // guess initial opponent
            $opponent = $foes->initial_opponent();
        }
        else
        {
            $this->analyze_last_round();
            $opponent = $foes->active();
        }
        return $this->do_switch ($opponent);
    }

    function choose_attacker ($foe)
    {
        foreach ($this->team->monster as $i=>$m) if ($m->can_attack($foe)) $candidate[$i] = $m;
        if (isset($candidate))
        {
            uasort ($candidate, function ($a,$b) use ($foe) { return ($a->atk_score != $b->atk_score) ? $b->atk_score - $a->atk_score : $b->life_expectancy($foe) - $a->life_expectancy($foe); });
            return key($candidate);
        }
        return -1;
    }

    function do_switch ($foe)
    {
        $replacement = $this->choose_attacker ($foe);
        if ($replacement < 0)
        {
            $candidate =  $this->team->monster;
            uasort ($candidate, function ($a,$b) use ($foe) { return $b->life_expectancy($foe) - $a->life_expectancy($foe); });
            $replacement = key($candidate);
        }

        $this->old_own = $this->team->monster[$replacement];
        $this->old_own->attack = "pass";
        return $replacement;
    }

    function choose_action ()
    {
        $this->analyze_last_round();
        $own = $this->team->active();
        $foe = $this->foes->active();
        $this->old_own = $own;

        if ($own->hp <= $own->max_damage($foe) && $own->can_do ("Heal")) return $own->execute("Heal");
        if ($attack = $own->can_attack($foe)) return $own->execute($attack);
        if ($own->hp <= 50 && $own->can_do ("Heal")) return $own->execute("Heal");

        return 10 + $this->do_switch ($foe);
    }

    function choose_bonus()
    {
        foreach ($this->team->monster as $m)
        {
            if ($m->spd_b == 0) { $m->spd_b++; $res[] = 2; }
            else                { $m->def_b++; $res[] = 1; }
        }
        return implode (":", $res);
    }

    function parse ($parts)
    {
        self::parse_team ($parts[1], true);
        self::parse_team ($parts[2], false);
    }

    function analyze_last_round()
    {
        if ($this->results_pending)
        {
            $this->results_pending = false;

            $foes = $this->foes;
            $foe = null;
            foreach ($foes->monster as $m) if ($m->hp != $m->old->hp) $foe = $m;
            if ($foe === null) $foe = $foes->monster[$foes->active];

            $this->old_own->guess_attack($foe);
        }
    }

    function process ($line)
    {
        $parts = explode ("#", $line);
        switch ($parts[0])
        {
        case "T": // register for tournament
            echo "$this->name|$this->team";
            break;
        case "C": // designate active monster
            $this->parse ($parts);
            echo $this->choose_active();
            break;
        case "A": // choose round action
            $this->parse ($parts);
            echo $this->choose_action();

            // save current state
            foreach (array($this->team, $this->foes) as $t)
            foreach ($t->monster as $m)
            {
                unset ($m->old);
                $m->old = clone ($m);
            }
            $this->results_pending = true;
            break;
        case "B": // distribute stat bonus
            echo $this->choose_bonus();
            break;
        }

    }
}
G::init();

// ============================================================================
// Move
// ============================================================================
class Move {
    function __construct ($move)
    {
        $this->register($move);
    }

    function register ($move)
    {
        $this->type = G::$decode_move[$move];
        $this->reinit();
    }

    function reinit()
    {
        $this->uses = G::$move_uses[$this->type];
    }

    function __tostring() { return G::$code_move[$this->type]."($this->uses)"; }
}

// ============================================================================
// Monster
// ============================================================================
class Monster {
    function __construct ($name="?", $type="?", $atk=100, $def=100, $spd=100, $m0="?", $m1="?", $m2="?")
    {
        $this->name = $name;
        $this->type = G::$decode_type[$type];
        $this->atk  = $atk;
        $this->def  = $def;
        $this->spd  = $spd;
        $this->hp   = 100;
        $this->move = array (new Move($m0), new Move($m1), new Move($m2));
        $this->atk_b = 0;
        $this->def_b = 0;
        $this->spd_b = 0;
        foreach (G::$code_effect as $e) $this->$e = 0;
    }

    function __tostring ()
    {
        return implode (":", array (
            $this->name,
            $this->type,
            $this->atk,
            $this->def,
            $this->spd,
            $this->move[0]->type,
            $this->move[1]->type,
            $this->move[2]->type));
    }

    function start_round()
    {
        foreach ($this->move as $m) $m->reinit();
    }

    function parse_monster ($own_team, $spack)
    {
        $pack = explode (":", $spack);
        $name = array_shift ($pack); // get name
        array_shift ($pack); // skip id
        if ($this->name == "?") $this->name = $name; // get paranoid
        else if ($this->name != $name) die ("expected $this->name, got $name");

        // store updated values
        foreach (G::$status_field as $var) $this->$var = array_shift ($pack);
        if ($own_team)
        {
            foreach ($this->move as $m) $m->new_count = array_shift($pack);
            $pack = array_slice ($pack, 3); // these are maintained internally
        }
        $var = array();
        foreach ($pack as $e) @$var[G::$code_effect[$e]]++;
        foreach (G::$code_effect as $e) $this->$e = @$var[$e]+0;
    }

    function damage_recieved ($attack, $foe=null)
    {
        if ($attack == "self") $foe = $this;
        $a = G::$decode_move[$attack];
        $type = G::$move_type[$a];
        $dmg = g::$move_dmg[$a];

        if ($dmg == 0) return 0;

        $atk = ($foe ->atk+$foe ->atk_b) * pow (.8, ($foe ->Weaken - $foe ->Sharpen));
        $def = ($this->def+$this->def_b) * pow (.8, ($this->Sap    - $this->Shield ));

        $boost = ($foe->type == $type) ? 1.2 : 1;
        return max (floor ($dmg * $atk / $def * $boost * G::$damage_multiplier[$this->type][$type]), 1);
    }

    function guess_attack_from_effect ($attacks)
    {
        foreach ($attacks as $status) if ($this->$status != $this->old->$status) return $status;
        return "?";
    }

    function guess_attack_from_damage ($foe, $damages)
    {
        $select = array();
        foreach (G::$possible_moves[$foe->type] as $attack)
        {
            $dmg = $this->damage_recieved ($attack, $foe);
            foreach ($damages as $damage) if ($damage != 0 && abs ($dmg/$damage-1) < 0.1) $select[$attack] = 1;
        }
        $res = array();
        foreach ($select as $a=>$x) $res[] = $a;
        return $res;
    }

    function guess_attack ($foe)
    {
        $attempt = G::$decode_move[$this->old->attack];
        $success = ($this->old->attack == "pass");
        foreach ($this->move as $m)
        {
            if ($m->type == $attempt)
            {
                if ($m->new_count == $m->uses-1)
                {
                    $m->uses--;
                    $success = true;
                }
                break;
            }
        }

        $possible = array();
        $attack = $this->guess_attack_from_effect (array("Burn", "Confuse", "Poison", "Sleep", "Slow", "Weaken", "Sap"));
        if ($attack == "?") $attack = $foe->guess_attack_from_effect (array("Sharpen", "Shield"));
        if ($attack == "?")
        {
            $foe_damage = $this->old->hp - $this->hp - (10 * $this->Burn + 5 * $this->Pturns*$this->Poison);
            if ($this->old->attack == "Heal" && $success) $foe_damage += 50;
            $possible_dmg[] = $foe_damage;
            //;!;if ($this->Confuse) $possible_dmg[] = $foe_damage + $this->damage_recieved ("self");
            $possible = $this->guess_attack_from_damage ($foe, $possible_dmg);
            if (count ($possible) == 1) $attack = $possible[0];
        }
        if ($attack == "?")
        {
            $own_damage = $foe->old->hp - $foe->hp
                        - (10 * $foe->Burn + 5 * $foe->Pturns*$foe->Poison)
                        + $foe->damage_recieved ($this->attack);
            if (abs ($own_damage/50+1) < 0.1) $attack = "Heal";
        }
        if ($attack != "?")
        {
            $type = G::$decode_move[$attack];
            if ($attack != "?")
            {
                foreach ($foe->move as $m) if ($m->type == $type) goto found_old;
                foreach ($foe->move as $m) if ($m->type == 15) { $m->register($attack); goto found_new; }
            }
            found_new:
            found_old:
        }
    }

    function max_damage($foe)
    {
        $dmg = 0;
        foreach ($foe->move as $m) $dmg = max ($dmg, $this->damage_recieved (G::$code_move[$m->type], $foe));
        return $dmg;
    }

    function expected_damage ($foe)
    {
        return $this->max_damage($foe) + 10 * $this->Burn + 5 * ($this->Pturns+1);
    }

    function life_expectancy ($foe)
    {
        $hp = $this->hp;
        $poison = $this->Pturns;
        $heal = $this->can_do ("Heal");
        $dmg = $this->max_damage($foe);
        for ($turn = 0 ; $hp > 0 && $turn < 10; $turn++)
        {
            $hp -= 10 * $this->Burn + 5 * $poison;
            if ($poison > 0) $poison++;
            $hp -= $dmg;
            if ($hp <= 0 && $heal > 0) { $hp+=50; $heal--; }
        }
        return 100 * $turn + $this->hp;
    }

    function can_attack ($foe)
    {
        $attack = false;
        if ($this->hp > 0)
        {
            if      (!$foe->Poison  && $this->can_do ("Poison" )) $attack = "Poison";
            else if (!$foe->Confuse && $this->can_do ("Confuse")) $attack = "Confuse";
            else if (!$foe->Burn    && $this->can_do ("Burn"   )) $attack = "Burn";
        }
        $this->atk_score = ($attack === false) ? 0 : G::$atk_score[$attack];
        return $attack;
    }

    function can_do($move)
    {
        $type = G::$decode_move[$move];
        foreach ($this->move as $m) if ($m->type == $type && $m->uses > 0) return $m->uses;
        return false;
    }

    function execute($move)
    {
        $type = G::$decode_move[$move];
        foreach ($this->move as $i=>$m) if ($m->type == $type)
        {
            if ($m->uses > 0)
            {
//;!;               $m->uses--;
                $this->attack = $move;
            }
            else $this->attack = "pass";
            return $i;
        }
        die ("$this asked to perform $move, available ".implode(",", $this->move));
    }
}

// ============================================================================
// Team
// ============================================================================
class Team {
    function __construct ($members)
    {
        $this->monster = $members;
    }

    function __tostring()
    {
        return implode ("|", $this->monster);
    }

    function active ()
    {
        return $this->monster[$this->active];
    }

    function initial_opponent()
    {
        return $this->monster[0];
    }
}

// ============================================================================
// main
// ============================================================================
$input = $argv[1];

$team_name = "H3C";
$mem_file = "$team_name/memory.txt";
$trc_file = "$team_name/trace.txt";
if (!file_exists($team_name)) mkdir($team_name, 0777, true) or die ("could not create storage directory '$team_name'");
if ($input == "T") array_map('unlink', glob("$team_name/*.txt"));

if (file_exists($mem_file)) $game = unserialize (file_get_contents ($mem_file));
else
{
    $team = new Team (
        array (
            new Monster ("Handy" , "Grass" , 50, 99, 81, "Confuse", "Poison", "Heal"),
            new Monster ("Nutty" , "Fire"  , 50, 99, 81, "Burn"   , "Poison", "Heal"),
            new Monster ("Flippy", "Water" , 50, 99, 81, "Confuse" , "Burn" , "Heal")));
    $game = new G($team_name,$team);
}

$game->process ($input);
file_put_contents ($mem_file, serialize($game));

```

## Results

LittleKid is still menacing, but my trio beat his venomous freaks by a fair margin.

Martin's bots are doomed by their lack of initiative, and increasing their speed would require to lower attack, which would blunt their edge in damage dealing capacity.

The new contenders from planet JavaScript are on par with the team in a one-on-one, but they fare worse against other competitors. They actually help decreasing LittleKid's score :).

So it seems my cuddly friends remain kings of the hill - for now...

```
170             H3C
158             Nodemon
145             LittleKid
55              InsideYourHead
42              HardenedTrio
30              BitterRivals

```
> 15 votes

# Answer
# HardenedTrio, Python 3

Since Geobits was nice enough to give us *two* submissions, I thought I'd submit something silly for the first one :P

The party is three Codemon (Metapod1, Metapod2, Metapod3) with the same stats and moves:

* 80 attack, 100 defense, 50 speed
* Punch, Heal, Shield Harden

All bonus points are also assigned to defense.

---

```
from collections import namedtuple
import sys

BattleState = namedtuple("BattleState", ["us", "them"])
TeamState = namedtuple("TeamState", ["name", "active", "members"])
MemberState = namedtuple("MemberState", ["name", "id", "attack", "defense", "speed", "hp",
                                         "typeid", "poisonedturns", "otherstats"])

def parse_battle_state(state):
    return BattleState(*map(parse_team_state, state.split("#")))

def parse_team_state(state):
    na, *members = state.split("|")
    name, active = na.split(":")
    return TeamState(name, int(active), list(map(parse_member_state, members)))

def parse_member_state(state):
    name, id_, attack, defense, speed, hp, typeid, poisonedturns, *rest = state.split(":")
    return MemberState(name, int(id_), float(attack), float(defense), float(speed),
                       float(hp), int(typeid), int(poisonedturns), rest)

command = sys.argv[1].strip()

if command.startswith("T"):
    print("HardenedTrio|Metapod1:0:80:100:50:0:1:11|"
          "Metapod2:0:80:100:50:0:1:11|Metapod3:0:80:100:50:0:1:11")

elif command.startswith("C"):
    battle_state = parse_battle_state(command[2:])

    for i, codemon in enumerate(battle_state.us.members):
        if codemon.hp > 0:
            print(i)
            break

elif command.startswith("A"):
    battle_state = parse_battle_state(command[2:])
    current_codemon = battle_state.us.members[battle_state.us.active]

    if current_codemon.hp < 50 and int(current_codemon.otherstats[1]) > 0:
        print(1) # Heal up if low

    elif int(current_codemon.otherstats[2]) > 0:
        print(2) # Harden!

    else:
        print(0) # Punch!

elif command.startswith("B"):
    print("1:1:1")

```

Run with

```
py -3 <filename>

```

(or with `python`/`python3` instead of `py` depending on your installation)
> 7 votes

# Answer
# LittleKid, Java

A little kid found 3 identical codémons and trained them. They are very annoying with their heal+poison attacks. Using only normal-type codémons removes the need to pair them up against specific enemies, since poison works well against all types.

```
public class LittleKid {

    public static void main(String[] args) {
        if(args.length < 1){
            System.out.println("Geobits says you can't do this.");
            System.exit(0);
        }

        String[] sections = args[0].split("#");
        String me, them, out = "";
        switch(sections[0]){
            case "T":
                out = "LittleKid";
                out += "|Poisoner:0:80:100:50:0:1:13";
                out += "|Poisoner:0:80:100:50:0:1:13";
                out += "|Poisoner:0:80:100:50:0:1:13";
                break;
            case "B":
                out = "1:1:1";
                break;
            case "C":
                me = sections[1];
                them = sections[2];
                int pick = 0;

                if(!isAlive(me, pick)){
                    for(int i=0;i<3;i++){
                        if(isAlive(me,i))
                            pick = i;
                    }
                }

                out = String.valueOf(pick);
                break;
            case "A":
                me = sections[1];
                them = sections[2];
                int active = getActive(me);
                int enemyActive = getActive(them);
                if (getField(me, HP, active) < 50 && getField(me, MOVE1, active) != 0) {
                    out = "1";
                } else if (getEffectCount(them, POISON, enemyActive, false) < 1 && getField(me, MOVE2, active) != 0) {
                    out = "2";
                } else {
                    out = "0";
                }
                break;
            default:
                out = "Invalid query from controller.";
        }
        System.out.println(out);
    }

    static boolean isAlive(String teamState, int who){
        return getField(teamState, HP, who) > 0;
    }

    static int getActive(String teamState){
        return Integer.parseInt(teamState.split("\\|")[0].split(":")[1]);
    }

    static int getField(String teamState, int field, int who){
        String[] fields = teamState.split("\\|")[who+1].split(":");
        return Integer.parseInt(fields[field]);
    }

    static int getEffectCount(String teamState, int effect, int who, boolean mine){
            String[] fields = teamState.split("\\|")[who+1].split(":");
            int count = 0;
            for(int i=mine?14:8;i<fields.length;i++){
                if(Integer.parseInt(fields[i]) == effect)
                    count++;
            }
            return count;
    }

    final static int ID =       1;
    final static int ATTACK =   2;
    final static int DEFENSE =  3;
    final static int SPEED =    4;
    final static int HP =       5;
    final static int TYPE =     6;
    final static int MOVE0 =    8;
    final static int MOVE1 =    9;
    final static int MOVE2 =    10;

    final static int POISON =           1;
}

```
> 6 votes

# Answer
# Inside Your Head, Ruby

* **Brian**: Psychic, Attack: 100, Defence: 50, Speed: 80, Pain, Fireball, Watergun
* **Elemon1**: Psychic, Attack: 100, Defence: 50, Speed: 80, Fireball, Watergun, Vine
* **Elemon2**: Psychic, Attack: 100, Defence: 50, Speed: 80, Fireball, Watergun, Vine

```
TEAM_SPEC = "InsideYourHead"+
            "|Brian:1:100:50:80:3:6:9"+
            "|Elemon1:1:100:50:80:6:9:12"+
            "|Elemon2:1:100:50:80:6:9:12"

def parse_battle_state request
    request.map do |team_state|
        state = {}
        parts = team_state.split '|'
        state[:active] = parts.shift.split(':')[1].to_i
        state[:monsters] = parts.map do |monster_state|
            monster = {}
            parts = monster_state.split(':')
            monster[:name] = parts[0]
            monster[:hp] = parts[5].to_i
            monster[:type] = parts[6].to_i
            monster
        end
        state
    end
end

request = ARGV[0].split '#'
case request.shift
when 'T'
    puts TEAM_SPEC
when 'C'
    battle_state = parse_battle_state request
    my_state = battle_state[0]
    puts my_state[:monsters].find_index {|monster| monster[:hp] > 0}
when 'A'
    battle_state = parse_battle_state request
    my_state, their_state = *battle_state
    my_monster = my_state[:monsters][my_state[:active]]
    their_monster = their_state[:monsters][their_state[:active]]
    puts [1,0,1,2,0][their_monster[:type]]
when 'B'
    puts '0:0:0'
end

```

Run with

```
ruby InsideYourHead.rb

```

This doesn't work very well against Manu's bot, but it beats the other three. The team and monster names are pretty random... I might change them if I come up with something better

The strategy is pretty simple: ***attack!*** All three monsters only have pure attack moves, and they choose their move based on the opponent's monster's type.

I might experiment with throwing in a Heal later.
> 6 votes

# Answer
# Nodémon - Javascript

Since status appears to be the dominant strategy, this team focuses on speed to get statuses like poison and confusion onto the opponents first, and then stalls out with heal and/or sleep while the opponent wastes away.

I don't have PHP installed so this isn't tested against the Campers, but it seems to be a decent competitor for LittleKid in my trials (and decimates Bitter Rivals).

```
/*jshint node:true*/
'use strict';

var fs = require('fs');

var dataFile = 'Nodemon/data.json';
function getData(callback) {
  fs.readFile(dataFile, 'utf8', function(err, contents) {
    var data = {round: 0};

    if(!err) {
      data = JSON.parse(contents);
    }

    callback(data);
  });
}

function saveData(data, callback) {
  fs.mkdir('Nodemon', function() {
    fs.writeFile(dataFile, JSON.stringify(data), callback);
  });
}

var effect = {
  poison: '1',
  confusion: '2',
  burn: '3',
  sleep: '4',
  heal: '5',
  attackUp: '6',
  attackDown: '7',
  defenseUp: '8',
  defenseDown: '9',
  speedDown: '10'
};

function parseMemberCommon(args) {
  return {
    name: args[0],
    id: args[1],
    baseAttack: +args[2],
    baseDefense: +args[3],
    baseSpeed: +args[4],
    hp: +args[5],
    typeId: args[6],
    poisonedTurns: +args[7],
    effects: args.slice(8)
  };
}

function parseOwnMember(arg) {
  var args = arg.split(':');

  var ownArgs = args.splice(8, 6);

  var member = parseMemberCommon(args);

  member.moveCount = [
    +ownArgs[0],
    +ownArgs[1],
    +ownArgs[2]
  ];

  member.bonusAttack = +ownArgs[3];
  member.bonusDefense = +ownArgs[3];
  member.bonusSpeed = +ownArgs[3];

  return member;
}

function parseOpponentMember(arg) {
  return parseMemberCommon(arg.split(':'));
}

function parseTeamStateCommon(arg, memberParse) {
  var args = arg.split(':');
  var state = {
    name: args[0],
    members: []
  };
  args = arg.substring(state.name.length + 1).split('|');
  var activeSlot = args[0];
  for(var index = 1; index < args.length; index++) {
    state.members.push(memberParse(args[index]));
  }
  state.activeMember = state.members[activeSlot];
  return state;
}

function parseOwnState(arg) {
  return parseTeamStateCommon(arg, parseOwnMember);
}

function parseOpponentState(arg) {
  return parseTeamStateCommon(arg, parseOpponentMember);
}

function parseBattleState(arg) {
  var args = arg.split('#');
  return {
    own: parseOwnState(args[0]),
    opponent: parseOpponentState(args[1])
  };
}

function teamData() {

  saveData({round:0}, function() {
    console.log('Nodemon|' +
      'Charasaur:0:50:80:100:10:13:1|' +
      'Bulbtortle:4:50:80:100:10:13:1|' +
      'Squirtmander:1:50:80:100:10:13:4');
  });
}

function getActiveIndex(battleState) {
  for(var index = 0; index < battleState.own.members.length; index++) {
    var member = battleState.own.members[index];
    if(member.hp > 0) {
      return index;
    }
  }
}

function chooseActive(arg) {
  var battleState = parseBattleState(arg);

  getData(function(data) {
    var allFull = true;
    for(var index = 0; index < battleState.opponent.members.length; index++) {
      var member = battleState.opponent.members[index];
      if(!data.maxSpeed || member.baseSpeed > data.maxSpeed) {
        data.maxSpeed = member.baseSpeed;
      }
      if(member.hp < 100) {
        allFull = false;
      }
    }

    if(allFull) {
      data.round++;
    }

    saveData(data, function() {
      console.log(getActiveIndex(battleState));
    });
  });
}

function useMove(moves, battleState) {
  var fighter = battleState.own.activeMember;

  for(var moveIndex = 0; moveIndex < moves.length; moveIndex++) {
    var move = moves[moveIndex];
    if(fighter.moveCount[move]) {
      return move;
    }

    for(var memberIndex = 0; memberIndex < battleState.own.members.length; memberIndex++) {
      var member = battleState.own.members[memberIndex];

      if(member.hp > 0 && member.moveCount[move] > 0) {
        return 10 + memberIndex;
      }
    }
  }

  return -1;  //do nothing
}

function battleAction(arg) {
  var battleState = parseBattleState(arg);

  var fighter = battleState.own.activeMember;
  var opponent = battleState.opponent.activeMember;

  var attemptedMoves = [];

  if(opponent.effects.indexOf(effect.poison) === -1) {
    attemptedMoves.push(1);
  }

  if(opponent.effects.indexOf(effect.confusion) === -1) {
    attemptedMoves.push(0);
  }

  if(fighter.name === 'Squirtmander') {
    //sleep
    if(opponent.effects.indexOf(effect.sleep) === -1) {
      attemptedMoves.push(2);
    }
  }
  else {
    //heal
    if(fighter.hp <= 60) {
      attemptedMoves.push(2);
    }
  }

  console.log(useMove(attemptedMoves, battleState));
}

function bonusStats(arg) {
  var teamState = parseOwnState(arg);

  getData(function(data) {
    var result = '1:';

    if(data.round % 4 === 0) {
      result += '1:';
    }
    else {
      result += '2:';
    }
    if(teamState.members[2].baseSpeed + teamState.members[2].bonusSpeed > data.maxSpeed + (data.round / 2)) {
      result += '1';
    }
    else {
      result += '2';
    }
    console.log(result);
  });
}

var actions = {
  'T': teamData,
  'C': chooseActive,
  'A': battleAction,
  'B': bonusStats
};

var arg = process.argv[2];
actions[arg[0]](arg.substring(2));

```

Run with

`node nodemon`

P.S. Apologies to nodemon.
> 5 votes

# Answer
# Bitter Rivals - Java

A Grass/Fire/Water team that likes to switch it up.

### Greenosaur

Has at least neutral coverage on anyone. High speed to make up for lack of defense.

```
Type: Grass
Attack:   80     Vine
Defense:  50     Punch
Speed:   100     Pain

```

### Searizard

Tries to Sap enemies with with low attack. Burns and Fireballs after that.

```
Type: Fire
Attack:  100     Fireball
Defense:  50     Burn
Speed:    80     Sap

```

### Blastshield

Uses Shield to enhance its already high defense. Heals when necessary.

```
Type: Water
Attack:   80     Watergun
Defense: 100     Shield
Speed:    50     Heal

```

### Code

This is also included with the controller. This *is* a competing team, unlike DummyTeam. The command needed for `players.conf` is:

```
java BitterRivals

```

---

```
public class BitterRivals {

    public static void main(String[] args) {
        if(args.length < 1){
            System.out.println("You're not doing this right. Read the spec and try again.");
            System.exit(0);
        }

        String[] sections = args[0].split("#");
        String me, them, out = "";
        switch(sections[0]){
            case "T":
                out = "BitterRivals";
                out += "|Greenosaur:4:80:50:100:12:0:3";
                out += "|Searizard:2:100:50:80:6:7:14";
                out += "|Blastshield:3:80:100:50:9:11:1";
                break;
            case "B":
                out = "2:0:1";
                break;
            case "C":
                me = sections[1];
                them = sections[2];

                int pick = 0;
                switch(getField(them, TYPE, getActive(them))){
                    case 0:
                    case 1:
                    case 3:
                        pick = 0;
                        break;
                    case 2:
                        pick = 2;
                        break;
                    case 4:
                        pick = 1;
                        break;
                }

                if(!isAlive(me, pick)){
                    for(int i=0;i<3;i++){
                        if(isAlive(me,i))
                            pick = i;
                    }
                }

                out = pick + "";
                break;
            case "A":
                me = sections[1];
                them = sections[2];
                int active = getActive(me);
                int oType = getField(them, TYPE, getActive(them));
                switch(active){
                    case 0:         // Greenosaur
                        switch(oType){
                            case 0:
                            case 4:
                                out = "1";
                                break;
                            case 1:
                                out = "2";
                                break;
                            case 3:
                                out = "0";
                                break;
                            case 2:
                                if(isAlive(me, 2)){
                                    out = "12";
                                } else if(isAlive(me, 1)){
                                    out = "11";
                                } else {
                                    out = "1";
                                }
                                break;
                        }
                        break;
                    case 1:         // Searizard
                        if(oType == 3){
                            if(isAlive(me, 0)){
                                out = "10";
                                break;
                            } else if(isAlive(me, 2)){
                                out = "12";
                                break;
                            }
                            if(getEffectCount(them, BURN, getActive(them), false) < 1 && getField(me, MOVE1, active) > 0){
                                out = "1";
                            } else if(getField(me, MOVE2, active) > 0){
                                out = "2";
                            } else {
                                out = "3";
                            }
                        } else {
                            if(getField(them, ATTACK, getActive(them)) < 80){
                                if(getEffectCount(them, DEFENSE_DOWN, getActive(them), false) < 1 && getField(me, MOVE2, active) > 0){
                                    out = "2";
                                    break;
                                } else if(getEffectCount(them, BURN, getActive(them), false) < 1 && getField(me, MOVE1, active) > 0){
                                    out = "1";
                                    break;
                                }
                            }
                            out = "0";
                        }
                        break;
                    case 2:         // Blastshield
                        if(oType == 4){
                            if(isAlive(me, 1)){
                                out = "11";
                                break;
                            } else if(isAlive(me, 0)){
                                out = "10";
                                break;
                            }
                        }
                        if(getField(me, HP, active) < 50 && getField(me, MOVE2, active) > 0){
                            out = "2";
                        } else if(getEffectCount(me, DEFENSE_UP, active, true) < 3 && getField(me, MOVE1, active) > 0){
                            out = "1";
                        } else {
                            out = "0";
                        }
                        break;
                }
                break;
            default:
                out = "Invalid query from controller.";
        }
        System.out.println(out);
    }

    static boolean isAlive(String teamState, int who){
        return getField(teamState, HP, who) > 0;
    }

    static int getActive(String teamState){
        return Integer.parseInt(teamState.split("\\|")[0].split(":")[1]);
    }

    static int getField(String teamState, int field, int who){
        String[] fields = teamState.split("\\|")[who+1].split(":");
        return Integer.parseInt(fields[field]);
    }

    static int getEffectCount(String teamState, int effect, int who, boolean mine){
            String[] fields = teamState.split("\\|")[who+1].split(":");
            int count = 0;
            for(int i=mine?14:8;i<fields.length;i++){
                if(Integer.parseInt(fields[i]) == effect)
                    count++;
            }
            return count;
    }

    final static int ID =       1;
    final static int ATTACK =   2;
    final static int DEFENSE =  3;
    final static int SPEED =    4;
    final static int HP =       5;
    final static int TYPE =     6;
    final static int PTURNS =   7;
    final static int MOVE0 =    8;
    final static int MOVE1 =    9;
    final static int MOVE2 =    10;
    final static int HA =       11;
    final static int HD =       12;
    final static int HS =       13;

    final static int POISON =           1;
    final static int CONFUSION =        2;
    final static int BURN =             3;
    final static int SLEEP =            4;
    final static int ATTACK_UP =        6;
    final static int ATTACK_DOWN =      7;
    final static int DEFENSE_UP =       8;
    final static int DEFENSE_DOWN =     9;
    final static int SPEED_DOWN =       10;
}

```
> 4 votes

# Answer
# Error 310 : Too Many Redirects - C++

*A highly trained and organized team to counter the ravages of poison*

For three weeks, I hardly trained my codémons. I formed several teams. And finally, I am ready to face this challenge. To answer all my poisoner opponents, I formed a team with very different codémons, each with a specific role.

---

## Antidote

## `Type : Normal - atk:50 def:100 spd:80 - Poison/Burn/Heal`

Antidote loves poison. So much so that I can't stop him from rushing to poison attacks.

---

## Zen

## `Type : Fire - atk:100 def:80 spd:50 - Poison/Vine/Heal`

Zen is a very surprising codémon which accommodates with all effects. He prefers to watch his enemies strive and exhaust against his silence.

---

## Triforce

## `Type : Psychic - atk:88 def:60 spd:82 - Fireball/Watergun/Vine`

Triforce is a classic codémon, always ready to fight. This one uses his psychic force to control the three elements and inflict as much damages as possible.

---

You can download the team here :

# Linux :

http://dl.free.fr/iHYlmTOQ2

launch with `./Error310TMR`

# Windows :

http://dl.free.fr/vCyjtqo2s

launch with `./Error310TMR.exe`

The code is a complete c++ project. I don't know how to publish it.

```
$ wc -l src/*
    165 src/BruteForce.cpp
     26 src/BruteForce.h
    349 src/Codemon.cpp
     77 src/Codemon.h
     21 src/Logger.cpp
     35 src/Logger.h
    105 src/NoTimeToExplain.cpp
     27 src/NoTimeToExplain.h
    240 src/Recoverator.cpp
     31 src/Recoverator.h
     26 src/StrManip.cpp
     16 src/StrManip.h
    303 src/Team.cpp
     68 src/Team.h
     88 src/TooManyRedirects.cpp
     24 src/TooManyRedirects.h
     87 src/Unrecoverable.cpp
     27 src/Unrecoverable.h
     59 src/enums.cpp
    119 src/enums.h
     68 src/main.cpp
   1961 total

```

But it is very effective :

```
------- Final Results -------

176     Error310TMR
131     H3C
130     LittleKid
121     Nodemon
58      InsideYourHead
47      HardenedTrio
37      BitterRivals

```
> 4 votes

# Answer
# FairyTale

A fairly generic middle-of-the-road team. Based on three archetypes who try to do their thing, and switch out if they can't do their thing at all.

This team was created before it seemed like poison was the new meta, I haven't really been keeping up with changing my team since I originally made it, most of the time was spent just trying to get the parsing down. I haven't been able to get the Tournament running yet to test it, but it's been a pretty busy week. If this one doesn't actually work like it seems to with my test data, I'll apply some more shine to it after work.

```
#!/bin/perl
use 5.20.0;
use strict;

use constant MINE => 0;
use constant THEIRS => 1;

$_ = $ARGV[0];

if(/^T/){
    say 'FairyTale|Fairy:1:89:90:51:3:4:13|Dragon:2:100:50:80:6:1:8|Assassin:0:70:60:100:0:1:10';

} elsif(/^C#(.*)/){
    my $state = readBattleState($1);
    if($state->[MINE]->{$state->[MINE]->{slot}}{hp}){
        say $state->[MINE]->{slot};
    } elsif($state->[MINE]->{($state->[MINE]->{slot}+1)%3}{hp}){
        say (($state->[MINE]->{slot}+1)%3);
    } else {
        say (($state->[MINE]->{slot}+2)%3);
    }

} elsif(/^A#(.*)/){
    my $state = readBattleState($1);
    my @actives = (
        $state->[MINE]->{$state->[MINE]->{slot}},
        $state->[THEIRS]->{$state->[THEIRS]->{slot}}
    );
    if($state->[MINE]->{slot} == 0){
        if(!exists($actives[THEIRS]{effects}{4}) && $actives[MINE]{pp}->[1]){
            say 1;
        } elsif(!exists($actives[THEIRS]{effects}{1}) && $actives[MINE]{pp}->[2]) {
            say 2;
        } elsif(!$actives[THEIRS]{type}) {
            if($state->[MINE]->{($state->[MINE]->{slot}+1)%3}{hp} > 0){
                say (($state->[MINE]->{slot}+1)%3);
            } elsif($state->[MINE]->{($state->[MINE]->{slot}+2)%3}{hp} > 0) {
                say (($state->[MINE]->{slot}+2)%3);
            } else {
                say 0;
            }
        } else {
            say 0;
        }
    } elsif($state->[MINE]->{slot} == 1){
        if(!exists($actives[MINE]{effects}{6}) && $actives[MINE]{pp}->[2]){
            say 2;
        } elsif ($actives[MINE]{hp} > 10 && $actives[MINE]{hp} < 50 && $actives[MINE]{pp}->[1]){
            say 1;
        } else {
            say 0;
        }
    } elsif($state->[MINE]->{slot} == 2){
        if(!exists($actives[MINE]{effects}{6}) && $actives[MINE]{pp}->[2]){
            say 2;
        } elsif ($actives[MINE]{hp} > 10 && $actives[MINE]{hp} < 50 && $actives[MINE]{pp}->[1]){
            say 1;
        } elsif($actives[THEIRS]{type} == 1) {
            if($state->[MINE]->{($state->[MINE]->{slot}+1)%3}{hp} > 0){
                say (($state->[MINE]->{slot}+1)%3);
            } elsif($state->[MINE]->{($state->[MINE]->{slot}+2)%3}{hp} > 0) {
                say (($state->[MINE]->{slot}+2)%3);
            } else {
                say 0;
            }
        } else {
            say 0;
        }
    }

} elsif(/^B#(.*)/){
    my $state = readTeam($1, 1);
    say '1:0:2';
}

sub readBattleState {
    local $_ = $_[0];
    if(/^(.*?)#(.*?)$/){
        my @teams;
        $teams[0] = readTeam($1, 1);
        $teams[1] = readTeam($2, 0);
        return \@teams;
    }
}

sub readTeam {
    my $isMine = $_[1];
    local $_ = $_[0];
    if(/.*?:(?<slot>.*?)\|(.*?)\|(.*?)\|(.*?)$/){
        my %team;
        $team{slot} = $1;
        $team{0} = $isMine ? readYourMember($2) : readTheirMember($2);
        $team{1} = $isMine ? readYourMember($3) : readTheirMember($3);
        $team{2} = $isMine ? readYourMember($4) : readTheirMember($4);
        return \%team;
    }
    return 0;
}

sub readYourMember {
    local $_ = $_[0];
    if(/(?<name>.*?):(?<id>.*?):(?<atk>.*?):(?<def>.*?):(?<spd>.*?):(?<hp>.*?):(?<type>.*?):(?<poison>.*?):(?<move0>.*?):(?<move1>.*?):(?<move2>.*?):(?<batk>.*?):(?<bdef>.*?):(?<bspd>.*?)(?<effects>(?::.*)|$)/){
        my %effects = map { $_ => 1 } readEffects($+{effects});
        my %member = (
            name   => $+{name},
            id     => $+{id},
            hp     => $+{hp},
            atk    => $+{atk}+$+{batk},
            def    => $+{def}+$+{bdef},
            spd    => $+{spd}+$+{bspd},
            type   => $+{type},
            pp     => [$+{move0}, $+{move1}, $+{move2}],
            poistrn=> $+{poison},
            effects=> \%effects
        );
        return \%member;
    }
}

sub readTheirMember {
    local $_ = $_[0];
    if(/(?<name>.*?):(?<id>.*?):(?<atk>.*?):(?<def>.*?):(?<spd>.*?):(?<hp>.*?):(?<type>.*?):(?<poison>.*?)(?<effects>(?::.*)|$)/){
        my %effects = map { $_ => 1 } readEffects($+{effects});
        my %member = (
            name   => $+{name},
            id     => $+{id},
            hp     => $+{hp},
            atk    => $+{atk},
            def    => $+{def},
            spd    => $+{spd},
            type   => $+{type},
            poistrn=> $+{poison},
            effects=> \%effects
        );
        return \%member;
    }
    return 0;
}

sub readEffects {
    local $_ = $_[0];
    my @retval = /:([^:]*)/g;
    if(!@retval){
        @retval = (0);
    }
    return @retval;
}

```

Run with

```
perl fairytale.pl

```
> 2 votes

# Answer
# Dummy Team - Java

### (non-competing CW)

This is a dummy team to practice on. It's all normal types, which choose randomly between their moves (Punch, Heal, Slow) each turn. Have fun with it.

```
public class DummyTeam {

    public static void main(String[] args) {
        if(args.length < 1){
            System.out.println("You need to run this from the tournament. Try to keep up.");
            System.exit(0);
        }

        String[] sections = args[0].split("#");
        String out = "";
        switch(sections[0]){
            // team data
            //      sends back all Normal types with minimum stats and Normal moves (randomized name suffixes to distinguish in tests)
            case "T":
                out = "DummyTeam";
                for(int i=0;i<3;i++)
                    out += "|Dummy"+((char)(Math.random()*26)+65) + i + ":0:50:50:50:0:1:2";
                break;
            // bonus points
            //      shoves them all in defense every time
            case "B":
                out = "1:1:1";
                break;
            // choose active
            //      picks last active if alive, otherwise loops to find first living member
            case "C":
                String[] team = sections[1].split("\\|");
                int current = Integer.parseInt(team[0].split(":")[1]);
                if(Integer.parseInt(team[current+1].split(":")[5]) > 0){
                    out = current + "";
                } else {
                    for(int i=1;i<team.length;i++){
                        if(Integer.parseInt(team[i].split(":")[5]) > 0){
                            out = (i - 1) + "";
                        }
                    }
                }
                break;
            // choose action
            //      chooses a random move. does not check if it ran out of uses, so wastes turns quite often
            case "A":
                out = ((int)(Math.random()*3)) + "";
                break;
            default:
                out = "Invalid query from controller.";
        }
        System.out.println(out);
    }

}

```
> 0 votes

---
Tags: game, king-of-the-hill
---


# Question
Title: Help me procrastinate on my computer repairs!
This challenge is brought to you by real (and tragic) inspiration. Recently, the number row on my keyboard has been a bit sporadic. The keys `1-9` work sometimes--but other times they have no result. As an avid programmer, this is horrible! (See that exclamation point? That's how you know they're working right now.) Not only do I often need the numbers themselves, but the symbols `!@#$%^&*(` are completely ineffective half the time as well! As a C programmer, rather than take time off my busy schedule of doodling around with code to fix my laptop, I've been more interested in working around the problem. Over the course of the past few weeks, slowly, all of the number literals in my code have been replaced with hexadecimal so that I don't have to go hunting around for numbers to copy and paste. However, some numbers aren't easy to type without the keys `1-9`. For example, the number `1` cannot be written so simply in hexadecimal, and I've resorted to replacing `1`s in my code with `0xF - 0xE`. The only keys that are affected are `1-9`, so I maintain full use of symbols like `+`, `-`, and `/`. However, I cannot use multiplication or parentheses, as `*` and `(` are often broken. This leads to your challenge.

# Input

An integer, `n` to stdin or your language's equivalent. If you wish, the integer may be preceded or followed by a new line or other whitespace character. Alternatively, you may receive input via a command line argument.

Your program should respond to negative input correctly, and be able to handle at least 32-bit signed integers.

# Output

Your program should output, in some observable form, the shortest (in non-whitespace characters) possible way to write the number `n` as a sum, difference, or division of one or more hexadecimal values. There is more than one way to solve this problem, and there is no requirement that you favor any equal-length output over any other.

The output should be in the form `A % A % A...` where `A` is a hexadecimal value following `0x` containing only digits `A-F a-f`, and `%` is one of of the symbols `-+/`. Let `/` describe integer division, not floating-point.

(Note that your output should result in `n` when evaluating divisions first, left to right, and then additions and subtractions, left to right, as is convention.)

# Test Cases

Input Output

1. `1`

`0xF - 0xE` (or `0xF-0xE` or `0xB-0xA` or `0xd - 0xc` or `0xF/0xF`)
2. `15`

`0xF`
3. `255`

`0xFF`
4. `30`

`0xF + 0xF`

# Scoring and Rules

This is code-golf. Your preliminary score is the number of bytes in your source file.

You may NOT use any of the digits `1-9` in your source.

You MAY use symbols `!@#$%^&*(` in your source, but each comes at a penalty of +20 to your score.

Your program may be replaced by a function that takes `n` as an argument as long as that function produces some form of human-readable output. Your function's return value does NOT count as output.

Standard loopholes are not allowed.

Lowest score wins! Good luck!

*Did I goof something up formatting/questioning/clarity-wise? Let me know! This is my first submission to this site!*

# Answer
# JavaScript 287 (187+20\*5) ~~295 (195 +20\*5) 338 (198 + 20\*7)~~

A function that check every possible combinations of the 6 allowed hex digits (0xA to 0xF) and the 3 allowed operators. Output via popup and not returning a value, as requested.

I used \[\] to group comma separated expression but could not avoid 5 ~~7~~ open brackets for loops and function calling.
To avoid digits there are variables A,B,C for 1,2,3 (this makes the code even more obscure)

**Edit** code revised focusing on avoiding '('. Removed `if`s and explicit RegExp creation

Beware: this function is incredibly slow, it will exceed the time limit for a script in FireFox, even for small input like 90.

To enumerate all the possible expression, I use number starting at 3 and going up forever. Digits encoding:
0,1,2 are the operators +,-,/
4 to 9 are the hex digits A..F
3 is not allowed
Each number is checked with a regexp `/3|[0-2]{2}/` to avoid the digit 3 and having 2 consecutive operators (the check also avoid traling and leading operators - see code)

The resulting string is something like `0xA + 0xA - 0xD` that is valid javascript, so I use eval to evaluate it. Unfortunatley the '/' operator is floating point and not integer in JavaScript, so I'm not 100% sure that the result are correct event casting to integer the final result (but I am quite confident, given that a small rounding error can not be amplified by a '\*')

```
F=x=>{
  for(A=-~0,B=A+A,i=C=A+B,j=0;j?x-~~eval(L):A;)
  {
    j=++i+'0',k=0+j;
    for(c of~k.search(C+'|[0-'+B+']{'+B+'}',L='',w='0x')?j='':j)
      c>C?w+=' ABCDEF'[c-C]:[L+=w,w=' '+'+-/'[c]+' 0x']
  }
  alert(L)
}

```

*Something else*

Now, something funnier. I used an oversimplified expressione parser to avoid the eval call and, amusingly, that turned out to be a lot faster.

The parser is really simplified, in a real parser V and O should be arrays containing the pending values stack and the pending operators stack. Here V is the single pending value (and also the return value) and O is a string with at most 2 characters. P contains the operators precedence table, for '-+/' =\> '112'

This scores 275 + 4\*20 =\> 355

```
F=x=>{
  for(A=-~0,B=A+A,i=C=A+B,D=A+C,j=0,P=''+A+A+B;j?x-V:A;)
  {
    j=++i+'0',k=0+j;
    for(c of~k.search(C+'|[0-'+B+']{'+B+'}',v=V=O=L='',w='0x')?j='':j)
      c>C?
        w+='ABCDEF'[v<<=D,v+=D+A-~c,c-D]
      :[
          P[O[0]]>=P[c]?[v=O>A?V/v|0:O>0?V+v:V-v,O=c]:O=c+O,
          L+=w,w=' '+'-+/'[c]+' 0x',V=v,v=0
      ]
  }
  alert(L)
}

```

**Test** In Firefox/FireBug console, change alert with return (a lot more usable)

```
;[0, 1, 15, 255, 30].forEach(x=>console.log(x,F(x)))

```

> 0 0xA - 0xA
> 1 0xA / 0xA
> 15 0xF
> 255 0xFF
> 30 0xF + 0xF

Just a little less obvious (but be patient)

```
;[16,40, 51, 62, 73, 84, 95].forEach(x=>console.log(x,F(x)))

```

> 16 0xBA / 0xB
> 40 0xA + 0xF + 0xF
> 51 0xDD - 0xAA
> 62 0xEA - 0xAC
> 73 0xA + 0xEA - 0xAB
> 84 0xFE - 0xAA
> 95 0xA + 0xFF - 0xAA
> 5 votes

# Answer
# Python 2: 185 byte + 2 * 20 = 225

Way too long for a serious answer. But since there are no answers yet, I'll post it anyways.

```
from itertools import product as p
n=input()
l=t=0
while~l:
 l=-~l
 for i in p("0xABCDEF+-/",repeat=l):
  j=""
  for k in i:j+=k
  try:exec"t="+j
  except:0
  if t==n:print j;l=~0;break

```

`product` creates all different arrangements of the allowed chars. `exec` tries to decode it. This sadly returns an exception, thence the long `try - catch` block. It the result is fine, it prints and exists.

2 times penalty, because of those braces during function calls.
> 3 votes

---
Tags: code-golf, restricted-source, conversion, hexadecimal, integer
---


title: Finding Programs in the Primes

text:
# Question
Title: Finding Programs in the Primes
Let's assign the numbers 0 through 94 to the 95 printable ASCII characters:

```
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
```

Space is 0, `!` is 1, and so on until `~` is 94. We'll also assign 95 to tab (`\t`) and 96 to newline (`\n`).

Now consider the infinite string whose Nth character is the character above that the Nth prime number, modulo 97, has been assigned to. We'll call this string S.

For example, the first prime number is 2, and 2 mod 97 is 2, and 2 is assigned to `"`, so the first character of S is `"`. Similarly, the 30th prime number is 113, and 113 mod 97 is 16, and 16 is assigned to `0`, so the 30th character of S is `0`.

The first 1000 characters of S are as follows:

```
"#%'+-137=?EIKOU[]cgiosy $&*,0>BHJTV\bflrt~
#%1=ACGMOY_ekmswy"046:HNXZ^dlrx|!)-5?AKMSW]eiko{"&.28DFX^hntv|%+139?CEQ[]agmo{  $,6>HPV\`hnrz~+5ACMOSU_mqsw$(*.BFNX`djp~!'-5;GKQS]_eoq{}"48:>DJRX^tv
'17=EQU[aciu    026<>DHJNZ\b#)/7ISaegkqy}   $0:<@BFLXdlx~!'/3;?MQWY]ceku(.24LPR\hjt|!'-?EIKWamu$28<>BDNZ`fxz)+AGOUY[_gmwy"0:@LNRT^jl|~#')3;Meiow&(,4DFJRX^bnp%+-37=KQUW]agsy    ,06BJPTn
)15;=CYegw  ".<FHLTZ`dfjpx|~#-/9AES]ikquw&48>FLPbjtz
'1=KOU[]y{$,0>BJV\hlr%/1A[_amsw"(04<RTXZf!#)/59?AMQ]_ik{},2FV^bdhj
'39CEIOQWacoy{$28<BJPVfrtx%+/7AIOUkqs}*.4FHR`dfp~!);?EGKQS_cw,8:>DJLRhjp
%139EUW[aosu&>HNPZ\fhrxz#%/5=[egqy  (:@LXZlrv|!35?MSWY]uw"(8@FL^nptz|!'17COacim &>BDHNP\`n+5;GU[eqsw}$*46:HNTX^`jl|'/AEKWY_ek&,:>FPXdvz|
7CIK[agu    ,0NTZ`hnrt
%)+1GMOSegkwy   "<BHLT^~-/59;?AKY_cku{.24:X\dntz!'37=?EIOQ[]ms&*6D`fz~/7=AGU[akmw"*46@HT^vx|#)-5GQW]_eo{}&,28@FPVX^djt|39OQcgoy6>PTV`fhnr#+7IY_ams} (*0:HLdfvx!#-AEGKScioq},48>\^hjptz
'-1=CKW[iu  6<HNPfn
)/=ACIS[aek(6@BNXZjl~5GM]ouw(,24>FPV\dhnpz|'+179EIWims&*28<DHV\`nz~
=AY_eq}*046:LR^

```

Stack Exchange turns tabs into spaces, so here's a PasteBin with the tabs intact.

# Challenge

Find a substring of S that is a valid program in your language of choice that outputs the first M prime numbers, **one per line, in order**, for some positive integer M.

For example, `2` is a substring of S (it occurs in multiple places but any will do), and `2` is a valid CJam program whose output is

```
2

```

which is the first M = 1 prime numbers, one per line, in order.

Similarly, the string `2N3N5` may be a substring of S somewhere, and `2N3N5` is a valid CJam program that outputs

```
2
3
5

```

which is the first M = 3 prime numbers, one per line, in order.

## Scoring

The submission with the highest M wins. Tie breaker goes to the submission posted first.

## Details

* There should be no additional output besides the single primes on each line, except for an optional trailing newline after the last line. There is no input.
* The substring may be any length as long as it's finite.
* The substring may occur anywhere within S. (And S may contain it in multiple places.)
* The program must be a full-fledged program. You may not assume it is run in a REPL environment.
* The program must run and terminate in a finite amount of time without errors.
* "Newline" may be interpreted as any common newline representation necessary for your system/interpreter/etc. Just treat it as one character.

You must give the index of S where your substring starts, as well as the length of the substring if not the substring itself. You may not only show that the substring must exist.

<sup>*Related: Looking for programs in a huge Boggle board*</sup>

# Answer
# Lenguage, M = ∞

All of the programs start at the beginning of the string. The following poorly written Python program calculates how many characters are needed for a given M.

```
def program_length(n):
    PLUS, MINUS, DOT = '000', '001', '100'
    i = 1
    s = ''
    while n > 0:
        i += 1
        if all(i%f for f in range(2,i)):
            s += str(i) + '\n'
            n -= 1
    out = '110111'
    ch = 0
    for c in s:
        dif = ord(c) - ch
        if dif > 0: out += PLUS * dif
        else: out += MINUS * -dif
        out += DOT
        ch = ord(c)
    return int(out, 2)

```

For example, for M = 5, the program is the first 2458595061728800486379873255763299470031450306332287344758771914371767127738856987726323081746207100511846413417615836995266879023298634729597739072625027450872641123623948113460334798483696686473335593598924642330139401455349473945729379748942060643508071340354553446024108199659348217846094898762753583206697609445347611002385321978831186831089882700897165873209445730704069057276108988230177356 characters.
> 18 votes

# Answer
# CJam, M = 2

Short and sweet:

```
2NZ

```

This sequence starts at position 54398, using 1-indexing of the string. You can test it online here.

I attempted to search for a few possible variations, but this was the first solution I found.

I am currently trying to find an M = 3 version, but I don't expect to find one within a reasonable period of time. If the sequence is uniformly random (an approximation), then the starting index for a length 5 sequence could be on the order of 10^9.
> 3 votes

---
Tags: code-challenge, restricted-source, primes, printable-ascii
---


title: Find largest sum of subsequence

text:
# Question
Title: Find largest sum of subsequence
Given a sequence of integers find the largest sum of a subsequence (integers on consecutive positions) of the sequence. The subsequence can be empty (in which case the sum is 0).

Input is read from standard input, one integer per line. The largest sum must be written to standard output.

I wrote a small generator for you:

```
#include <stdio.h>
#include <assert.h>

/* From http://en.wikipedia.org/wiki/Random_number_generation */
unsigned m_w;
unsigned m_z;

unsigned get_random()
{
  m_z = 36969 * (m_z & 65535) + (m_z >> 16);
  m_w = 18000 * (m_w & 65535) + (m_w >> 16);
  return (m_z << 16) + m_w;  /* 32-bit result */
}

int main(int argc, char **argv)
{
  int i;

  assert(argc == 3);
  m_w = atoi(argv[1]);
  m_z = atoi(argv[2]);

  i = 10;
  while (i--);
    get_random();

  i = atoi(argv[2]);
  while (i--)
    printf("%d\n", (int) get_random() << 8 >> 22);

  return 0;
}

```

Examples:

```
$ printf "1\n2\n-1\n4\n" | ./sum
6
$ printf "0\n-2\n-3\n" | ./sum
0

$ ./a.out 1 1 | ./sum
387
$ ./a.out 1 10 | ./sum
571
$ ./a.out 1 100 | ./sum
5867
$ ./a.out 1 1000 | ./sum
7531
$ ./a.out 1 10000 | ./sum
27268
$ ./a.out 1 100000 | ./sum
101332
$ ./a.out 1 1000000 | ./sum
187480
$ ./a.out 1 10000000 | ./sum
666307

```
* `./sum` is my solution
* `./a.out` is the generator

Your solution must run in reasonable time for all tests above (mine runs in 1.2s on the last test case).

Shortest code wins.

**Edit**: Please provide an example run on one of the tests above.

# Answer
## Ruby, 53 characters

```
p$<.inject(-1.0/s=0){|a,b|[s=[0,s+b.to_i].max,a].max}

```

Takes about 28 seconds for the last testcase here.
> 3 votes

# Answer
**Python, 91 84 64 chars**

```
s=m=0
try:
 while 1:s=max(s+input(),0);m=max(m,s)
except:print m

```

Takes about 14 12 72 seconds on the last test case. Edit: using algorithm Paul R found. Edit: nixed the import, using `input()`.
> 6 votes

# Answer
## C, 100 characters

```
main(){char s[80];int i,m=0,n=0;while(gets(s)){i=atoi(s);n=n+i>0?n+i:0;m=m>n?m:n;}printf("%d\n",m);}

```

Run time = **1.14 s** for final test case (10000000) on 2.67 GHz Core i7 with ICC 11.1 (previously: **1.44 s** with gcc 4.2.1).

Note: The algorithm used for the above solution comes from *Programming Pearls* by Jon Bentley. Apparently this algorithm is known as Kadane's Algorithm.
> 6 votes

# Answer
## Haskell (~~88~~ 64)

Implementing Kadane's algorithm.

```
main=interact$show.maximum.scanr(\x->max x.(x+))0.map read.lines

```
> 3 votes

# Answer
**Python - 114 chars**

```
import sys
s=map(int,sys.stdin.readlines())
l=range(len(s)+1)
print`max(sum(s[i:j])for i in l[:-1]for j in l[i:])`

```

It surely isn't as fast as required, but it works allright.
> 2 votes

# Answer
**Python, using dynamic programming - 92 chars**

```
import sys
s=map(int,sys.stdin.readlines())
f=h=0
for x in s:h=max(0,h+x);f=max(f,h)
print f

```
> 2 votes

# Answer
## J (~~34~~ 33 characters)

This solution implements a variant of Kadane's algorithm and is reasonable fast.

```
echo>./0,([>.+)/\.0".];._2(1!:1)3

```

Here is an explanation:

* `u/ y` – The verb `u` *inserted* between items of `y`. E.g., `+/ 1 2 3 4` is like `1 + 2 + 3 + 4`. Notice that all verbs in J are right-associated, that is, `-/ 1 2 3 4` is like `1 - (2 - (3 - 4))` and computes the alternating sum of `1 2 3 4`.
* `x >. y` – the maximum of `x` and `y`.
* `x ([ >. +) y` – The maximum of `x` and `x + y`. `[ >. +` is a verb in tacit notation and evaluates to the same as `x >. x + y`.
* `([ >. +)/ y` – the non-empty prefix of `y` with the largest sum.
* `u\. y``u` applied to all suffixes of `y`. Notice that special code handles the common case `u/\. y` such that this runs in linear instead of quadratic time.
* `([ >. +)/\. y` – A vector denoting the largest non-empty subarray that starts at each position of `y`.
* `0 , ([ >. +)/\. y``0` preprended to the previous result as `0` is the length of an empty subarray of `y`.
* `>./ 0 , ([ >. +)/\. y` – The largest subarray of `y`.
* `0 ". ];._2 (1!:1) 3` – Standard input marshalled into a vector of numbers.
* `>./ 0 , ([ >. +)/\. 0 ". ];._2 (1!:1) 3` – The largest subarray in standard input.
> 2 votes

# Answer
## Ruby, 68 chars

```
m=-2**31;n=0;$<.lines.map{|x|n+=x.to_i;n=0 if n<0;m=n if n>m};puts m

```

Also a bit slow, but completes the 1-10000000 tests in a bit over half minute, most of the time spent in the last test...

Indented version:

```
m=-2**31
n=0
$<.lines.map {|x|
  n+=x.to_i
  n=0 if n<0
  m=n if n>m
}
puts m

```
> 1 votes

# Answer
C++, 192 chars

```
#include <iostream>
#include <string>
#include <stdlib.h>
#define S std::
main(){long a=0,m=0,M=0;char s[9];while(S cin.getline(s,9)){a+=atoi(s);if(m>a)m=a;if(M<a-m)M=a-m;}S cout<<M<<S endl;}

```

Works reasonably fast on my laptop (4 seconds for the last test).
> 1 votes

# Answer
```
{if((r+$1)>0)
   r=r+$1
 else r=0;
 if(m<r)
   m=r;
}
END{print m}

```

**awk Code (66)**, very slow, 8+ seconds for last test case

```
dwang@dwang-ws ~/Playground/lss $ time ./random 1 10000000 | awk -f lss.awk
666307

real    0m6.705s
user    0m8.671s
sys 0m0.052s

```
> 1 votes

---
Tags: code-golf, subsequence
---


title: Identifying the triangles

text:
# Question
Title: Identifying the triangles
Counting the amount of triangles in a picture is a task commonly used in brain tests. You are given a picture that contains shapes consisting of triangles. You then must find all possible triangles in the picture.

# Task

You are given a list of lines in a format of your choice. You must then output a list of triangles found in that

## Input

You are given a list of lines, each given by four integer coordinates (eg. `x1 y1 x2 y2`). You may choose the input format, as long as it is clearly documented. Examples:

```
0 4 8 1
0 4 9 5
8 1 9 5
2 8 0 4
9 5 2 8

[[0, 4, 8, 1], [0, 4, 9, 5], [8, 1, 9, 5], [2, 8, 0, 4], [9, 5, 2, 8]]

```

Here's the same input as an image:

Another one, with intersections (only in one format to save space):

```
[[2, 1, 5, 0], [2, 1, 2, 7], [5, 0, 6, 6], [5, 0, 2, 7], [6, 6, 2, 1], [2, 7, 6, 6]]

```

## Output

You must output a list of all triangles, each given by six floating-point coordinates (eg. `x1 y1 x2 y2 x3 y3`), in the picture specified by the input. These might not be integers, since the lines may cross at any point. You may choose the output format, as long as it is clearly documented. Example outputs for the example inputs above:

```
0 4 8 1 9 5
0 4 9 5 2 8

[[0, 4, 8, 3, 9, 5], [0, 4, 9, 5, 2, 8]]

```

```
[[2, 1, 5, 0, 2, 7], [2, 1, 5, 0, 6, 6], [5, 0, 6, 6, 2, 7], [2, 1, 6, 6, 2, 7], [2, 1, 5, 0, 3.674, 3.093], [5, 0, 6, 6, 3.674, 3.093], [6, 6, 2, 7, 3.674, 3.093], [2, 7, 2, 1, 3.674, 3.093]]

```

## You may assume that

* there are no edge cases where a line crosses an intersection but not any lines, like

```
[[0, 9, 1, 8], [1, 8, 2, 9], [2, 9, 3, 8], [3, 8, 4, 9], [4, 9, 0, 9]]

```
* there are no angles over 179 degrees, like

```
[[0, 0, 0, 1], [0, 1, 0, 2], [0, 2, 0, 0]]

```

## Rules

* You may use any language you want.
* No external resources must be used.
* Standard loopholes apply.

## Scoring

This is , so the shortest answer in **bytes** wins.

# Answer
# PostGIS, 162

I think this complies with the rules, It is a query for PostGIS, which is an extension of PostgreSQL. The input is assumed to be a table of coordinates for each line called L The output is a set of rows with the polygon definition for the triangles formed.

```
SELECT ST_AsText(D)FROM(SELECT(ST_Dump(ST_Polygonize(B))).geom D FROM(SELECT ST_Union(ST_MakeLine(ST_Point(A,B),ST_Point(C,D)))B FROM L)A)B WHERE ST_NPoints(D)=4;

```

In use it looks like the following

```
-- Create a table for the input
CREATE TABLE L (A INT, B INT, C INT,D INT);
INSERT INTO L VALUES(2, 1, 5, 0), (2, 1, 2, 7), (5, 0, 6, 6), (5, 0, 2, 7), (6, 6, 2, 1), (2, 7, 6, 6);

SELECT ST_AsText(D)FROM(SELECT(ST_Dump(ST_Polygonize(B))).geom D FROM(SELECT ST_Union(ST_MakeLine(ST_Point(A,B),ST_Point(C,D)))B FROM L)A)B WHERE ST_NPoints(D)=4;

-- Cleanup
DROP TABLE L;

```

The output is as follows

```
POLYGON((5 0,2 1,3.67441860465116 3.09302325581395,5 0))
POLYGON((6 6,5 0,3.67441860465116 3.09302325581395,6 6))
POLYGON((3.67441860465116 3.09302325581395,2 7,6 6,3.67441860465116 3.09302325581395))
POLYGON((2 7,3.67441860465116 3.09302325581395,2 1,2 7))

```
> 1 votes

# Answer
# Mathematica ~~915 395 401~~ 405

**Update**

This programming challenge is much more difficult than it first appears to be.

The present approach works with simple cases, where there is but a single intersection along the length of any line segment. With multiple crossings along one segment, it is necessary to keep track of all of the intersection points along each line and create new sub-segments (hence additional graph edges) connecting the new intersection to all the intersection points along the target line.

Despite that limitation, it may be worth sharing the logic underlying the current approach.

---

The input line segments are treated as regions. If they intersect, the centroid will be the coordinates of the intersection. We need to eliminate those intersections that occur at the vertices of line segments. Lines that do not intersect will have an indeterminate centroid.

Four new edges are created for each intersection point. They connect the intersection point to the four vertices of the two intersecting lines.

A graph such as the one below on the right is generated using both the old and new edges.

The vertices are the coordinates of the respective points. Cycles, i.e., closed loops of three vertices will be triangles provided that the three vertices are not collinear.

Presently we check to see whether any "triangle" has an indeterminate area. (For some reason it does not return an area of 0 for three collinear points.)

---

## A simple example

Below are (a) the figure plotted in the coordinate plane and (b) the graph showing the given nodes as well as the intersection node, `{114/23, 314/69}`. In the latter, the vertices are not located at the respective Cartesian coordinates.

It may appear that their are more edges in the right figure than in the left. But remember that there are overlapping graph edges on the left. Each diagonal actually corresponds to 3 graph edges!

---

```
    f@w_ :=(h@{a_, b_, c_, d_} := (r = RegionCentroid@RegionIntersection[Line@{a, b}, Line@{c, d}];
     {r <-> a, r <-> b, r <-> c, r <-> d});
      Cases[FindCycle[Graph[Union@Join[w /. {{a_, b_Integer}, {c_, d_}} :> {a, b} <-> {c, d},
      Cases[Flatten[h /@ Cases[{Length[Union@#] < 4, #} & /@ (FlattenAt[#, {{1}, {2}}] & /@
      Subsets[w, {2}]),{False, c_} :> c]], Except[{Indeterminate, _} <-> _]]]], {3}, 50],
      x_ /; NumericQ[RegionMeasure@Triangle[x[[All, 1]]]]][[All, All, 1]]//N//Grid)

```

Each row below is a triangle.

```
f[{{{2,8},{8,1}},{{0,4},{8,1}},{{0,4},{9,5}},{{8,1},{9,5}},{{2,8},{0,4}},{{9,5},{2,8}}}]

```

---

## A more complex example

```
f@{{{9, 5}, {0, -10}}, {{9, 5}, {0, 2}},  {{9, 5}, {2, -1}}, {{0, -10}, {2, -1}}, {{0, -10}, {-2, -1}}, {{-9, 5}, {0, -10}}, {{-9, 5}, {0, 2}}, {{-9, 5}, {-2, -1}}, {{0, 2}, {0, -10}}, {{-9, 5}, {2, -1}}, {{9, 5}, {-2, -1}}, {{-9, 5}, {9, 5}}}

```

Here's the graph corresponding to the **input** coordinates. The vertices are at their expected Cartesian coordinates. (If you run the golfed code it will display the vertices elsewhere while respecting the vertex labels and edges. For readability, I assigned the vertex coordinates using a smattering of additional code, not necessary for the solution.)

---

Here's the derived graph.
It includes the derived point of intersection `(0,1/11)`, where some of the input lines cross.

The code found 19 triangles. Nine of them have the point, `(0,1/11)` as one of the vertices.
> 7 votes

# Answer
# Java, ~~1051~~ 1004

*(Fully working program)*

I thought this is a nice challenge not just to golf some code, but mainly to practice writing mathematical functions.

And to draw a "baseline" I made this one in Java **\*Waits for everyone to start laughing\***.

**Code**

```
import java.util.*;class P{double x,y;static P l(double... i){double a=i[0],b=i[1],c=i[2],d=i[3],e=i[4],f=i[5],k,l,x=(k=i[7]-f)*(c-a)-(l=i[6]-e)*(d-b),n=(l*(b-f)-k*(a-e))/x,m=((c-a)*(b-f)-(d-b)*(a-e))/x;P p=new P();p.x=a+n*(c-a);p.y=b+n*(d-b);return(n>=0&n<=1&m>=0&m<=1&x!=0)?p:null;}public static void main(String[]p){Set<String>v=new HashSet();P q,w,e;Integer a,b,c,d,k,f,g,h,i,j,m,l,r,t,y,z;int[][]x=new int[l=p.length/4][4];for(c=0;c<l;c++){for(d=0;d<4;){x[c][d]=l.parseInt(p[c*4+d++]);}}z=x.length;for(r=0;r<z;r++){a=x[r][0];b=x[r][1];c=x[r][2];d=x[r][3];for(t=0;t<z;t++){if(t!=r){k=x[t][0];f=x[t][1];g=x[t][2];h=x[t][3];q=l(a,b,c,d,k,f,g,h);if(q!=null){for(y=0;y<z;y++){if(y!=r&y!=t){i=x[y][0];j=x[y][1];m=x[y][2];l=x[y][3];w=l(a,b,c,d,i,j,m,l);e=l(k,f,g,h,i,j,m,l);if(w!=null&&e!=null&&q.x!=e.x&q.y!=e.y&!v.contains(""+r+y+t)){v.add(""+r+t+y);v.add(""+r+y+t);v.add(""+t+r+y);v.add(""+t+y+r);v.add(""+y+r+t);v.add(""+y+t+r);System.out.printf("%s %s %s %s %s %s\n",q.x,q.y,w.x,w.y,e.x,e.y);}}}}}}}}}

```

---

**Input**

Space separated integers. In pairs of 4 (x1, y1, x2, y2)

```
2 1 5 0 2 1 2 7 5 0 6 6 5 0 2 7 6 6 2 1 2 7 6 6

```

---

**Output (real output does not round to 3 decimals)**

Each line contains one triangle Each line consist out of space separated floating points in pairs of 2 (x1, y1, x2, y2, x3, y3). *(Note: the order of the 3 points that form the triangle is undefined.)*

```
5.0 0.0 2.0 1.0 6.0 6.0
5.0 0.0 2.0 1.0 2.0 7.0
5.0 0.0 2.0 1.0 3.674 3.093
2.0 7.0 2.0 1.0 3.674 3.093
2.0 1.0 2.0 7.0 6.0 6.0
5.0 0.0 6.0 6.0 3.674 3.093
5.0 0.0 6.0 6.0 2.0 7.0
3.674 3.093 2.0 7.0 6.0 6.0

```

---

**Explanation**

I started to write a method to find the intersection between two not-infinite lines. The resulting method is for a Java style one pretty short (246). Instead of letting the method input consists out of 8 double's or two Points (P) I choose to use a arbitrary parameter to safe massive amounts of characters. To minimize the array operator usage each parameter used more than 2 times is placed in it's own variable.

```
static P l(double... i){double a=i[0],b=i[1],c=i[2],d=i[3],e=i[4],f=i[5],k,l,x=(k=i[7]-f)*(c-a)-(l=i[6]-e)*(d-b),n=(l*(b-f)-k*(a-e))/x,m=((c-a)*(b-f)-(d-b)*(a-e))/x;P p=new P();p.x=a+n*(c-a);p.y=b+n*(d-b);return(n>=0&n<=1&m>=0&m<=1&x!=0)?p:null;}

```

More explanation to be added... (this answer can probably be golfed even more)
> 4 votes

# Answer
# BBC BASIC

Emulator at http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

I'm expecting this to golf down into the 400's.

**Input / Output**

Every time the user enters a new line, the program checks if any new triangles have been created, and outputs them immediately, see below.

A new triangle is created wherever the new line intersects with two pre-existing lines that are also mutually intersecting (except when all three lines intersect at a point, which is a special case that has to be dealt with.)

**Code**

The main program is about as simple as can be. At the end is the function, which performs the complex task of detecting intersections, according to the formula in http://en.wikipedia.org/wiki/Line%E2%80%93line\_intersection

The function returns zero if there is no intersection and a nonzero floating point number if there is. It also has a side effect: the coordinates of the intersection are appended to the string z$. Additionally, in BBC basic the variables of a function are visible to the main program provided the main program does not have a variable of the same name (even after the function has finished.)

Therefore the main program has access to the variables `x` and `y`, and `m` and `n`, which store the coordinates of the current and previous intersections. This is used to detect if we have really found a triangle and not just three lines intersecting at a point.

```
  DIM a(99),b(99),c(99),d(99)                                                    :REM declare 4 arrays to hold the ata
  y=0                                                                            :REM x and y are only initialized
  x=0                                                                            :REM to avoid a no such varialbe error later
  FOR i=0 TO 99                                                                  :REM for each input line
    INPUT a(i),b(i),c(i),d(i)
    FOR j=0 TO i-1                                                               :REM iterate through all combinations of 2 previous lines
      FOR k=0 TO j-1
        z$=""                                                                    :REM clear z$, three function calls on next line will write the triangle (if found) to it
        IF i>j AND j>k AND FNf(i,j)*FNf(i,k)*FNf(j,k)<>0 IF x<>m OR y<>n PRINT z$:REM to avoid printing the same triangle twice, print only if j,k,i in lexicographic order. Also reject if x,y (3rd FNf call) and m,n (2nd FNf call) are the same: this means a point, not a triangle.
      NEXT
    NEXT
  NEXT

  DEF FNf(g,h)                                                                   :REM returns zero if no intersection found, otherwise a floating point value
  m=x                                                                            :REM backup previous x and y
  n=y                                                                            :REM to use in test for point versus triangle
  p=a(g)-c(g)
  q=b(g)-d(g)
  r=a(h)-c(h)
  s=b(h)-d(h)
  t=a(g)*d(g)-b(g)*c(g)
  u=a(h)*d(h)-b(h)*c(h)
  e=p*s-q*r                                                                      :REM following method in wikipedia, calculate denominator of expression
  IF e<>0 x=(t*r-u*p)/e : y=(t*s-u*q)/e: z$=z$+" "+STR$(x)+" "+STR$(y)           :REM if denominator not zero, calculate x and y and append a string copy to z$
  IF (a(g)-x)*(c(g)-x)>0 OR (b(g)-y)*(d(g)-x)>0 OR(a(h)-x)*(c(h)-x)>0 OR(b(h)-y)*(d(h)-y)>0 e=0
  =e          :REM return e                                                      :REM previous line sets e to zero if the intersection falls outside the line segment. This is detected when both are on the same side of the intersection, which yields a positive multiplication result.

```
> 0 votes

---
Tags: code-golf, geometry
---


# Question
Title: count number of valid, unique sequences for moving on a 1xn board
There's a board with *n* squares in a horizontal row.

You start in the leftmost square, and roll a 3-faced dice.

3 possible outcomes for a single roll of the die:

1. **Left**: you move 1 step to the left, if possible.
2. **None**: you stay where you are
3. **Right**: you move 1 step to the right, if possible.

You want to roll the dice exactly *t* times, and end up at the rightmost square on the last roll.

If you arrive at the rightmost square before *t* rolls, your only valid move is **None**.

You need to determine the number of valid (meaning, for instance, that you don't count sequences that try to move left or right from the rightmost square), unique sequences of dice rolls, for given (t,n) pairs. As the answer may be large, give it modulo 1000000007 (ie. 10^9+7).

* t is a positive integer s.t. t \<= 1000
* n is a positive integer s.t. 2 \<= n \<= 1000

Sample testcases:

* t=1, n=2, answer=1
* t=3, n=2, answer=3
* t=4, n=3, answer=7

The shortest code in bytes wins.

# Answer
# Python, 74

```
f=lambda t,n,i=1:i==n or t*i and sum(f(t-1,n,i+d)for d in[-1,0,1])%(1e9+7)

```

A recusive solution. The current position `i` is stored 1-indexed as an optional argument.

* If the current position `i==n`, we've arrived at the final square and are forced to stay still, giving 1 path.
* Otherwise,
    + If the remaining time `t==0`, we've run out of time, so there's 0 paths.
    + If the current position `i==0`, we've run off the left end already, so there's 0 paths.
* If neither of those was true, there we recurse. We add up the path counts for each of the directions left, none, and right, corresponding to displacements `[-1,0,1]`, and take the result modulo `1e9+7` as required.

An alternative solution that uses `eval` with string substitution to do the sum. Same number of chars. Note the use of unary `+` to start the sum.

```
f=lambda t,n,i=1:i==n or t*i and eval(3*'+f(t-1,n,i+%d)'%(-1,0,1))%(1e9+7)

```

---

Here's another a solution that is surely short for any language with built-in matrices, so anyone who can golf it is welcome to take it.

Let `M` be the `n*n` transition matrix for the walk, which is a tridiagonal banded matrix with 1's on the main diagonal and the diagonals above and below it, except for a 0 for movement left from the rightmost cell.

```
1 1 0 0 0
1 1 1 0 0
0 1 1 1 0
0 0 1 1 1
0 0 0 0 1

```

Then, the output is `(1,n)` entry of the matrix power `M^t`.
> 6 votes

---
Tags: code-golf, combinatorics, counting
---


# Question
Title: Vim - surround comment line with comment character
Today I realised that I often like to define sections in my code like so:

```
####################
# Helper Functions #
####################

```

But that it's tedious to do. Assuming I have a line such as this:

```
# Helper Functions #

```

What is the shortest set of `vim` keystrokes to wrap it in a `#`? Shift does **not** count as a keystroke in this challenge.

Test cases:

```
Input: "#test test test#"
Output:
################
#test test test#
################

Input: "#this is a nice block comment#"
Output:
##############################
#this is a nice block comment#
##############################

Input: "# s p a c e s must be supported a l s o#"
Output:
########################################
# s p a c e s must be supported a l s o#
########################################

```

# Answer
## ~~11~~ ~~8~~ 7 keystrokes

```
YpVkr#p

Yp - duplicate current line, leaving the cursor at the lower of the two
V - enter visual line mode
k - go up and select both lines
r# - replace every selected character with #. Leaves visual mode and leaves cursor at the upper line.
p - put the yanked line (the original) on the next line.

```

(thanks to doorknob for reminding Y=yy)
> 40 votes

# Answer
# ~~16~~ ~~15~~ 14 keystrokes

```
Yp
:s/./#/g
<cr>
YkP

```

The straight-forward approach: duplicate the line, replace all characters with `#`, copy the the result and paste it above.

I'm counting `P` and `:` as one keystroke each (instead of two for `Shift`+`p` or `Shift`+`;`). That being said, the question specifies to count "commands", where I'm not sure how to count the substitution.
> 10 votes

---
Tags: code-golf, vim, comment
---