title: The Ultimate Samurai Showdown

text:
# Question
Title: The Ultimate Samurai Showdown
> **Notice:** This challenge has completed. This means that the green checkmark, which has been awarded to C5H8NNaO4 for their entry The Observer will not be moved to any new answer.
>
> You may still submit new entries, but there may be delays in new tournaments running as I am not actively checking for new entries anymore.

## Introduction

In this challenge, you are playing an arcade game titled *The Ultimate Samurai Showdown Ultimate Edition Special Version 2.0 X Alpha Omega Turbo* (or just *Ultimate Samurai Showdown* for short). Your opponents? None other than the other members of Programming Puzzles & Code Golf!

As you might expect from a PPCG arcade game, you do not play *Ultimate Samurai Showdown* directly, but rather write a program that will play the game for you. This program will fight against programs submitted by other users in one on one duels. The most skilled program will be crowned the Ultimate Samurai of PPCG, and be granted the green tick of legend.

## Game Description

This section describes the mechanics behind the game.

### Victory Condition

A *match* consists of two *samurai* which are facing off against each other. Each samurai begins each match with 20 *hit points* and 1 *honour*. A samurai wins if his opponent is dead and he is still alive. There are two methods by which a samurai can die:

1. If a samurai's hit points are brought down to 0, he will die.
2. If a samurai brings their own honour *below* 0, he will be struck down by the gods for acting dishonourably in a duel.

Being struck down by the gods has higher priority over having hit points reduced to 0, so in a situation where one samurai is at 0 health points and the other is at -1 honour, the samurai with 0 health points will win. In a situation where both samurai are at -1 honour, they both get struck down by the gods and the game is a draw.

A match consists of up to 500 *turns*. If all 500 turns pass and the match has not been decided (neither samurai has died), the gods grow bored and strike down both of the samurai, thus resulting in a draw.

### Actions

On each turn, the samurai must perform exactly one of the following actions:

**`W`**

The samurai shall wait and perform no action. This makes him look cool but doesn't help him defeat his opponent. This is also the default action.

**`B`**

The samurai shall bow to his opponent in an honourable fashion. This pleases the gods and thus the samurai will gain 1 Honour. Honour is vital to your samurai's success because Honour is essentially the "resource" for this game -- all moves apart from `B` and `W` can decrease Honour. Also, if a samurai gains 7 Honour or more, he is granted use of the *Sword of the Gods*. The implications of this are described below.
However, bowing to your opponent leaves you open if your opponent decides to strike you with his sword, so be careful when you choose to bow.

**`G`**

The samurai shall enter a defensive position and guard against any sword strikes. This move will successfully block all sword strikes, even ones made with the *Sword of the Gods*.
However, the gods frown upon an overly defensive samurai, so this move will consume 1 Honour *if* the samurai's action on the immediately preceding turn was also guarding. It does not consume Honour otherwise.

**`I`**

The samurai shall attempt to strike his opponent with a quick draw of his sword from its scabbard. If the samurai has 7 Honour or more, he will use the *Sword of the Gods* instead of his regular sword. This move consumes 1 Honour.
The quick draw is a fast strike that will beat slower overhead attacks, however, it will lose against parries. If the strike connects successfully it will do 1 damage, or 2 damage with the *Sword of the Gods*.

**`P`**

The samurai shall attempt to parry any incoming attack, then launch his own attack. If the samurai has 7 Honour or more, he will use the *Sword of the Gods* instead of his regular sword. This move consumes 1 Honour.
The parry is a good manoeuvre against fast strikes, but it will be overpowered by slower overhead attacks. If the strike connects successfully it will do 1 damage, or 2 damage with the *Sword of the Gods*.

**`O`**

The samurai shall attempt to strike his opponent with a slower overhead attack. If the samurai has 7 Honour or above, he will use the *Sword of the Gods* instead of his regular sword. This move consumes 1 honour.
The overhead strike can overpower parries, but it will lose against fast strikes. If the strike connects successfully it will do 1 damage, or 2 damage with the *Sword of the Gods*.

### Sword of the Gods

A samurai with Honour that is 7 or more gains the ability to use the *Sword of the Gods*. If his Honour is reduced below 7, the ability to use the *Sword of the Gods* will be revoked from him. The *Sword of the Gods* deals 2 damage instead of 1.

The *Sword of the Gods* does not allow a strike to defeat a sword strike that it would not ordinarily defeat. For instance, a *Sword of the Gods* parry will still lose to an ordinary overhead strike, and a *Sword of the Gods* quick draw will not overpower an ordinary quick draw. Indeed, the so-called *Sword of the Gods* is actually not all that powerful -- perhaps it is a cosmic joke played by the gods...

### Interaction Table

The Stack Snippet below contains a table which explicitly lists all the possible results of the different combinations of actions the two samurai can take. To view it, click on "Show Code Snippet", then click "Run Code Snippet".

```
td,
th {
  border: 1px solid #ccc;
  text-align: center;
  font-family: sans-serif;
}
```

```
<table>
  <tr>
    <th></th>
    <th>W (Wait)</th>
    <th>B (Bow)</th>
    <th>G (Guard)</th>
    <th>I (Quick Draw)</th>
    <th>P (Parry)</th>
    <th>O (Overhead Strike)</th>
  </tr>
  <tr>
    <td>W (Wait)</td>
    <td>Nothing occurs.</td>
    <td>The player that bowed gains +1 Honour.</td>
    <td>If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>The player that waited takes 1 damage (or 2 if the Sword of the Gods was used.) The player that struck loses 1 Honour.</td>
    <td>The player that waited takes 1 damage (or 2 if the Sword of the Gods was used.) The player that struck loses 1 Honour.</td>
    <td>The player that waited takes 1 damage (or 2 if the Sword of the Gods was used.) The player that struck loses 1 Honour.</td>
  </tr>
  <tr>
    <td>B (Bow)</td>
    <td>The player that bowed gains +1 Honour.</td>
    <td>Both players gain +1 Honour.</td>
    <td>The player that bowed gains +1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>The player that bowed gains +1 Honour and takes 1 damage (or 2 if the Sword of the Gods was used). The player that struck loses 1 Honour.</td>
    <td>The player that bowed gains +1 Honour and takes 1 damage (or 2 if the Sword of the Gods was used). The player that struck loses 1 Honour.</td>
    <td>The player that bowed gains +1 Honour and takes 1 damage (or 2 if the Sword of the Gods was used). The player that struck loses 1 Honour.</td>
  </tr>
  <tr>
    <td>G (Guard)</td>
    <td>If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>The player that bowed gains +1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>If a guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>The player that struck loses 1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour. </td>
    <td>The player that struck loses 1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>The player that struck loses 1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
  </tr>
  <tr>
    <td>I (Quick Draw)</td>
    <td>The player that waited takes 1 damage (or 2 if the Sword of the Gods was used.) The player that struck loses 1 Honour.</td>
    <td>The player that bowed gains +1 Honour and takes 1 damage (or 2 if the Sword of the Gods was used). The player that struck loses 1 Honour.</td>
    <td>The player that struck loses 1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>Both players lose 1 Honour. </td>
    <td>Both players lose 1 Honour. The player that quick drawed takes 1 damage (or 2 if the Sword of the Gods was used.).</td>
    <td>Both players lose 1 Honour. The player that used an overhead strike takes 1 damage (or 2 if the Sword of the Gods was used.).</td>
  </tr>
  <tr>
    <td>P (Parry)</td>
    <td>The player that waited takes 1 damage (or 2 if the Sword of the Gods was used.) The player that struck loses 1 Honour.</td>
    <td>The player that bowed gains +1 Honour and takes 1 damage (or 2 if the Sword of the Gods was used). The player that struck loses 1 Honour.</td>
    <td>The player that struck loses 1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>Both players lose 1 Honour. The player that quick drawed takes 1 damage (or 2 if the Sword of the Gods was used.).</td>
    <td>Both players lose 1 Honour. </td>
    <td>Both players lose 1 Honour. The player that parried takes 1 damage (or 2 if the Sword of the Gods was used.).</td>
  </tr>
  <tr>
    <td>O (Overhead Strike)</td>
    <td>The player that waited takes 1 damage (or 2 if the Sword of the Gods was used.) The player that struck loses 1 Honour.</td>
    <td>The player that bowed gains +1 Honour and takes 1 damage (or 2 if the Sword of the Gods was used). The player that struck loses 1 Honour.</td>
    <td>The player that struck loses 1 Honour. If the guarding player guarded the previous turn, that player loses 1 Honour.</td>
    <td>Both players lose 1 Honour. The player that used an overhead strike takes 1 damage (or 2 if the Sword of the Gods was used.).</td>
    <td>Both players lose 1 Honour. The player that parried takes 1 damage (or 2 if the Sword of the Gods was used.).</td>
    <td>Both players lose 1 Honour. </td>
  </tr>
</table>
```

## Program Communication

To facilitate the running of the tournament, a controller program was written to play the role of the "gods" -- it keeps records of honour and health and smites samurai accordingly. This section describes how your program will communicate with the controller program.

### Input Description

The controller program will call your program from the command line like this:

```
<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>

```

where:

* `<command>` is the command required to run your program. For instance, if your program is in a file `super_sentai.pl`, the command is probably `perl super_sentai.pl`.
* `<history>` is a history of moves that you made. For instance, `WWBP` would mean you waited twice, bowed once, and parried once.
* `<enemy_history>` is a history of moves your enemy made. For instance, `BBBI` would mean your enemy bowed three times and performed one quick draw.
* `<your_health>` is your current health.
* `<enemy_health>` is the enemy's current health.
* `<your_honour>` is your current honour.
* `<enemy_honour>` is the enemy's current honour.

For the first turn, the `history` and `enemy_history` will be empty, so your program will just be called with the last four arguments like this:

```
<command> <your_health> <enemy_health> <your_honour> <enemy_honour>

```

Please be prepared for this!

Astute readers may notice that the four arguments providing the honour and health of both samurai are, to some extent, superfluous; since this is a perfect information game, the honour and health of the samurai can be determined using only the histories.

These values are provided for convenience purposes so that you do not have to parse the history arguments. This should prove useful for implementing simple strategies, such as not attacking when your Honour is 0.

### Output Description

To choose an action, your program should output one of `W`, `B`, `G`, `I`, `P`, or `O` to standard output, depending on what action you want to make. If your program doesn't output anything within 1000ms, it will be terminated and your program will be treated as if it outputted `W`.

If your program outputs more than one letter, only the first letter will be considered -- so outputting `Parry` will be the same as outputting `P`.

If the output of your program's first letter is not any of the options listed above, it will default to `W`.

### Submission Format

Submit a program as an answer to this post. You may submit multiple programs. If you are submitting multiple simple programs, I recommend submitting them as a single answer; if you are submitting multiple complex programs, I recommend submitting them as separate answers. Once I have successfully added your program/s to the tournament, I will make a commit to the git repository with your entry (linked below).

If I encounter problems that prevent your program from being added to the tournament, I will leave a comment on your entry indicating the problem.

Please include the following in your submission:

1. The human readable name of your program, for use in scoreboards. Spaces are allowed here; commas and Unicode characters are not.
2. The language your program is written in. Please avoid writing in strange, difficult to access languages like TinyMUSH.
3. A short synopsis of your program. This can be a description on how the program works, or just some flavour text about your program (if you want to be all secretive), or perhaps both.
4. The command/s required to run your program. For instance, if you were writing your submission in Java called `example.java`, you would provide compiling instructions `javac example.java` then running instructions `java example`.
5. The source code for the program.

To assist in submitting, I provide a submission template which can be found here. The template makes submissions look nicer. I strongly encourage using it.

I also provide two example entries. Although the example entries will be participating in the round robin, their main purpose is to clarify the submission and input/output formats for the tournament, rather than being serious contenders for the title of Ultimate Samurai.

## Tournament Structure

This section describes how the tournament between the participants will be run.

### Control Program

The control program is written in Python 2 and can be found on the Ultimate Samurai Showdown Github repository. If you'd like to run it yourself, instructions on how to run it are included in the README.md file in the link. However, only tournaments run on my computer will be official to avoid hardware differences affecting tournament results.

