title: KOTH : Monster Hunter

text:
# Question
Title: KOTH : Monster Hunter
**Updated Results**

# Introduction

To celebrate Monster Hunter 4 Ultimate launch on new 3DS (February 13th), here's a King of the Hill themed on this game.

You are a novice hunter, who'll take part in a tournament consisting of 5 consecutives hunts. At the end of these hunts, hunters will be ranked depending on the damage they dealt to monsters and of course wether they slayed it or have been vanquished by it. Also, as a novice, you'll have to stick to the weapon you choose until you are more experienced.

# Lexicon

`ATK` : Attack
`DEF` : Defense
`HP` : Health Points
`NRG` : Energy
`GRD` : Guard
`SPD` : Speed
`SHP` : Sharpness
`AGR` : Aggressivity
`POT` : Potion
`RAT` : Ration
`WHE` : Whetstone

# Principle

Hunters can choose among a variety of **4 weapons** :

```
              |   Id   |  ATK  |  GRD  |  SPD  |
------------------------------------------------
Great Sword   |   GS   |   7   |   2   |   2   |
Dual Blade    |   DB   |   3   |   0   |   7   |
Lance         |   LA   |   5   |   4   |   3   |
Hammer        |   HA   |   9   |   0   |   1   |

```

The **5 monsters** to hunt are :

```
              |   HP   |  ATK  |  DEF  |
----------------------------------------
Yian Kut-ku   |  1500  |   5   |   4   |
Rathian       |  1800  |   7   |   4   |
Rathalos      |  1800  |   4   |   7   |
Tigrex        |  2000  |   8   |   6   |
Fatalis       |  2500  |  11   |   7   |

```

When the game begins, you have to choose a weapon. Then, for each of the 5 hunts, you'll be split among teams of **4 players** and you'll start hunting.

Each hunter basic stats are :

```
              |   HP  |  NRG  |  DEF  |  SHP  |  AGR  |
-------------------------------------------------------
Hunter        |  100  |  100  |   5   |   4   |   0   |

```

Stats can't go beyond their initial values (i.e. taking a potion with 50HP only restores your health up to 100HP).

Each hunter starts with :

```
              |  POT  |  RAT  |  WHE  |
---------------------------------------
Hunter Items  |   5   |   5   |   5   |

```

The controller provides you with input via command arguments, your program has to output via stdout.

# Syntax

**Output (preparation)**
Before the game starts, the controller invokes you submission without arguments. This means you have to choose one of the 4 weapon by outputing its Id. You'll keep this weapon till the end of the game.

You need to output : `WeaponID`

For example : `GS`.

**Input**
Each time your program is called, it will receive arguments in this format (newlines *not* part of the input an only used for formatting):

```
Round;YourPlayerId;Monster_ATK;Monster_DEF;Monster_HP;Monster_TargetId;Monster_NextMoveId;
PlayerId_WeaponId_ATK_DEF_HP_NRG_GRD_SPD_SHP_AGR_POT_RAT_WHE_CurrentCombo;
PlayerId_WeaponId_ATK_DEF_HP_NRG_GRD_SPD_SHP_AGR_POT_RAT_WHE_CurrentCombo;
PlayerId_WeaponId_ATK_DEF_HP_NRG_GRD_SPD_SHP_AGR_POT_RAT_WHE_CurrentCombo;
PlayerId_WeaponId_ATK_DEF_HP_NRG_GRD_SPD_SHP_AGR_POT_RAT_WHE_CurrentCombo

```

**Example input**

```
3;3;5;5;1164;2;S;
0_LA_5_5_75_45_4_3_2_55_5_5_5_AA;
1_HA_9_5_75_100_0_1_3_321_5_5_5_N;
2_GS_7_5_75_35_2_2_2_59_5_5_5_BB;
3_DB_3_5_75_78_0_7_2_0_5_5_5_AB

```

Here, you see it is the 3rd minute (starts at 1) and you are player 3. You are carrying Dual Blades, you have 3 ATK, 5 DEF, 75 HP, 78 NRG, 0 GRD, 7 SPD, 2 SHP, 5 POT, 5 RAT, 5 WHE and your current combo is A-\>B.

**Output**

See gameplay.

# Gameplay

Teams of 4 hunters are made randomly at the start of each hunt. If there are not enough hunters to make teams, the game will automatically add 1 or more of the 4 "helper" (Felyne, Melynx, Palico or Koneko) choosen randomly to reach desired numbers.

Each hunt lasts **50 minutes**, and you can take **1 action per minute** (i.e. 50 actions per hunt). For each of these 50 minutes, you'll need to output a letter corresponding to the action you'll take (see actions).

Hunters go first (in a random order choosen at the beginning), then the monster executes its action (which was provided as `Monster_NextMoveId`). So each minute goes like this : Hunter 1 \> Hunter 2 \> Hunter 3 \> Hunter 4 \> Monster \> Next minute...

On the first minute, the monster will always use `O` (see actions). Each turn after its action, the monster will choose its next target by selecting the hunter with the highest `AGR` value. `AGR` decreases by 30 per minute.

If the monster or all hunters are killed, the hunt stops. The hunters are revived after each hunts, and their stats, items, combos and actions are reset to their default values.

# Hunters' actions

> * `A` : Attack A \[Requires `NRG`\]
> * `B` : Attack B \[Requires `NRG`\]
> * `C` : Attack C \[Requires `NRG`\]
> * `G` : Guard \[Requires 15 `NRG`. Can only be used if the weapon has GRD \> 0. Activates `GRD` stat in damage formula for next turn.\]
> * `D` : Dodge \[Requires 30 `NRG`. Completely dodge damage for next turn.\]
> * `W` : Wait \[Restores 30 `NRG`. Does nothing else.\]
> * `T` : Taunt \[Restores 80 `NRG`. Increases `AGR` by 300.\]
> * `P` : Potion \[Requires 1 `POT`. Restores 90 `HP`. Reduces `DEF` by 2 for next turn.\]
> * `R` : Ration \[Requires 1 `RAT`. Restores 30 `HP` AND 50 `NRG`. Reduces `DEF` by 2 for next turn.\]
> * `S` : Sharpen \[Requires 1 `WHE`. Restores `SHP` to 4. Reduces `DEF` by 2 for next turn.\]

# Monsters' actions

Monsters choose their action randomly.

> * `O` : Observe (5% chance) \[Does nothing.\]
> * `A` : Attack (40% chance) \[Attacks target (defined in `Monster_TargetId`).\]
> * `R` : Roar (10% chance) \[Stuns everyone. Hunters do nothing next turn.\]
> * `F` : Fly (10% chance) \[Completely dodge every attack next turn.\]
> * `C` : Charge (15% chance) \[Attacks target (defined in `Monster_TargetId`). Completely dodge every attack next turn.\]
> * `S` : Spin (20% chance) \[Attacks every hunter.\]

# Attacks & Combos

Each weapon can be used to launch 3 differents attacks : `A`, `B` and `C`.

Each attacks requires and consumes `NRG` according to this formula : `energy = floor(100 / (SPD + 2))`

Damages are calculated with this formula : `damage = ATK * (10 + SHP - DEF [- GRD])`. `GRD` is only applied if the hunter is currently guarding (see actions). When a hunter is using an item (see actions), his `DEF` is reduced by 2. Each hit on a monster reduces `SHP` by 1 till the minimum of 1. Monsters have a `SHP` of 0. Each damage inflicted to a monster increases `AGR` by the same value.

If you manage to chain attack to create a specific combo, your damage will be multiplicated by the corresponding bonus. Any action other than an attack reset your current combo, and combo with `reset = 1` will also reset it.

```
              |   Combo                    | Bonus | Reset |
------------------------------------------------------------
Great Sword   | B -> B -> A                |   3   |   1   |
Great Sword   | B -> B -> B -> C           |   4   |   1   |
------------------------------------------------------------
Dual Blade    | C -> C                     |   2   |   1   |
Dual Blade    | A -> B -> A -> B           |   3   |   0   |
Dual Blade    | A -> B -> A -> B -> A      |   4   |   0   |
Dual Blade    | A -> B -> A -> B -> A -> C |   5   |   1   |
------------------------------------------------------------
Lance         | B -> B -> B                |   3   |   1   |
Lance         | A -> A -> A                |   2   |   0   |
Lance         | A -> A -> A -> C           |   4   |   1   |
------------------------------------------------------------
Hammer        | B -> B -> A                |   2   |   1   |
Hammer        | C -> C -> A                |   2   |   1   |

```

# Rules

* Writing to files is allowed. Please write to "yoursubmissionname.txt", the folder will be emptied before a game starts. Other external resources are disallowed.
* Your submission has 1 second to respond.
* Provide commands to compile and run your submissions.

# Scoring & Winning

You get :

* +1000 points for surviving a successful hunt (monster dead).
* +0 points for surviving a unsuccessful hunt (monster alive).
* -1000 points for passing away (hunter dead) no matter of the result of the hunt.
* +1 point per damage dealt to the monster

Winner is the one with the highest score after 5 hunts.

# Controller

You can find the controller on github. It also contains 4 samplebots, written in Java. Open it in Eclipse, place the compiled bots in the root folder and add a class to the control program (just like the samplebots).

# Results

Average of 10 games :

```
1. Lancer: 5495
2. Felyne: 4786
3. Melynx: 4190
4. RedViper: 3886
5. Koneko: 3639
6. TheKingsJester: 3100
7. RoranStronghammer: 3046
8. WeaselWill: 2849

```

Complete logs of 1 game : http://pastebin.com/bfR5ZiMJ
Results of 10 games : http://pastebin.com/YWFf6qT7

# Answer
# Lancer

A disciplined warrior who employs a defensive fighting style

