text:
The Great Wumpus Hunt
COMPLETE
Wumpus season has ended, and with, the lives of many a vicious Wumpus and brave Hunter. As well as some cowardly, immoral and downright stupid Hunters. But at the end of the day, NascarHunter by Dr Heckle came away with the most loot and glory. We salute you, oh brave... driver?
It's open season on Wumpuses, and hunters from around the world are flocking to the Wumpus Caves to try to get rich of off valuable Wumpus Pelts.
The Game
Based on the classic Hunt the Wumpus game, with a few variations.
The Map
A dodecahedron. There are 20 rooms, each connected to 3 other room, making basically 3 rings with bridges in between.
The Wumpus
The Wumpus is a mystical beast. None are sure what it looks like, but all agree that it is ferocious. The Wumpus lives in the caves, and likes to eat dead things. If there is a corpse in a cave next to the Wumpus, he will move there and eat it. If the Wumpus happens to move into a cave containing hunters, he will kill and eat them as well. If the Wumpus hears an arrow near him, he will panic and run into a random room.
Optional traits: These are currently included to make the game more interesting, but can be removed at popular request if they add too much randomness.
Enraged Wumpus: If the Wumpus is shot, he has a 20% of surviving and rampaging for 3 days. When rampaging, he will randomly move twice a day, but still be attracted to corpses. After 3 days, he will die. A second arrow shot will also kill the Wumpus.
Wandering Wumpus: Each day, if nothing else triggers the Wumpus, he has a 25% chance of moving.
The Hunters
Four hunters can enter the caves at a time. The caves are dark, so the hunters cannot see, but they can use their other senses. Hunters can smell the Wumpus in an adjacent room, smell a corpse in an adjacent room, hear other hunters moving in adjacent rooms, and hear if an arrow is shot into an adjacent room.
Hunters have two actions: Shoot or move. A hunter can shoot an arrow into an adjacent room or his own room, and move similarly.
Gameplay
In each round, hunters will first take note of their surroundings, and then make one move. Movement occurs before arrows, so if an arrow is shot into a room that a hunter is moving out of, the hunter will survive. After all hunter moves have been made, the arrows are evaluated. If a single occupant and arrow are in the same room, the occupant will be shot and die. If two or more occupants share a room, one will randomly be hit and die. Note: Corpses are occupants, so a dead body may serve as a partial shield.
After all hunter moves, the Wumpus will respond. If a hunter has moved into the room with the Wumpus, the Wumpus will eat him/her. If the Wumpus moves, it will also eat the occupants of the new room.
After 100 days, if the hunters have not killed the Wumpus, or fallen victim, they will die of starvation within the caves.
The Code
All source code can be found here. All submissions should be in Java, unless somebody wants to write me a stdIn/stdOut adaptor ;)
Bots should extend the Hunter class.
To name your Hunter, add a constructor with no parameters that sets the name field. T
o respond, override the getResponse function. In this function, each turn, you will be passed an array of 5 booleans that tells you about your surroundings.
status 0 = "You smell a wumpus"
status 1 = "You hear another hunter"
status 2 = "You smell a corpse"
status 3 = "You hear an arrow clatter"
status 4 = "You feel another hunter in the same room as you"
The Hunter class has 2 slots: nextMove and nextDirection, that use the enums Move and Direction respectively. Move can either be MOVE or SHOOT, direection can be LEFT, RIGHT, BACK, or HERE. Directions are consistent, meaning back will always return you to the previous room you were in, and if entering from the same room, LEFT and RIGHT will always be the same. However, if you enter from a different direction, LEFT and RIGHT will take you to different places.
Feel free to implement your own methods as well. Memory is persistent throughout the whole tournament, meaning your hunter will only be constructed once. However, at the start of each round, the newGame() method is called to let your hunter know a new game has started.
Scoring
Four hunters compete at a time. If killed, the Wumpus pelt is worth 60 points, split evenly among all surviving hunters. Full round robin style, so each combination of 4 hunters will play together.
5 sample Hunters are included: 4 with very basic functionality, and one that allows user input to play, for testing purposes.
If you have any suggestions/requests, please let me know!
The End is in sight!
The worlds Wumpus population is being hunted at an alarming rate. The Protect Our Wumpuses Act is expected to be passed on Wednesday, June 17th. After this date, no more hunters will be allowed in the caves, and a winner will be chosen.
Scoreboard
Note : My apologies, there was a bug in the code that could cause Hunters to stay dead through multiple games. Having fixed it, it does not change the overall rankings very much, but does largely change the stats.
Scores are in, running each set of hunter in 1000 games each. NascarHunter and FullCoverageHunter lead the pack, and although the addition of AntiHunter has given the Wumpuses a 2% survival boost, they are  still shaking in their suckered feet at the 32% survival rate of their kind. Arrows from fellow hunters are more than ever the biggest threat in the caves.
1. NascarHunter : 16557175 (17.08)
2. FullCoverageHunter : 15195545 (15.68)
3. Trig : 14459385 (14.92)
4. Idomeneus : 13428570 (13.85)
5. Eats Shoots and Leaves : 12763945 (13.17)
6. WalkingIdiot : 12329610 (12.72)
7. NealHunter : 12287140 (12.68)
8. Unnamed : 11013720 (11.36)
9. MonsterHunter : 10686035 (11.02)
10. Pacer : 9187000 (9.48)
11. Badger : 9042570 (9.33)
12. Stay : 8721210 (9.0)
13. Emo Wumpus : 7831050 (8.08)
14. Paranoid : 7722965 (7.97)
15. Huddle : 7465420 (7.7)
16. ElmerFudd : 7245995 (7.47)
17. Laomedon : 6963845 (7.18)
18. Pacifist : 6944960 (7.16)
19. ScaredyCat : 6937370 (7.15)
20. Wumpus : 114170 (0.11)

Total rounds: 4845000
Humans killed by arrows: 5289674 (1.09)
Humans dead by starvation: 1046024 (0.21)
Humans killed by wumpus: 1887634 (0.38)
Wumpus victories: 1563372 (0.32)

Can you hit another hunter with an arrow?

Yessir, or yourself if you shoot an arrow at HERE

Are we allowed to examine the entire map when coming up with the move?  Given that a hunter can get the current room and each room has pointers to its neighbors it should be possible to know where the wumpus and all other humans are.

Room is actually not visible to anything that extends Hunter, because it's private not protected. So although your hunter contains a reference to the room it's in, it can't actually access it from code. So no, your hunter can't actually get the room, just the status update passed to it from getResponse

Is this by chance inspired by the Microsoft hunt the Wumpus competition?

@Cain Can I submit more than one Hunter ? :p Also, tehre's a problem with your description. Room.getInfo() actually give an array of 5 boolean, not 4. The fifth one (index 4) is for when there is a Hunter in the same room as you.

Instead of an array for 5 booleans, why not just pass an int valued 0-31? We're big boys here, we can do bit operations :)

@DoctorHeckle Sure we are, but it's still more dev-friendly to have an array rather than a single int ^^.

More than one Hunter is fine, actually if you can create multiple hunters that work together, all the better. Just keep them with at least tangibly different logic.

@Cain No problem. And thanks, will try to work on multiple hunters :). By the way, there's a problem when you write the scores. The amount of human killed by arrows and the number of wumpus wins are false. You used a bad index :)
Ho, and **** Trigger, he's winning the more points out of all the current submissions x)

Haha also fixed the index while I was in there, I was getting more wumpus victories than games. The trend so far seems to be the more shooting the better haha, I was hoping a little altruism might pay off, but haven't seen it yet

Quick mechanics question for @Cain:

If I'm in the same room as a hunter, and Shoot.HERE, I'll kill them and not myself, correct? If there are more than one other hunters in the room, do I randomly kill another hunter?

If I enter a room with a corpse, and the Wumpus comes in, will the Wumpus eat me first, or go for the corpse?

Do stati 0, 2, and 3 refer to surrounding rooms AND the currently occupied room, or EXCLUSIVELY surrounding rooms?

@Katenkyo what's even more depressing is that RandomHunter seems to do just as well :(

If you're in the same room and shoot here, you could kill yourself or the other hunter, it's very dark in there. 2. Anytime you are in a room with the Wumpus, you die. Although, I do like the idea of the Wumpus eating the corpse first, I could maybe add that. And then remove the corpse after, so the Wumpus doesn't get bogged down in one spot so much.

But for now, being in the same room = death, and corpses are permanent

Can you detect an arrow, a hunter, or a corpse in your own room?

For arrows and corpses, if one is in the same room as you you get the same status as if it is adjacent. Hunters are the only ones you can distinguish between being next to the room or in the room.

@Cain The Wumpus with by starvation not because the number of days is too small, but because some entry don't move, and will never fight with the wumpus. And even when they move, if there is only 1 hunter remaining, there's a high chance he will never meet it. Anyway, I'm glad my MonsterHunter did 5/13 :D

@ Katenkyo Yeah, you're right, especially because the Wumpus becomes mostly stationary after finding a corpse

Lots of competition! I dig it. For when Wumpus Season is over, I'd love to see which quartet is the most successful in addition to which individual hunter is most successful.

Am I allowed to use a language that compiles to Java (e.g. Kotlin or Scala)?

If hunters are only constructed once and asked to reset each round, does that mean we can make a hunter that behaves differently depending on the round? Or do we have to reset everything each round? Basically, is it against the rules to carry over player state between rounds?

Carrying over state between rounds is completely acceptable, just be aware that you may be with different hunters as well, and have no way of knowing this.

Well, was fun, I'm happy seeing MonsterHunter is 9/20 ! Well done for doing such a great KotH :). Do you think you'll do a variant of the wumpus hunt one day? By the way, Congratulations to @DoctorHeckle !

@Katenkyo Thanks! Yeah, I definitely might re-visit this someday, personally I felt like the game design partially failed, when a bot that didn't use any of the statuses for along time stil wrecked as hard as it did. Basically, shooting everywhere was too strong a strategy to reward anything more clever :P My goal would be to see people mapping the caves, setting corpse traps, triangulating the wumpus, etc. But I've got a very different KotH cooked up for next week ;)

Thanks much @Katenkyo! It appears that Occam's Razor was a little too sharp for this KotH. I'm gonna keep my eyes peeled for the next competition, @Cain. This one was a lot of fun!