The control program will be ran on a laptop computer running Arch Linux. It has an Intel Core i7 processor and 8GB of RAM. I will endeavour to get all entries running on my computer, but I'd appreciate it immensely if you avoid languages that can't be accessed freely (as in no monetary cost).

### Scoring System

The scoring system is a round robin. Each program will play eight matches against every other program. A win grants the program 1 point, a loss no points, and a draw 0.5 points. The program with the highest score wins the game. If there is a draw, I will duel the top two programs against each other to determine the winner.

The number of times each program will play each other program may be decreased from 8 if there is an extremely large number of entrants. I will add a note here if this occurs.

I will be running the round robin many times as new submissions are posted, but it is only the most recent round robin that will count.

### Disqualifications

It is possible for your program to be disqualified from the tournament. Disqualification may occur if:

* Your program does not compile or run;
* Your program is a *strategic duplicate* of another program (that is, it implements the exact same strategy as another program);
* Your program attempts to sabotage other programs by modifying the controller code, other program's code, etc;
* Your program attempts to exploit a bug in the controller code. Instead of exploiting bugs you should instead open an issue in the git repository, make a comment here, or ping me in chat.

### Past Results

Detailed results of all tournaments are made available at the wiki page.

The most recent tournament was completed on 2015-07-17 07:20. Here is a summary of the results:

```
The Observer: 209.0
Coward: 203.0
Monk: 173.0
Elephant Warrior: 157.0
Iniqy: 157.0
Agent 38: 144.0
Ninja: 138.0
Meiyo Senshi: 138.0
Kakashi: 136.0
Yoshimitsu: 131.0
Hermurai: 121.0
Warrior Princess: 120.0
Gargoyle: 119.5
The Honourable: 119.0
Hebi: 118.5
Predictor: 116.0
Whack-a-mole: 107.0
The Fool: 106.0
The Prophet: 105.0
Copy-san: 97.0
YAGMCSE: 80.0
The Waiter: 66.0
Swordsman: 43.0
Spork Holder: 32.5
Blessed Samurai: 27.5
Attacker: 27.0
The Terminator: 17.0
Master Yi: 16.0

```

# Answer
# The Monk (Java)

The Monk values honour and praises the blessings of the Gods. Being trained in patience he calmly sends his prayers to heaven until he feels being favoured by God.

Enjoying his life, he tries to protect it. When he's losing health over a certain rate, he defends himself as best as he can.

Hoping for the support of his Gods he randomly sends ejaculations\[1\] to heaven, otherwise he fights as best as he can.

If his opponent is worn out from the battle he finishes him using his remaining honour to grant him a fast and painless death.

Compile/Run

```
javac Monk.java
java Monk

```

---

```
public class Monk {
    public static void main(String[] args){
        char  r = 'B';
        double  s = Math.random ();
        int n = Math.max (args [0].length ()- 8, 1);
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int l = Integer.parseInt (args [3]);
        int m = Integer.parseInt (args [2]);
        double d = 1 + (20 - m) / n;
        double e = 1 + (20 - l) / n;

        if (((p>8&&s<.7)||l<11||m<2)&&p>0) {
                r=(s<(.14)||d>=2||e/d<.618)?'G':"OPI".charAt((int)(Math.random()*3));
        }

        System.out.print (r);
    }
}

```

# The Ninja (Java)

The Ninja is fast and attacks even faster. He attacks right away after a friendly formal greeting, further confusing his enemy by bowing before and after every attack.

Upon being blessed the ninja keeps up this behaviour, waiting for his opponent to make his first move(s). Using this opportunity he unleashs a series of blasts, blessed by the ninja Goddess until he's too worn out from the battle. Using his remaining honor he hides under the leaves beneath, guarding himself from the next attack. He jumps out and attacks his foe from behind, being hidden as fast again.

If he receives a fatal wound he goes all out to take his opponent's live with him -- of course, keeping a miminum of honour.

```
javac Ninja.java
java Ninja

```

---

```
public class Ninja {
    public static void main(String[] args){
        char  r = 'B';
        int n = args [0].length ();
        int p = args.length > 4 ? Integer.parseInt (args [4]):0;
        int m = Integer.parseInt (args [2]);
        int a = n % 3;
        if (p>7) {
           if (m>17) {
                r = "BBI".charAt (a);
           } else if (m>13) {
                r = "BII".charAt (a);
           } else {
               r  = "GIG".charAt (a);
           }

        } else if (p>0) {
           if (m > 10) {
                    r = "BBI".charAt (a);
           } else {
                r="IGI".charAt (n%2);
           }
        }
        System.out.print (r);
    }
}

```

# Kakashi, The Copycat Ninja (Java)

Kakashi copies his opponents moves by randomly choosing between the last two moves the opponent made. If the opponent waits, he bows -- He keeps his honour as well.

```
javac Kakashi.java
java Kakashi

```

---

```
public class Kakashi {
    public static void main(String[] args){
        char  r;
        String h = args [1];
        if (h=="W" || Integer.parseInt ( args.length > 4?args [4]:"0") < 1){
                 r = 'B';
        } else if (Math.random ()<.1) {
            r = 'I';
        } else {
            r  = h.charAt ((int) (h.length()==1?0: h.length()-Math.random ()*2));
        }

        System.out.print (r);
    }
}

```

*
I wish Kakashi could be blessed with the sharingan.. I thought about reading the cast.txt. Simulate every round of his history against every opponent in there. Try to find out against which opponent he's fighting by comparing the simulated enemies history with the real enemies history. Then use that information to predict the next move the opponent would do and pick the best countermove from a predefined list. But I feel this could take a bit as I have super slow Internet at the moment and about no Java skills*

# The Observer, (node.js)

The Observer bows before trying to predict the opponent's next move from its past 5 moves, choosing the best counterpart for the predicted move.

Edit: Thanks to @apsillers for sharing the node.js boilerplate!.

```
node observer.js

```

---

```
var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var m = {
    m:{},
    l:function (a,b) {
        if (!this.m[a]) {
           this.m [a] = [];
        }
        this.m[a].push (b);
    },
    p:function (a) {
       for (var k=0;k<a.length;k++)
       for (var j=1;j<a.length;j++)
       for (var i=-1+k; i<a.length-j; i++)this.l (a.slice (i,i+j),a[i+j]);
    },
    a:function (a) {
      if (!this.m[a])return;
      return this.m[a][0|Math.random () * this.m[a].length-1]
    }
}
var g={
   B:"IPO",
   G:"B",
   I:"PG",
   O:"IG",
   P:"OG",
   W:"I"
}
var c,i=0;
m.p(enemy.history);
while (!c && i++<enemy.history.length) {
   c=m.a (enemy.history.slice (i));
}
decide.apply  (0,my.honor < 7?["B"]:g[c].split (''))

```

---

Edit: I had a major flaw in the observer, I actually don't know what I thought yesterday night. It seems he only looked at the past two moves of the enemy. He did surprisingly well like this.

His memory now get's queried for the longest (end) part of the enemies history he already has seen. This contains an array with all the moves that followed the history of moves. One is randomly selected. So if one move followed more often, it is as well more likely to be picked. Kind of like markov chains.

The Observer, now guards as well.

---

\[1\]: *TIL: ejaculation has a religious meaning*
> 8 votes

# Answer
# Spork Holder (Ruby)

Spork Holder bows on the first turn, then acts randomly afterwards. It is one of the two example entries.

Command: `ruby spork-holder.rb`

```
if ARGV.length == 4
    print "B"
else
    print ["W", "B", "G", "I", "P", "O"].sample
end

```

---

# The Waiter (bash)

The Waiter only waits on every turn. It is one of the two example entries.

Command: `echo W`

There is no source code required.
> 7 votes

# Answer
# Meiyo Senshi (Java)

Hailing from the Haijima area, not much is known about the Meiyo. They do not normally participate in games of sport, but have sent a warrior to this one in order to assess their rivals.

They are an honorable bunch, though, so you can be assured he will make his presence known to the gods in short order. Once he has seen enough of his foe to report, he will use the blessings received to strike down his opponent.

To compile run, it's the standard Java way:

```
> javac MeiyoSenshi.java
> java MeiyoSenshi

```

```
public class MeiyoSenshi {
    public static void main(String[] args){
        System.out.print(
                Integer.valueOf(args[args.length<5?0:2])>12 ||
                Integer.valueOf(args[args.length<5?2:4])<1  ?
                "B":
                "IPO".charAt((int)(Math.random()*3))
        );
    }
}

```
> 7 votes

# Answer
# Coward (Node.js)

> *I'm a coward / It's a miracle I dare breathe*
> *Overpowered / By the gentlest summer breeze*

* Checks for `BXBXBX`/`BBB` patterns to bow (or hit you) when you're bowing.
* Checks for `GXGXGX` patterns to bow when you're guarding.
* If his random bravery roll overcomes his fear threshold for that round, he'll try for a hit.
    + Having a Sword of the Gods makes him braver.
    + An opponent with a Sword of the Gods makes him more fearful.
    + An opponent who leads by at least 5 Health or more also makes him a little scared.
* Otherwise, he takes turns guarding and bowing.

**If you want to write a Node.js submission**, please feel free to use my boilerplate code; everything up to an including the `decide` function is fully general and free to take.

---

```
node coward.js

```

---

```
var argv = process.argv;
var history = argv.length>6?argv[2]:"";
var enemyHistory = argv.length>6?argv[3]:"";
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:history };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;
function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

var enemyGuards = !!enemy.history.match(/G.G.G.$/);
var enemyBows = !!enemy.history.match(/(B.B.B.$)|(BBB$)/);

// open with a bow
if(!my.history) { decide("B"); }

// enemy will likely bow? Hit them with your super sword! (or bow)
if((!enemy.honor || enemyBows)) {
    if(my.godSword) { decide("P","I","O"); }
    else { decide("B"); }
}

// no point in hitting them if they're going to guard
if(enemyGuards) { decide("B"); }

// calculate bravery level
var braveryLevel = 0.3;
braveryLevel += (my.godSword * 0.2) - (enemy.godSword * 0.2);
braveryLevel -= (enemy.health - my.health > 5) * 0.1;

// if we're feeling brave, hit them
if(Math.random() < braveryLevel && my.honor) { decide("P","I","O"); }

// if we didn't just guard, and we're not feeling brave, cower in fear
if(!my.history.match(/G$/)) {
    decide("G");
}

// if we did just guard, and we're feeling cowardly,
//   if we don't have sword of the gods, bow
//   otherwise, do anything except guard
if(!my.godSword) {
    decide("B");
} else {
    decide("B","P","I","O");
}

```
> 7 votes

# Answer
# Whack-a-mole (R)

Strikes when enemy is likely to bow, else guards.

```
args <- commandArgs(TRUE)
L <- length(args)
my_health <- as.integer(args[L-3])
enemy_health <- as.integer(args[L-2])
my_honour <- as.integer(args[L-1])
enemy_honour <- as.integer(args[L])
if(L>4){enemy_history <- args[L-4]}else{enemy_history <- ""}
if(my_honour<1){
    out <- "B"
}else if (enemy_honour<=1 | grepl("BB$",enemy_history)){
    out <- sample(c("I","O"),1)
}else{
    out <- "G"
}
cat(out)

```

Run using `Rscript Whack-a-mole.R`.
> 6 votes

# Answer
# Gargoyle (Java)

Tries to use the defensive move without consuming honor.

Since it's a java entry:

```
> javac Gargoyle.java
> java Gargoyle

```

```
public class Gargoyle {
    public static void main(String args[]) {
        if (args.length < 5 || Integer.valueOf(args[4]) > 0) {
            System.out.println("IPO".charAt((int)(Math.random()*3)));
        } else if (args[0].charAt(args[0].length()-1) != 'G') {
            System.out.println('G');
        } else {
            System.out.println('B');
        }
    }
}

```
> 3 votes

# Answer
# Swordsman (C/Java)

Swordsman bows on the first turn and whenever he is running low on honor. He then checks if the opponent hadn't bowed or defended or waited in the previous turn. If the opponent hadn't, there is a big probability that he will do one of these in the current turn and swordsman thus randomly strikes on the opponent. If this isn't true, he defends if he hasn't defended the previous turn. If he had, he bows to gain honor.

**C version:**