```
/*jshint node:true */
'use strict';
var fs = require('fs');

var dataFile = 'lancer.txt';

function getData(callback) {
  fs.readFile(dataFile, 'utf8', function(err, contents) {
    var data = {};

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

    callback(data);
  });
}

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

function parseArgs(args){
  var gameState = {
    monster: {},
    hunters: [],
    otherHunters: []
  };

  var argArray = args.split(';');

  gameState.round = +argArray.shift();
  var myId = +argArray.shift();

  gameState.monster.attack = +argArray.shift();
  gameState.monster.defense = +argArray.shift();
  gameState.monster.hp = +argArray.shift();
  var monsterTargetId = +argArray.shift();
  gameState.monster.nextMove = argArray.shift();
  gameState.monster.guard = 0;
  gameState.monster.sharpness = 0;

  for(var index = 0; index < argArray.length; index++) {
    var hunterArgs = argArray[index].split('_');
    var hunterId = +hunterArgs.shift();
    var hunter = {};
    hunter.weapon = hunterArgs.shift();
    hunter.attack = +hunterArgs.shift();
    hunter.defense = +hunterArgs.shift();
    hunter.hp = +hunterArgs.shift();
    hunter.energy = +hunterArgs.shift();
    hunter.guard = +hunterArgs.shift();
    hunter.speed = +hunterArgs.shift();
    hunter.sharpness = +hunterArgs.shift();
    hunter.aggro = +hunterArgs.shift();
    hunter.potions = +hunterArgs.shift();
    hunter.rations = +hunterArgs.shift();
    hunter.whetstones = +hunterArgs.shift();
    hunter.combo = hunterArgs.shift().split('');

    gameState.hunters.push(hunter);

    if(myId === hunterId) {
      gameState.me = hunter;
    }
    else {
      gameState.otherHunters.push(hunter);
    }

    if(monsterTargetId === hunterId) {
      gameState.monster.target = hunter;
    }
  }

  return gameState;
}

function getAttackEnergy(hunter) {
  return Math.floor(100 / (hunter.speed + 2));
}

function getDamage(attacker, defender, useGuard) {
  var guard = useGuard ? defender.guard : 0;

  return attacker.attack * (10 + attacker.sharpness - defender.defense - guard);
}

function isAttackingMe(gameState) {
  var nextMove = gameState.monster.nextMove;
  return nextMove === 'S' || (gameState.monster.target === gameState.me && (nextMove === 'A' || nextMove === 'C'));
}

function isSafeToTaunt(gameState) {
  var maxAggro = Math.max.apply(null, gameState.otherHunters.map(function(hunter){return hunter.aggro;}));
  return gameState.me.aggro + 300 < maxAggro;
}

function getAction(gameState) {
  var damage = getDamage(gameState.me, gameState.monster);
  if(gameState.me.combo.length === 2) {
    damage *= 3;
  }

  if(damage >= gameState.monster.hp && !gameState.monster.isImmune && gameState.me.energy >= getAttackEnergy(gameState.me)) {
    return 'B';
  }

  var monsterDamage = getDamage(gameState.monster, gameState.me);
  var attackingMe = isAttackingMe(gameState);

  if(monsterDamage > gameState.me.hp) {
    if(attackingMe) {
      if(gameState.me.energy >= 30) {
        return 'D';
      }

      if(monsterDamage < getDamage(gameState.monster, gameState.me, true) && gameState.me.energy >= 15) {
        return 'G';
      }
    }

    if(gameState.me.potions > 0) {
      return 'P';
    }

    if(gameState.me.rations > 0) {
      return 'R';
    }
  }

  if(attackingMe && gameState.me.energy >= 15) {
    return 'G';
  }

  if(gameState.me.sharpness <= 1 && gameState.me.whetstones > 0 && !attackingMe) {
    return 'S';
  }

  if(gameState.me.energy >= getAttackEnergy(gameState.me) * Math.min((3 - gameState.me.combo.length), 1) && (gameState.me.combo.length < 2 || !gameState.monster.isImmune)) {
    return 'B';
  }

  if(gameState.me.energy <= 20 && isSafeToTaunt(gameState)) {
    return 'T';
  }

  if(gameState.me.rations > 0 && gameState.me.hp <= 70 && gameState.me.energy <= 50 && !attackingMe) {
    return 'R';
  }

  return 'W';
}

function startGame() {
  console.log('LA');
}

if(process.argv.length <= 2) {
  startGame();
}
else {
  var gameState = parseArgs(process.argv[2]);
  getData(function(data) {
    if(data.monsterLastAttack === 'F' || data.monsterLastAttack === 'C') {
      gameState.monster.isImmune = true;
    }
    data.monsterLastAttack = gameState.monster.nextMove;

    saveData(data, function() {
      console.log(getAction(gameState));
    });
  });
}
/*jshint node:true */
'use strict';
var fs = require('fs');

var dataFile = 'lancer.txt';

function getData(callback) {
  fs.readFile(dataFile, 'utf8', function(err, contents) {
    var data = {};

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

    callback(data);
  });
}

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

function parseArgs(args){
  var gameState = {
    monster: {},
    hunters: [],
    otherHunters: []
  };

  var argArray = args.split(';');

  gameState.round = +argArray.shift();
  var myId = +argArray.shift();

  gameState.monster.attack = +argArray.shift();
  gameState.monster.defense = +argArray.shift();
  gameState.monster.hp = +argArray.shift();
  var monsterTargetId = +argArray.shift();
  gameState.monster.nextMove = argArray.shift();
  gameState.monster.guard = 0;
  gameState.monster.sharpness = 0;

  for(var index = 0; index < argArray.length; index++) {
    var hunterArgs = argArray[index].split('_');
    var hunterId = +hunterArgs.shift();
    var hunter = {};
    hunter.weapon = hunterArgs.shift();
    hunter.attack = +hunterArgs.shift();
    hunter.defense = +hunterArgs.shift();
    hunter.hp = +hunterArgs.shift();
    hunter.energy = +hunterArgs.shift();
    hunter.guard = +hunterArgs.shift();
    hunter.speed = +hunterArgs.shift();
    hunter.sharpness = +hunterArgs.shift();
    hunter.aggro = +hunterArgs.shift();
    hunter.potions = +hunterArgs.shift();
    hunter.rations = +hunterArgs.shift();
    hunter.whetstones = +hunterArgs.shift();
    hunter.combo = hunterArgs.shift().split('');

    gameState.hunters.push(hunter);

    if(myId === hunterId) {
      gameState.me = hunter;
    }
    else {
      gameState.otherHunters.push(hunter);
    }

    if(monsterTargetId === hunterId) {
      gameState.monster.target = hunter;
    }
  }

  return gameState;
}

function getAttackEnergy(hunter) {
  return Math.floor(100 / (hunter.speed + 2));
}

function getDamage(attacker, defender, useGuard) {
  var guard = useGuard ? defender.guard : 0;

  return attacker.attack * (10 + attacker.sharpness - defender.defense - guard);
}

function isAttackingMe(gameState) {
  var nextMove = gameState.monster.nextMove;
  return nextMove === 'S' || (gameState.monster.target === gameState.me && (nextMove === 'A' || nextMove === 'C'));
}

function isSafeToTaunt(gameState) {
  var maxAggro = Math.max.apply(null, gameState.otherHunters.map(function(hunter){return hunter.aggro;}));
  return gameState.me.aggro + 300 < maxAggro;
}

function getAction(gameState) {
  var damage = getDamage(gameState.me, gameState.monster);
  if(gameState.me.combo.length === 2) {
    damage *= 3;
  }

  if(damage >= gameState.monster.hp && !gameState.monster.isImmune && gameState.me.energy >= getAttackEnergy(gameState.me)) {
    return 'B';
  }

  var monsterDamage = getDamage(gameState.monster, gameState.me);
  var attackingMe = isAttackingMe(gameState);

  if(monsterDamage > gameState.me.hp) {
    if(attackingMe) {
      if(gameState.me.energy >= 30) {
        return 'D';
      }

      if(monsterDamage < getDamage(gameState.monster, gameState.me, true) && gameState.me.energy >= 15) {
        return 'G';
      }
    }

    if(gameState.me.potions > 0) {
      return 'P';
    }

    if(gameState.me.rations > 0) {
      return 'R';
    }
  }

  if(attackingMe && gameState.me.energy >= 15) {
    return 'G';
  }

  if(gameState.me.sharpness <= 1 && gameState.me.whetstones > 0 && !attackingMe) {
    return 'S';
  }

  if(gameState.me.energy >= getAttackEnergy(gameState.me) * Math.min((3 - gameState.me.combo.length), 1) && (gameState.me.combo.length < 2 || !gameState.monster.isImmune)) {
    return 'B';
  }

  if(gameState.me.energy <= 20 && isSafeToTaunt(gameState)) {
    return 'T';
  }

  if(gameState.me.rations > 0 && gameState.me.hp <= 70 && gameState.me.energy <= 50 && !attackingMe) {
    return 'R';
  }

  return 'W';
}

function startGame() {
  console.log('LA');
}

if(process.argv.length <= 2) {
  startGame();
}
else {
  var gameState = parseArgs(process.argv[2]);
  getData(function(data) {
    if(data.monsterLastAttack === 'F' || data.monsterLastAttack === 'C') {
      gameState.monster.isImmune = true;
    }
    data.monsterLastAttack = gameState.monster.nextMove;

    saveData(data, function() {
      console.log(getAction(gameState));
    });
  });
}

```

Save as `lancer.js`, run with `node lancer`
> 4 votes

# Answer
# Java, Roran Stronghammer

He wields the hammer of death.