NascarHunter
Not much logic to it. Its rules are simple: turn left, scorched earth, repeat. And, hey, he might get lucky!
8 June edit:
Added in additional logic to Nascar to account of adjacency to a Wumpus relative to its last move. Consider it a pit stop, to stay in theme. If it sense a Wumpus after shooting down a hallway, then it must have arrived in one of the other two adjacent rooms, since it would've died to the shot the hunter just took. It effectively give either the Wumpus 2 turns to live if it doesn't move again, or Nascar 1 turn to live if he's standing on a corpse. Also accounts for a third option if it's the first turn, but just the once. I'll port to to FCH eventually, busy busy.
package Hunters;

import Mechanics.*;

public class NascarHunter extends Hunter {

    private int state;
    private boolean shootHall;
    private boolean newGame;

    public NascarHunter(){

        name = "NascarHunter";
        state = 0;
        shootHall = true;
        newGame = true;

    }

    public void newGame(){

        state = 0;
        newGame = true;

    }

    public void getResponse(boolean[] status){

        // Wumpus about - stand and deliver
        if( status[0] ){

            nextMove = Move.SHOOT;

            switch( state ){

            case 0: // Must be in either Right or Back
                if(newGame){

                    // try Left if this is the first turn, just in case
                    nextDirection = Direction.LEFT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.RIGHT;
                shootHall = !shootHall;
                break;
            case 2: // Must be in either Left or Back
                if(newGame){

                    // try Right if this is the first turn, just in case
                    nextDirection = Direction.RIGHT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;
            default: // Must be in either Left or Right
                if(newGame){

                    // try Back if this is the first turn, just in case
                    nextDirection = Direction.BACK;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.RIGHT;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;

            }

        }else{

            // disregard state, shove out and light 'em up!
            switch( state ){

            case 0: // move out
                nextMove = Move.MOVE;
                nextDirection = Direction.LEFT;
                state++;
                break;
            case 1: // shoot right
                nextMove = Move.SHOOT;
                nextDirection = Direction.RIGHT;
                state++;
                break;
            case 2: // shoot behind
                nextMove = Move.SHOOT;
                nextDirection = Direction.BACK;
                state++;
                break;
            case 3: // shoot left
                nextMove = Move.SHOOT;
                nextDirection = Direction.LEFT;
                state = 0;
                break;

            }

        }

    }

}

FullCoverageHunter
Follows the same credo of the NascarHunter, but alternates his pathing, which is guaranteed to form a loop 10 unique rooms long. Since every room is unique, and we fire at every direction per room, all rooms get fired into. This is true for any starting room (postulated by my buddy Neal, thanks Neal!). Dodecahedra are pretty cool like that!
I'd like to point out that this is is different than our friend, the MonsterHunter, as he doesn't try any trickery or any real "tactics." The strength of this is the fact that every room gets fired into, again: the brute force solution. This has a theoretical leg up on the NascarHunter, since Nascar will only hit 10 of the 20 rooms, covering only half the area.
11 June edit:
Added in Wumpus detection logic pattern from NascarHunter. Should objectively improve score.
package Hunters;

import Mechanics.*;

public class FullCoverageHunter extends Hunter {

    private int state;
    private boolean headLeft;
    private boolean shootHall;
    private boolean newGame;

    public FullCoverageHunter(){

        name = "FullCoverageHunter";
        state = 0;
        headLeft = false;
        shootHall = true;

    }

    public void newGame() {
        state = 0;
        headLeft = false;
        newGame = true;
    }

    public void getResponse(boolean[] status){

        // Wumpus about - stand and deliver
        if( status[0] ){

            nextMove = Move.SHOOT;

            switch( state ){

            case 0: // Must be in either Right or Back
                if(newGame){

                    // try Left if this is the first turn, just in case
                    nextDirection = Direction.LEFT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.RIGHT;
                shootHall = !shootHall;
                break;
            case 2: // Must be in either Left or Back
                if(newGame){

                    // try Right if this is the first turn, just in case
                    nextDirection = Direction.RIGHT;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.BACK;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;
            default: // Must be in either Left or Right
                if(newGame){

                    // try Back if this is the first turn, just in case
                    nextDirection = Direction.BACK;
                    newGame = false;

                }
                else if(shootHall) nextDirection = Direction.RIGHT;
                else               nextDirection = Direction.LEFT;
                shootHall = !shootHall;
                break;

            }

        }else{

            // disregard state, shove out (in an alternating fashion!) and light 'em up!
            switch( state ){

            case 0: // move out, change alternation state
                nextMove = Move.MOVE;
                if(headLeft) nextDirection = Direction.LEFT;
                else         nextDirection = Direction.RIGHT;
                state++;
                headLeft = !headLeft;
                break;
            case 1: // shoot into non-exit path
                nextMove = Move.SHOOT;
                if(headLeft) nextDirection = Direction.RIGHT;
                else         nextDirection = Direction.LEFT;
                state++;
                break;
            case 2: // shoot behind
                nextMove = Move.SHOOT;
                nextDirection = Direction.BACK;
                state++;
                break;
            default: // shoot into next room,
                nextMove = Move.SHOOT;
                if(headLeft) nextDirection = Direction.LEFT;
                else         nextDirection = Direction.RIGHT;
                state = 0;
                break;

            }

        }

    }

}

Let me know if there're any errors, package didn't play nice with my IDE :(

I'm pretty sure this should be called MadMaxHunter, as I don't recall too many NASCAR races involving gunfire between vehicles. Seems to do well!

I had to put brackets around the headLeft in the if statements to get FullCoverageHunter to work. Both of your bots do very well- NascarHunter is slightly better

The variable newGame in FullCoverageHunter seems to never be declared. I added a private boolean newGame and set it to true in the newGame() method, is that what you intended?

@Cain whoops! Yeah big oversight from me, I'll edit that in here, my bad.

Badger
He doesn't like visitors.
package Hunters;

import Mechanics.*;

public class Badger extends Hunter {

    public Badger(){
        name = "Badger";
    }

    @Override
    public void getResponse(boolean[] status){
        nextMove = Move.SHOOT;
        nextDirection = Direction.values()[((int) (Math.random() * 3))];
    }
}

Elmer Fudd
"Shhh. Be vewy vewy quiet, I'm hunting wumpus"
Elmer is fixated on the prey and ignores everything except corpses and the Wumpus. He tries to find a corpse then backs off and starts shooting.  If he smells a Wumpus, he will back off and if he still smells him he will shoot.
My apologies to all the java programmers, this is probably extremely ugly, full of syntax errors and I have probably messed up my logic.
package Hunters;

import Mechanics.*;

public class ElmerFudd extends Hunter {

    private state int;
    private previousDir int;

    public ElmerFudd(){
        name = "ElmerFudd";
    }

    public void newGame() {
        state=0;
        previousDir = Direction.LEFT;
    }

    public void getResponse(boolean[] status){

        nextMove = Move.MOVE;
        switch (previousDir) {
            case Direction.LEFT:
                nextDirection = Direction.RIGHT;
                break;
            case Direction.RIGHT:
                nextDirection = Direction.LEFT;
                break;
        }

        if(status[2]&&state==0) {
            state = 1;
            return;
        }

        if(state==1){
            if(status[2]){
                state=2;
            };
            nextDirection = Direction.BACK;
            return;
        }

        if(state==2){
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            return;
        }

        if(state==3&&status[0])
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            return;
        }

        if(state==3) {
            state = 0;
        }

        if(status[0]){
            state=3;
            nextDirection = Direction.BACK;
        }

    }
}

Pacifist
This guy is morally against any sort of blood sport and wondering how he turned up in this situation at all.  He will run away from any sort of contact and never take a shot.
package Hunters;

import Mechanics.*;

public class Pacifist extends Hunter {

    public Pacifist(){
        name = "Pacifist";
    }

    public void getResponse(boolean[] status){
        nextMove = Move.MOVE;
        if(status[0]||status[1]||status[2]||status[3]||status[4]){
            nextDirection = Direction.values()[((int) (Math.random() * 3))];
            return;
        }
        nextDirection = Direction.HERE;
    }
}

I think this might work. All you have to do in a game is hope someone gets the wumpus before it gets you and you get full credit.

That was the general idea.  Let the others do the hard work:-)

That's why I waited for you to code this, even though I thought of it first :-)

MonsterHunter
We are hunting a monster and we are 4... It reminds me of my favorite game !
This hunter will walk most of the map by moving left-right alternatively, and if the Wumpus is near, he will lure him by going backward to be able to determine precisely were it is.
I could get rid of lastDirection, but I keep for semantics and readability :).
Actually, it dies quite a lot, but the controller often put 2/3 hunter in the same room at the start, and often with the Wumpus near (can also be in the same room)... so insta death ^^'.
package Hunters;

import Mechanics.*;

public class MonsterHunter extends Hunter
{
    private Direction lastDirection=Direction.HERE;
    private boolean[] lastStatus=new boolean[5];
    private int   shooted=0;
    private boolean   walkMode=true;
    private int         turnStayed=0;

    public MonsterHunter(){
        super();
        name = "MonsterHunter";
    }

    @Override
    public void getResponse(boolean[] status)
    {
        if(status[0])
        {
            if(!lastStatus[0]||shooted==0)
            {
                nextDirection=(walkMode)?Direction.RIGHT:Direction.LEFT;;
                nextMove=Move.SHOOT;
            }
            else if(lastStatus[0]&&shooted==1)
            {
                nextDirection=Direction.BACK;
                nextMove=Move.MOVE;
            }
            else
            {
                nextDirection=Direction.BACK;
                nextMove=Move.SHOOT;
            }
        }

        else if(status[2])
        {
            nextMove=Move.MOVE;
            if(Math.random()*6<turnStayed)
            {
                nextDirection=Direction.HERE;
                turnStayed++;
            }
            else
                nextDirection=(walkMode)?Direction.RIGHT:Direction.LEFT;
        }
        else
        {
            nextMove=(!status[1]&&Math.random()<0.5)?Move.MOVE:Move.SHOOT;
            nextDirection=(walkMode)?Direction.RIGHT:Direction.LEFT;
        }

        if(nextMove==Move.MOVE)
        {
            if(shooted>0)
                walkMode=walkMode^(shooted>0);
            if(lastStatus[0]&&shooted==1)
                shooted++;
            else
                shooted=0;
            lastDirection=nextDirection;
        }
        else
            shooted++;
        for(int i=0;i<status.length;i++)
            lastStatus[i]=status[i];
    }
}

Thanks for pointing that out, controller is fixed so that each occupant has a unique start

ScaredyCat
ScaredyCat is scared of everything. If it smells a wumpus or a corpse or hears an arrow or a hunter, it runs to a random direction. Otherwise, it simply keeps shooting arrows in random directions.
package Hunters;

import Mechanics.*;

public class ScaredyCat extends Hunter {

    public ScaredyCat(){
        name = "ScaredyCat";
    }

    @Override
    public void getResponse(boolean[] status){

        for(int i=0; i<status.length; i++)
            if(status[i])
            {
                nextMove = Move.MOVE;
                nextDirection = Direction.values()[((int) (Math.random() * 3))];
                return;
            }

        nextMove = Move.SHOOT;
        nextDirection = Direction.values()[((int) (Math.random() * 3))];
    }
}

Lol I don't know if this was intentional, but he will scare himself by shooting arrows and then run.

Eats Shoots and Leaves
Unlike the Panda of grammar book fame, this hunter doesn't actually eat anything, but we either shoot if the Wumpus is about or we leave on a trail that should hopefully keep us from walking in circles.
package Hunters;

import java.util.Random;

import Mechanics.Hunter;
import Mechanics.Move;
import Mechanics.Direction;
import Mechanics.Room;

public class EatsShootsAndLeaves extends Hunter {

    private static Direction [] allDirections = { Direction.LEFT, Direction.RIGHT, Direction.BACK, Direction.HERE };
    private static Direction [] movePath = { Direction.LEFT, Direction.RIGHT, Direction.LEFT, Direction.BACK, Direction.RIGHT, Direction.BACK };

    private static int numGames = 0;
    private static int totalLife = 0;

    private static class RoomInfo  {

        public boolean hasWumpus = false;
        public boolean hasLocalHunter = false;
        public boolean hasNeighborHunter = false;
        public boolean hasCorpse = false;
        public boolean hasArrow = false;
        public RoomInfo(Room r) {
            boolean [] status = r.getInfo();
            hasWumpus = status[0];
            hasNeighborHunter = status[1];
            hasCorpse = status[2];
            hasArrow = status[3];
            hasLocalHunter = status[4];
        }

        public String toString() {
            return new String("Status: "
                              + (hasWumpus ? "Wumpus " : "")
                              + (hasNeighborHunter ? "Close Hunter " : "")
                              + (hasCorpse ? "Corpse " : "")
                              + (hasArrow ? "Arrow " : "")
                              + (hasLocalHunter ? "Local Hunter " : ""));
        }
    }

    int turnsAlive = 0;
    int shots = 0, moves = 0;

    public EatsShootsAndLeaves(){
        name = "Eats Shoots and Leaves";
    }

    public void newGame() {

        totalLife += turnsAlive;
        numGames++;

        turnsAlive = shots = moves = 0;
    }

    public void getResponse(boolean[] status){

        turnsAlive++;

        RoomInfo info = new RoomInfo(this.getRoom());
        if (info.hasNeighborHunter || info.hasWumpus) {
            nextMove = Move.SHOOT;
            nextDirection = allDirections[shots++ % 3];
        } else {
            nextMove = Move.MOVE;
            nextDirection = movePath[moves++ % movePath.length];
        }
    }
}

PacingHunter
Back and forth, between to rooms. if it smells a Wumpus or hears a player it shoots left then right. if a Wumpus is next to him to start with than he shoots the room he will move to.
package Hunters;

import Mechanics.Direction;
import Mechanics.Hunter;
import Mechanics.Move;

public class PacingHunter extends Hunter {

    int state = 0;//Pacing
    int turn = 0;

    public PacingHunter() {
        name = "Pacer";
    }

    public void newGame() {
        turn =  0;
        state = 0;
    }

    public void getResponse(boolean[] status){
        turn += 1;
        if(state == 0 && status[0] && turn == 1){
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            return;
        }
        if(state == 0 &&(status[0] || status[1])){
            nextMove = Move.SHOOT;
            nextDirection = Direction.LEFT;
            state = 1;
            return;
        }
        if(state == 1 && (status[0] || status[1])){
            nextMove = Move.SHOOT;
            nextDirection = Direction.RIGHT;
            state = 0;
            return;
        }
        if(status[1] && state == 0){
            nextMove = Move.SHOOT;
            nextDirection = Direction.BACK;
            state = 0;
            return;

    }
    nextMove = Move.MOVE;
    nextDirection = Direction.BACK;
}

}

Idomeneus
Idomeneus is quite simple- if the Wumpus or another hunter is nearby, he fire sarrows everywhere and prays that the goddess of hunting is on his side. If he's near a corpse he lies in wait for the Wumpus. He doesn't like other hunters and will run away if they start firing arrows near him, or if they are in the same room as him. Finally if he's feeling bored he randomly paces the eternal corridors.
package Hunters;
import Mechanics.Direction;
import Mechanics.Hunter;
import Mechanics.Move;
import java.util.Random;

public class Idomeneus extends Hunter
{
    int direction;
    Random r;
    public Idomeneus()
    {
        super();
        name = "Idomeneus";
        direction = 0;
        r = new Random();
    }

    @Override
    public void getResponse(boolean[] status){
        boolean wumpusNear = status[0];
        boolean hunterNear = status[1];
        boolean corpseNear = status[2];
        boolean arrowNear = status[3];
        boolean hunterHere = status[4];
        direction++;

        if(wumpusNear)
        {
            //ATTACK!!!
            nextMove = Move.SHOOT;
            nextDirection = Direction.values()[direction%3];
        }
        else if(hunterHere || arrowNear)
        {
            //Run away
            nextMove = Move.MOVE;
            nextDirection = Direction.values()[r.nextInt(3)];
        }
        else if(hunterNear)
        {
            //ATTACK!!!
            nextMove = Move.SHOOT;
            nextDirection = Direction.values()[direction%3];
        }
        else if(corpseNear)
        {
            //Stay and wait...
            nextMove = Move.MOVE;
            nextDirection = Direction.HERE;
        }
        else
        {
            //wander around
            nextMove = Move.MOVE;
            nextDirection = Direction.values()[r.nextInt(3)];
        }

    }

    public void newGame(){}

}

Be careful: According to @Cain, you can shoot yourself if you fire into your own room.

Emo Wumpus (Hunter)
Emo Wumpuses (related to Emo Wolves which sometimes use guns and fly planes) hate everything (especially Java). They make no distinction between Hunters and Wumpuses, and try to shoot them all the same. They also hate Nascar drivers, and will always shoot right. If no one is around to shoot, they move right, but will only do this thirteen times in a row before they get even more depressed about being alone and try to shoot themselves (thirteen is an unlucky number). On turn 99, if they are still alive, they will attempt to shoot themselves because starvation is such a lame way to die.
Wumpuses are larger (and heavier) than Wolves, but this one has still starved itself to 424 bytes (as opposed to the hefty 2.72 kb of NascarHunter).
package Hunters;import Mechanics.*;public class EmoWumpus extends Hunter{private int c, t;public EmoWumpus(){name="Emo Wumpus";this.c=0;this.t=0;}public void newGame(){this.c=0;this.t=0;}public void getResponse(boolean[] status){nextMove=Move.SHOOT;if(c<13 && t<100){if(status[0]||status[1]){nextDirection=Direction.RIGHT;}else{nextMove=Move.MOVE;nextDirection=Direction.RIGHT;c++;}}else{nextDirection=Direction.HERE;}t++;}}

Why not just commit suicide in the first place? Emo Wumpuses believe that the one act of good that can do is end the suffering of others before killing themselves. Therefore, they will kill all that they can before it is their time to die.
Wumpus? (Anti-Hunter)
Um, What is a Wumpus doing on the hunters roster? This guy got super pissed that humans were killing his kin, so he decided to dress up as one of them and join in on the hunt. His main goal is to just kill hunters. He tries to hide near corpses, which will give him a chance at a shield from the hunters. If no hunters are nearby, he will move in a direction until hunters are detected, in which case he will try to kill them before moving in the other direction.
Unfortunately, most Wumpuses are stupid, and are still going to try to kill him. Regardless, he considers his sacrifices necessary for the good of Wumpuses everywhere.
package Hunters;

import Mechanics.*;

public class AntiHunter extends Hunter {

private boolean left;

public AntiHunter() {
    name = "Wumpus";
    this.left = true;
}

public void newGame() {
    this.left = true;
}

public void getResponse(boolean[] status) {
    if(status[4]) {
        nextMove = Move.SHOOT;
        nextDirection = Direction.HERE;
    }
    else if(status[2] || status[1]) {
        nextMove = Move.SHOOT;
        if(this.left) {
            this.left = false;
            nextDirection = Direction.LEFT;
        }
        else {
            this.left = true;
            nextDirection = Direction.RIGHT;
        }
    }
    else {
        nextMove = Move.MOVE;
        if(this.left)
            nextDirection = Direction.LEFT;
        else
            nextDirection = Direction.RIGHT;
    }
}

}

No longer funny.

Good thing this isn't code golf. Was wondering how long it'd be until an Emo bot would show up, lol.

@Martin Note that this isn't just suicidal. Out of the bots available for testing, it did not rank last.

EmoSolution is always funny !

NealHunter
After talking about this with my friend DoctorHeckle, I'd thought it would be fun to try it myself. Used the idea for alternating left and right to cover the most area, and then decided to add a bit of responding to the states, but only 0 and 1 - whether or not a Wumpus or hunter are nearby. Doesn't perform as well as NascarHunter, which surprised me at first. After some thinking though, I realized that shooting an arrow in a random direction (like this does) after hearing a hunter/smelling a Wumpus won't do anything if they're moving that turn, since arrows are shot into rooms, but movement is carried out before it kills them. Not quite as effective as I thought... still performs well though!
package Hunters;

import Mechanics.*;
import java.util.Random;

public class NealHunter extends Hunter {

    private boolean goLeft;

    public NealHunter(){
        name = "NealHunter";
        goLeft = false;
    }

    public void newGame() {
        goLeft = false;
    }

    public void getResponse(boolean[] status){

        Random rand = new Random();

        if(status[0] || status[1]){
            nextMove = Move.SHOOT;

            switch ( rand.nextInt(3) ){
                case 0:
                    nextDirection = Direction.LEFT;
                    break;
                case 1:
                    nextDirection = Direction.BACK;
                    break;
                case 2:
                    nextDirection = Direction.RIGHT;
                    break;
            }
        } else {
            nextMove = Move.MOVE;
            if (goLeft) {
                nextDirection = Direction.LEFT;
            } else {
                nextDirection = Direction.RIGHT;
            }

            goLeft = !goLeft;
        }
    }
}

Laomedon
Laomedon wanders aimlessly trying to find a corpse. Once he's found one and works out where it is he stays in the same place next to the corpse. When he smells the Wumpus he fires arrows into the Corpse's room.
package Hunters;
import Mechanics.Direction;
import Mechanics.Hunter;
import Mechanics.Move;
public class Laomedon extends Hunter {
    private enum status
    {
        START,
        SEARCHED_LEFT,
        SEARCHED_RIGHT,
        INITIAL_CORPSE_LEFT,
        INITIAL_CORPSE_RIGHT,
        SMELT_CORPSE,
        CORPSE_BEHIND,
        CORPSE_LEFT
    }

    status myState;
    public Laomedon() {
        this.name = "Laomedon";
    }
    @Override
    public void getResponse(boolean[] status) {
        boolean wumpusNear = status[0];
        boolean hunterNear = status[1];
        boolean corpseNear = status[2];
        boolean arrowNear = status[3];
        boolean hunterHere = status[4];
        switch (myState) {
        case CORPSE_BEHIND:
            if(wumpusNear)
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.SHOOT;
            }
            else
            {
                this.nextDirection = Direction.HERE;
                this.nextMove = Move.MOVE;
            }
            break;
        case CORPSE_LEFT:
            if(wumpusNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.SHOOT;
            }
            else
            {
                this.nextDirection = Direction.HERE;
                this.nextMove = Move.MOVE;
            }
            break;
        case INITIAL_CORPSE_LEFT:
            if(corpseNear)
            {
                this.nextDirection = Direction.RIGHT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.INITIAL_CORPSE_RIGHT;
            }
            else
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        case INITIAL_CORPSE_RIGHT:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                myState = Laomedon.status.INITIAL_CORPSE_LEFT;
            }
            else
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        case SEARCHED_LEFT:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SMELT_CORPSE;
            }
            else
            {
                this.nextDirection = Direction.RIGHT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_RIGHT;
            }
            break;
        case SEARCHED_RIGHT:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SMELT_CORPSE;
            }
            else
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        case SMELT_CORPSE:
            if(corpseNear)
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.CORPSE_BEHIND;
            }
            else
            {
                this.nextDirection = Direction.BACK;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.CORPSE_LEFT;
            }
            break;
        case START:
            if(corpseNear)
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.INITIAL_CORPSE_LEFT;
            }
            else
            {
                this.nextDirection = Direction.LEFT;
                this.nextMove = Move.MOVE;
                this.myState = Laomedon.status.SEARCHED_LEFT;
            }
            break;
        }
    }

    @Override
    public void newGame() {

        super.newGame();
        myState = status.START;
    }
}