```
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

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

    srand(time(NULL));
    char* attack_moves[]={"I", "P", "O"};
    int random_num = rand() % 3;

    if(argc == 5 || atoi(argv[5]) == 0)
        print_and_exit("B");
    else if(argv[2][strlen(argv[2])-1] != 'B' && argv[2][strlen(argv[2])-1] != 'G' && argv[2][strlen(argv[2])-1] != 'W')
        print_and_exit(attack_moves[random_num]);
    else if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit("G");

     print_and_exit("B");
}

```

Install GCC (compiler) and save the code into a file named "*Swordsman.c*" command for compiling:

```
gcc Swordsman.c -o Swordsman

```

Executable named "*Swordsman*" will be created. Run using

```
Swordsman

```

**Java version:**

```
public class Swordsman {

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        int random_num = (int)(Math.random()*3);

        if(argv.length == 4 || Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else if(argv[2].charAt(argv[2].length()-1) != 'B' && argv[2].charAt(argv[2].length()-1) != 'G' && argv[2].charAt(argv[2].length()-1) != 'W')
            print_and_exit(attack_moves[random_num]);
        else if(argv[1].charAt(argv[1].length()-1) != 'G')
            print_and_exit("G");

         print_and_exit("B");
    }

}

```

Install javac (compiler) and save the code into a file named "*Swordsman.java*" command for compiling:

```
javac Swordsman.java

```

Class file named "*Swordsman.class*" will be created. Run using

```
java Swordsman

```

---

---

# Attacker (Java)

Attacker doesn't care about anything except that he wants his opponent dead. He randomly strikes one of the attack moves and if has low honor, bows.

```
public class Attacker {

    static int position = -1;

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }
    public static void main(String[] argv) {

        String attack_moves[]={"I", "P", "O"};
        position = (position + 1) % 3;

        if(argv.length != 5 && Integer.valueOf(argv[5]) == 0)
            print_and_exit("B");
        else
            print_and_exit(attack_moves[position]);
    }

}

```

Install javac (compiler) and save the code into a file named "*Attacker.java*" command for compiling:

```
javac Attacker.java

```

Class file named "*Attacker.class*" will be created. Run using

```
java Attacker

```

---

---

# Predictor (C/Java)

Predictor predicts the enemies moves. In the first turn, it uses a random move. Bows if his honor is low, strikes if the enemies honor is low or has bowed in the previous turn. If predictor hasn't guarded the previous turn, guards in the current turn. Else, does the same move as the enemy has done in the previous turn, provided that it isn't `'W'` in which case, Predictor bows.

**C version:**

```
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

void print_and_exit(char* str)
{
    puts(str);
    exit(0);
}

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

    srand(time(NULL));
    int random = rand() % 5;
    char* moves[] = {"B", "G", "I", "P", "O"};

    if(argc == 5)
        print_and_exit(moves[random]);

    if(atoi(argv[5]) <= 0)
        print_and_exit(moves[0]);
    if(atoi(argv[6]) <= 0)
        print_and_exit(moves[4]);
    if(argv[2][strlen(argv[2])-1] == 'G')
        print_and_exit(moves[4]);
    if(argv[1][strlen(argv[1])-1] != 'G')
        print_and_exit(moves[1]);

    if(argv[2][strlen(argv[2])-1] != 'W'){
        char buf[2]={0};
        *buf = argv[2][strlen(argv[2])-1];
        print_and_exit(buf);
    }

    print_and_exit(moves[0]);

}

```

Install GCC (compiler) and save the code into a file named "*Predictor.c*" command for compiling:

```
gcc Predictor.c -o Predictor

```

Executable named "*Predictor*" will be created. Run using

```
Predictor

```

**Java version:**

```
public class Predicator{

    public static void print_and_exit(String str)
    {
        System.out.println(str);
        System.exit(0);
    }

    public static void main(String[] argv){

        int random = (int)(Math.random() * 5);
        String moves[] = {"B", "G", "I", "P", "O"};

        if(argv.length == 4)
            print_and_exit(moves[random]);
        else if(Integer.valueOf(argv[5]) <= 0)
            print_and_exit(moves[0]);
        else if(Integer.valueOf(argv[6]) <= 0)
            print_and_exit(moves[4]);
        else if(argv[2].charAt((argv[2].length())-1) == 'G')
            print_and_exit(moves[4]);
        else if(argv[1].charAt((argv[1].length())-1) != 'G')
            print_and_exit(moves[1]);
        else if(argv[2].charAt((argv[1].length())-1) != 'W'){
                    print_and_exit(""+argv[2].charAt((argv[2].length())-1));
        }
        else
            print_and_exit(moves[0]);
    }
}

```

Install javac (compiler) and save the code into a file named "*Predicator.java*" command for compiling:

```
javac Predicator.java

```

Class file named "*Predicator.class*" will be created. Run using

```
java Predicator

```

---

Not sure how effective these bots will be as I don't have the python2 interpreter to test it.
> 3 votes

# Answer
# Elephant Warrior (Java)

The Elephant Warrior is from an older, more natural time. He has seen much, and remembers all. He curries favor with the gods while he examines his opponent, and then once he takes them into his heart, he takes them apart.

Compile: `javac ElephantWarrior.java`
Command: `java ElephantWarrior`

```
import java.util.LinkedList;

//Elephants never forget
class ElephantWarrior
{

  static LinkedList<Choice> analysis = new LinkedList<Choice>();

  public static void main(String[] args){
      if(args.length < 6){ respond("B");}
      String myhis = args[0];
      String enHis = args[1];
      int health = Integer.parseInt(args[2]);
      int enHealth = Integer.parseInt(args[3]);
      int honour = Integer.parseInt(args[4]);
      int enHonour = Integer.parseInt(args[5]);

        //Bow a few times until I know how he operates
        if(enHis.length() <= 5){
            respond("B");
        }

        //Special cases
        //If I'm at 0 honor, better bow
        else if(honour <= 0){
            respond("B");

        }
        else{
          analyze(enHis);

          //Narrow it down to applicable choices
          char hisLast = enHis.toCharArray()[enHis.toCharArray().length - 1];
          LinkedList<Choice> hisOptions = new LinkedList<Choice>();
          for(Choice c: analysis){
              if(c.pattern.toCharArray()[0] == hisLast){
                  hisOptions.add(c);
              }
          }

           //Default to assuming they bow
          char hisNext = 'B';
          int mostLikely = 0;

          //What will they do next?
          for(Choice c : hisOptions){
              if(c != null && c.probability > mostLikely){
                  //System.out.println("Option = " + c.pattern);
                  //System.out.println("Prob = " + c.probability);
                  mostLikely = c.probability;
                  hisNext = c.pattern.toCharArray()[1]; }
          }

          //Now go through potential case
          switch(hisNext){
              case 'W':
                  respond("I");
                  break;
              case 'B':
                  respond("O");
                  break;
              case 'G':
                  respond("B");
                  break;
              case 'I':
                  if(enHonour  > 0){
                      respond("P");
                  }
                  else{
                      respond("B");
                  }
                  break;
              case 'P':
                  respond("O");
                  break;
              case 'O':
                  respond("I");
                  break;
              default:
                  respond("G");
          }
        }
    }

      static void analyze(String his){

        //Keep track of his previous moves
        char[] shortString = his.substring(1,his.length() - 1).toCharArray();
        char[] longString = his.toCharArray();
        for( int i = 0; i < shortString.length; i++) {
          String pattern = "" + longString[i] + shortString[i];
          boolean exists = false;
          for(Choice c : analysis){
              if(c.pattern.equals(pattern)){
                  exists = true;
                  c.probability++;
              }
          }
          if(!exists){
              analysis.add(new Choice(pattern, 1));
          }
        }
      }

      private static void respond(String s){
            System.out.println(s);
            System.exit(0);
        }

    }

class Choice{
        String pattern;
        int probability;

       Choice(String p, int i){
            pattern = p;
            probability = i;
       }
}

```
> 3 votes

# Answer
# Warrior Princess (Julia)

This is the first King of the Hill challenge I've competed in. Let's see how this goes.

The Warrior Princess prioritizes attack and honor, and resorts to self-preservation when needed. She's rather eager and never waits. In an effort to remain nimble, she also doesn't use an overhead attack.

---

Save as `warrior-princess.jl` and run from the command line like so:

```
julia warrior-princess.jl <arguments>

```

If you don't have Julia, you can download it here. To avoid issues, the latest stable version is recommended (i.e. not the development version).

---

```
type Samurai
    history::String
    health::Int
    honor::Int
end

A = length(ARGS) < 5 ? ["", "", ARGS] : ARGS

me = Samurai(A[1], int(A[3]), int(A[5]))
opponent = Samurai(A[2], int(A[4]), int(A[6]))

if length(me.history) == 0

    # Always begin the match with an honorable bow
    action = "B"

elseif (!ismatch(r"[OIP]", opponent.history) && me.history[end] != 'G') ||
       (me.health < 2 && me.honor > 0)

    # Guard if the enemy has not yet attacked and I did not previously
    # guard, or if my health is low and my honor is sufficient
    action = "G"

elseif me.honor < 2

    # Bow if I'm low on honor
    action = "B"

elseif opponent.honor >= 7 && opponent.history[end] ∈ ['B', 'W']

    # Assume the enemy will attack with the Sword of the Gods if they
    # most recently bowed or waited
    action = "I"

else
    action = "P"
end

println(action)

```
> 3 votes

# Answer
# Master Yi (Python)

The master assassin gains much favor in the early game, building it up until he's invincible. Tries to attack when they least expect it.

```
import sys, random

class MasterYi(object):
    def __init__(self):
        self.attack = lambda: random.choice(['I','P','O'])
        self.bow   = "B"
        self.guard = "G"
        self.wait  = "W"
        if len(sys.argv)>6:
            self.hist = sys.argv[1]; self.ohist = sys.argv[2]
            self.hp   = sys.argv[3]; self.ohp   = sys.argv[4]
            self.hon  = sys.argv[5]; self.ohon  = sys.argv[6]
        else:
            self.hist = [];          self.ohist = []
            self.hp   = sys.argv[1]; self.ohp   = sys.argv[2]
            self.hon  = sys.argv[3]; self.ohon  = sys.argv[4]
        self.last  = self.hist  and self.hist[-1]  or "W"
        self.olast = self.ohist and self.ohist[-1] or "W"
        self.oGuarder = len(self.ohist)>4 and self.ohist[-4]==self.ohist[-2]=="G"

    def move(self):
        if self.hon < 1: return self.bow
        if self.olast == "G": return self.attack
        if self.hon > 6:
            if self.oGuarder: return self.bow
            if self.ohon > 6: return self.guard
            if self.ohon < 7: return self.attack
            return self.attack
        if self.ohon > 6: return self.guard
        return self.bow

Yi = MasterYi()
print(Yi.move())

```

To run: Save as `MasterYi.py`

```
python MasterYi.py <args>

```
> 2 votes

# Answer
# Copy-san (C)

Copies every move of his opponent. Pretty sure he's guaranteed to lose. Compile: `gcc copy-san.c`

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

int main(int argc, char *argv[]) {
    if (argc == 5) {
        putchar('B');
    } else {
        char *enemy_hist = argv[2];
        size_t len = strlen(enemy_hist);
        putchar(enemy_hist[len - 1]);
    }
    putchar('\n');
    return 0;
}

```
> 2 votes

# Answer
## Hebi (Java)

Hebi follow The Way Of The Snake.

The Snake has no need for the blessing of the gods.

The Snake slithers its strikes; like waves upon the beach, what comes in recedes back the way it came.

The Snake never waits.

The Snake has no sense of aptness, elsewise it would've been written in Python.

Running instructions:

```
> javac hebi.java
> java hebi

```

Code body:

```
public class hebi{