```
import java.util.ArrayList;
import java.util.List;

public class RoranStronghammer {

    int round;
    int playerID;
    Hunter thisHunter;
    List<Hunter> hunters = new ArrayList<>();
    List<Hunter> otherHunters = new ArrayList<>();
    Monster monster;
    boolean canTauntSafely;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("HA");//ha!
        } else {
            System.out.println(new RoranStronghammer(args).hunt());
        }
    }

    private String hunt() {

        int requiredEnergy = 100 / (thisHunter.getSpeed() + 2);

        if (requiredEnergy > thisHunter.getEnergy()){
            if (canTauntSafely){
                return "T";
            }
            if (thisHunter.getRations() > 0){
                return "R";
            }
            return "T";
        }

        int damage = thisHunter.getAtk() * (10 + thisHunter.getSharpness() - monster.getDef());
        int monsterDamage = monster.getAtk() * (10 - thisHunter.getDef());

        String currentCombo = thisHunter.getAttacks();

        if (damage > monster.getHp()){//Kill monster if possible.
            return "B";
        }

        if (currentCombo.length() >= 2 && damage * 2 > monster.getHp()){//Kill monster if possible.
            return "A";
        }

        if (monsterDamage > thisHunter.getHp()){
            if (thisHunter.getPotions() > 0 && thisHunter.getHp() <= 10){
                return "P";
            }
            if (thisHunter.getEnergy() <= 50 && thisHunter.getRations() > 0){
                return "R";
            }
            if (thisHunter.getPotions() > 0){
                return "P";
            }
        }

        if (currentCombo.length() >= 2){
            return "A";                    //Do critical hit
        }

        if (currentCombo.length() == 0){
            if (thisHunter.getEnergy() < requiredEnergy * 3) {
                if (canTauntSafely){
                    return "T";
                }
                if (thisHunter.getRations() > 0) {
                    return "R";
                }
                return "T";
            }
            if (thisHunter.getSharpness() < 4){
                return "S";
            }
        }
        if (currentCombo.length() == 1){
            if (thisHunter.getEnergy() < requiredEnergy * 2) {
                if (canTauntSafely){
                    return "T";
                }
                if (thisHunter.getRations() > 0) {
                    return "R";
                }
                return "T";
            }
            if (thisHunter.getSharpness() < 3){
                return "S";
            }
        }
        return "B";                   //Attack constantly.

    }

    public RoranStronghammer(String[] args) {

        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        monster = new Monster(args[2]+";"+args[3]+";"+args[4]+";"+args[5]+";"+args[6]);

        for (int i = 7; i < args.length; i++){
            hunters.add(new Hunter(args[i]));
        }

        int mostAggressiveness = 0;
        int myAggressiveness = 0;

        for (Hunter hunter : hunters) {
            if (hunter.isMe()){
                thisHunter = hunter;
                myAggressiveness = hunter.getAggro();
            } else {
                otherHunters.add(hunter);
                mostAggressiveness = Math.max(mostAggressiveness, hunter.getAggro());
            }
        }

        canTauntSafely = myAggressiveness + 300 < mostAggressiveness;
    }

    private class Monster {

        int atk;
        int def;
        int hp;
        int targetId;
        String nextMove;

        public Monster(String string) {
            String[] args = string.split(";");
            atk = Integer.parseInt(args[0]);
            def = Integer.parseInt(args[1]);
            hp = Integer.parseInt(args[2]);
            targetId = Integer.parseInt(args[3]);
            nextMove = args[4];
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getTargetId() {
            return targetId;
        }

        public void setTargetId(int targetId) {
            this.targetId = targetId;
        }

        public String getNextMove() {
            return nextMove;
        }

        public void setNextMove(String nextMove) {
            this.nextMove = nextMove;
        }
    }

    private class Hunter {
        int hunterID;
        String weapon;
        int atk;
        int def;
        int hp;
        int energy;
        int guard;
        int speed;
        int sharpness;
        int aggro;
        int potions;
        int rations;
        int whetstones;
        String attacks;

        public Hunter(String string) {
            String[] args = string.split("_");
            hunterID = Integer.parseInt(args[0]);
            weapon = args[1];
            atk = Integer.parseInt(args[2]);
            def = Integer.parseInt(args[3]);
            hp = Integer.parseInt(args[4]);
            energy = Integer.parseInt(args[5]);
            guard = Integer.parseInt(args[6]);
            speed = Integer.parseInt(args[7]);
            sharpness = Integer.parseInt(args[8]);
            aggro = Integer.parseInt(args[9]);
            potions = Integer.parseInt(args[10]);
            rations = Integer.parseInt(args[11]);
            whetstones = Integer.parseInt(args[12]);
            attacks = args[13];
        }

        public int getHunterID() {
            return hunterID;
        }

        public void setHunterID(int hunterID) {
            this.hunterID = hunterID;
        }

        public String getWeapon() {
            return weapon;
        }

        public void setWeapon(String weapon) {
            this.weapon = weapon;
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getEnergy() {
            return energy;
        }

        public void setEnergy(int energy) {
            this.energy = energy;
        }

        public int getGuard() {
            return guard;
        }

        public void setGuard(int guard) {
            this.guard = guard;
        }

        public int getSpeed() {
            return speed;
        }

        public void setSpeed(int speed) {
            this.speed = speed;
        }

        public int getSharpness() {
            return sharpness;
        }

        public void setSharpness(int sharpness) {
            this.sharpness = sharpness;
        }

        public int getAggro() {
            return aggro;
        }

        public void setAggro(int aggro) {
            this.aggro = aggro;
        }

        public int getPotions() {
            return potions;
        }

        public void setPotions(int potions) {
            this.potions = potions;
        }

        public int getRations() {
            return rations;
        }

        public void setRations(int rations) {
            this.rations = rations;
        }

        public int getWhetstones() {
            return whetstones;
        }

        public void setWhetstones(int whetstones) {
            this.whetstones = whetstones;
        }

        public String getAttacks() {
            return attacks;
        }

        public void setAttacks(String attacks) {
            this.attacks = attacks;
        }

        public boolean isMe() {
            return getHunterID() == playerID;
        }
    }
}

```
> 8 votes

# Answer
## RedViper

Waits for the right moment to strike.

```
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class RedViper {
    private static final int ENERGY_PER_GUARD = 15;
    private static final int ENERGY_PER_HIT = 20;
    private static final String FILE_PATH = "RedViper.txt";

    int round;
    int playerID;
    Hunter me;
    List<Hunter> otherHunters = new ArrayList<>();;
    Monster monster;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("LA");
        } else {
            RedViper redViper = new RedViper(args);
            String output = redViper.hunt();
            redViper.updateDataFile();
            System.out.println(output);
        }
    }

    private void updateDataFile() {
        File f = new File(FILE_PATH);
        if (f.exists())
            f.delete();
        if(monster.nextMove.equals("F") || monster.nextMove.equals("C")) {
            try {
                f.createNewFile();
            } catch (IOException e) {}
        }
    }

    private String hunt() {
        //low hp
        if (me.hp <= monster.dmg(me, false, false)) {
            if (!monster.attacksMe()) {
                if (me.potions > 0)
                    return "P";
                else if (me.rations > 0)
                    return "R";
            } else {
                if (me.hp > monster.dmg(me, true, false) && me.energy > ENERGY_PER_GUARD)
                    return "G";
                else if (me.potions > 0)
                    return "P";
                else if (me.rations > 0 && me.hp + 30 > monster.dmg(me, false, true))
                    return "R";
                else
                    return "B";
            }
        }
        if (monster.attacksMe() && me.energy >= ENERGY_PER_GUARD)
            return "G";
        if (isSafeToTaunt() && me.energy < 80)
            return "T";
        if (!monster.attacksMe()
                && !(me.attacks.equals("BB") && me.energy >= ENERGY_PER_HIT && !monster.dodges())
                && !(me.attacks.equals("B") && me.energy >= ENERGY_PER_HIT*2)
                && round < 48) {
            if (me.sharpness < 2 && me.whetstones > 0)
                return "S";
            if (me.energy <= 50 && me.hp <= 70 && me.rations > 0)
                return "R";
        }
        if ((monster.dodges() && !(me.attacks.equals("B") && me.energy >= ENERGY_PER_HIT*2)) || me.energy < ENERGY_PER_HIT)
            return "W";

        return "B";
    }

    private boolean isSafeToTaunt() {
        int highestAggro = Integer.MIN_VALUE;
        for (Hunter hunter : otherHunters) {
            if (hunter.aggro > highestAggro)
                highestAggro = hunter.aggro;
        }
        return highestAggro > me.aggro + 300;
    }

    public RedViper(String[] args) {
        List<Hunter> allHunters = new ArrayList<>();
        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        monster = new Monster(args[2]+";"+args[3]+";"+args[4]+";"+args[5]+";"+args[6]);

        for (int i = 7; i < args.length; i++){
            allHunters.add(new Hunter(args[i]));
        }

        for (Hunter hunter : allHunters) {
            if (hunter.isMe()){
                me = hunter;
            } else {
                otherHunters.add(hunter);
            }
        }
    }

    private class Monster {

        int atk;
        int targetId;
        String nextMove;

        public Monster(String string) {
            String[] args = string.split(";");
            atk = Integer.parseInt(args[0]);
            targetId = Integer.parseInt(args[3]);
            nextMove = args[4];
        }

        public boolean attacksMe() {
            return nextMove.equals("S")
                    || (nextMove.equals("C") && targetId == playerID)
                    || (nextMove.equals("A") && targetId == playerID);
        }

        public int dmg(Hunter hunter, boolean guard, boolean using) {
            int damageMultiplicator = 10 - hunter.def;
            if (guard) { damageMultiplicator -= hunter.guard; }
            if (using) { damageMultiplicator += 2; }

            int damage = monster.atk * damageMultiplicator;
            return damage;
        }

        public boolean dodges() {
            File f = new File(FILE_PATH);
            return f.exists();
        }
    }

    private class Hunter {
        int id;
        int def;
        int hp;
        int energy;
        int guard;
        int sharpness;
        int aggro;
        int potions;
        int rations;
        int whetstones;
        String attacks;

        public Hunter(String string) {
            String[] args = string.split("_");
            id = Integer.parseInt(args[0]);
            def = Integer.parseInt(args[3]);
            hp = Integer.parseInt(args[4]);
            energy = Integer.parseInt(args[5]);
            guard = Integer.parseInt(args[6]);
            sharpness = Integer.parseInt(args[8]);
            aggro = Integer.parseInt(args[9]);
            potions = Integer.parseInt(args[10]);
            rations = Integer.parseInt(args[11]);
            whetstones = Integer.parseInt(args[12]);
            attacks = args[13];
        }

        public boolean isMe() {
            return id == playerID;
        }
    }
}

```
> 6 votes

# Answer
# Weasel Will

I'm not sure I entirely trust this guy, but his blades are nice to have around in case of trouble.

```
public class WeaselWill {
    int id, round, atk, def, hp,
        energy, guard, speed,
        sharp, aggro, potions,
        rations, whets;
    String combo;
    Monster monster;
    int[] aggros;

    void hunt(){
        if(willKillMe(false))
            dontDie();
        if(energy < 11){
            if(aggroDiff() > 300)
                output("T");
            output("W");
        }
        if(willHitMe()&&energy>29)
            output("D");
        int potDamage = attack(false);
        if(potDamage>monster.hp/2)
            attack(true);
        if(aggroDiff()*2>potDamage || round==1)
            attack(true);
        if(sharp==1&&whets>0&&!willKillMe(true))
            output("S");
        output("W");
    }

    int aggroDiff(){
        int highest = 0;
        for(int agg : aggros)
            highest = agg>highest?agg:highest;
        return highest - aggro;
    }

    int attack(boolean output){
        if(output)
            output("C");
        return willHitFor(combo.length()+1);
    }

    void dontDie(){
        if(energy>=30)
            output("D");
        int dmg = hitsMeFor(true);
        if(hp-dmg>-30 && rations>0)
            output("R");
        if(potions>0)
            output("P");
        if(energy>10)
            attack(true);
        output("W");
    }

    boolean willKillMe(boolean item){return willHitMe()&&(hitsMeFor(item)>=hp);}
    boolean willHitMe(){
        if(monster.move.equals("S"))
            return true;
        else if((monster.move.equals("A")||monster.move.equals("C"))&&monster.target==id)
            return true;
        return false;
    }

    int hitsMeFor(boolean item){
        return monster.atk*(10-def+(item?2:0));
    }

    int willHitFor(int combo){
        return atk*(10+sharp-monster.def)*combo;
    }

    static int atoi(String in){
        return Integer.parseInt(in);
    }

    void output(String out){
        System.out.println(out);
        System.exit(0);
    }

    public static void main(String[] args){
        if(args.length==0){
            System.out.println("DB");
        } else {
            new WeaselWill(args[0]).hunt();
        }
    }

    WeaselWill(String input){
        String[] tokens = input.split(";");
        round = atoi(tokens[0]);
        id = atoi(tokens[1]);
        monster = new Monster(new String[]{tokens[2],tokens[3],tokens[4],tokens[5],tokens[6]});
        aggros = new int[3];
        for(int i=7,j=0;i<tokens.length;i++){
            String[] in = tokens[i].split("_");
            if(atoi(in[0])==id){
                atk = atoi(in[2]);
                def = atoi(in[3]);
                hp = atoi(in[4]);
                energy = atoi(in[5]);
                guard = atoi(in[6]);
                speed = atoi(in[7]);
                sharp = atoi(in[8]);
                aggro = atoi(in[9]);
                potions = atoi(in[10]);
                rations = atoi(in[11]);
                whets = atoi(in[12]);
                combo = in[13];
            } else {
                aggros[j++] = atoi(in[9]);
            }
        }
    }

    class Monster{
        int atk, def, hp, target;
        String move;

        Monster(String[] in){
            atk = atoi(in[0]);
            def = atoi(in[1]);
            hp = atoi(in[2]);
            target = atoi(in[3]);
            move = in[4];
        }
    }
}

```
> 6 votes