Unfortunately for him, the other hunters don't appreciate his skills and they seem to shoot him a lot...

WalkingIdiot
This one walks until he finds the wumpus. Then, he shoots right. If the wumpus is still there, it must be on the left, so shoot once again. On the way, he doesn't care about other hunters or corpses, hence the name.
package Hunters;

import Mechanics.*;

public class WalkingIdiot extends Hunter {
    private boolean wumpusNear = false;

    @Override
    public void newGame() {
        wumpusNear = false;
    }

    public WalkingIdiot(){
        name = "WalkingIdiot";
    }

    @Override
    public void getResponse(boolean[] status){
        boolean wumpusWasNear = wumpusNear;
        wumpusNear = status[0];
        if (status[0]) {
            nextMove = Move.SHOOT;
            if (wumpusWasNear) {
                nextDirection = Direction.LEFT;
            } else {
                nextDirection = Direction.RIGHT;
            }
            return;
        }
        nextMove = Move.MOVE;
        nextDirection = Math.random() < 0.5 ? Direction.LEFT : Direction.RIGHT;
    }
}

Stay
Stay doesn't like to walk. It simply shoots around and remembers if he shot a hunter.
package Hunters;

import Mechanics.*;

public class Stay extends Hunter {
    private Direction lastShot = Direction.LEFT;
    private Direction corpse = null;
    private boolean hunterNear = false;