    public static void main(String args[]){

        if( (args.length < 5) || (args[0].length() % 18 == 0) ) System.out.println( "IPO".charAt((int)(Math.random()*3)) );
        else{

            int hist_size = args[0].length();

            if      (hist_size % 3 == 1) System.out.println("G");
            else if (hist_size % 3 == 2) System.out.println("B");
            else{

                if     (hist_size % 18 ==  9) System.out.println(args[0].charAt(hist_size -  3));
                else if(hist_size % 18 == 12) System.out.println(args[0].charAt(hist_size -  9));
                else if(hist_size % 18 == 15) System.out.println(args[0].charAt(hist_size - 15));
                else{

                    char move_head = args[0].charAt( (hist_size / 18) * 18 );
                    char move_mid;
                    if( hist_size % 18 == 3 ){
                        if     ( move_head == 'I' ) move_mid = "PO".charAt((int)(Math.random()*2));
                        else if( move_head == 'O' ) move_mid = "IP".charAt((int)(Math.random()*2));
                        else                        move_mid = "OI".charAt((int)(Math.random()*2));
                        System.out.println(move_mid);
                    }
                    else{
                        move_mid = args[0].charAt( ((hist_size / 18) * 18) + 3 );
                        char move_tail;

                        if( move_head == 'I' ){
                            if( move_mid == 'P' ) move_tail = 'O';
                            else                  move_tail = 'P';
                        }else if( move_head == 'P' ){
                            if( move_mid == 'O' ) move_tail = 'I';
                            else                  move_tail = 'O';
                        }else{
                            if( move_mid == 'I' ) move_tail = 'P';
                            else                  move_tail = 'I';
                        }

                        System.out.println( move_tail );

                    }

                }

            }

        }

    }

}

```
> 2 votes

# Answer
# The Honourable (Java)

The Honourable values honor above all. That is, his honor above everyone else's. If the enemy samurai has greater or equal honor, he bows. None shall be more honorable than he. Otherwise, he does a random move. He never guards twice in a row - that would be dishonorable!

to compile:

```
> javac TheHonourable.java
> java TheHonourable

```

Source:

```
public class TheHonourable {
    public static void main(String[] args) {
        char move;

        if (args.length < 5) {
            move = 'B';
        } else if (Integer.valueOf(args[5]) >= Integer.valueOf(args[4])){
            move = 'B';
        } else {
            move =  (args[0].endsWith("G")) ?
                    "IPO".charAt((int)(Math.random()*3)) :
                    "GIPO".charAt((int)(Math.random()*4));
        }

        System.out.print(move);
    }
}

```
> 2 votes

# Answer
# Blessed Samurai (Python)

This Samurai tries to keep the gods' favor for a long as possible. He rushes to get the holy sword, then alternates between Guarding and Attacking with one of the strikes, restocking honour when needed. If it looks like either he or his opponent may soon fall, he rushes in for a kill. He will easily fall to an oponent that can track his pattern, but his strategy of always attacking at two damage should be pretty effective.

```
import sys
import random
class BlessedSamurai(object):
    def __init__(self):
        if len(sys.argv) < 7:
            print("B")
        else:
            self.attack = ['O', 'I', 'P']
            self.hp = sys.argv[3]
            self.ohp = sys.argv[4]
            self.hon = sys.argv[5]
            self.last = sys.argv[1][-1]
            print(self.move())

    def move(self):
        #check if I have low health or should rush the kill
        if (self.hp < 5 or self.ohp < 5) and self.hon > 0:
            return(random.choice(self.attack))
        # charge honour to get SOTG
        elif self.hon < 7:
            return 'B'
        #Alternate guarding and attacking
        else:
            if self.last == 'G':
                return(random.choice(self.attack))
            return 'G'
Sam = BlessedSamurai()

```

---

To run:
Save as BlessedSamurai.py

```
python BlessedSamurai.py <args>

```
> 1 votes

# Answer
# Hermurai (C++)

Admires his opponent, and is a little paranoid. Wants to know if he can do what other samurai can, because he still can't believe himself to be a samurai. His never-fading dream became reality before him knowing it. Which could cost his head...

```
#include <stdio.h>
#include <string>
#include <sstream>

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string enemy_history(argv[2]);

    int ho;
    string honour(argv[5]);
    stringstream(honour) >> ho;

    if(ho > 20){
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }

    char lastMove = enemy_history[enemy_history.length()-1];
    if(lastMove == 'W' || lastMove == 'G')
        lastMove = 'B';
    printf("%c", lastMove);
    return 0;
}

```

---

# Iniqy (C++)

Strikes as hard as possible. Goes into unstoppable attack mode when he is in danger.

```
#include <stdio.h>
#include <string>
#include <sstream>

using namespace std;

char getLastAttack(string enemy_history)
{
    size_t found = enemy_history.find_last_of("IPO");
    if(found == string::npos)
    {
        return 'I';
    }

    return enemy_history[found];
}

int main(int argc, const char * argv[])
{
    if(argc != 7){
        printf("B");
        return 0;
    }

    string history(argv[1]);
    string enemy_history(argv[2]);
    string health(argv[3]);
    string enemy_health(argv[4]);
    string honour(argv[5]);
    string enemy_honour(argv[6]);

    int he, enemy_he, ho, enemy_ho;
    stringstream(health) >> he;
    stringstream(enemy_health) >> enemy_he;
    stringstream(honour) >> ho;
    stringstream(enemy_honour) >> enemy_ho;

    if(ho > 6 || ((he < 6 || enemy_he < 6) && ho > 0))
    {
        char atk = getLastAttack(enemy_history);
        printf("%c", atk);
        return 0;
    }

    printf("B");
    return 0;
}

```

---

Both are written in C++. To compile:

```
g++ iniqy.cpp -o iniqy

```

To run on Linux: `./iniqy`

To run on Windows: `iniqy.exe`
> 1 votes

# Answer
# The Terminator (ruby)

The Terminator doesn't pay attention to his own health. The Terminator has no notion of honor. The Terminator is sent from the future and simply determined to terminate its opponent. It does so by watching its opponents moves, and nothing else. It samples the moves and calculates the appropriate response in such an intricate manner that no present-day technology can predict the Terminator's actions. In fact, to anyone living in 2015 the Terminator may seem somewhat random ...

```
responses = {
  ?W => %w(B I),
  ?B => %w(I O),
  ?G => %w(B B),
  ?I => %w(G P),
  ?P => %w(B O),
  ?O => %w(G I)
}

if ARGV.size > 4
  pool = ARGV[1].chars.map{ |c| responses[c] }.flatten
  puts pool.sample
else
  puts %w(O I P B).sample
end

```
> 1 votes

# Answer
# Agent 38\[1\] (C)

As a product of extensive genetic manipulation, Agent 38 has the physique and mental acuity of a super\[2\]-samurai, and is definitely superior to all its helplessly\[citation needed\] flawed\[citation needed\] competitors.

---

```
//Agent 38
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#ifdef _WIN32
#include <Windows.h>
unsigned int tick_count(){
    return GetTickCount();
}
#else
#include <sys/time.h>
unsigned int tick_count(){
    struct timeval t;
    gettimeofday(&t, NULL);
    return 1000 * t.tv_sec + t.tv_usec / 1000;
}
#endif