# Answer
# The King's Jester

The monsters (especially Fatalis) have an extreme dislike for his rock throwing skills.

```
import java.util.ArrayList;
import java.util.List;

public class TheKingsJester {

    int round;
    int playerID;
    Hunter thisHunter;
    List<Hunter> hunters = new ArrayList<>();
    List<Hunter> otherHunters = new ArrayList<>();
    Monster monster;
    boolean canTauntSafely;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("HA");//Ha ha ha ha
        } else {
            System.out.println(new TheKingsJester(args).hunt());
        }
    }

    private String hunt() {

        String monstersNextMove = monster.getNextMove();
        boolean rest = false;

        switch (monstersNextMove){
            case "A":
            case "C":
            case "S":
                int mostAggresiveness = 0;
                for (Hunter hunter : otherHunters){
                    mostAggresiveness = Math.max(mostAggresiveness, hunter.getAggro());
                }
                if (thisHunter.getAggro() >= mostAggresiveness || monstersNextMove.equals("S")) {
                    if (thisHunter.getEnergy() >= 30){
                        return "D";
                    }
                } else if (thisHunter.getAggro() + 300 >= mostAggresiveness) {
                    rest = true;
                }
            default:
                if (thisHunter.getHp() <= 10 && thisHunter.getPotions() > 0){
                    return "P";
                }
                int monsterAttack = monster.getAtk() * 7;
                int difference = monsterAttack - thisHunter.getHp() + 1;
                if (difference > 0){
                    if (difference <= 30 && thisHunter.getRations() > 0){
                        return "R";
                    }
                    if (thisHunter.getPotions() > 0) {
                        return "P";
                    }
                    if (thisHunter.getRations() > 0){
                        return "R";
                    }
                }
                if (rest){
                    return "W";
                }
                return "T";
        }

    }

    public TheKingsJester(String[] args) {

        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        monster = new Monster(args[2]+";"+args[3]+";"+args[4]+";"+args[5]+";"+args[6]);

        for (int i = 7; i < args.length; i++){
            hunters.add(new Hunter(args[i]));
        }

        int mostAggressiveness = 0;
        int myAggressiveness = 0;

        for (Hunter hunter : hunters) {
            if (hunter.isMe()){
                thisHunter = hunter;
                myAggressiveness = hunter.getAggro();
            } else {
                otherHunters.add(hunter);
                mostAggressiveness = Math.max(mostAggressiveness, hunter.getAggro());
            }
        }

        canTauntSafely = myAggressiveness + 300 < mostAggressiveness;
    }

    private class Monster {

        int atk;
        int def;
        int hp;
        int targetId;
        String nextMove;

        public Monster(String string) {
            String[] args = string.split(";");
            atk = Integer.parseInt(args[0]);
            def = Integer.parseInt(args[1]);
            hp = Integer.parseInt(args[2]);
            targetId = Integer.parseInt(args[3]);
            nextMove = args[4];
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getTargetId() {
            return targetId;
        }

        public void setTargetId(int targetId) {
            this.targetId = targetId;
        }

        public String getNextMove() {
            return nextMove;
        }

        public void setNextMove(String nextMove) {
            this.nextMove = nextMove;
        }
    }

    private class Hunter {
        int hunterID;
        String weapon;
        int atk;
        int def;
        int hp;
        int energy;
        int guard;
        int speed;
        int sharpness;
        int aggro;
        int potions;
        int rations;
        int whetstones;
        String attacks;

        public Hunter(String string) {
            String[] args = string.split("_");
            hunterID = Integer.parseInt(args[0]);
            weapon = args[1];
            atk = Integer.parseInt(args[2]);
            def = Integer.parseInt(args[3]);
            hp = Integer.parseInt(args[4]);
            energy = Integer.parseInt(args[5]);
            guard = Integer.parseInt(args[6]);
            speed = Integer.parseInt(args[7]);
            sharpness = Integer.parseInt(args[8]);
            aggro = Integer.parseInt(args[9]);
            potions = Integer.parseInt(args[10]);
            rations = Integer.parseInt(args[11]);
            whetstones = Integer.parseInt(args[12]);
            attacks = args[13];
        }

        public int getHunterID() {
            return hunterID;
        }

        public void setHunterID(int hunterID) {
            this.hunterID = hunterID;
        }

        public String getWeapon() {
            return weapon;
        }

        public void setWeapon(String weapon) {
            this.weapon = weapon;
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getEnergy() {
            return energy;
        }

        public void setEnergy(int energy) {
            this.energy = energy;
        }

        public int getGuard() {
            return guard;
        }

        public void setGuard(int guard) {
            this.guard = guard;
        }

        public int getSpeed() {
            return speed;
        }

        public void setSpeed(int speed) {
            this.speed = speed;
        }

        public int getSharpness() {
            return sharpness;
        }

        public void setSharpness(int sharpness) {
            this.sharpness = sharpness;
        }

        public int getAggro() {
            return aggro;
        }

        public void setAggro(int aggro) {
            this.aggro = aggro;
        }

        public int getPotions() {
            return potions;
        }

        public void setPotions(int potions) {
            this.potions = potions;
        }

        public int getRations() {
            return rations;
        }

        public void setRations(int rations) {
            this.rations = rations;
        }

        public int getWhetstones() {
            return whetstones;
        }

        public void setWhetstones(int whetstones) {
            this.whetstones = whetstones;
        }

        public String getAttacks() {
            return attacks;
        }

        public void setAttacks(String attacks) {
            this.attacks = attacks;
        }

        public boolean isMe() {
            return getHunterID() == playerID;
        }
    }
}

```
> 6 votes

# Answer
# Java, Felyne (helper)

One of the 4 example bots. This one wields a Lance.

```
import java.util.ArrayList;
import java.util.List;

public class Felyne {

    private static final int ENERGY_PER_DODGE = 30;
    private static final int ENERGY_PER_GUARD = 15;
    private static final int ENERGY_PER_WAIT = 30;
    private static final int ENERGY_PER_TAUNT = 80;
    private static final int AGGRO_PER_TAUNT = 300;

    int round;
    int playerID;
    Hunter thisHunter;
    List<Hunter> hunters = new ArrayList<>();;
    List<Hunter> otherHunters = new ArrayList<>();;
    Monster monster;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("LA");
        } else {
            System.out.println(new Felyne(args).hunt());
        }
    }

    private String hunt() {

        if (thisHunter.getHp() <= (monster.getAtk() * 5)) {
            if (thisHunter.getPotions() > 0)
                return "P";
            else if (thisHunter.getRations() > 0)
                return "R";
            else if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (monster.getTargetId() == playerID) {
            if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (thisHunter.getSharpness() < 2) {
            if (thisHunter.getWhetstones() > 0)
                return "S";
            else
                return attack();
        } else {
            return attack();
        }
    }

    private String attack() {

        int energyPerHit = Math.floorDiv(100, thisHunter.getSpeed() + 2);

        // Lance Combos : AAA, AAAC, BBB
        if (thisHunter.getEnergy() >= (energyPerHit * 4) && thisHunter.getAttacks().equals("N"))
            return "A";
        else if (thisHunter.getEnergy() <= (energyPerHit * 4) && thisHunter.getAttacks().equals("N"))
            if (100 - thisHunter.getAggro() <= ENERGY_PER_TAUNT && thisHunter.getAggro() < (otherHunters.stream().max((x, y) -> x.getAggro() - y.getAggro()).get().getAggro() + AGGRO_PER_TAUNT + 1))
                return "T";
            else
                return "W";
        else if (thisHunter.getEnergy() >= (energyPerHit * 3) && thisHunter.getAttacks().equals("A"))
            return "A";
        else if (thisHunter.getEnergy() >= (energyPerHit * 2) && thisHunter.getAttacks().equals("AA"))
            return "A";
        else if (thisHunter.getEnergy() >= (energyPerHit * 1) && thisHunter.getAttacks().equals("AAA"))
            return "C";
        else
            return "W";
    }

    public Felyne(String[] args) {

        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        monster = new Monster(args[2]+";"+args[3]+";"+args[4]+";"+args[5]+";"+args[6]);

        for (int i = 7; i < args.length; i++){
            hunters.add(new Hunter(args[i]));
        }

        for (Hunter hunter : hunters) {
            if (hunter.isMe()){
                thisHunter = hunter;
            } else {
                otherHunters.add(hunter);
            }
        }
    }

    private class Monster {

        int atk;
        int def;
        int hp;
        int targetId;
        String nextMove;

        public Monster(String string) {
            String[] args = string.split(";");
            atk = Integer.parseInt(args[0]);
            def = Integer.parseInt(args[1]);
            hp = Integer.parseInt(args[2]);
            targetId = Integer.parseInt(args[3]);
            nextMove = args[4];
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getTargetId() {
            return targetId;
        }

        public void setTargetId(int targetId) {
            this.targetId = targetId;
        }

        public String getNextMove() {
            return nextMove;
        }

        public void setNextMove(String nextMove) {
            this.nextMove = nextMove;
        }
    }

    private class Hunter {
        int hunterID;
        String weapon;
        int atk;
        int def;
        int hp;
        int energy;
        int guard;
        int speed;
        int sharpness;
        int aggro;
        int potions;
        int rations;
        int whetstones;
        String attacks;

        public Hunter(String string) {
            String[] args = string.split("_");
            hunterID = Integer.parseInt(args[0]);
            weapon = args[1];
            atk = Integer.parseInt(args[2]);
            def = Integer.parseInt(args[3]);
            hp = Integer.parseInt(args[4]);
            energy = Integer.parseInt(args[5]);
            guard = Integer.parseInt(args[6]);
            speed = Integer.parseInt(args[7]);
            sharpness = Integer.parseInt(args[8]);
            aggro = Integer.parseInt(args[9]);
            potions = Integer.parseInt(args[10]);
            rations = Integer.parseInt(args[11]);
            whetstones = Integer.parseInt(args[12]);
            attacks = args[13];
        }

        public int getHunterID() {
            return hunterID;
        }

        public void setHunterID(int hunterID) {
            this.hunterID = hunterID;
        }

        public String getWeapon() {
            return weapon;
        }

        public void setWeapon(String weapon) {
            this.weapon = weapon;
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getEnergy() {
            return energy;
        }

        public void setEnergy(int energy) {
            this.energy = energy;
        }

        public int getGuard() {
            return guard;
        }

        public void setGuard(int guard) {
            this.guard = guard;
        }

        public int getSpeed() {
            return speed;
        }

        public void setSpeed(int speed) {
            this.speed = speed;
        }

        public int getSharpness() {
            return sharpness;
        }

        public void setSharpness(int sharpness) {
            this.sharpness = sharpness;
        }

        public int getAggro() {
            return aggro;
        }

        public void setAggro(int aggro) {
            this.aggro = aggro;
        }

        public int getPotions() {
            return potions;
        }

        public void setPotions(int potions) {
            this.potions = potions;
        }

        public int getRations() {
            return rations;
        }

        public void setRations(int rations) {
            this.rations = rations;
        }

        public int getWhetstones() {
            return whetstones;
        }

        public void setWhetstones(int whetstones) {
            this.whetstones = whetstones;
        }

        public String getAttacks() {
            return attacks;
        }

        public void setAttacks(String attacks) {
            this.attacks = attacks;
        }

        public boolean isMe() {
            return getHunterID() == playerID;
        }
    }
}

```
> 5 votes