    public Stay(){
        name = "Stay";
    }

    @Override
    public void newGame() {
        corpse = null;
        hunterNear = false;
        lastShot = Direction.LEFT;
    }

    @Override
    public void getResponse(boolean[] status){
        nextMove = Move.SHOOT;//always
        boolean hunterWasNear = hunterNear;
        hunterNear = status[1];

        if (hunterWasNear && status[2] && !status[1]) {
            corpse = lastShot;
        }

        if (status[0]) {
            if (corpse != null) {
                nextDirection = corpse;
                return;
            }
        }
        if ((status[1] && !status[4]) || status[0]) {
            switch (lastShot) {
                case LEFT: lastShot = nextDirection = Direction.RIGHT; break;
                case RIGHT: lastShot = nextDirection = Direction.BACK; break;
                case BACK: lastShot = nextDirection = Direction.LEFT; break;
            }
            return;
        }

        //default
        lastShot = nextDirection = Direction.LEFT;
    }
}


text:
Read numbers in the base of the largest digit and write it using underscores
This isn't as much a "challenge" as "a unique problem that there are no built-in functions to solve." Basically, you need to do this:

Read some lines of numbers from stdin. These lines may contain trailing or preceding whitespace, and there may be empty lines. No lines will contain "just whitespace" other than a newline. Each non-empty line will have exactly one number. This:
 123

456\t

(where \t is a tab) is considered valid input.
Read the numbers in the input in base N+1, where N is the largest digit in any of the lines. In this case, the largest digit is 6, so the numbers would be read in base 7, resulting in 6610 and 23710.
Find the sum of the numbers. The sum of 6610 and 23710 is 30310.
Convert the sum back to base N+1 again. We'd convert 30310 to base 7, which would be 6127.
For each digit, print that many underscores, followed by a space. The last digit should instead be followed by a newline or a space and a newline. In our example, that would be ______ _ __\n or ______ _ __ \n, where \n is the newline character.

Here's an example in Python:
import sys

def convert_to_base(n, b):
    'Convert `n` to base `b`'
    res = []
    while n:
        res.append(n % b)
        n /= b
    return res[::-1]

# read the lines, discarding empty ones and stripping any whitespace
lines = map(str.strip, filter(None, list(sys.stdin)))
# find the largest digit, and add 1 to it to make our base
base = max(map(max, (map(int, line) for line in lines)))+1
# read the lines in the base and sum them
result = sum(int(line, base) for line in lines)
# print the result in the original base using underscores, separated by spaces
for number in convert_to_base(result, base):
    print '_'*number,
# print a newline
print

This is code golf: the shortest program wins!

Can you add 7 and 10 to your instructions? - nevermind - i just did that.

@NotthatCharles What do you mean?

I was unclear about which base numbers were in.  I edited your question to make them explicit (pending review)

@NotthatCharles Ah! Thanks!

Pyth, 24 bytes
Just found this question via Twitter.
Notice that quite large parts of the program are similar to isaacg's solution (like base-conversion and the printing part), but the main algorithm is completely different.
.V0#jd*R\_jsiRbcjd.z)b.q

Try it online: Demonstration
My solution is based on this answer, I gave to a similar question two months ago.
Explanation:
.V0                       for b in [0, 1, 2, ...):
   #__________________.q    try-catch block. If ___ is successful, exit the program (.q),
                            otherwise do nothing
               cjd.z)         read all input (.z), join lines by spaces (jd) and split (c))
                              this gives a list of numbers (but still in string format)
            iRb               convert each number from base b
           s                  sum, add all numbers up
          j          b        convert to base b
      *R\_                    multiply each digit with "_"
    jd                        join with spaces
                              implicit print

The infinite loop .V0 combined with the try-catch #___.q basically finds the first number b >= 0, with which the conversion iRb doesn't throw an error. And this happens, when b is equal to the largest digit + 1.

Pyth, 26
JscR).zjd*R\_jsiRKhseSsJJK

Demonstration.
JscR).z
     .z                       Take the input as a list of lines.
  cR)                         Remove all whitespace from each line.
 s                            Combine the lines.
J                             Save the result to J.
                              J is now the list of the string forms of the numbers.
       jd*R\_jsiRKhseSsJJK
                      sJ      Combine J into one string.
                    eS        Find the maximum of that string.
                   s          Convert it to an integer.
                  h           Add one.
                 K            Save to K. K is the base.
               iRK      J     Convert the strings in J to base K.
              s               Add them together.
             j           K    Convert the result back to base K, as a list of ints.
         *R\_                 Map each int in that list to that many underscores.
       jd                     Join on spaces and print.

Your Pyth answers always manage to surprise me!

CJam, 28 27 bytes
q_$W=~)_@N%::~fb:+\b'_f*S*N

UPDATE - 1 byte saved thanks to Martin
Try it online here