float program[5][4][4][4][4]={
    {{{{-1.192779,0.693321,-1.472931,-0.054087},{0.958562,0.557915,0.883166,-0.631304},{-0.333221,1.410731,0.496346,0.087134},{0.459846,0.629780,-0.479042,-0.025909}},{{0.547976,1.059051,-0.748062,-0.675350},{-0.607591,-0.152156,-0.400350,-0.685337},{1.686450,0.628706,0.312865,0.324119},{1.652558,0.403733,-0.456481,-0.081492}},{{0.371629,-0.036948,-0.982682,0.065115},{1.360809,0.681294,0.505074,0.782737},{-0.545192,0.954937,-0.727853,0.273542},{-0.575777,1.615253,-0.064885,-0.516893}},{{0.577015,-0.112664,0.456595,-0.007560},{-0.660930,-0.738453,0.668093,1.716388},{1.972322,0.108558,0.535114,-0.337916},{0.640208,-0.019680,-0.769389,0.873087}}},{{{-0.021140,-0.095956,-0.098309,-0.280295},{-0.926284,1.724028,0.278855,0.678060},{0.153006,-1.860947,-0.577699,-1.931683},{-0.187152,0.529719,-1.164157,0.125499}},{{0.582208,-0.835029,-0.329857,0.088176},{-0.030797,0.389396,0.584636,-0.025866},{-0.736538,1.624658,0.690493,0.387515},{0.973253,-0.530825,1.934379,-0.872921}},{{0.812884,0.138399,-1.452478,-1.504340},{-0.119595,0.986078,-0.993806,1.102894},{0.848321,-0.268764,0.876110,0.782469},{0.948619,-0.557342,0.749764,-0.712915}},{{-1.195538,0.783784,-1.973428,-0.873207},{0.085426,-0.241360,-0.534561,-0.372105},{0.029696,-0.906821,0.932227,-0.834607},{0.764903,-0.276117,-1.346102,-0.093012}}},{{{0.168113,0.855724,1.817381,-0.547482},{0.468312,0.923739,-0.723461,0.798782},{-0.875978,-0.942505,-0.684104,-0.046389},{0.893797,-0.071382,0.283264,0.811233}},{{0.391760,0.309392,-0.045396,-0.977564},{0.085694,0.257926,-0.775461,0.060361},{0.486737,-0.175236,0.806258,-0.196521},{0.691731,-0.070052,0.636548,0.464838}},{{0.532747,-1.436236,-0.900262,-0.697533},{0.566295,0.650852,0.871414,-0.566183},{-0.075736,-0.886402,0.245348,-0.438080},{-0.811976,0.022233,-0.685647,0.323351}},{{-1.864578,1.141054,1.636157,-0.455965},{0.592333,0.890900,-0.259255,0.702826},{0.404528,0.905776,0.917764,0.051214},{0.761990,0.766907,-0.595618,-0.558207}}},{{{0.209262,-1.126957,-0.517694,-0.875215},{0.264791,0.338225,0.551586,0.505277},{0.183185,0.782227,0.888956,0.687343},{0.271838,0.125254,1.071891,-0.849511}},{{0.261293,-0.445399,0.170976,-0.401571},{0.801811,0.045041,-0.990778,-0.013705},{-0.343000,-0.913162,0.840992,0.551525},{-0.526818,-0.231089,0.085968,0.861459}},{{0.540677,-0.844281,-0.888770,0.438555},{0.802355,-0.825937,0.472974,-0.719263},{-0.648519,1.281454,0.470129,-0.538160},{-0.851015,0.985721,-0.993719,0.558735}},{{1.164560,-0.302101,0.953803,0.277318},{0.886169,0.623929,1.274299,-0.559466},{-0.948670,0.807814,-1.586962,-0.502652},{-0.069760,1.387864,-0.423140,0.285045}}}},
    {{{{0.747424,-0.044005,0.402212,-0.027484},{0.785297,0.169685,0.734339,-0.984272},{-0.656865,-1.397558,0.935961,-0.490159},{-0.099856,-0.293917,0.129296,-0.920536}},{{0.546529,-0.488280,-0.516120,-1.112775},{0.155881,-0.103160,0.187689,0.485805},{0.918357,0.829929,0.619437,0.877277},{0.389621,0.360045,0.434281,0.456462}},{{-0.803458,-0.525248,-0.467349,0.714159},{-0.648302,-0.005998,-0.812863,0.205664},{0.591453,0.653762,-0.227193,-0.946375},{0.080461,0.311794,0.802115,-1.115836}},{{-0.495051,-0.869153,-0.179932,0.925227},{-1.950445,1.908723,-0.378323,-0.472620},{-0.688403,-1.470251,1.991375,-1.698926},{-0.955808,-0.260230,0.319449,-1.368107}}},{{{-0.029073,-0.622921,-1.095426,-0.764465},{-0.362713,-0.123863,0.234856,-0.772613},{0.697097,0.103340,0.831709,0.529785},{0.103735,-0.526333,-0.084778,0.696831}},{{-0.670775,0.289993,-0.082204,-1.489529},{0.336070,0.322759,0.613241,0.743160},{0.298744,-1.193191,0.848769,-0.736213},{0.472611,-0.830342,0.437290,-0.467557}},{{-0.529196,-0.245683,0.809606,-0.956047},{-1.725613,0.187572,0.528054,-0.996271},{-0.330207,0.206237,0.218373,0.187079},{0.243388,0.625787,-0.388859,0.439888}},{{-0.802928,-0.811282,0.788538,0.948829},{0.966371,1.316717,0.004928,0.832735},{-0.226313,0.364653,0.724902,-0.579910},{-0.544782,-0.143865,0.069256,-0.020610}}},{{{-0.393249,0.671239,-0.481891,0.861149},{-0.662027,-0.693554,-0.564079,-0.477654},{0.070920,-0.052125,-0.059709,0.473953},{-0.280146,-0.418355,0.703337,0.981932}},{{-0.676855,0.102765,-0.832902,-0.590961},{1.717802,0.516057,-0.625379,-0.743204},{-0.170791,-0.813844,-0.269250,0.707447},{0.057623,0.472053,-0.211435,0.147894}},{{-0.298217,0.577550,1.845773,0.876933},{0.617987,0.502801,0.951405,0.122180},{0.924724,-0.166798,0.632685,-0.466165},{-0.834315,-0.864180,-0.274019,0.568493}},{{0.669850,-0.961671,0.790462,0.738113},{-0.534215,-0.556158,0.653896,0.031419},{0.065819,0.220394,0.153365,-0.373006},{0.886610,-0.742343,1.282099,0.198137}}},{{{0.092579,-0.026559,-1.121547,0.143613},{-0.289030,0.265226,-0.350741,-0.897469},{-0.918046,0.038521,-1.515900,0.488701},{-0.759326,-1.782885,-1.787784,0.249131}},{{-0.849816,-0.857074,-0.843467,-0.153686},{0.998653,0.356216,0.926775,0.300663},{-0.749890,-0.003425,-0.607109,0.317334},{-0.561644,0.446478,-0.898901,0.711265}},{{0.232020,-0.445016,0.618918,0.162098},{0.381030,-0.036170,0.084177,0.766972},{0.493139,0.189652,-0.511946,-0.273525},{0.863772,-0.586968,0.829531,-0.075552}},{{0.191787,-0.627198,0.975013,-0.448483},{-0.197885,0.151927,-0.558646,-1.308541},{-0.582967,1.207841,0.746132,0.245631},{0.314827,-0.702463,-0.301494,0.787569}}}},
    {{{{0.670028,-1.825749,-0.739187,0.482428},{0.175521,-0.020120,-0.154805,0.187004},{0.971728,-0.160181,-0.164031,-0.868147},{-0.954732,-0.175713,0.791116,0.294173}},{{-0.958337,-0.843157,-0.472882,0.273517},{-0.999058,0.824762,-0.223130,-0.150628},{0.393747,-0.301297,0.095572,-0.798950},{-0.119787,0.746673,0.955094,0.259353}},{{0.951590,0.225539,0.503282,0.668746},{-0.384898,-0.979592,-0.005485,-0.191883},{-0.692369,-0.642401,-0.825598,0.171933},{-0.321919,-0.498635,0.449704,0.780842}},{{-0.387902,0.522435,0.565608,0.166193},{-0.799671,-0.295871,-0.702573,-0.151006},{0.040550,-0.468503,0.651076,0.636352},{-0.839299,-0.090651,0.428761,0.187043}}},{{{-0.369823,0.377011,0.422936,0.284752},{-0.181514,-0.701449,0.748768,0.540533},{0.734381,0.149410,-0.867043,-0.397142},{-0.770904,-0.581897,-1.578306,-0.402638}},{{0.859015,-0.540358,0.202715,-0.975354},{-0.773629,-0.382342,-0.022498,-0.129286},{-0.901210,-0.641866,1.219216,0.731525},{0.740457,0.858546,-0.408661,-0.364897}},{{-0.830865,-1.370657,-1.226303,-0.392147},{-0.810554,-0.975232,-0.717845,-0.825379},{-0.150096,-0.664533,0.347084,0.243443},{-0.447383,0.842164,1.491342,0.380295}},{{-0.383958,0.811219,0.160459,0.841601},{1.631515,0.371637,0.110000,0.467783},{-0.689356,-0.004289,-0.081057,-0.317243},{0.092451,-0.181268,-0.575747,-0.580061}}},{{{0.908549,-0.013975,-0.880165,-0.938937},{-0.225713,0.449478,0.372569,-0.229889},{0.255711,-0.264752,0.307982,0.260505},{0.314966,-0.540905,0.743032,-0.078475}},{{-0.307472,-1.268296,0.020383,1.798401},{-0.150954,0.909716,-0.407903,0.379046},{0.621853,-0.003629,-0.582697,0.614618},{-0.122843,-0.627133,-0.217968,0.608322}},{{0.071923,0.807315,0.538905,-0.630660},{0.495641,0.240202,-0.920822,-0.258533},{-1.760363,-0.448525,-0.351553,-0.551666},{0.152720,0.900531,0.061966,-0.544377}},{{0.648923,0.450945,-1.530020,1.570190},{0.536210,0.078454,0.577168,0.464872},{-0.888258,-0.950748,0.781474,0.958593},{0.463631,0.319614,-0.248374,-0.413144}}},{{{0.293463,0.236284,1.721511,0.107408},{-0.790508,-0.072027,-0.559467,-0.955839},{-0.777662,-0.169876,0.896220,0.776105},{0.003944,-0.745496,-0.236446,-0.824604}},{{-1.770746,-0.051266,-0.174258,0.003074},{-0.339553,-0.868807,-0.032754,-0.494847},{-0.896712,0.957339,-0.003444,-1.582125},{-0.699883,0.626691,0.799635,-0.542343}},{{-0.635123,-0.755960,0.576373,-0.899530},{-0.393745,0.718900,0.312400,0.511415},{-0.647565,0.368431,0.214726,0.892693},{-0.511960,-0.513262,0.885908,-0.536478}},{{-0.590074,0.623328,0.268674,-0.401391},{0.308868,-0.869862,0.233132,0.243337},{-0.242908,-0.557192,-0.728454,0.867029},{0.156435,-0.805308,-0.815392,-1.437798}}}},
    {{{{0.613484,1.454566,-0.363858,0.634053},{0.535096,-0.641079,-0.607553,0.852559},{0.959100,-0.398621,0.375819,0.385756},{-0.601982,0.494128,0.809699,0.608804}},{{-1.390871,-0.943062,1.556671,0.966501},{-0.013242,0.152716,-0.089592,0.230793},{0.933785,0.119358,0.057387,0.502033},{-0.332925,0.537509,-0.081436,-0.701995}},{{-0.435117,0.996885,0.646630,-0.092342},{0.004343,-0.737514,-0.716187,-0.946819},{0.814258,-0.766971,-0.488162,-0.531619},{-0.923069,0.683915,-0.023809,-1.242992}},{{-0.909155,-0.166488,-0.159273,-0.908121},{-0.783871,-0.522598,0.691845,-0.164065},{1.255966,0.051373,-0.566025,0.820081},{0.186583,0.266032,-0.793747,-0.510092}}},{{{0.890639,0.970042,-0.507885,-0.029557},{-0.771142,-0.875802,0.400070,-1.264247},{-0.881146,0.570950,-0.051624,0.347612},{0.312110,-0.374885,0.600112,0.388460}},{{-0.417107,-0.309284,-0.128477,0.689671},{-0.695866,1.254585,-0.381883,-0.313415},{0.433565,0.919626,0.159180,-0.657310},{-1.396139,0.346053,0.108768,0.061238}},{{-0.776695,0.084491,0.045357,0.312823},{-0.379268,1.217006,-0.014838,-1.032272},{-1.251344,-0.366283,-0.124786,0.729754},{0.979936,0.669519,-0.900018,-0.596954}},{{-0.998834,0.593942,0.375639,-0.627459},{0.297281,0.400240,0.839707,0.960262},{-0.872143,0.574040,-0.559580,-1.965570},{-0.559218,-0.778780,-0.955526,-0.253380}}},{{{-1.919625,-1.911049,0.025035,0.754917},{-0.110993,0.535933,-0.572788,-0.856476},{-0.810836,-0.496261,1.128368,1.758826},{-0.564368,-1.849772,-0.251560,0.635528}},{{0.768196,-0.934122,0.207228,0.884610},{-0.356145,0.265792,-0.835582,0.377675},{-0.410745,0.613212,0.245560,-0.873826},{1.725191,-0.263344,-0.077167,-0.976379}},{{-0.736299,-0.109476,0.044512,-0.004005},{0.692230,0.316670,0.267247,-1.076821},{-0.903184,0.189762,-0.674111,0.219113},{0.639162,1.347521,0.428823,-0.765664}},{{-0.509165,0.458806,-0.851011,0.455027},{-0.218564,-0.063492,0.889320,-0.762062},{0.145950,0.985037,-0.489372,-0.879851},{0.352346,-0.127275,0.896496,-0.596037}}},{{{0.402678,1.479855,0.089187,0.967153},{-0.431225,0.402980,0.883584,-0.900324},{0.262233,-0.647278,0.637005,0.142678},{-0.003253,-0.671924,0.969458,-0.316752}},{{0.345185,-0.477503,-0.326822,-0.106251},{0.239521,1.617125,0.632651,0.969976},{-1.015183,-0.676629,0.955842,0.134925},{-0.319063,-0.493157,-0.488088,0.713008}},{{-0.468621,1.301292,-1.826501,1.138666},{0.170247,-0.661171,0.895204,-0.400700},{-0.077645,-0.978179,-0.245724,0.245282},{-0.258300,0.287261,-0.006274,0.549716}},{{-0.932247,-0.274950,0.920451,0.016237},{0.888865,-0.845248,1.661716,-0.108960},{0.712357,0.586609,-0.867356,0.355058},{-0.540912,0.892622,0.302627,0.247194}}}},
    {{{{0.817578,0.719047,0.438903,0.637398},{0.750466,-0.911799,-0.609606,0.358541},{-1.782979,-0.851717,-0.802122,0.735913},{0.490604,-0.417822,-0.332074,0.836756}},{{-0.650232,-0.442026,0.874916,0.705671},{0.217602,-0.755841,0.573944,0.279365},{-0.713729,0.358880,-0.308992,0.778297},{0.832099,-0.916695,-0.887834,1.041483}},{{1.019467,1.099488,-0.130674,-0.241995},{0.792572,0.756977,0.518186,0.070411},{-0.815779,-0.790757,-1.027439,-0.163698},{0.721461,-0.403364,0.656609,-0.367364}},{{-0.279333,-0.742041,0.515832,-0.408114},{0.834577,0.736056,0.900594,0.276357},{0.726000,0.464991,-0.569281,0.098139},{-0.582324,0.875666,-0.681556,-0.903009}}},{{{1.300969,-0.798351,0.107230,1.611284},{0.239211,0.418231,-0.795764,-0.398818},{-0.939666,1.768175,-0.297023,-0.064087},{-0.239119,-0.365132,0.864138,0.595560}},{{1.898313,-0.343816,1.066256,0.876655},{-0.053636,0.544756,-0.937927,0.189233},{0.445371,-0.656790,-0.675091,0.753163},{-0.293330,-0.002717,0.341173,0.095493}},{{0.951658,0.513912,-0.678347,-0.981140},{-0.020791,0.571138,-0.890648,0.881789},{-1.783345,0.909598,-0.393155,0.240630},{-0.057908,-0.237435,-0.124993,-0.754091}},{{-0.014153,0.127172,0.097134,0.538952},{0.167943,0.786395,0.946153,-0.762513},{-0.562758,0.675657,-0.226395,0.979761},{0.850214,0.818309,0.397074,-0.372059}}},{{{0.803316,-0.659538,-1.987864,-0.186366},{-0.259213,0.315848,-0.427898,0.326521},{-0.168181,-0.620898,0.562309,0.722064},{-1.949690,0.307720,-0.147760,0.603492}},{{0.898339,0.986228,0.724530,0.105193},{0.066046,0.037689,-0.553543,0.597864},{0.296553,0.165199,0.500125,-0.395978},{0.790120,-1.873361,0.354841,-0.187812}},{{-0.559746,0.357012,0.373903,-0.113564},{-0.671918,-0.919720,0.258328,-0.283453},{0.008365,0.597272,0.355827,0.391287},{0.355297,-0.631888,0.221383,1.448221}},{{0.259199,-0.491776,0.721151,0.391427},{0.494000,0.652814,-0.153306,-0.615687},{0.142167,-0.601161,0.281702,0.563390},{0.904019,1.284241,0.901663,0.244620}}},{{{-0.664638,-0.564596,0.839897,0.153358},{-0.506883,0.822337,-0.974957,-0.098112},{-0.962870,-0.274566,0.418039,-0.020525},{-0.965969,0.954587,-0.250493,-0.031592}},{{-0.966475,0.455338,0.868491,0.723032},{-0.002141,0.021922,-0.131429,-0.601106},{-1.240003,1.483318,1.612920,-0.653210},{-0.505979,0.005588,-0.087506,-0.705789}},{{-0.203137,0.765652,-0.132974,-0.900534},{0.731132,0.133467,-1.086363,0.600763},{1.795911,-0.411613,-1.990494,0.405937},{0.729332,-0.119175,-0.979213,0.362346}},{{-0.049014,0.228577,-1.728796,-0.898348},{-0.540969,1.245881,-0.820859,0.285859},{0.430751,-0.373652,0.034535,0.434466},{0.365354,0.243261,0.910114,1.497873}}}}
};
float eval_polynomial(float variables[4],int program_index,int variable_index,int indices[4]){
    if(variable_index==4)return program[program_index][indices[0]][indices[1]][indices[2]][indices[3]];
    float result=0,base=1;
    for(int power=0;power<4;++power){
        indices[variable_index]=power;
        result+=base*eval_polynomial(variables,program_index,variable_index+1,indices);
        base*=variables[variable_index];
    }
    return result;
}
int main(int argc,char *argv[]){
    srand(tick_count());
    rand();
    float variables[4],probability[5],total=0;
    int i,indices[4],temp;
    for(i=0;i<4;++i){
        sscanf(argv[i-4+argc],"%d",&temp);
        variables[i]=temp;
    }
    temp=variables[1];
    variables[1]=variables[2];
    variables[2]=temp;
    if(variables[1]==0){ //bow if our honour is 0
        putchar('B');
        return 0;
    }

    variables[0]/=20;variables[2]/=20;
    variables[1]=1/(variables[1]+1);variables[3]=1/(variables[3]+1);
    for(i=0;i<5;++i){
        probability[i]=eval_polynomial(variables,i,0,indices);
        if(probability[i]<0)probability[i]=0;
        total+=probability[i];
        probability[i]=total;
    }
    total*=(float)rand()/RAND_MAX;
    for(i=0;i<5;++i)if(total<probability[i]){
        putchar("BGIPO"[i]);
        return 0;
    }
    putchar('B');
    return 0;
}