# Answer
# Java, Koneko (helper)

One one of the 4 example bot. This one wields Dual Blades

```
import java.util.ArrayList;
import java.util.List;

public class Koneko {

    private static final int ENERGY_PER_DODGE = 30;
    private static final int ENERGY_PER_GUARD = 15;
    private static final int ENERGY_PER_WAIT = 30;
    private static final int ENERGY_PER_TAUNT = 80;
    private static final int AGGRO_PER_TAUNT = 300;

    int round;
    int playerID;
    Hunter thisHunter;
    List<Hunter> hunters = new ArrayList<>();;
    List<Hunter> otherHunters = new ArrayList<>();;
    Monster monster;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("DB");
        } else {
            System.out.println(new Koneko(args).hunt());
        }
    }

    private String hunt() {

        if (thisHunter.getHp() <= (monster.getAtk() * 5)) {
            if (thisHunter.getPotions() > 0)
                return "P";
            else if (thisHunter.getRations() > 0)
                return "R";
            else if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (monster.getTargetId() == playerID) {
            if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (thisHunter.getSharpness() < 2) {
            if (thisHunter.getWhetstones() > 0)
                return "S";
            else
                return attack();
        } else {
            return attack();
        }
    }

    private String attack() {

        int energyPerHit = Math.floorDiv(100, thisHunter.getSpeed() + 2);

        // Dual Blade Combos : CC, ABAB, ABABA, ABABAC
        if (thisHunter.getEnergy() >= (energyPerHit * 6) && thisHunter.getAttacks().equals("N"))
            return "A";
        else if (thisHunter.getEnergy() <= (energyPerHit * 6) && thisHunter.getAttacks().equals("N"))
            if (100 - thisHunter.getAggro() <= ENERGY_PER_TAUNT && thisHunter.getAggro() < (otherHunters.stream().max((x, y) -> x.getAggro() - y.getAggro()).get().getAggro() + AGGRO_PER_TAUNT + 1))
                return "T";
            else
                return "W";
        else if (thisHunter.getEnergy() >= (energyPerHit * 5) && thisHunter.getAttacks().equals("A"))
            return "B";
        else if (thisHunter.getEnergy() >= (energyPerHit * 4) && thisHunter.getAttacks().equals("AB"))
            return "A";
        else if (thisHunter.getEnergy() >= (energyPerHit * 3) && thisHunter.getAttacks().equals("ABA"))
            return "B";
        else if (thisHunter.getEnergy() >= (energyPerHit * 2) && thisHunter.getAttacks().equals("ABAB"))
            return "A";
        else if (thisHunter.getEnergy() >= (energyPerHit * 1) && thisHunter.getAttacks().equals("ABABA"))
            return "C";
        else
            return "W";
    }

    public Koneko(String[] args) {

        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        monster = new Monster(args[2]+";"+args[3]+";"+args[4]+";"+args[5]+";"+args[6]);

        for (int i = 7; i < args.length; i++){
            hunters.add(new Hunter(args[i]));
        }

        for (Hunter hunter : hunters) {
            if (hunter.isMe()){
                thisHunter = hunter;
            } else {
                otherHunters.add(hunter);
            }
        }
    }

    private class Monster {

        int atk;
        int def;
        int hp;
        int targetId;
        String nextMove;

        public Monster(String string) {
            String[] args = string.split(";");
            atk = Integer.parseInt(args[0]);
            def = Integer.parseInt(args[1]);
            hp = Integer.parseInt(args[2]);
            targetId = Integer.parseInt(args[3]);
            nextMove = args[4];
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getTargetId() {
            return targetId;
        }

        public void setTargetId(int targetId) {
            this.targetId = targetId;
        }

        public String getNextMove() {
            return nextMove;
        }

        public void setNextMove(String nextMove) {
            this.nextMove = nextMove;
        }
    }

    private class Hunter {
        int hunterID;
        String weapon;
        int atk;
        int def;
        int hp;
        int energy;
        int guard;
        int speed;
        int sharpness;
        int aggro;
        int potions;
        int rations;
        int whetstones;
        String attacks;

        public Hunter(String string) {
            String[] args = string.split("_");
            hunterID = Integer.parseInt(args[0]);
            weapon = args[1];
            atk = Integer.parseInt(args[2]);
            def = Integer.parseInt(args[3]);
            hp = Integer.parseInt(args[4]);
            energy = Integer.parseInt(args[5]);
            guard = Integer.parseInt(args[6]);
            speed = Integer.parseInt(args[7]);
            sharpness = Integer.parseInt(args[8]);
            aggro = Integer.parseInt(args[9]);
            potions = Integer.parseInt(args[10]);
            rations = Integer.parseInt(args[11]);
            whetstones = Integer.parseInt(args[12]);
            attacks = args[13];
        }

        public int getHunterID() {
            return hunterID;
        }

        public void setHunterID(int hunterID) {
            this.hunterID = hunterID;
        }

        public String getWeapon() {
            return weapon;
        }

        public void setWeapon(String weapon) {
            this.weapon = weapon;
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getEnergy() {
            return energy;
        }

        public void setEnergy(int energy) {
            this.energy = energy;
        }

        public int getGuard() {
            return guard;
        }

        public void setGuard(int guard) {
            this.guard = guard;
        }

        public int getSpeed() {
            return speed;
        }

        public void setSpeed(int speed) {
            this.speed = speed;
        }

        public int getSharpness() {
            return sharpness;
        }

        public void setSharpness(int sharpness) {
            this.sharpness = sharpness;
        }

        public int getAggro() {
            return aggro;
        }

        public void setAggro(int aggro) {
            this.aggro = aggro;
        }

        public int getPotions() {
            return potions;
        }

        public void setPotions(int potions) {
            this.potions = potions;
        }

        public int getRations() {
            return rations;
        }

        public void setRations(int rations) {
            this.rations = rations;
        }

        public int getWhetstones() {
            return whetstones;
        }

        public void setWhetstones(int whetstones) {
            this.whetstones = whetstones;
        }

        public String getAttacks() {
            return attacks;
        }

        public void setAttacks(String attacks) {
            this.attacks = attacks;
        }

        public boolean isMe() {
            return getHunterID() == playerID;
        }
    }
}

```
> 3 votes

# Answer
# Java, Palico (helper)

One of the 4 example bots. This one wields a Hammer.

```
import java.util.ArrayList;
import java.util.List;

public class Palico {

    private static final int ENERGY_PER_DODGE = 30;
    private static final int ENERGY_PER_GUARD = 15;
    private static final int ENERGY_PER_WAIT = 30;
    private static final int ENERGY_PER_TAUNT = 80;
    private static final int AGGRO_PER_TAUNT = 300;

    int round;
    int playerID;
    Hunter thisHunter;
    List<Hunter> hunters = new ArrayList<>();;
    List<Hunter> otherHunters = new ArrayList<>();;
    Monster monster;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("HA");
        } else {
            System.out.println(new Palico(args).hunt());
        }
    }

    private String hunt() {

        if (thisHunter.getHp() <= (monster.getAtk() * 5)) {
            if (thisHunter.getPotions() > 0)
                return "P";
            else if (thisHunter.getRations() > 0)
                return "R";
            else if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (monster.getTargetId() == playerID) {
            if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (thisHunter.getSharpness() < 2) {
            if (thisHunter.getWhetstones() > 0)
                return "S";
            else
                return attack();
        } else {
            return attack();
        }
    }

    private String attack() {

        int energyPerHit = Math.floorDiv(100, thisHunter.getSpeed() + 2);

        // Hammer Combos : CCA, BBA
        if (thisHunter.getEnergy() >= (energyPerHit * 3) && thisHunter.getAttacks().equals("N"))
            return "C";
        else if (thisHunter.getEnergy() <= (energyPerHit * 3) && thisHunter.getAttacks().equals("N"))
            if (100 - thisHunter.getAggro() <= ENERGY_PER_TAUNT && thisHunter.getAggro() < (otherHunters.stream().max((x, y) -> x.getAggro() - y.getAggro()).get().getAggro() + AGGRO_PER_TAUNT + 1))
                return "T";
            else
                return "W";
        else if (thisHunter.getEnergy() >= (energyPerHit * 3) && thisHunter.getAttacks().equals("C"))
            return "C";
        else if (thisHunter.getEnergy() >= (energyPerHit * 2) && thisHunter.getAttacks().equals("CC"))
            return "A";
        else
            return "W";
    }

    public Palico(String[] args) {

        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        monster = new Monster(args[2]+";"+args[3]+";"+args[4]+";"+args[5]+";"+args[6]);

        for (int i = 7; i < args.length; i++){
            hunters.add(new Hunter(args[i]));
        }

        for (Hunter hunter : hunters) {
            if (hunter.isMe()){
                thisHunter = hunter;
            } else {
                otherHunters.add(hunter);
            }
        }
    }

    private class Monster {

        int atk;
        int def;
        int hp;
        int targetId;
        String nextMove;

        public Monster(String string) {
            String[] args = string.split(";");
            atk = Integer.parseInt(args[0]);
            def = Integer.parseInt(args[1]);
            hp = Integer.parseInt(args[2]);
            targetId = Integer.parseInt(args[3]);
            nextMove = args[4];
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getTargetId() {
            return targetId;
        }

        public void setTargetId(int targetId) {
            this.targetId = targetId;
        }

        public String getNextMove() {
            return nextMove;
        }

        public void setNextMove(String nextMove) {
            this.nextMove = nextMove;
        }
    }

    private class Hunter {
        int hunterID;
        String weapon;
        int atk;
        int def;
        int hp;
        int energy;
        int guard;
        int speed;
        int sharpness;
        int aggro;
        int potions;
        int rations;
        int whetstones;
        String attacks;

        public Hunter(String string) {
            String[] args = string.split("_");
            hunterID = Integer.parseInt(args[0]);
            weapon = args[1];
            atk = Integer.parseInt(args[2]);
            def = Integer.parseInt(args[3]);
            hp = Integer.parseInt(args[4]);
            energy = Integer.parseInt(args[5]);
            guard = Integer.parseInt(args[6]);
            speed = Integer.parseInt(args[7]);
            sharpness = Integer.parseInt(args[8]);
            aggro = Integer.parseInt(args[9]);
            potions = Integer.parseInt(args[10]);
            rations = Integer.parseInt(args[11]);
            whetstones = Integer.parseInt(args[12]);
            attacks = args[13];
        }

        public int getHunterID() {
            return hunterID;
        }

        public void setHunterID(int hunterID) {
            this.hunterID = hunterID;
        }

        public String getWeapon() {
            return weapon;
        }

        public void setWeapon(String weapon) {
            this.weapon = weapon;
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getEnergy() {
            return energy;
        }

        public void setEnergy(int energy) {
            this.energy = energy;
        }

        public int getGuard() {
            return guard;
        }

        public void setGuard(int guard) {
            this.guard = guard;
        }

        public int getSpeed() {
            return speed;
        }

        public void setSpeed(int speed) {
            this.speed = speed;
        }

        public int getSharpness() {
            return sharpness;
        }

        public void setSharpness(int sharpness) {
            this.sharpness = sharpness;
        }

        public int getAggro() {
            return aggro;
        }

        public void setAggro(int aggro) {
            this.aggro = aggro;
        }

        public int getPotions() {
            return potions;
        }

        public void setPotions(int potions) {
            this.potions = potions;
        }

        public int getRations() {
            return rations;
        }

        public void setRations(int rations) {
            this.rations = rations;
        }

        public int getWhetstones() {
            return whetstones;
        }

        public void setWhetstones(int whetstones) {
            this.whetstones = whetstones;
        }

        public String getAttacks() {
            return attacks;
        }

        public void setAttacks(String attacks) {
            this.attacks = attacks;
        }

        public boolean isMe() {
            return getHunterID() == playerID;
        }
    }
}

```
> 3 votes