PHP, 188 182
function f($s){$b=max(str_split($s))+1;foreach(preg_split('/\s/',$s)as$x)$m+=base_convert($x,$b,10);foreach(str_split(base_convert($m,10,$b))as$d)echo' ',str_repeat('_',$d);echo'

';}
prints a leading blank instead of a trailing one. if not accepted, add +1.
breakdown:
function f($s)
{
    $b=max(str_split($s))+1;           // find base
    foreach(preg_split('/\s/',$s)as$x) // extract all words and loop
        $m+=base_convert($x,$b,10);    // convert, sum up
    foreach(str_split(base_convert($m,10,$b))as$d) // convert back, split into array, loop
        echo' ',str_repeat('_',$d);    // print underscores
    echo'
';                                     // append newline
}

I wonder if there is a golfier approach to this ...

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/

sort: votes


text:
Sorting for Bozos
Introduction
This challenge is about three (bad) sorting algorithms: Bogosort, and two others variants that I came up with (but have probably been thought of by others at some point in time): Bogoswap (AKA Bozosort) and Bogosmart.
Bogosort works by completely shuffling the array randomly and checking if it becomes sorted (ascending). If not, repeat.
Bogoswap works by selecting two elements, randomly, and swapping them. Repeat until sorted (ascending).
Bogosmart works by selecting two elements, randomly, and only swapping them if it makes the array closer to being sorted (ascending), ie. if the element with the lower index was originally larger than the one with the higher. Repeat until sorted.
The Challenge
This challenge explores the efficiency (or lack of) of each of these three sorting algorithms. The golfed code will

generate a shuffled 8 element array of the integers 1-8 inclusive (keep reading to see how you should do this);
apply each algorithm to this array; and
display the original array, followed by the number of computations required for each algorithm, separated by one space (trailing space ok), in the format <ARRAY> <BOGOSORT> <BOGOSWAP> <BOGOSMART>.

The program will produce 10 test cases; you can generate all ten at the beginning or generate one at a time, whatever. Sample output below.
Details:
For Bogosort, it should record the number of times the array was shuffled.
For Bogoswap, it should record the number of swaps made.
For Bogosmart, it should record the number of swaps made.
Example output:
87654321 1000000 100 1
37485612 9050000 9000 10
12345678 0 0 0
28746351 4344 5009 5
18437256 10000 523 25
15438762 10000 223 34
18763524 58924 23524 5
34652817 9283 21 445
78634512 5748 234 13
24567351 577 24 34

I made up these numbers; of course, your program will print different output but in the same format.
Rules

All randomness used in your program must come from pseudorandom number generators available to you, and otherwise not computed extensively by you. You don't have to worry about seeds.
There is no time limit on the programs.
The arrays are to be sorted ascendingly.
Trailing spaces or an extra newline is no big deal.
For Bogosort, the array is to be shuffled using any unbiased shuffling algorithm such as Fisher-Yates or Knuth Shuffling, explicitly specified in your explanation. Built-in shuffling methods are not allowed. Generate your test arrays in the same manner.
If after shuffling or swapping the array remains the same, it still counts and should be included in the program's count. For example, shuffling the array to itself by coincidence counts as a shuffle, and swapping an element with itself counts as a swap, even though none of these operations change the array.
If my memory serves me correctly, an 8 element array shouldn't take too long for any of the three algorithms. In fact, I think a few times for a 10 element array, when I tried it, Bogoswap only required a few thousand (or less) actual shuffles and well under 10 seconds.
Your code must actually sort the arrays, don't just give expected values or mathematical calculations for an expected answer.
This is a code-golf challenge, so shortest program in bytes wins.

Here are some sample steps for each sorting algorithm:
BOGOSORT
56781234
37485612
28471653
46758123
46758123
12685734
27836451
12345678

BOGOSWAP
56781234
16785234
17685234
12685734
12685743
12685734
12485763
12385764
12385764
12345768
12345678

BOGOSMART
56781234
16785234
12785634
12785364
12785364
12385764
12385674
12345678

In this case, the program would output 56781234 7 10 7, and then do the same thing 10 times. You do not have to print the arrays while sorting is going on, but I gave the above sample steps so you can understand how each algorithm works and how to count computations.

There are 8! = 40,320 possible orders for an 8 element array. My math is not good enough to translated this into the expected (average) number of bogosort steps. But intuitively, it should be at least within an order of magnitude of that number. My theory is that bogosort and bogoswap will require the same average number of steps. Only that one step of bogoswap is cheaper, so the time will be lower.

I've done this before, and believe me you will be amazed at how different your thoughts differ from reality. You will find that, not surprisingly, Bogosort has the largest number of computations, then surprisingly Bogoswap has a lower, and of course Bogosmart takes even fewer. You will also be surprised by how few computations Bogosort needs, well below 40320.

In short, I don't expect this challenge to ruin your computer or swamp your memory.

Related. (For the shuffling and Bogosort part.)

Can we just output the number of steps from the mathematically correct distribution without doing the sorting?

No, the point of the challenge is to do the sorting. But a mathematical analysis of the algorithms and a mathematical explanation of the results would always be nice to see!

@FarazMasroor Then you need some rule to enforce that the sorting was done. You could require the sequence of arrays or steps as output.

I thought that it would be rather obvious to tell whether a program actually does the sorting, but I'll add that in anyway.

@FryAmTheEggman changed

May I assume that builtins returning a unique list of random numbers are also disallowed?

@kirbyfan64sos Correct

@FarazMasroor You did something wrong if Bogosort needed below 40320 trials. There is only one sorted partition out of 40320, and we stop after we find it. This is a geometric distribution. This tells us that the mean amount of shuffles we must do is 40320.

@FarazMasroor My BogoSwap and BogoSort are taking almost exactly the same number of steps...

@TheE I think they have to. Performing a random swap on a randomly order sequence produces another randomly ordered sequence. So you're testing randomly ordered sequences in both cases. I'm fairly confident that my initial thoughts don't "differ from reality" all that much. ;)

@RetoKoradi that's what I thought too, but it's always nice to check :)

Bozosort is listed on the Wikipedia page for Bogosort, so that one at least was thought of several years before you did.

It should also be noted that the average-case performance of these algorithms is O (( n +1)!).

Heads up, attempting to shuffle a list by doing a sort-by-random is biased.

Pyth, 62 60 bytes
VTjd[jkKJ=boO0=ZS8fqZ=KoO0K0fqZ=XJO.CJ2)0fqZ=Xb*>F=NO.Cb2N)0

This was quite fun. Not sure if this is valid, I'm probably using some unwritten loopholes.
A sample output would be:
23187456 22604 23251 110
42561378 125642 115505 105
62715843 10448 35799 69
72645183 7554 53439 30
61357428 66265 6568 77
62348571 1997 105762 171
78345162 96931 88866 241
17385246 51703 7880 80
74136582 36925 19875 100
26381475 83126 2432 25

Explanation:
My shuffle function uses the built-function order-by. Basically I assign each element of the list a random number of the interval [0-1) and sort the list by them. This gives me an unbiased random shuffle.
Outer loop
The VT at the start repeats the following code 10 times.
Preparation
jkKJ=boO0=ZS8
           S8        create the list [1, 2, 3, 4, 5, 6, 7, 8]
         =Z          and store in Z
      oO0            shuffle
    =b               and store in b
   J                 and store in J
  K                  and store in K (3 copies of the same shuffled array)
jkK                  join K with ""

Bogosort
fqZ=KoO0K0
     oO0K            shuffle K
   =K                and store the result in K
f        0           repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogoswap
fqZ=XJO.CJ2)0
       .CJ2          give all possible pairs of elements of J
      O              take a random one
    XJ     )         swap these two elements in J
   =                 and store the result in J
f           0        repeat ^ until:
 qZ K                  Z == K
                     and give the number of repeats

Bogosmart
fqZ=Xb*>F=NO.Cb2N)0
            .Cb2     give all possible pairs of elements of b
           O         take a random one
         =N          assign it to N
       >F N          check if N[0] > N[1]
      *         N    multiply the boolean with N
    Xb           )   swap the two (or zero) values in b
   =                 and assign to b
f                 0  repeat ^ until:
 qZ                    Z == b
                     and give the number of repeats

Printing
jd[
  [                  put all 4 values in a list
jd                    join by spaces and print

=JXJO.cJ2) is the same as =XJO.cJ2) - augmented assignment. Same holds for =bXb later. Also, I think swaps are supposed are supposed to have the pairs chosen with replacement (.C)

@isaacg Thanks, corrected things. Not sure if either .c or .C are allowed. For instance .C[3 1 2)2 doesn't return the pair [2, 1]. Which is a property, that I'm exploiting in my algorithm.

maybe *JJ then? It's also one character shorter, which is nice.

JavaScript (ES6), 319 345
Unsurprisingly this is quite long.
For Random shuffle, credits to @core1024 (better than mine for the same chellenge)
Test running the snippet (Firefox only as usual)

// FOR TEST : redefine console
var console = { log: (...p)=>O.innerHTML += p.join(' ')+'\n' }
// END

// Solution
R=n=>Math.random()*n|0,
S=a=>(a.map((c,i)=>(a[i]=a[j=R(++i)],a[j]=c)),a), // shuffle
T=f=>{for(a=[...z];a.join('')!=s;)f(a)}, // apply sort 'f'  algorithm until sorted

s='12345678';
for(i=0;i<10;i++)
  z=S([...s]),
  n=l=m=0,
  T(a=>S(a,++n)),
  T(a=>(t=a[k=R(8)],a[k]=a[j=R(8)],a[j]=t,++m)),
  T(a=>(t=a[k=R(8)],u=a[j=R(8)],(t<u?j<k:k<j)&&(a[k]=u,a[j]=t,++l))),
  console.log(z.join(''),n,m,l)

The "Run code snippet" link does not work for me. Not sure if it's my browser/system, but the snippet links have worked for me in the past.

Same, the code snippet doesnt work on my browser

@Reto et al EcmaScript 6: run on Firefox only.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
Heightmap of Boxes
Have a look at this ascii art diagram of various boxes:
+--------------------------------------------------------------+
|                                                              |
|   +-------------------------------+          +-------+       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   |     +----------------+        |          |       |       |
|   |     |                |        |          +-------+       |
|   |     |                |        |                          |
|   |     |                |        |          +-------+       |
|   |     +----------------+        |          |       |       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   +-------------------------------+          +-------+       |
|                                                              |
+--------------------------------------------------------------+

Each box is formed with pipe characters for the vertical parts (|), dashes for the horizontal parts (-), and pluses for the corners (+).
The diagram also shows boxes inside other boxes. We'll call the number of boxes that a box is contained within that box's layer. Here's the diagram again with the layer of each box annotated:
+--------------------------------------------------------------+
|                                                              |
|   +-------------------------------+          +-------+       |
|   |                               |          |       |       |
|   |                               |          |   1   |       |
|   |     +----------------+        |          |       |       |
|   |     |                |        |    0     +-------+       |
|   |     |        2       |   1    |                          |
|   |     |                |        |          +-------+       |
|   |     +----------------+        |          |       |       |
|   |                               |          |   1   |       |
|   |                               |          |       |       |
|   +-------------------------------+          +-------+       |
|                                                              |
+--------------------------------------------------------------+