```

---

\[1\] Completely irrelevant number \[2\] Guaranteed to be true 1% of the time

---

# YAGMCSE

Monte Carlo methods seem to exhibit decent play, so here's Yet Another Generic Monte Carlo Simulation Entry!

Unlike most of the other entries in this contest, this entry uses a large number of simulations of random games, and thus requires the use of the -O3 flag for optimal performance.

Compile the program with the command: *gcc monte.c -o monte -O3 -std=c99*

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#include <Windows.h>
unsigned int tick_count(){
    return GetTickCount();
}
#else
#include <sys/time.h>
unsigned int tick_count(){
    struct timeval t;
    gettimeofday(&t, NULL);
    return 1000 * t.tv_sec + t.tv_usec / 1000;
}
#endif

const int turn_limit=500;
enum Move{
    WAIT,BOW,GUARD,QUICK,PARRY,OVERHEAD
};
struct Player{
    int health,honour;
    enum Move lastMove;
};
typedef struct Player Player;
//<command> <history> <enemy_history> <your_health> <enemy_health> <your_honour> <enemy_honour>
//<command> <your_health> <enemy_health> <your_honour> <enemy_honour>
int damage_table[6][6][2]={
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is waiting
    {{0,0},{0,0},{0,0},{1,0},{1,0},{1,0}}, //P1 is bowing
    {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, //P1 is guarding
    {{0,1},{0,1},{0,0},{0,0},{1,0},{0,1}}, //P1 is using quick draw
    {{0,1},{0,1},{0,0},{0,1},{0,0},{1,0}}, //P1 is parrying
    {{0,1},{0,1},{0,0},{1,0},{0,1},{0,0}} //P1 is using overhead attack
};
enum Move decode_move(char x){
    switch(x){
        case 'W': return WAIT; break;
        case 'B': return BOW; break;
        case 'G': return GUARD; break;
        case 'I': return QUICK; break;
        case 'P': return PARRY; break;
        case 'O': return OVERHEAD; break;
    }
    return WAIT;
}
struct SimulationStat{
    enum Move first_me_move;
    int win,draw,lose,compound;
};
int stat_compare(const void*a,const void*b){
    return ((struct SimulationStat*)b)->compound-((struct SimulationStat*)a)->compound;
}
struct SimulationStat monte_carlo(int num_iters,enum Move first_me_move,Player original_me,Player original_opponent){
    struct SimulationStat simulation_result={first_me_move,0,0,0};

    for(int iter=0;iter<num_iters;++iter){
    Player me=original_me,opponent=original_opponent;
        int turn,game_result;
        for(turn=0;turn<turn_limit;++turn){
            enum Move me_move,opponent_move=rand()%(OVERHEAD-BOW+1)+BOW;
            if(turn==0)me_move=first_me_move;
            else me_move=rand()%(OVERHEAD-BOW+1)+BOW;

            //update honour for guarding
            if(me.lastMove==GUARD&&me_move==GUARD)--me.honour;
            if(opponent.lastMove==GUARD&&opponent_move==GUARD)--opponent.honour;

            int me_attacking=me_move==QUICK||me_move==PARRY||me_move==OVERHEAD,opponent_attacking=opponent_move==QUICK||opponent_move==PARRY||opponent_move==OVERHEAD;

            //update health of players
            me.health-=damage_table[me_move][opponent_move][0]*(1+(opponent.honour>=7));
            opponent.health-=damage_table[me_move][opponent_move][1]*(1+(me.honour>=7));

            //update honour for attacking (Sword of the Gods is revoked after the player attacks with an original honour value of 7)
            if(me_attacking)--me.honour;
            if(opponent_attacking)--opponent.honour;

            //printf("%d %d\n",me.health,me.honour);
            //printf("%d %d\n",opponent.health,opponent.honour);

            //check if any of the terminating conditions are met
            //c. both players fall off the graces of the gods (me.honour<0&&opponent.honour<0)
            if(me.honour<0&&opponent.honour<0){
                game_result=0; //draw
                break;
            }
            //a. player 1 falls off the graces of the gods (me.honour<0)
            else if(me.honour<0){
                game_result=-1; //loss
                break;
            }
            //b. player 2 falls off the graces of the gods (opponent.honour<0)
            else if(opponent.honour<0){
                game_result=1; //win
                break;
            }
            //d. both players are dead (me.health<0&&opponent.health<0)
            else if(me.health<0&&opponent.health<0){
                game_result=0; //draw
                break;
            }
            //e. player 1 is dead (me.health<0)
            else if(me.health<0){
                game_result=-1; //loss
                break;
            }
            //f. player 2 is dead (opponent.health<0)
            else if(opponent.health<0){
                game_result=1; //win
                break;
            }
        }
        //both players get struck down by the guards for being boring
        if(turn==turn_limit)game_result=0; //draw

        if(game_result==1)++simulation_result.win;
        else if(game_result==0)++simulation_result.draw;
        else ++simulation_result.lose;
    }
    return simulation_result;
}
int main(int argc,char*argv[]){
    //const int num_iters=200000,num_shortlist_iters=1000000;
    const int num_iters=20000,num_shortlist_iters=55000;

    srand(tick_count());
    Player me,opponent;
    if(argc==5){
        sscanf(argv[1],"%d",&me.health);
        sscanf(argv[2],"%d",&opponent.health);
        sscanf(argv[3],"%d",&me.honour);
        sscanf(argv[4],"%d",&opponent.honour);
        me.lastMove=WAIT;
        opponent.lastMove=WAIT;
    }else{
        sscanf(argv[3],"%d",&me.health);
        sscanf(argv[4],"%d",&opponent.health);
        sscanf(argv[5],"%d",&me.honour);
        sscanf(argv[6],"%d",&opponent.honour);
        me.lastMove=decode_move(argv[1][strlen(argv[1])-1]);
        opponent.lastMove=decode_move(argv[2][strlen(argv[2])-1]);
    }

    struct SimulationStat results[6];
    results[0].first_me_move=WAIT;
    results[0].win=0;
    results[0].draw=0;
    results[0].lose=num_iters;
    results[0].compound=-num_iters*2-1000; //waiting is worse than any other action

    for(enum Move first_me_move=BOW;first_me_move<=OVERHEAD;++first_me_move){
        results[first_me_move]=monte_carlo(num_iters,first_me_move,me,opponent);
        struct SimulationStat *cur=&results[first_me_move];
        cur->compound=cur->win*4+cur->draw*1-cur->lose*2;
    }
    qsort(results,OVERHEAD-WAIT+1,sizeof(*results),stat_compare);

    for(int i=0;i<OVERHEAD-BOW+1;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_iters*100.,(double)cur->draw/num_iters*100.,(double)cur->lose/num_iters*100.,cur->compound);
    }

    for(int i=0;i<2;++i){
        results[i]=monte_carlo(num_shortlist_iters,results[i].first_me_move,me,opponent);
        struct SimulationStat *cur=&results[i];
        cur->compound=cur->win*2+cur->draw*1;
    }
    qsort(results,2,sizeof(*results),stat_compare);

    for(int i=0;i<2;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_shortlist_iters*100.,(double)cur->draw/num_shortlist_iters*100.,(double)cur->lose/num_shortlist_iters*100.,cur->compound);
    }
    putchar("WBGIPO"[results[0].first_me_move]);
    return 0;
}

```
> 1 votes

# Answer
After my failed attempt to enter Target Dummy, I present to you my next bot...

# ScroogeBot - Python 2

This bot will bow if he has one honor. Otherwise he will flip a coin.

If it lands on heads, he will perform a random attack. If it lands on tails, he will either bow or guard.

Command: `python scroogebot.py`

```
import random, sys
# If he has more than one honor...
if int(sys.argv[5]) > 1:
    #Flip a coin.
    coin = random.choice(['heads','tails'])
    #If the coin lands on heads...
    if coin == 'heads':
        #Attack!
        print random.choice(['I','O','P'])
    #If the coin lands on tails...
    else:
        #Don't attack!
        print random.choice(['G','B'])
#If he has 1 honor...
else:
    #Bow!
    print "B"

```
> 1 votes

# Answer
## Yoshimitsu (JS)

Tries to not get guarded by checking the last two moves, will get bravery with higher honor. based off the template apsillers made

```
var attacks = ['I','P','O'];
var pasive = ['B','W'];
var argv = process.argv;
var playerHistory = argv.length>6?argv[2].split(''):[];
var enemyHistory = argv.length>6?argv[3].split(''):[];
var offset = 8 - argv.length;
var my = { health:+argv[4-offset], honor:+argv[6-offset], history:playerHistory };
var enemy = { health:+argv[5-offset], honor:+argv[7-offset], history:enemyHistory };
my.godSword = my.honor >= 7;
enemy.godSword = enemy.honor >= 7;

enemy.lastMove = enemyHistory.pop();
enemy.secondToLast = enemyHistory.pop();

enemy.didAttack = !!attacks.indexOf(enemy.lastMove);

my.lastMove = playerHistory.pop();

function decide() {
    process.stdout.write(arguments[Math.floor(arguments.length*Math.random())]);
    process.exit();
}

chooseAnAttack = function(){ decide.apply(this,attacks); };

if( ( pasive.indexOf( enemy.lastMove ) && my.honor < 15 ) || (my.honor < 7 && enemy.health > 10) || my.honor === 1 ){
    if( Math.random * 15 < my.honor ){
        chooseAnAttack();
    } else {
        decide('B');
    }
} else if( enemy.honor < 2 ){
    chooseAnAttack();
} else if( enemy.didAttack ){

    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }

} else if( enemy.lastMove = 'G' ) {
    chooseAnAttack();
} else if( enemy.lastMove === 'W' ){
    if( attacks.indexOf( enemy.secondToLast ) ){
        decide('G');
    } else if( pasive.indexOf( enemy.secondToLast ) ){
        chooseAnAttack();
    } else if( enemy.secondToLast == 'G' ){
        decide('B');
    }
}

```
> 0 votes

# Answer
# The Fool (C)

The Fool implores a rather erratic strategy, never repeating the same move twice unless forced to through lack of honour. His movements are largely based on randomness, making it hard to predict his actions. His well-being is the last thing on his mind, as his thoughts are set only upon bloodshed and ultimate victory