# Answer
# Java, Melynx (helper)

One of the 4 example bots. This one wields a Great Sword.

```
import java.util.ArrayList;
import java.util.List;

public class Melynx {

    private static final int ENERGY_PER_DODGE = 30;
    private static final int ENERGY_PER_GUARD = 15;
    private static final int ENERGY_PER_WAIT = 30;
    private static final int ENERGY_PER_TAUNT = 80;
    private static final int AGGRO_PER_TAUNT = 300;

    int round;
    int playerID;
    Hunter thisHunter;
    List<Hunter> hunters = new ArrayList<>();;
    List<Hunter> otherHunters = new ArrayList<>();;
    Monster monster;

    public static void main(String[] args){
        if (args.length == 0) {
            System.out.println("GS");
        } else {
            System.out.println(new Melynx(args).hunt());
        }
    }

    private String hunt() {

        if (thisHunter.getHp() <= (monster.getAtk() * 5)) {
            if (thisHunter.getPotions() > 0)
                return "P";
            else if (thisHunter.getRations() > 0)
                return "R";
            else if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (monster.getTargetId() == playerID) {
            if (thisHunter.getEnergy() > ENERGY_PER_GUARD)
                return "G";
            else
                return attack();
        } else if (thisHunter.getSharpness() < 2) {
            if (thisHunter.getWhetstones() > 0)
                return "S";
            else
                return attack();
        } else {
            return attack();
        }
    }

    private String attack() {

        int energyPerHit = Math.floorDiv(100, thisHunter.getSpeed() + 2);

        // Great Sword Combos : BBA, BBBC
        if (thisHunter.getEnergy() >= (energyPerHit * 4) && thisHunter.getAttacks().equals("N"))
            return "B";
        else if (thisHunter.getEnergy() <= (energyPerHit * 4) && thisHunter.getAttacks().equals("N"))
            if (100 - thisHunter.getAggro() <= ENERGY_PER_TAUNT && thisHunter.getAggro() < (otherHunters.stream().max((x, y) -> x.getAggro() - y.getAggro()).get().getAggro() + AGGRO_PER_TAUNT + 1))
                return "T";
            else
                return "W";
        else if (thisHunter.getEnergy() >= (energyPerHit * 3) && thisHunter.getAttacks().equals("B"))
            return "B";
        else if (thisHunter.getEnergy() >= (energyPerHit * 2) && thisHunter.getAttacks().equals("BB"))
            return "B";
        else if (thisHunter.getEnergy() >= (energyPerHit * 1) && thisHunter.getAttacks().equals("BBB"))
            return "C";
        else
            return "W";
    }

    public Melynx(String[] args) {

        args = args[0].split(";");

        round = Integer.parseInt(args[0]);
        playerID = Integer.parseInt(args[1]);
        monster = new Monster(args[2]+";"+args[3]+";"+args[4]+";"+args[5]+";"+args[6]);

        for (int i = 7; i < args.length; i++){
            hunters.add(new Hunter(args[i]));
        }

        for (Hunter hunter : hunters) {
            if (hunter.isMe()){
                thisHunter = hunter;
            } else {
                otherHunters.add(hunter);
            }
        }
    }

    private class Monster {

        int atk;
        int def;
        int hp;
        int targetId;
        String nextMove;

        public Monster(String string) {
            String[] args = string.split(";");
            atk = Integer.parseInt(args[0]);
            def = Integer.parseInt(args[1]);
            hp = Integer.parseInt(args[2]);
            targetId = Integer.parseInt(args[3]);
            nextMove = args[4];
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getTargetId() {
            return targetId;
        }

        public void setTargetId(int targetId) {
            this.targetId = targetId;
        }

        public String getNextMove() {
            return nextMove;
        }

        public void setNextMove(String nextMove) {
            this.nextMove = nextMove;
        }
    }

    private class Hunter {
        int hunterID;
        String weapon;
        int atk;
        int def;
        int hp;
        int energy;
        int guard;
        int speed;
        int sharpness;
        int aggro;
        int potions;
        int rations;
        int whetstones;
        String attacks;

        public Hunter(String string) {
            String[] args = string.split("_");
            hunterID = Integer.parseInt(args[0]);
            weapon = args[1];
            atk = Integer.parseInt(args[2]);
            def = Integer.parseInt(args[3]);
            hp = Integer.parseInt(args[4]);
            energy = Integer.parseInt(args[5]);
            guard = Integer.parseInt(args[6]);
            speed = Integer.parseInt(args[7]);
            sharpness = Integer.parseInt(args[8]);
            aggro = Integer.parseInt(args[9]);
            potions = Integer.parseInt(args[10]);
            rations = Integer.parseInt(args[11]);
            whetstones = Integer.parseInt(args[12]);
            attacks = args[13];
        }

        public int getHunterID() {
            return hunterID;
        }

        public void setHunterID(int hunterID) {
            this.hunterID = hunterID;
        }

        public String getWeapon() {
            return weapon;
        }

        public void setWeapon(String weapon) {
            this.weapon = weapon;
        }

        public int getAtk() {
            return atk;
        }

        public void setAtk(int atk) {
            this.atk = atk;
        }

        public int getDef() {
            return def;
        }

        public void setDef(int def) {
            this.def = def;
        }

        public int getHp() {
            return hp;
        }

        public void setHp(int hp) {
            this.hp = hp;
        }

        public int getEnergy() {
            return energy;
        }

        public void setEnergy(int energy) {
            this.energy = energy;
        }

        public int getGuard() {
            return guard;
        }

        public void setGuard(int guard) {
            this.guard = guard;
        }

        public int getSpeed() {
            return speed;
        }

        public void setSpeed(int speed) {
            this.speed = speed;
        }

        public int getSharpness() {
            return sharpness;
        }

        public void setSharpness(int sharpness) {
            this.sharpness = sharpness;
        }

        public int getAggro() {
            return aggro;
        }

        public void setAggro(int aggro) {
            this.aggro = aggro;
        }

        public int getPotions() {
            return potions;
        }

        public void setPotions(int potions) {
            this.potions = potions;
        }

        public int getRations() {
            return rations;
        }

        public void setRations(int rations) {
            this.rations = rations;
        }

        public int getWhetstones() {
            return whetstones;
        }

        public void setWhetstones(int whetstones) {
            this.whetstones = whetstones;
        }

        public String getAttacks() {
            return attacks;
        }

        public void setAttacks(String attacks) {
            this.attacks = attacks;
        }

        public boolean isMe() {
            return getHunterID() == playerID;
        }
    }
}

```
> 3 votes

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


title: Paeth-transform arrays

text:
# Question
Title: Paeth-transform arrays
One of the key parts of PNG's compression algorithm is the *Paeth transformation,* which transforms the image in a way that makes it compress better (usually). In this challenge, your task is to write a program to compute a Paeth transformation. The operation of a Paeth transformation is described below.

## The Paeth Transformation

The Paeth transformation subtracts from each member `X` of a 2-dimensional array a predictor. The predictor is that element of the array member to the left (`A`), top (`B`), and top-left (`C`) of `X` whose value has the least difference to `A + B - C`.

```
┼─┼─┼
│C│B│
┼─┼─┼
│A│X│
┼─┼─┼

```

If one of `A`, `B`, or `C`, would be out of bounds, its value is replaced by 0. Here is pseudocode from the PNG specification outlining how this predictor is computed:

```
function PaethPredictor (a, b, c)
begin
     ; a = left, b = above, c = upper left
     p := a + b - c        ; initial estimate
     pa := abs(p - a)      ; distances to a, b, c
     pb := abs(p - b)
     pc := abs(p - c)
     ; return nearest of a,b,c,
     ; breaking ties in order a,b,c.
     if pa <= pb AND pa <= pc then return a
     else if pb <= pc then return b
     else return c
end

```

For this challenge, the array members are natural numbers in the range from 0 to 255. If the Paeth transformation results in a value outside of that range, it shall be reduced modulo 256 to a value in that range.

## Input and Output

The input is two integers *x* and *y* in the range from 2 to 1023 denoting width and height of the matrix to transform and an array of *x* × *y* elements. The input is formatted as decimal numbers separated by one blank character terminated with a linefeed. Here is what this input could look like:

```
2 3 4 5 6 7 8 9

```

This would represent a 2 by 3 matrix with the entries:

```
4 5
6 7
8 9

```

The output shall have the same format as the input with the relaxiation that the numbers may be separated by an arbitrary non-zero amount of whitespace characters (space, horizontal or vertical tab, line or form feed) and be terminated by an arbitrary amount of whitespace characters.

Input shall be received from `stdin`, output shall go to `stdout`. If this is not possible, choose a different way of receiving input and writing output that is not hard-coding the input.

The behaviour of your program when presented with invalid input is not part of this challenge.

## Judging and Reference Implementation

An ANSI C program is provided to generate sample input, solve instances and verify solutions. Call the program with `g` to **g**enerate input, with `s` to **s**olve an input instance and with `v` to **v**erify the correctness of a solution.

If you think the reference implementation is faulty, please let me know so I can correct it as soon as possible.

## Example input and output

By popular request.

```
10 5 166 156 108 96 63 227 122 99 117 135 125 46 169 247 116 55 151 1 232 114 214 254 6 127 217 88 206 102 252 237 75 250 202 145 86 198 172 84 68 114 58 228 66 224 186 217 210 108 11 179

```

representing the array