Your program will take in a box diagram similiar to the one at the top as input. As output, your program should output the box diagram with:

The box on layer 0 should be filled with the character # (NB: There will only ever be one box on layer 0);
Boxes on layer 1 should be filled with the character =;
Boxes on layer 2 should be filled with the character -;
Boxes on layer 3 should be filled with the character .;
Boxes on layer 4 and above should not be filled.

Here is what the output of the example input should look like:
+--------------------------------------------------------------+
|##############################################################|
|###+-------------------------------+##########+-------+#######|
|###|===============================|##########|=======|#######|
|###|===============================|##########|=======|#######|
|###|=====+----------------+========|##########|=======|#######|
|###|=====|----------------|========|##########+-------+#######|
|###|=====|----------------|========|##########################|
|###|=====|----------------|========|##########+-------+#######|
|###|=====+----------------+========|##########|=======|#######|
|###|===============================|##########|=======|#######|
|###|===============================|##########|=======|#######|
|###+-------------------------------+##########+-------+#######|
|##############################################################|
+--------------------------------------------------------------+

Here is another input and output showing layers 3, 4, and 5. Note the horizontal lines at the top that are very close together. In these cases there is not enough space to fill any characters there.
+-----------------------------------------------------------------------+
|     +--------------------------------------------------------------+  |
|     |      +-----------------------------------------------------+ |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           |         |             |   | | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |                                         | | |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |                                                     | |  |
|     |      |                                                     | |  |
|     |      +-----------------------------------------------------+ |  |
|     |                                                              |  |
|     +--------------------------------------------------------------+  |
|                                                                       |
|                                                                       |
|                                                                       |
+-----------------------------------------------------------------------+

The output:
+-----------------------------------------------------------------------+
|#####+--------------------------------------------------------------+##|
|#####|======+-----------------------------------------------------+=|##|
|#####|======|---------+-----------------------------------------+-|=|##|
|#####|======|---------|...........+---------------------------+.|-|=|##|
|#####|======|---------|...........|         +-------------+   |.|-|=|##|
|#####|======|---------|...........|         |             |   |.|-|=|##|
|#####|======|---------|...........|         +-------------+   |.|-|=|##|
|#####|======|---------|...........+---------------------------+.|-|=|##|
|#####|======|---------|.........................................|-|=|##|
|#####|======|---------+-----------------------------------------+-|=|##|
|#####|======|-----------------------------------------------------|=|##|
|#####|======|-----------------------------------------------------|=|##|
|#####|======+-----------------------------------------------------+=|##|
|#####|==============================================================|##|
|#####+--------------------------------------------------------------+##|
|#######################################################################|
|#######################################################################|
|#######################################################################|
+-----------------------------------------------------------------------+

Another input, this time with the vertical lines close together as well:
+-------------+
|+-----------+|
||           ||
||           ||
||           ||
|+-----------+|
+-------------+

The output:
+-------------+
|+-----------+|
||===========||
||===========||
||===========||
|+-----------+|
+-------------+

Additional Notes