```
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>

const char commands[] =
{
    'W', 'B', 'G', 'I', 'P', 'O'
};

char select_candidate(const char c[])
{
    unsigned i = 0;
    int n_candidates = 0;
    char candidates[sizeof(commands)];

    for (; i < sizeof(commands); i++)
        if (c[i])
            candidates[n_candidates++] = c[i];

    /* There are no candidates for actions, so the fool blindly attacks his opponent, hoping for the best */
    return n_candidates == 0 ? 'I' : candidates[rand() % n_candidates];
}

int main(int argc, char *argv[])
{
    unsigned i = 0;
    int honour;
    char candidates[sizeof(commands)];
    char last_action;

    srand(time(NULL));

    memcpy(candidates, commands, sizeof(commands));

    /* It's the first round, the fool selects a random action except for waiting */
    if (argc != 7)
    {
        candidates[0] = 0;
        putchar(select_candidate(candidates));
        return 0;
    }

    last_action = argv[1][strlen(argv[1]) - 1];
    honour = atoi(argv[5]);

    if (honour == 0)
    {
        /* The fool realises he will meet his doom if he performs any of the following moves */
        /* and removes them from his list of possible actions */
        candidates[3] = 0;
        candidates[4] = 0;
        candidates[5] = 0;

        /* Only omit the blocking action if the last action was blocking */
        if (last_action == 'G')
            candidates[2] = 0;
    } else if (honour >= 7) {

        /* If the fool has the opportunity to abuse power, he will */
        candidates[0] = 0;
        candidates[1] = 0;
    }

    /* However unintellegent, the fool decides never to repeat the same move twice */
    for (; i < sizeof(commands); i++)
    {
        if (candidates[i] == last_action)
        candidates[i] = 0;
    }

    /* The fool randomly selects a possible action and hopes for the best */
    putchar(select_candidate(candidates));

    return 0;
}

```

---

# The Prophet (C)

The Prophet uses the knowledge of his opponent's previous 2 moves in order to make a predict his next move and provides a swift and deadly counter-attack. Also, he does astrology and stuff.

```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main(int argc, char* argv[])
{
    char* hist;
    char* enemy_hist;
    int hist_len;
    int enemy_hist_len;
    int health;
    int enemy_health;
    int honour;
    int enemy_honour;

    if (argc != 7)
    {
        /* Always start with guarding */
        putchar('G');
        return 0;
    }

    srand(time(NULL));

    /* Grab the command-line values */
    hist         = argv[1];
    enemy_hist   = argv[2];
    health       = atoi(argv[3]);
    enemy_health = atoi(argv[4]);
    honour       = atoi(argv[5]);
    enemy_honour = atoi(argv[6]);

    hist_len = strlen(hist);
    enemy_hist_len = strlen(enemy_hist);

    /* Looks like the enemy is starving for honour. */
    /* This means that they have to bow, so attack them,  */
    /* But only if we have the honour to do so. */
    if (enemy_honour == 0 && honour > 0)
    {
        putchar('O');
        return 0;
    } else if (honour == 0) {
        /* We have to bow */
        putchar('B');
        return 0;
    } else if (honour <= 3) {
        /* We have low honour, attack if the enemy has no honour, otherwise bow to restore some of our honour */
        putchar(enemy_honour == 0 ? ((rand() % 2) ? 'I' : 'O') : 'B');
        return 0;
    }

    switch (enemy_hist[enemy_hist_len - 1])
    {
        /* The enemy has previously performed a passive action, so they will likely attack this round */
        case 'W':
        case 'B':
        case 'G':
            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G'); /* Protect ourselves, using `guard` if we did not use it last turn */
            return 0;

        default:
            if (enemy_hist_len >= 2)
            {
                switch (enemy_hist[enemy_hist_len - 2])
                {
                    case 'I':
                    case 'P':
                    case 'O':
                        /* The enemy has attacked for the last 2 turns, they will likely rest now */
                        putchar((rand() % 2) ? 'I' : 'O');
                        return 0;

                    default:
                        /* Low health, block an incoming attack */
                        if (health <= 5)
                        {
                            putchar(hist[hist_len - 1] == 'G' ? 'P' : 'G');
                            return 0;
                        } else {
                            /* Choose randomly to bow or attack */
                            int decision = rand() % 3;
                            putchar(decision == 2 ? 'B' : decision == 1 ? 'I' : 'O');
                            return 0;
                        }
                }
            } else {
                /* Attack! */
                putchar((rand() % 2) ? 'I' : 'O');
                return 0;
            }
    }

    /* If somehow we get to this point, parry */
    putchar('P');
    return 0;
}

```

---

## Compilation

Both programs are written in C, and can be compiled with `gcc`:

```
gcc fool.c -o fool
gcc prophet.c -o prophet

```

---

## Running

### \*nix

```
./fool <args>
./prophet <args>

```

### Windows

```
fool.exe <args>
prophet.exe <args>

```
> 0 votes

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


title: Indent a string using given parentheses

text:
# Question
Title: Indent a string using given parentheses
Given the following input to the program:

1. List of block start characters
2. List of block end characters
3. A string to format

format the string with the blocks delimited by the two character sets indented.

Formatting is done with two spaces per level and the parentheses are placed as shown in the example below. You may assume the sets of opening and closing characters to be disjoint.

E.g. for `{[(<` and `}])>` as the opening and closing character sets and the following string:

```
abc{xyz{text[note{comment(t{ex}t)abc}]}}

```

the following output would be expected:

```
abc
{
  xyz
  {
    text
    [
      note
      {
        comment
        (
          t
          {
            ex
          }
          t
        )
        abc
      }
    ]
  }
}

```

You may not hard-code the list of “parentheses” characters. How input is given is not specified, though; this could be either command-line arguments or via standard input, as you wish.

# Answer
## Perl - 131 96 94 chars

```
$i="";for$_(split/([\Q$ARGV[0]$ARGV[1]\E])/,$ARGV[2]){$i=~s/..// if/[\Q$ARGV[1]\E]/;print "$i$_\n"if$_;$i.='  'if/[\Q$ARGV[0]\E]/;}

```

Seems like there should be room for eliminating common expressions, at least, but it's a quick take that handles the example, as well as Joey Adams's hypothetical about arbitrary brackets.

---

There was, indeed, plenty of room for improvement:

```
$_=pop;($s,$e)=map"[\Q$_\E]",@ARGV;for(split/($s|$e)/){print"  "x($i-=/$e/),"$_\n"if$_;$i+=/$s/}

```

---

...and still a little more:

```
$_=pop;($s,$e)=map"[\Q$_\E]",@ARGV;map{print"  "x($i-=/$e/),"$_\n"if$_;$i+=/$s/}split/($s|$e)/

```
> 7 votes

# Answer
## Ruby, 106 101 96 95

```
s,e,i=$*
i.scan(/[#{z=Regexp.quote s+e}]|[^#{z}]*/){|l|puts'  '*(s[l]?~-$.+=1:e[l]?$.-=1:$.)+l}

```

Input is provided via the command line.
> 7 votes

# Answer
# JavaScript, ~~255~~ ~~227~~ 205 characters

~~Hey, its length fits perfectly in a byte! :D~~

```
function(s,e,t){R=eval.bind(0,"Array(n).join(' ')");for(i=n=0,b=r='';c=t[i++];)~s.indexOf(c)?(r+=b,b='\n'+R(++n)+c+'\n '+R(++n)):~e.indexOf(c)?b+='\n'+((n-=2)?R()+' ':'')+c+'\n'+(n?R()+' ':''):b+=c;return r+b}

```

It's a function, pass it the start characters, the end characters, then the text.
> 3 votes

# Answer
## Python – 162 chars

```
i=f=0
s=""
l,r,z=[raw_input()for c in'   ']
o=lambda:s+("\n"+"  "*i)*f+c
for c in z:
 if c in l:f=1;s=o();i+=1
 elif c in r:i-=1;f=1;s=o()
 else:s=o();f=0
print s

```
> 2 votes

# Answer
# Python 2.7.X - 136 chars

```
import sys
a,c=sys.argv,0
for i in a[3]:
 if not(i in a[2]):print ' '*c+i
 else:print ' '*(c-4)+i
 if i in a[1]:c+=4
 if i in a[2]:c-=4

```

**Usage** : $ ./foo.py '(' ')' '(ab(cd(ef)gh)ij)'

**Resulting Output:**

```
(
    a
    b
    (
        c
        d
        (
            e
            f
        )
        g
        h
    )
    i
    j
)

```
> 2 votes

# Answer
### C - ~~213~~ 209

I hate stupid mistakes... \>.\<

```
#include<stdio.h>
#include<string.h>
int main(int i,char**s){for(char q,r,c,t,a=0;~(c=getchar());t=q|r){q=!!strchr(s[1],c);a-=r=!!strchr(s[2],c);for(i=0;t|q|r&&i<2*a+1;putchar(i++?' ':'\n'));a+=q;putchar(c);}}

```

Reads left-parens from first command-line argument, right-parens from second argument, and input to indent on stdin.

Pretty-printed & commented:

```
int main(int i, char **s) {
  for (char q, r, /* is left-paren? is right-paren? */
            c,    /* character read from input */
            t,    /* last char was a paren-char */
            a=0;  /* indentation */
       ~(c = getchar());
       t = q|r) {
         q = !!strchr(s[1],c);
    a -= r = !!strchr(s[2],c);
    for (i=0; t|q|r && i<2*a+1; putchar(i++? ' ' : '\n'));
    a += q;
    putchar(c);
  }
}

```
> 2 votes

# Answer
## Python3, 184 182 chars

```
import sys
_,p,q,t=sys.argv
i,f,x=0,1,print
for e in t:
 if e in p:f or x();x(' '*i+e);i+=2;f=1
 elif e in q:f or x();i-=2;f=1;x(' '*i+e)
 else:not f or x(' '*i,end='');f=x(e,end='')

```

Example:

```
$ python3 ./a.py '{[(<' '}])>' 'abc{xyz{text[note{comment(t{ex}t)abc}]}}'
abc
{
  xyz
  {
    text
    [
      note
      {
        comment
        (
          t
          {
            ex
          }
          t
        )
        abc
      }
    ]
  }
}

```
> 1 votes

# Answer
# **C (159 225 chars)**

```
#define q(s,c)strchr(s,c)
#define p(i,j,k)printf("\n%*s%c%c%*s",i,"",*s,k,j,"")
g(char*b,char*e,char*s){int i;for(i=0;*s;s++)q(b,*s)?p(i-2,i+=2,'\n'):q(e,*s)?q(b,*(s+1))||q(e,*(s+1))?p(i-=2,i-2,0):p(i-=2,i-2,'\n'):putchar(*s);}

```