```
166 156 108  96  63 227 122  99 117 135
125  46 169 247 116  55 151   1 232 114
214 254   6 127 217  88 206 102 252 237
 75 250 202 145  86 198 172  84  68 114
 58 228  66 224 186 217 210 108  11 179

```

is transformed into

```
166 246 208 244 223 164 151 233  18  18
215 177 123  78 125  84  96 135 231 138
 89 129   8 121 101 228  55 101  20 123
117 175 196 199 125 112 222 238  72  46
239 234 120 158  41  19  12  24 183 111

```

which is encoded as

```
10 5 166 246 208 244 223 164 151 233 18 18 215 177 123 78 125 84 96 135 231 138 89 129 8 121 101 228 55 101 20 123 117 175 196 199 125 112 222 238 72 46 239 234 120 158 41 19 12 24 183 111

```

## Winning Condition

For this challenge, write a *program* that generates correct Paeth transformation of the input and writes them out. This is *code-golf,* the program with the least amount of characters in its source code wins. Please try to attach an explanation and a readable version of your code to your submission so others can see what it does.

# Answer
> 4 votes
# J - 77 char

Taking an approach that looks different from FUZxxl's answer but is actually very similar.

```
1!:2&4":2({.,|.@{.,@(256|$-0(0{[/:+`-/|@-])"1@|:(-#:1 2 3)|.!.0$)}.)0".1!:1]3

```

Some comments on the interesting bits.

* `1!:2&4":` (...) `0".1!:1]3` \- If J wasn't terrible about I/O and parsing, this could be refactored as to use `&.".&.stdin''`, to save 3 chars. But it is so we can't. Rest in peace, precious characters.
* `2 ({.,|.@{.,@( ... stuff using $ ... )}.)` \- This disassembles the input and reassembles the output. We use `$` both as a reference to the input in `stuff using $`, and as an operation we need to perform on the input before running the `stuff` on it.
* `0( blah )"1@|:` \- Yes, that's a dyadic Transpose: we regroup the three rotation results as the innermost array axis, so that the Paeth logic can apply on each set separately with `"1`.
* `0{[/:+`-/|@-]` \- The Paeth logic: sort `a,b,c` by the magnitudes of (`p` minus each of `a,b,c`), and take the first.

# Answer
> 2 votes
## J, ~~97~~ ~~91~~ ~~88~~ 87 characters

Let's get this started. Notice the absent `exit`; J prints a prompt (three blanks) after all the output has been written, but then gets an EOF on `stdin`, causing it to terminate.

I believe that quite a couple of improvements are possible in this code.

```
1!:2&4":(|.@$,,)256|((-+`-/+[:(>&|{,)"0/]-"2+`-/)(3 2$-*i.3)|.!.0])2(|.@{.$}.)0".1!:1]3

```

Here is the code before golfing it; it's mostly equal to the current code.

```
NB. A, B, and C values
abc =: (0 _1 , _1 0 ,: _1 _1)&(|.!.0)
p =: +`-/@abc
NB. minimum of magnitudes
mmin =: (>&| { ,)"0
pred =: p + [: mmin/ abc -"2 2 p
paeth =: 256 | ] - pred
input =: [: (2&}. $~ 2 |.@{. ]) 0 ". 1!:1
output =: [: 1!:2&4 LF ,~ [: ": |.@$ , ,
output paeth input 3
exit 0

```

---
Tags: code-golf, array
---


# Question
Title: Fastest way to compute order of magnitude in x86 assembly
The task is simple: write assembly that computes the order of magnitude of an integer using as few clock cycles as possible.