There can be whitespace around the outermost box.
Boxes cannot have an internal width or height of 0 (so they'll always be some space inside them)
Boxes on the same layer can touch each other.

Ruby 163 164
w=l=-1
x=$<.map{|l|w=l.size;l}.join
b=[]
x.size.times{|i|c=x[i]
x[i..i+1]=='+-'&&(x[i+w]!=?|?b-=[i%w]:b<?z&&l+=b&[i%w]!=[]?1:-1
$><<(c==' '&&'#=-.'[l]||c)}

Try online: test case #1, test case #2.
The ungolfed program:
  # read all lines from STDIN
  input = $<.map{|l|l}.join
  width = input.index(?\n)+1

  box_left_margins = []
  current_layer = -1

  input.size.times{|i|
    c = input[i]

    if c == ?+ && input[i+1] == ?-
      #we're at a box's left margin
      if input[i+width] == ?|
        # we're at the box's top - mark this index as a left margin
        box_left_margins <<< ('#=-.'[current_layer]||' ')
    else
      $><<c
    end
  }

Java, 476 466 bytes
import java.util.*;class H{public static void main(String[]a){Scanner p=new Scanner(System.in);char[]l=p.nextLine().toCharArray(),d={'#','=','-','.'};int s=l.length,b,i;int[]m=new int[s];String o=new String(l);for(;;){o+='\n';l=p.nextLine().toCharArray();if(l[0]=='+')break;o+='|';b=0;for(i=1;i<s;++i){char c=l[i];switch(c){case' ':c=b>3?' ':d[b];break;case'+':m[i]=l[i-1]=='-'?-++m[i]:- --m[i];break;case'|':b+=m[i];}o+=c;}}o+=new String(l);System.out.println(o);}}

This reads the first line to determine the width (s) of the outermost box. With this it keeps an array of length s. This array stores from left to right where boxes begin and end and is initialized with 0s. It also stores the box-height.
The program reads the input line by line and watches for the following characters:

'+' is, as we know, the edge of a box. If the input char to the left is a '-', it is the end of the box, else it is the beginning. The marker array gets updated as follows:

If the marker at this index is 0, set the value to 1 (beginning) or -1 (end).
Else set the value to 0. (We reached the bottom of the box, it is not important anymore)

'|' changes the current box-height by the marker at the current index.
' ' Every char gets output as it was, except for blanks, which are replaced according to the current box-height.

Edit: Thanks to TheNumberOne for the suggestion.
I also replaced while(true) with for(;;).

You can replace import java.util.Scanner with import java.util.*

CJam, 114 111 108 104 103 102 98 bytes
q"-+":R/Ws*N/z{_,{"|1"/Bs*}*}%z{_,,{_I=S&{_I>_1sf&s,\"|+"f&s,m5e<" #=2."=I\t}&}fI}%N*Ws/R*Cs"|-"er

Try it online in the CJam interpreter.
How it works
q               e# Read all input from STDIN.
"-+":R/Ws*      e# Replace each "-+" with "-1".
N/z             e# Split at linefeeds and zip. Pushes the array of columns.
{               e# For each column:
  _,            e#   Push its length.
  {             e#   Do that many times:
    "|1"/Bs*    e#   Replace each "|1" with "11".
  }*            e#
}%              e#
z               e# Transpose. Goes back to array of rows.
{               e# For each row:
  _,,           e#   Push the array of its indexes.
  {             e#   For each index I:
    _I=         e#     Get the Ith character of the row.
    S&{         e#     If it is a space:
      _I>       e#       Get the characters after the Ith.
      _1sf&s,   e#       Count how many characters are 1's.
      \"|+"f&s, e#       Count how many are |'s or +'s.
      m5e<      e#       Subtract and truncate at 5.
      " #=2."=  e#       Retrieve the corresponding character.
      I\t       e#       Replace the Ith character of the row with that one.
    }&          e#
  }fI           e#
}%              e#
N*              e# Join the rows, separating by linefeeds.
Ws/R*           e# Turn "-1"s back to "-+"s.
Cs"|-"er        e# Turn 1's and 2's into |'s and -'s.

JavaScript (ES6) 156
Run snippet in Firefox to test

F=b=>(
  r=b.split(/\n/),q=[n=0],
  r.map((r,i)=>(
    [...r].map((c,p)=>c=='+'?(q[p]=r[p-1]=='-'?-1:1,c):c<'!'?' #=-.'[n]||' ':((n+=q[p]|0),c)).join(''))
  ).join('\n')
)

// TEST

o=x=>O.innerHTML += x+'\n\n'

;[`+--------------------------------------------------------------+
|                                                              |
|   +-------------------------------+          +-------+       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   |     +----------------+        |          |       |       |
|   |     |                |        |          +-------+       |
|   |     |                |        |                          |
|   |     |                |        |          +-------+       |
|   |     +----------------+        |          |       |       |
|   |                               |          |       |       |
|   |                               |          |       |       |
|   +-------------------------------+          +-------+       |
|                                                              |
+--------------------------------------------------------------+`
,`+-----------------------------------------------------------------------+
|     +--------------------------------------------------------------+  |
|     |      +-----------------------------------------------------+ |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           |         |             |   | | | |  |
|     |      |         |           |         +-------------+   | | | |  |
|     |      |         |           +---------------------------+ | | |  |
|     |      |         |                                         | | |  |
|     |      |         +-----------------------------------------+ | |  |
|     |      |                                                     | |  |
|     |      |                                                     | |  |
|     |      +-----------------------------------------------------+ |  |
|     |                                                              |  |
|     +--------------------------------------------------------------+  |
|                                                                       |
|                                                                       |
|                                                                       |
+-----------------------------------------------------------------------+`
,`+-------------+
|+-----------+|
||           ||
||           ||
||           ||
|+-----------+|
+-------------+`
].forEach(t=>o(t+'\n'+F(t)+'\n'))
pre { font-size:10px;}

CJam, 76 74 bytes
q:Q"-+":R/Ws*{_"| "#"]_QN#~%'|m0='+=2*(U+:U+~; \"#=-.\"+U5e<= "S/=~}%Ws/R*

Try it online in the CJam interpreter.
How it works
q:Q        e# Read all input from STDIN and save it in the variable Q.
"-+":R/Ws* e# Replace each "-+" with "-1".
           e# This allows us to easily keep track of right corners.
{          e# For each charcter in the modified input:
  _"| "#   e#   Push its index in the string (0 for '|', 1 for ' ', -1 otherwise).

  "]_QN#~%'|m0='+=2*(U+:U+~; \"#=-.\"+U5e<= "S/

           e#   Split the pushed string at spaces, which results in three chunks:

           e#     ]        Turn the entire stack into a string.
           e#     _QN#     Compute the first index of a linefeed (row length).
           e#     ~%       Retrieve every previous character in the current column,
           e#              starting with the last.
           e#     '|m0=    Get the first character that is not a vertical bar.
           e#     '+=2*(   Push 1 if it's a plus sign and -1 otherwise.
           e#     U+:U     Add to U (initially 0) to keep track of the layer.
           e#     +~;      Add U to the string (casts to Array), dump and discard U.

           e#     "#=-."+  Concatenate this string with the space on the stack.
           e#     U5e<     Truncate U at 5.
           e#     =        Retrieve the corresponding character to replace the space.

           e#     (empty)

  =~       e#   Select and execute the proper chunk.
}%         e#
Ws/R*      e# Replace each "-1" with "-+".

APL (Dyalog Unicode), 50 bytesSBCS
s[⊃¨0~¨⍨a,¨5|5⌊+⍀+\(⊢×¯1*+⍀++\)5=a←⎕⍳⍨s←' #=-.+|']

Try it online!
s←' #=-.+|' assign a string to variable s
⎕ evaluated input, it must be a character matrix
⎕⍳⍨s replace every element of ⎕ with its index in s
a← assign to a
5= return a boolean matrix of where the +-es are in a (s[5] is '+')
(⊢×¯1*+⍀++\) this is a train of functions:

+\ matrix of partial sums by row
+ plus
+⍀ matrix of partial sums by column
¯1* negative one to the power of - turn odds into ¯1 and evens into 1
⊢× multiply by the train's argument - zero out everything except box corners

+⍀+\ partial sums by column of partial sums by row
5⌊ minimum of that and 5
5| modulo 5
a,¨ pair up the elements of a and of the current matrix
0~¨⍨ remove 0 from the pairs
⊃¨ first each of what's remaining
s[ ] use every element as an index in s

oh no!

@EriktheOutgolfer No need to worry, the answer is correct :) The expression that prepares the argument (mixes raw input lines into a matrix) should reverse it because ↑⍞⍞...⍞ evaluates right-to-left. For the first example it didn't matter and I forgot to mention this.

except that it still fills with .s where it shouldn't

@EriktheOutgolfer ah, I see... I'll delete the answer now and I'll fix it later. Thanks.

should be fixed now

And you still beat CJam. Cool!

C (gcc), 190 179 bytes
-11 bytes thanks to ceilingcat
Fails if sizeof(int) > 9, but then you can take solace in the fact that your computer is from the future.
l;*H,*h,d;f(S){h=H=calloc(l=index(S,10)-S,9);for(char*s=S;*s;s++)h=*s^10?h:H-1,d=*s-43?d:s!=S&s[-1]==45|s-S>l&s[~l]=='|'?-1:1,*h+=*s^45?0:d,h+=write(1,*s^32|*h>4?s:" #=-."+*h,1);}

Try it online!

><>, 118 115 87 bytes
]0{i:0(?;:"-"=?\:"+"=?\:" "=?\$3l$g+}:ob(?
~$?:g2.10p1+4f:<p3l+10/.16@:$/>.!0"#"$
 #=-.

Try it online!
If one of the symbols wasn't a - then this could be 6 bytes shorter. Eh, made it a bit lot smaller anyway
How It Works:
] Resets the stack
 0{ Pushes a 0 and rotates the stack
    If the stack is empty, this initialises 0 as the counter
    Otherwise it adds an extra 0 to the stack and pushes the counter to the top
   i:0(?; Gets input and ends if it is EOF
         :"-"=?\ If the inputted character is a -
         p1+4f:< Put a - at cell (19, 1)
      .10        And skip to the end of this line

         :"+"=?\ Else if the inputted character is +
            ?10/ Generate either -1 or 1, depending on what was last put into cell (19,1)
                 The question mark represents cell (19,1), which is either + or -
         p3l     Put this number on (3, length of the stack)
.10p1+4f:<       Repeat the exact same code as with the -, except we put a + at cell (19,1)
         :" "=?\ Else if the character is a space
            @:$/ Create a copy of the counter
         .16     Skip to cell (1,6)
      g2         Get the cell (2, counter) (the  #=-.)
   ~$?           If that cell is a zero, pop it, leaving the initial space.
                 Else pop the space, leaving the fetched character
        Else if the character is a | or a newline
        $3l$g+   Get the cell at (3, length of the stack) and add it to the counter
    For everything but the last else, we are at the end of the second line
       >.!0"#"$ Skip to the 35th instruction on the first line

 } Push the counter to the bottom of the stack
  :o Output the current character
    b(? If the character is smaller than 11 (a newline)
 ]          Skip the clear stack at the start of the line
 Repeat this until EOF

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
Chaining autograms
Write a program that takes one integer input n and one format letter and outputs n autograms in the format This sentence contains ? "A"s, ? "B"s ... and ? "Z"s.

Each question mark ? represents the number of times the the following letter appears in the text
All numbers will be written as text. To make it equally unfair for Americans and Brits your program has to be able to print either system! Pass a format letter in to choose which system, A for American and B for British. This will not matter for the first few sentences as they will have fewer than one hundred of each letter but will definitely be needed by the time you get to ten sentences

American: one hundred twenty three, etc.
British: one hundred and twenty three, etc.

The integer (let's call it n) is used to vary the number of sentences produced. When n is greater than 1 each subsequent sentence will start with two newlines and then the following text: The preceding text plus this sentence contain ... where the ellipsis ... represents the count of each letter that appears
You do not have to include a letter if it doesn't otherwise appear, although if you do choose to, it might simplify the challenge. I don't know, though, it might make it harder so it's your call! If you include all twenty six letters your answer will also be a pangram!
You can't say zero "Y"s because you have to use a Y to say it!
You can only say one "Y" if Y doesn't appear anywhere else in the text
You can't repeat a letter and its count within each sentence, i.e. three "N"s, three "N"s is not allowed
Your output must use good English! Any appearance of ... "X"s, one "Y"s..., for example, will invalidate your answer!
In each sentence you must enumerate the letters in alphabetical order
Only letters A-Z will be counted, not symbols, punctuation or spaces
The letters will be counted case-insensitively, i.e. A will be equivalent to a

Since the level n output also contains the output for each lower level to n-1 you only need to show your source code and the output for level 10. There may be multiple solutions so your answer might be different from someone else's answer!
An example (n=1) is:
This sentence employs two a’s, two c’s, two d’s, twenty-eight e’s, five f’s, three g’s, eight h’s, eleven i’s, three l’s, two m’s, thirteen n’s, nine o’s, two p’s, five r’s, twenty-five s’s, twenty-three t’s, six v’s, ten w’s, two x’s, five y’s, and one z.

Note, however, that my requirements are slightly different! You must use contains, not employs and surround each letter (in capitals) with double quotes ". It's your choice whether you use hyphens - or not between the words of the numbers.
Your final output will look something like this. Note that the first sentence uses contains but the subsequent sentences use contain:
This sentence contains ten "A"s, ...

The preceding text plus this sentence contain twenty "A"s, ...

The preceding text plus this sentence contain thirty "A"s, ...

...

The preceding text plus this sentence contain one hundred "A"s, ...

You can use the following snippet to check your output.

// Apologies for the hugeness of this snippet. It's my first!
word = {
  1: 'one',
  2: 'two',
  3: 'three',
  4: 'four',
  5: 'five',
  6: 'six',
  7: 'seven',
  8: 'eight',
  9: 'nine',
  10: 'ten',
  11: 'eleven',
  12: 'twelve',
  13: 'thirteen',
  14: 'fourteen',
  15: 'fifteen',
  16: 'sixteen',
  17: 'seventeen',
  18: 'eighteen',
  19: 'nineteen',
  20: 'twenty',
  30: 'thirty',
  40: 'forty',
  50: 'fifty',
  60: 'sixty',
  70: 'seventy',
  80: 'eighty',
  90: 'ninety',
  100: 'hundred',
  1000: 'thousand',
}

var format;

function count_letters() {
  var check_text = [];
  var text = document.getElementById("golf").value;
  text = text.replace(/-/g, " ");
  text = text.replace(/\r\n?/g, "\n");
  format = text.match(/\w\w and /)? 'B': 'A';
  var lines = text.split(/\n\n/);
  var let_count = {};
  for (n = 0; n < lines.length; ++n) {
    var keys = [];
    var sentence = '';
    var letters = lines[n].toUpperCase().match(/[A-Z]/g);
    for (var i = 0; i < letters.length; ++i) {
      if (!(letters[i] in let_count)) {
        let_count[letters[i]] = 0;
      }
      let_count[letters[i]]++;
    }
    for (i in let_count) {
      if (let_count.hasOwnProperty(i)) {
        keys.push(i);
      }
    }
    keys.sort();
    for (i = 0; i < keys.length - 1; ++i) {
      if (sentence) {
        sentence += ", ";
      }
      var num_text = number(let_count[keys[i]], format);
      sentence += num_text + ' "' + keys[i] + '"';
      if (let_count[keys[i]] > 1) {
        sentence += "s";
      }
    }
    num_text = number(let_count[keys[i]], format);
    sentence += " and " + num_text + ' "' + keys[i] + '"';
    if (let_count[keys[i]] > 1) {
      sentence += "s";
    }
    sentence = check_text.length == 0? "This sentence contains " + sentence + ".": "The preceding text plus this sentence contain " + sentence + ".";
    check_text.push(sentence);
  }
  document.getElementById("output").value = check_text.join("\n\n");

  for (n = 0; n < lines.length; ++n) {
    if (check_text[n] != lines[n]) {
      break;
    }
  }
  document.getElementById("correct").innerText = n;
}

function number(num, format) {
  num = (num + "").split("").reverse().join("");
  digit = num.match(/\d/g);
  text = "";

  // Thousands
  if (digit[3]) {
    text += word[digit[3]] + " " + word[1000];
    // Hundreds
    if (digit[2] > 0) {
      text += " ";
    }
    // Tens and units
    else if ((digit[1] + digit[0]) * 1 > 0) {
      text += " and ";
    }
  }

  // Hundreds
  if (digit[2] > 0) {
    text += word[digit[2]] + " " + word[100];
    // Tens and units
    if ((digit[1] + digit[0]) * 1 > 0) {
      text += " and ";
    }
  }
  if (typeof(digit[1]) == "undefined") {
    digit[1] = 0;
  }
  if (digit[1] < 2) {
    if ((digit[1] + digit[0]) * 1) {
      text += word[(digit[1] + digit[0]) * 1];
    }
  }
  else {
    text += word[digit[1] * 10];
    if (digit[0] > 0) {
      text += " " + word[digit[0]];
    }
  }

  if (format != 'B') {
    text = text.replace(/ and /g, format == 'A'? " ": " ! ");
  }

  return text;
}
<textarea id="golf" cols="80" rows="25">
This sentence employs two "A"s, two "C"s, two "D"s, twenty-eight "E"s, five "F"s, three "G"s, eight "H"s, eleven "I"s, three "L"s, two "M"s, thirteen "N"s, nine "O"s, two "P"s, five "R"s, twenty-five "S"s, twenty-three "T"s, six "V"s, ten "W"s, two "X"s, five "Y"s, and one z.</textarea>

<input type="button" value="Count the letters!" onclick="count_letters()"/>

<textarea id="output" cols="80" rows="10">
</textarea>

Number of correct sentences:

Surely there are a finite number of autograms?

@feersum When you chain them together there are an infinite number.

What's the largest number name we need to support theoretically?

I doubt you'll get to one thousand after only ten times but I'm pretty sure you'll get over one hundred. Take a look at the example autogram. It uses 28 "E"s, 25 "S"s and 23 "T"s for n=1.

You mention in the first sentence that one input is a "format letter". But I can't find anything describing how that input is used, and I also don't see a value specified for the example.

so... no hyphens for, e.g., twenty-eight?

@NotthatCharles You can use hyphens if you want. Both twenty eight and twenty-eight will be considered valid.

There seems to be a problem with your code snippet. For the sentences >= 2, It contains the string The previous text while the code golf specifies The preceding text

Haskell, 2161 bytes
-- https://codegolf.stackexchange.com/questions/51264/chaining-autograms
-- https://www.leesallows.com/files/Reflexicons%20NEW(4c).pdf

import Data.Char
import Data.List
import Data.Array

import System.IO.Unsafe
import System.Random

pick []=[]
pick pool=[pool!!(unsafePerformIO.randomRIO)(0,length pool-1)]

instance (Num a, Ix i) => Num(Array i a) where
 a+b=accum(+)a(assocs b)
 a-b=accum(-)a(assocs b)
 (*)=undefined;fromInteger=undefined;signum=undefined;abs=undefined

azarra=accumArray(+)0('A','Z')::[(Char,Int)]->Array Char Int
squeeze=azarra.map(\c->(toUpper c,1)).filter isLetter

autogram n b = let
 band
  |b=='B'=" and "
  |b=='A'=" "
 name 0="zero";
 name 1="one"
 name 2="two"
 name 3="three"
 name 4="four"
 name 5="five"
 name 6="six"
 name 7="seven"
 name 8="eight"
 name 9="nine"
 name 10="ten"
 name 11="eleven"
 name 12="twelve"
 name 13="thirteen"
 name 14="fourteen"
 name 15="fifteen"
 name 16="sixteen"
 name 17="seventeen"
 name 18="eighteen"
 name 19="nineteen"
 name 20="twenty"
 name 30="thirty"
 name 40="forty"
 name 50="fifty"
 name 60="sixty"
 name 70="seventy"
 name 80="eighty"
 name 90="ninety"
 name n|n<100=name(10*div n 10)++'-':name(mod n 10)
 name n|n<1000&&mod n 100==0=name(div n 100)++" hundred"
 name n|n<1000=name(100*div n 100)++band++name(mod n 100)
 name n|mod n 1000==0=name(div n 1000)++" thousand"
 name n=name(1000*div n 1000)++" "++name(mod n 1000)

 endr=9999
 nam2 0=""
 nam2 i='s':name(1+i)
 wtwo(i,v)=if v>0 then tail$nam2 v++" \""++[i]++"\"s" else ""
 repr=listArray(0,endr)$map(squeeze.nam2)[0..endr]
 self=foldl1(+).map(repr!).filter(>0).elems

 solv pret=let
  fixall guess=pret+self guess
  deficit guess=fixall guess-guess
  fixone guess=accum(+)guess$pick.filter((/=0).snd).assocs.deficit$guess
  terminate(a:b:c)|a==b=a|True=terminate(b:c)
  in terminate$iterate(fixone.fixall)pret

 solve prepent=
  (prepent++).(++".\n").
  intercalate", ".(\s->init s++["and "++last s]).map wtwo.
  filter((>0).snd).assocs.solv.squeeze$prepent++"and"

 in solve$if n==1 then "This sentence contains "
  else autogram(n-1)b++"The preceding text plus this sentence contain "

main=putStrLn $ autogram 2 'B'

Try it online!
This sentence contains three "A"s, three "C"s, two "D"s, twenty-seven "E"s, four "F"s, two "G"s, ten "H"s, eight "I"s, thirteen "N"s, six "O"s, ten "R"s, twenty-five "S"s, twenty-three "T"s, three "U"s, three "V"s, six "W"s, three "X"s, and four "Y"s.
The preceding text plus this sentence contain six "A"s, seven "C"s, five "D"s, sixty-four "E"s, thirteen "F"s, six "G"s, eighteen "H"s, twenty-six "I"s, four "L"s, thirty-three "N"s, eleven "O"s, three "P"s, nineteen "R"s, fifty-five "S"s, forty-five "T"s, seven "U"s, eleven "V"s, eight "W"s, nine "X"s, and ten "Y"s.
The preceding text plus this sentence contain ten "A"s, eleven "C"s, eleven "D"s, one hundred and fourteen "E"s, nineteen "F"s, ten "G"s, twenty-six "H"s, forty-two "I"s, nine "L"s, sixty-seven "N"s, eighteen "O"s, six "P"s, twenty-five "R"s, eighty-six "S"s, seventy-one "T"s, eleven "U"s, nineteen "V"s, thirteen "W"s, fifteen "X"s, and seventeen "Y"s.
The preceding text plus this sentence contain seventeen "A"s, fifteen "C"s, twenty-six "D"s, one hundred and sixty-three "E"s, twenty-eight "F"s, fifteen "G"s, thirty-nine "H"s, sixty-two "I"s, twelve "L"s, one hundred and eight "N"s, twenty-seven "O"s, nine "P"s, thirty-five "R"s, one hundred and fifteen "S"s, one hundred and nine "T"s, eighteen "U"s, twenty-four "V"s, twenty-two "W"s, twenty "X"s, and twenty-nine "Y"s.
The preceding text plus this sentence contain twenty-four "A"s, nineteen "C"s, forty-one "D"s, two hundred and eight "E"s, forty-five "F"s, nineteen "G"s, fifty-two "H"s, seventy-eight "I"s, fifteen "L"s, one hundred and forty-two "N"s, forty-seven "O"s, twelve "P"s, fifty-four "R"s, one hundred and forty-three "S"s, one hundred and forty-seven "T"s, twenty-six "U"s, thirty-one "V"s, thirty-one "W"s, twenty-three "X"s, and forty-five "Y"s.
The preceding text plus this sentence contain thirty-two "A"s, twenty-three "C"s, fifty-nine "D"s, two hundred and fifty-six "E"s, fifty-nine "F"s, twenty-seven "G"s, seventy-two "H"s, one hundred and six "I"s, seventeen "L"s, one hundred and eighty-one "N"s, fifty-eight "O"s, fifteen "P"s, sixty-eight "R"s, one hundred and seventy-five "S"s, one hundred and eighty-nine "T"s, thirty-four "U"s, thirty-eight "V"s, thirty-eight "W"s, twenty-nine "X"s, and sixty-three "Y"s.
The preceding text plus this sentence contain forty "A"s, twenty-seven "C"s, seventy-seven "D"s, three hundred and eight "E"s, sixty-seven "F"s, thirty-five "G"s, ninety "H"s, one hundred and twenty-five "I"s, nineteen "L"s, two hundred and eighteen "N"s, seventy "O"s, eighteen "P"s, eighty-four "R"s, two hundred and eight "S"s, two hundred and twenty-eight "T"s, forty-two "U"s, forty-seven "V"s, forty-six "W"s, thirty-three "X"s, and seventy-nine "Y"s.
The preceding text plus this sentence contain fifty-one "A"s, thirty-one "C"s, one hundred and four "D"s, three hundred and forty-nine "E"s, eighty-five "F"s, forty "G"s, one hundred and eight "H"s, one hundred and forty-nine "I"s, twenty-one "L"s, two hundred and sixty-one "N"s, ninety-two "O"s, twenty-one "P"s, one hundred and four "R"s, two hundred and thirty-six "S"s, two hundred and sixty-five "T"s, fifty-five "U"s, fifty-two "V"s, fifty-four "W"s, thirty-eight "X"s, and ninety-seven "Y"s.
The preceding text plus this sentence contain sixty-four "A"s, thirty-five "C"s, one hundred and thirty-seven "D"s, four hundred and six "E"s, ninety-four "F"s, forty-three "G"s, one hundred and twenty-nine "H"s, one hundred and sixty-seven "I"s, twenty-five "L"s, three hundred and eleven "N"s, one hundred and eleven "O"s, twenty-four "P"s, one hundred and twenty-eight "R"s, two hundred and seventy "S"s, three hundred and two "T"s, seventy-one "U"s, sixty-one "V"s, sixty-two "W"s, forty-six "X"s, and one hundred and thirteen "Y"s.
The preceding text plus this sentence contain seventy-eight "A"s, thirty-nine "C"s, one hundred and seventy-three "D"s, four hundred and seventy "E"s, one hundred and seven "F"s, fifty-one "G"s, one hundred and fifty-five "H"s, one hundred and eighty-eight "I"s, twenty-seven "L"s, three hundred and sixty-two "N"s, one hundred and twenty-eight "O"s, twenty-seven "P"s, one hundred and fifty-one "R"s, three hundred and four "S"s, three hundred and forty-three "T"s, eighty-six "U"s, seventy "V"s, sixty-eight "W"s, fifty-one "X"s, and one hundred and thirty-two "Y"s.

Very good! No, really truly excellent! But it doesn't exactly meet the requirements (I realise now I could have been a bit more specific). 'This sentence contains two "A"s, three "C"s, [...], three "X"s, and three "Y"s.' There should be an "and" before the final letter and its count. Can you make that modification?

Yes.  Inserted the and.

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/