It cost me 66 extra characters just to fix the bug with the empty lines :( Frankly, I need a fresh approach, but I'll call it a day for now.

```
#define p(i,j)printf("\n%*s%c\n%*s",i,"",*s,j,"")
f(char*b,char*e,char*s){int i;for(i=0;*s;s++){strchr(b,*s)?p(i-2,i+=2):strchr(e,*s)?p(i-=2,i-2):putchar(*s);}}

```

A rather quick & dirty approach. It has a bug of producing empty lines between consecutive closing parenthesis, but otherwise it does the job (or so I think). I will revisit it for a better & cleaner solution, sometime this week.

**char \*b** is the opening parenthesis set, **char \*e** is the closing parenthesis set and **char \*s** is the input string.
> 1 votes

# Answer
## Scala(2.9), 211 characters

```
object P extends App{def x(j:Int)={"\n"+"  "*j}
var(i,n)=(0,"")
for(c<-args(2)){if(args(0).exists(_==c)){print(x(i)+c)
i+=1
n=x(i)}else{if(args(1).exists(_==c)){i-=1
print(x(i)+c)
n=x(i)}else{print(n+c)
n=""}}}}

```
> 1 votes

# Answer
## Perl - 89 85 bytes

A version of Hojung Youn's answer which accepts the block characters via two arguments.

```
#!perl -p
BEGIN{$b=pop;$a=pop}s/([$a])|([$b])|\w+/"  "x($1?$t++:$2?--$t:$t)."$&
"/ge

```

Called like:

```
perl golf.pl<<<'abc{xyz{text[note{comment(t{ex}t)abc}]}}' '[{(<' ']})>'

```
> 1 votes

# Answer
## Groovy, 125

```
p=args;i=0;s={a,b->"\n"+"\t"*(b?i++:--i)+a+"\n"+"\t"*i};p[0].each{c->print p[1].contains(c)?s(c,1):p[2].contains(c)?s(c,0):c}

```

You can save the script in a file indent.groovy and try it with:
groovy indent.groovy "abc{xyz{text\[note{comment(t{ex}t)abc}\]}}" "{\[(" ")\]}"
> 1 votes

# Answer
# Python - 407

```
from sys import*;o=argv[1];c=argv[2];t=argv[3];p=0;n=False;a=lambda:h not in e;b=lambda s:print(s+(" "*p)+h);r="";e=o+c
for h in t:
 for k in o:
  if h==k:
   if(r in e)and(r!=""):b("")
   else:b("\n")
   p+=2;n=True;break
 for k in c:
  if h==k:
   p-=2
   if(r in e)and(r!=""):b("")
   else:b("\n")
   n=True;break
 if a()and n:print((" "*p)+h,end="");n=False
 elif a():print(h,end="")
 r=h

```

An ungolfed version of the program:

```
import sys

open_set = sys.argv[1]
close_set = sys.argv[2]
text = sys.argv[3]
spaces = 0
newline = False
a = lambda : char not in b_set
b = lambda s: print(s + (" " * spaces) + char)
prev = ""
b_set = open_set + close_set

for char in text:
    for bracket in open_set:
        if char == bracket:
            if (prev in b_set) and (prev != ""):
                b("")
            else:
            b("\n")
        spaces += 2
        newline = True
        break
    for bracket in close_set:
        if char == bracket:
            spaces -= 2
            if (prev in b_set) and (prev != ""):
                b("")
            else:
                b("\n")
            newline = True
            break
    if a() and newline:
        print((" " * spaces) + char, end="")
        newline = False
    elif a():
        print(char, end="")
    prev = char

```

The arguments to the program are (in order): the opening parentheses, the closing parentheses, and the text to indent.

Example ($ is command line prompt):

```
$ python indent.py "{[(<" "}])>" "abc{xyz{text[note{comment(t{ex}t)abc}]}}"
abc
{
  xyz
  {
    text
    [
      note
      {
        comment
        (
          t
          {
            ex
          }
          t
        )
        abc
      }
    ]
  }
}

```
> 1 votes

# Answer
# C 284 Non White space Characters

I'm no fan of obfuscation but well...

```
#include<cstdio>
#include<cstring>
#define g printf
#define j char
int main(int a,j**b){int c=0;for(j*f=b[3];*f!='\0';++f){if(strchr(b[1],*f)!=0){g("\n%*c\n%*c",c,*f,c+2,'\0');c+=2;}else if(strchr(b[2],*(f))!=0){c-=2;g("\n%*c",c,*f);if(strchr(b[2],*(f+1))==0)g("\n%*c",c,'\0');}else putchar(*f);}}

```

Usage: ./program start\_brackets end\_brackets string\_to\_parse
> 0 votes

# Answer
## php (187) (153)

```
function a($s,$o,$e){while(''!=$c=$s[$i++]){$a=strpbrk($c,$o)?2:0;$b=strpbrk($c,$e)?2:0;echo ($a+$b||$r)?"\n".str_pad('',$t-=$b):'',$c;$t+=$a;$r=$a+$b;}}

```

Function takes string, opening delimiters, ending delimiters as arguments.
> 0 votes

# Answer
# C, 256

Parameters:

* **e** is the ending char,
* **n** is the indentation,
* **b** the opening brackets,
* **d** the closing brackets.

I broke the code up to avoid the horizontal scrollbar.

```
#define r char
#define P(c) putchar(c);
#define N P(x)
#define W printf("%*s",n,"");
r*s,x='\n';i(r e,int n,r*b,r*d){r*t=s,*p;int l=0;W while(*s!=e)
{if(p=strchr(b,*s)){if(s!=t){N W}P(*s++)N i(d[p-b],n+2,b,d); N W
P(*s++);l=1;}else{if(l){N W l=0;}P(*s++)}}}

```

Complete program is 363 characters.

```
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define r char
#define P(c) putchar(c);
#define N P(x)
#define W printf("%*s",n,"");
r*s,x='\n';i(r e,int n,r*b,r*d)
{r*t=s,*p;int l=0;W while(*s!=e)
{if(p=strchr(b,*s)){if(s!=t){N W}
P(*s++)N i(d[p-b],n+2,b,d); N W
P(*s++);l=1;}else{if(l){N W l=0;}
P(*s++)}}}main(int c,r*v[]){s =
v[3];i('\0',0,v[1],v[2]);}

```
> 0 votes

# Answer
# Powershell, 146 Bytes

```
param([char[]]$s,[char[]]$e,[char[]]$f)$f|%{}{if($_-in$s){$o;'  '*$i+$_;$o='  '*++$i;}elseif($_-in$e){$o;'  '*--$i+$_;$o='  '*$i}else{$o+=$_}}{$o}

```

Ungolfed Explanation

```
param([char[]]$start,             # Cast as array of Chars
      [char[]]$end,
      [char[]]$string)
$string | foreach-object { } {    # For every char in string. Empty Begin block
    if ( $_ -in $start ) {        # If char is in start
        $o                        # Print stack ($o)
        '  ' * $i + $_            # Newline, indent, insert start char
        $o = '  ' * ++$i          # Set stack to ident (incremented)
    } elseif ( $_ -in $end ) {    # If char is in end
        $o                        # Print stack
        '  ' * --$i + $_          # Newline, decrement indent, insert end char
        $o = '  ' * $i            # Set stack to indent
    } else {
        $o+ = $_                  # Otherwise add character to stack
    }
} { $o }                          # Print remaining stack (if any)

```
> 0 votes

# Answer
# C, 181 characters

```
#define d(m,f)if(strchr(v[m],*s)){puts("");for(j=f;j--;)printf("  ");}
i;main(j,v,s)char**v,*s;{for(s=v[3];*s;s++){d(1,i++)d(2,--i)putchar(*s);d(1,i)if(!strchr(v[2],*(s+1)))d(2,i)}}

```

Pretty much the most straightforward approach imaginable. Iterate through the string (v\[3\]), if it's a left brace (as defined in v\[1\]), increase the indent level, if it's a right brace (as defined in v\[2\]), decrease the indent level.
> 0 votes

---
Tags: code-golf, string, whitespace, balanced-string
---


title: Exploit "free whitespace"

text:
# Question
Title: Exploit "free whitespace"
Suppose a codegolf challenge doesn't count whitespace in the length of your program. Cheat this system by encoding your script into whitespace, and golf a script which decodes and executes embedded whitespace.

**Example**

My solution to JBernardo's Meta Golf Challenge was to encode Sage (or Python) code into whitespace, and golf the decoder.

```
s = ' '
for c in '<lots of whitespace>'.split(s):
    s+=chr(len(c))
exec s

```

The encoding is to take a script, prepend a newline, and for each character `c` in the script, output `ord(c)` tabs followed by a space. Prepending a newline is necessary since I'm using Python and I start the script `s` with a space.

**Scoring**

A complete solution contains a description of the encoding you use (if it's complicated, provide a script), and a 'decode-and-execute' script. Your score is the number of non-whitespace characters in the decode-and-execute script.

**Whitespace (the language) is forbidden**

Moreover, any language which has a complete set of operators which only use whitespace characters is not allowed: I'll accept the lowest nonzero score.

# Answer
## Golfscript, 12 chars

String delimited by `'` goes before these 10 chars:

```
n/{,}%''+~

```

Each line is decoded into one character, whose ASCII (probably Unicode, in fact) value is the length of the line.

Unfortunately if I try pasting my Hello World example, Markdown removes the extra spaces, even in a `<pre>` block.
> 8 votes

# Answer
## CPAN, 16

```
use Acme::Bleach;

```

CPAN has it all. Or at least, just the right module.
> 9 votes

# Answer
## Perl, 29

```
$_="";s/     */chr length $&/ge;eval

```

Inside that `s///` are a tab then a space. The encoding is an ultra-basic encode with spaces, precede with tabs.

Try this one on the command line:

```
$ tr ST ' \t' <<< '$_="TSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSTSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"; s/TS*/chr length $&/ge; eval' | perl

```

~~Edit: well, lol, I can't find a proper way to copy-paste the tab/space mix. Believe me, it works at home :)~~ Update: there, there, encoded with `tr`
> 3 votes

# Answer
## JavaScript

Replace `\t` with a tab to get the posted character count.

### Standard (64 characters)

```
eval(eval("'<code here>'".replace(/\t */g,function(s){return"\\"+s.length})))

```

### Arrow function (49 characters)

```
eval(eval("'<code here>'".replace(/\t */g,(s)=>"\\"+s.length)))

```

### Encoder program for both

```
for(var i = 0, si = prompt("Enter the code."), so = ""; i < si.length; ++i) so += '\t' + Array(+si.charCodeAt(i).toString(8)).join(' '); prompt("Here is the result.", so);

```
> 3 votes

# Answer
## C (99 characters)

```
main(c, p)
{
    char *s = "<code here>";
    for (p = popen("cc -xc -oa -", "w"); *s;)
        *s++ - 9 ? c -= putc(c, p) : ++c;
    execl("a", pclose(p));
}

```

Tested only with (and perhaps only works with) GCC.

Corresponding encoder program (manually remove the first character from its output):

```
#include <stdio.h>

int main()
{
    int c;
    while ((c = getchar()) != EOF) {
        while (c--) putchar(9);
        putchar(32);
    }
    return 0;
}

```
> 2 votes

# Answer
## Yabasic (88 characters)

```
a$ = "<code here>"
for a = 1 to len(a$)
    if mid$(a$, a) < " " then b = b + 1
    else b$ = b$ + chr$(b) : b = 0
    endif
next
compile(b$)
a()

```

Use the same encoder program as for my C solution, but do not remove the first character. Your original code must be in the form of a subroutine `a()`, for example:

```
sub a():?"hello, world":end sub

```
> 2 votes

# Answer
## D (101 chars)

```
import std.algorithm;mixin((){char[]r;foreach(c;splitter("<lots of whitspace>"," "))r~=cast(char)c.length;return r;}());

```

same encoding as in the question (no need for the newline)
> 1 votes

# Answer
## Bash (builtins only, 44 characters)

```
IFS=
eval `while read a
do printf '\'${#a}
done<<a
<code here>
a`

```

Corresponding encoder script:

```
od -b | cut -b9- | tr ' ' '\n' | while read a
do
    for (( b = 0; b < $((10#$a)); ++b ))
    do
        echo -n ' '
    done
    echo
done

```
> 1 votes

# Answer
# K5, 12 bytes

```
.`c$-':&9=" "

```

Execute (`.`) the string formed from the ascii values (``c$`) given by the difference between each pair (`-':`) of the indices where (`&`) the input is a tab (`9=" "`).

Input is a string of tab- and non-tab characters, and the character values are encoded in the number of non-tabs (spaces or newlines) between each tab. An example encoder:

```
" ",/{(x#" "),"\t"}'-1+

```

Perform a running join beginning with a space over (`" ",/`) x spaces (`x#" "`) joined with a tab (`,"\t"`) where X is each of (`{...}'`) one minus the character values of the input string (`-1+`).

In action:

```
  enc: " ",/{(x#" "),"\t"}'-1+
  dec: .`c$-':&9=

  enc "2+3"
"                                                  \t                                          \t                                                  \t"
  dec enc "2+3"
5

```
> 1 votes

# Answer
# Ruby, 43

Very straightforward, encoding is putting x spaces per line, where x is the ascii value of the char, decoding is reverse.

The following script is just a unary to ASCII converter and works even when things other than spaces are free:

```
eval("".split("\n").map{|x|x.length.chr}.join)

```

Just replace the empty string with the program that pleases you.

The thing in a more reusable format:

```
from_space = lambda {|text| text.split("\n").map{|x| x.length.chr}.join}
to_space = lambda {|text| text.chars.map{|x| " " * x.ord}.join("\n")}

p from_space [ to_space [ "abc" ] ] #=> "abc"

```
> 0 votes

---
Tags: code-golf, whitespace
---