* Order of magnitude is defined as `log10`, not `log2`.
* The range of valid input is `0` to `10<sup>12</sup>`, inclusive. Behaviour for input outside that range is undefined.
* Values should be rounded down to the nearest integer, with the exception that given input `0` the output should be `0`. (You can consider this to be the best representation of negative infinity that's possible in unsigned integers).
* Must be x86 assembly.
* The integer must be a *runtime* value, not a static/inline integer. So we don't know what it is at compile time.
* Assume that you have an integer loaded into a register already. (But include setting the value in the register in the answer for clarity).
* Can't call any external libraries or functions.
* Free to use any of the available instructions in the Intel docs.
* No C.
* Any of the ~7 Intel Core architectures are acceptable (listed on page 10). Ideally Nehalem (Intel Core i7).

The winning answer is one that uses the fewest clock cycles possible. That is, it can have the most operations per second. Approximate clock cycle summaries are here: http://www.agner.org/optimize/instruction\_tables.pdf. Calculating clock cycles can happen after the answer is posted.

# Answer
> 9 votes
### 7 cycles, *constant time*

Here's a solution based on my answer to this SO Question. It uses BSR to count how many bits are needed to hold the number. It looks up how many decimal digits needed to represent the largest number that many bits can hold. Then it subtracts 1 if the actual number is less than the nearest power of 10 with that many digits.

```
    .intel_syntax noprefix
    .globl  main
main:
    mov rdi, 1000000000000              #;your value here
    bsr rax, rdi
    movzx   eax, BYTE PTR maxdigits[1+rax]
    cmp rdi, QWORD PTR powers[0+eax*8]
    sbb al, 0
    ret
maxdigits:
    .byte   0
    .byte   0
    .byte   0
    .byte   0
    .byte   1
    .byte   1
    .byte   1
    .byte   2
    .byte   2
    .byte   2
    .byte   3
    .byte   3
    .byte   3
    .byte   3
    .byte   4
    .byte   4
    .byte   4
    .byte   5
    .byte   5
    .byte   5
    .byte   6
    .byte   6
    .byte   6
    .byte   6
    .byte   7
    .byte   7
    .byte   7
    .byte   8
    .byte   8
    .byte   8
    .byte   9
    .byte   9
    .byte   9
    .byte   9
    .byte   10
    .byte   10
    .byte   10
    .byte   11
    .byte   11
    .byte   11
    .byte   12
powers:
    .quad   0
    .quad   10
    .quad   100
    .quad   1000
    .quad   10000
    .quad   100000
    .quad   1000000
    .quad   10000000
    .quad   100000000
    .quad   1000000000
    .quad   10000000000
    .quad   100000000000
    .quad   1000000000000

```

Compiles on GCC 4.6.3 for ubuntu and returns the value in the exit code.

I'm not confident interpreting that cycles table for any modern processor, but using @DigitalTrauma's method, on the Nehalim processor, I get **7**?

```
ins        uOps Latency
---        -    -
BSR r,r  : 1    3
MOVZX r,m: 1    -
CMP m,r/i: 1    1
SBB r,r/i: 2    2

```

# Answer
> 6 votes
# Best case 8 cycles, Worst case 12 cycles

Since it is not clear in the question, I am basing this off the Ivy Bridge latencies.

The approach here is to use the `bsr` (bit scan reverse) instruction as a poor-man's log2(). The result is used as an index into a jump table which contains entries for bits 0 to 42. I am assuming that given that operation on 64bit data is implicitly required, then use of the `bsr` instruction is OK.

In the best case inputs, the jumptable entry can map the `bsr` result directly to the magnitude. e.g. For inputs in the range 32-63, the `bsr` result will be 5, which is mapped to a magnitude of 1. In this case, the instruction path is:

```
Instruction    Latency

bsrq                 3
jmp                  2
movl                 1
jmp                  2

total                8

```

In the worst case inputs, the `bsr` result will map to two possible magnitudes, so the jumptable entry does one additional `cmp` to check if the input is \> 10n. E.g. for inputs in the range 64-127, the `bsr` result will be 6. The corresponding jumptable entry then checks if the input \> 100 and sets the output magnitude accordingly.

In addition for the worst case path, we have an additional mov instruction to load a 64bit immediate value for use in the `cmp`, so the worst case instruction path is:

```
Instruction    Latency

bsrq                 3
jmp                  2
movabsq              1
cmpq                 1
ja                   2
movl                 1
jmp                  2

total               12

```

Here is the code:

```
    /* Input is loaded in %rdi */
    bsrq    %rdi, %rax
    jmp *jumptable(,%rax,8)
.m0:
    movl    $0, %ecx
    jmp .end
.m0_1:
    cmpq    $9, %rdi
    ja  .m1
    movl    $0, %ecx
    jmp .end
.m1:
    movl    $1, %ecx
    jmp .end
.m1_2:
    cmpq    $99, %rdi
    ja  .m2
    movl    $1, %ecx
    jmp .end
.m2:
    movl    $2, %ecx
    jmp .end
.m2_3:
    cmpq    $999, %rdi
    ja  .m3
    movl    $2, %ecx
    jmp .end
.m3:
    movl    $3, %ecx
    jmp .end
.m3_4:
    cmpq    $9999, %rdi
    ja  .m4
    movl    $3, %ecx
    jmp .end
.m4:
    movl    $4, %ecx
    jmp .end
.m4_5:
    cmpq    $99999, %rdi
    ja  .m5
    movl    $4, %ecx
    jmp .end
.m5:
    movl    $5, %ecx
    jmp .end
.m5_6:
    cmpq    $999999, %rdi
    ja  .m6
    movl    $5, %ecx
    jmp .end
.m6:
    movl    $6, %ecx
    jmp .end
.m6_7:
    cmpq    $9999999, %rdi
    ja  .m7
    movl    $6, %ecx
    jmp .end
.m7:
    movl    $7, %ecx
    jmp .end
.m7_8:
    cmpq    $99999999, %rdi
    ja  .m8
    movl    $7, %ecx
    jmp .end
.m8:
    movl    $8, %ecx
    jmp .end
.m8_9:
    cmpq    $999999999, %rdi
    ja  .m9
    movl    $8, %ecx
    jmp .end
.m9:
    movl    $9, %ecx
    jmp .end
.m9_10:
    movabsq $9999999999, %rax
    cmpq    %rax, %rdi
    ja  .m10
    movl    $9, %ecx
    jmp .end
.m10:
    movl    $10, %ecx
    jmp .end
.m10_11:
    movabsq $99999999999, %rax
    cmpq    %rax, %rdi
    ja  .m11
    movl    $10, %ecx
    jmp .end
.m11:
    movl    $11, %ecx
    jmp .end
.m11_12:
    movabsq $999999999999, %rax
    cmpq    %rax, %rdi
    ja  .m12
    movl    $11, %ecx
    jmp .end
.m12:
    movl    $12, %ecx
    jmp .end

jumptable:
    .quad   .m0
    .quad   .m0
    .quad   .m0
    .quad   .m0_1
    .quad   .m1
    .quad   .m1
    .quad   .m1_2
    .quad   .m2
    .quad   .m2
    .quad   .m2_3
    .quad   .m3
    .quad   .m3
    .quad   .m3
    .quad   .m3_4
    .quad   .m4
    .quad   .m4
    .quad   .m4_5
    .quad   .m5
    .quad   .m5
    .quad   .m5_6
    .quad   .m6
    .quad   .m6
    .quad   .m6
    .quad   .m6_7
    .quad   .m7
    .quad   .m7
    .quad   .m7_8
    .quad   .m8
    .quad   .m8
    .quad   .m8_9
    .quad   .m9
    .quad   .m9
    .quad   .m9
    .quad   .m9_10
    .quad   .m10
    .quad   .m10
    .quad   .m10_11
    .quad   .m11
    .quad   .m11
    .quad   .m11_12
    .quad   .m12
    .quad   .m12
    .quad   .m12

.end:
/* output is given in %ecx */

```

This was mostly generated from gcc assembler output for proof-of-concept C code I wrote. Note the C code uses a computable goto to implement the jump table. It also uses the `__builtin_clzll()` gcc builtin, which compiles to the `bsr` instruction (plus an `xor`).

---

I considered several solutions before arriving at this one:

* `FYL2X` to calculate the natural log, then `FMUL` by the necessary constant. This would presumably win this if it was an \[tag:instruction:golf\] contest. But `FYL2X` has as latency of 90-106 for Ivy bridge.
* Hard-coded binary search. This may actually be competitive - I'll leave it to someone else to implement :).
* Complete lookup table of results. This I'm sure is theoretically fastest, but would require a 1TB lookup table - not practical yet - maybe in a few years if Moore's Law continues to hold.

---
Tags: math, fastest-algorithm, assembly
---


title: Water held in a hexagonal rod scuplture

text:
# Question
Title: Water held in a hexagonal rod scuplture
I have bunch of hexagonal rods glued together into an odd sculpture. The rods are 1 to 99 centimetres (cm) long and 1 square cm in cross-section area. All rods are glued on a hexagonal face to at least one other rod. The rods are all aligned at their bottom edge.

After some heavy rain, the sculpture is full of water. How much water does it hold?

## Input

Your program should read in (via stdin or a file) a number of lines consisting of pairs of spaces and pairs of digits specifying the length of the rods in this format:

```
  aa  bb
cc  dd  ee
  ff  gg

```

Each rod (like dd here) is glued to a maximum of 6 surrounding rods as shown in the examples. Missing rods are holes and do not gather water. For example, the input

```
  04  04
04  01  03
  04  04

```

would represent the following sculpture:

The centre rod is height `1` (I didn't find a good angle where that rod is also visible). Now the column above that rod could hold 2 cm of water, before it would overflow over the `3` rod on the right. Since none of the other rods can hold any water above them, the answer would be `2`. Here are two more complex examples:

```
Example 2:
55  34  45  66
  33  21  27
23  12  01  77
  36  31  74
answer = 35 (  2 on top of 21
             +11 on top of 12
             +22 on top of 01, before everything overflows over 23)

Example 3:
        35  36  77  22                      23  32  54  24
      33  07  02  04  21                  54  07  07  07  76
    20  04  07  07  01  20              54  11  81  81  07  76
  20  67  67  22  07  01  78          54  07  81  07  81  09  76
20  67  07  67  22  22  07  44  55  54  07  81  07  07  61  07  20
  67  57  50  50  07  07  14  03  02  15  81  99  91  07  81  04
67  07  50      50  87  39  45  41  34  81  07  07  89  07  81  79
  67  07  50  50  07  07  07  27  07  27  81  07  07  79  81  78
20  67  67  07  07  07  07  99  33  46  02  81  07  07  81  01  20
  33  07  07  01  05  01  92          20  02  81  07  81  15  32
    22  07  20  20  07  20              63  02  80  81  15  32
      45  20  01  20  39                  20  15  07  15  32
        23  20  20  29  43  21  18  41  20  66  66  43  21
      90                  99  47  07  20
    50                      20  02  48
  70                          56  20
                                90

answer = 1432

```

## Output

Your program should output a single integer giving the volume of water in cubic centimetres.

## Score

Your score is the byte count of your source code. Lowest wins.

The standard loopholes are prohibited as usual.

This puzzle was inspired by a SPOJ Question.

# Answer
> 4 votes
# Python 2, 222 bytes

```
import sys
y=h=v=0;B={}
for l in sys.stdin:
 z=y;y+=2j
 while l:
    if"0"<l:B[z]=int(l[:2])
    l=l[2:];z+=1
while B:C=B;B={b:B[b]for b in B if(h<B[b])+sum(3>abs(c-b)for c in B)/7};a=C==B;h+=a;v+=a*sum(h>B[b]for b in B)
print v

```

Reads input through STDIN and writes the result to STDOUT.

## Explanation

We start at zero and incrementally increase the water level as follows: Suppose that the water level is *h*, and we want to add 1 centimeter of water. We'll call hexagons of height *h* or less, ones that are about to go (or already are) underwater, "*submerged*." The water will spill through any submerged hexagon that isn't surrounded by six neighbors. We eliminate all such hexagons; of course, now some other submerged hexagons might have less than six neighbors, and they need to be eliminated as well. We continue in this fashion until convergence, i.e., until all remaining submerged hexagons have exactly six neighbors. At this point we add the number of submerged hexagons (the gained water volume) to the total count, and increment the water level.

Eventually, all the hexagons will have been eliminated and we halt.

# Answer
> 2 votes
# Ruby 299

```
f=->i{s={}
l=i.lines
y=0
l.map{|r|x=0
r.scan(/../){s[[x,y]]=[v=$&.to_i,v<1?0:99];x+=1}
y+=1}
loop{break if s.map{|c,r|x,y=c
m = [[-1,-1],[1,-1],[-2,0],[2,0],[1,-1],[1,1]].map{|w,z|s[[x+w,y+z]]}.map{|n|n ?n[0]+n[1]:0}.min
r[1]=[0,m-r[0]].max if r[0]+r[1]>m&&r[1]>0}.none?}
s.map{|c,r|r[1]}.reduce :+}

```

Brief description of the algorithm:

* parses the input, and for each rod saves a two-element array of the form \[rod\_height, water\_height\]
* rods are placed in a hash and indexed by their x,y coordinates
* the water leaking part takes into account the rod/water heights of the immediate neighbors

A slightly more readable version is available here: http://ideone.com/cWkamV

Run the golfed version online with tests: http://ideone.com/3SFjPN

---
Tags: code-golf, grid, puzzle-solver, hexagonal-grid
---


title: How to count the syllables in a word

text:
# Question
Title: How to count the syllables in a word
**Input:** You will be passed a string containing a single english word. All letters will be lowercase, and there will be no non-alphabetic characters in the string.

**Output:** You will return an integer from 1 to 7 representing how many syllables you think are in the word.

**Scoring:** Your program will be run against all of the words found on this repository. If you get `N` words correct, and your program is `M` bytes large, then your score is `N-(M*10)`. Largest score wins.

To generate my syllable count, I used this as my word list and this to count the syllables.

# Answer
> 13 votes
# Ruby, 8618 correct (91.1%), 53 bytes, 8618 - 10 * 53 = 8088 score

```
->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}

```

This is an anonymous Ruby function which uses regexes to count syllables.

The function adds a syllable for every instance of:

* A run of non-`e` vowels, followed by zero of more `e`s
* An `e` which is *not* part of a trailing `ed` or `ely`, with the exception of trailing `ted` or `ded`s
* A trailing `le`

## Analysis

The basic idea is to count runs of vowels, but this by itself isn't very accurate (`[aeiouy]+` gets 74% correct). The main reason for this is because of the silent `e`, which modifies the previous vowel sound while not being pronounced itself. For example, the word `slate` has two vowels but only one syllable.

To deal with this, we take `e` out of the first part of the regex and treat it separately. Detecting silent `e`s is hard, but I found two cases where they occur often:

* As part of a trailing `ed` (unless it's a `ted` or `ded` like `settled` or `saddled`),
* As part of a trailing `evy` (e.g. `lovely`)

These cases are specifically excluded in what would otherwise be `e.`.

The reason for the `.` in `e(?!d$|ly).` is to consume the next char if there is a double vowel (e.g. `ea` or `ee`), and so that `e` at the end of the word are not counted. However a trailing `le` *is* usually pronounced, so that is added back in.

Finally, vowel runs are counted as one syllable. While this may not always be the case (e.g. `curious`), it's often difficult to work out whether there are multiple syllables. Take the `ia` of `celestial` and `spatial`, as an example.

## Test program

I don't really know Ruby so I'm not sure how well it can be golfed. I did manage to scrape together a test program by consulting a lot of SO though:

```
cases = 0
correct = 0

s = "->s{s.scan(/[aiouy]+e*|e(?!d$|ly).|[td]ed|le$/).size}"

f = eval s

for i in 1 ... 8
    filepath = i.to_s + "-syllable-words.txt"
    file = File.open(filepath)

    while (line = file.gets)
        word = line.strip
        cases += 1
        if f.call(word) == i
            correct += 1
        end
    end
end

p "Correct: #{correct}/#{cases}, Length: #{s.length}, Score: #{correct - s.length*10}"

```

# Answer
> 5 votes
# Python3, 7935 - 10 * 71 = 7225

My quick-and-dirty answer: count runs of consecutive vowels, but remove any final e's first.

```
lambda w:len(''.join(" x"[c in"aeiouy"]for c in w.rstrip('e')).split())

```

After stripping off the e's, this replaces vowels with `x` and all other characters with a space. The result is joined back into a string and then split on whitespace. Conveniently, whitespace at the beginning and end is ignored (e.g. `" x xx ".split()` gives `["x","xx"]`). The length of the resulting list is therefore the number of vowel groups.

The original, 83-byte answer below was more accurate because it only removed a single e at the end. The newer one thus has problems for words like `bee`; but the shortened code outweighs that effect.

```
lambda w:len(''.join(" x"[c in"aeiouy"]for c in(w[:-1]if'e'==w[-1]else w)).split())

```

Test program:

```
syll = lambda w:len(''.join(c if c in"aeiouy"else' 'for c in w.rstrip('e')).split())

overallCorrect = overallTotal = 0
for i in range(1, 7):
    with open("%s-syllable-words.txt" % i) as f:
        words = f.read().split()
    correct = sum(syll(word) == i for word in words)
    total = len(words)
    print("%s: %s correct out of %s (%.2f%%)" % (i, correct, total, 100*correct/total))
    overallCorrect += correct
    overallTotal += total

print()
print("%s correct out of %s (%.2f%%)" % (overallCorrect, overallTotal, 100*overallCorrect/overallTotal))

```

Evidently this was too dirty and not quick enough to beat Sp3000's Ruby answer. ;^)

# Answer
> 1 votes
# Perl, 8145 - 3 * 30 = 7845

Using the lists from before the recent commits.

```
#!perl -lp
$_=s/(?!e[ds]?$)[aeiouy]+//g

```

# Answer
> 0 votes
# Python, 5370-10\*19 = 5180

This program simply assumes that longer words means more syllables.

```
lambda x:len(x)/6+1

```

The tester program I use is:

```
correct = 0
y = lambda x:len(x)/6+1
for i in xrange(1,8):
    f = file(str(i)+"-syllable-words.txt")
    lines = f.read().split("\n")
    f.close()
    correct += len([1 for line in lines if y(line)==i])
print correct

```

---
Tags: code-challenge, word
---