text:
Convert English to a number
Short and sweet description of the challenge:
Based off the ideas of several other questions on this site, your challenge is to write the most creative code in any program that takes as input a number written out in English and converts it to integer form.
Really dry, long and thorough specifications:

Your program will receive as input an integer in lowercase English between zero and nine hundred ninety-nine thousand nine hundred ninety-nine inclusive.
It must output only the integer form of the number between 0 and 999999 and nothing else (no whitespace).
The input will NOT contain , or and, as in one thousand, two hundred or five hundred and thirty-two.
When the tens and ones places are both nonzero and the tens place is greater than 1, they will be separated by a HYPHEN-MINUS character - instead of a space. Ditto for the ten thousands and thousands places. For example, six hundred fifty-four thousand three hundred twenty-one.
The program may have undefined behavior for any other input.

Some examples of a well-behaved program:
zero -> 0
fifteen -> 15
ninety -> 90
seven hundred four -> 704
sixty-nine thousand four hundred eleven -> 69411
five hundred twenty thousand two -> 520002

This isn't especially creative, nor does it precisely match the specification here, but it might be useful as a starting point: https://github.com/ghewgill/text2num/blob/master/text2num.py

I could almost post my answer to this question.

Why do complicated string parsing? http://pastebin.com/WyXevnxb

By the way, I saw an IOCCC entry which is the answer of this question.

What about things like "four and twenty?"

@fluffy Assume the program only needs to handle standard American English, so it would be inputted as twenty-four rather than four and twenty.

This has been put on hold as off-topic. See the [popularity-contest] tag wiki for info on creating a good popularity contest. A clear specification of the goal that must be achieved. Questions like "do (this) the most creative way" should be avoided. Creativity should be the tool, not the goal.

Applescript
A silly, hacky mash-up that might upset some Cupertino/Mountain View folks, but I think its a creative silly, hacky mash-up.
set myNumber to text returned of (display dialog ¬
    "Enter number as text:" buttons {"Continue…"} ¬
    default answer "" default button 1)
tell application "Google Chrome"
    activate
    open location "https://www.google.com"
end tell
delay 5
say "ok google. " & myNumber
delay 2
tell application "System Events"
    tell application process "Google Chrome"
        set fullURL to value of text field 1 of toolbar 1 of window 1
    end tell
end tell
set AppleScript's text item delimiters to "="
display alert item 2 of text items of fullURL

Uses OSX text to speech to speak the text number, and google audio search to listen for it and convert it to an integer.
Requirements

OSX
Google chrome
speech-recognition enabled in your google account
volume turned up to a reasonable level

The delay timings may need to be adjusted depending on your chrome load time and google lookup time.
Example input:

Example output:

I think that might be just a little creative... ;)

Lol, this is cool

Maybe too creative.

After one week, your answer is clearly in the lead at 74 votes, so I think that means that.. you win! By the way, mind if I use this code? It would be really useful for a lot of real-world projects I'm working on right now! ;)

@Abraham Thanks!  You're joking about using this in production code, right?

Bash, 93 64 55 characters*
In the fantastic bsd-games package that's available on most Linux operating systems, there's a small command-line toy called number. It turns numbers into English text, that is, it does the exact opposite of this question. It really is the exact opposite: all the rules in the question are followed by number. It's almost too good to be a coincidence.
$ number 42
forty-two.

Of course, number doesn't answer the question. We want it the other way around. I thought about this for a while, tried string parsing and all that, then realised that I can just call number on all 999.999 numbers and see if something matches the input. If so, the first line where it matches has twice the line number I'm looking for (number prints a line of dots after every number). Simple as that. So, without further ado, here's the complete code for my entry:
seq 0 999999|number -l|awk "/$1/{print (NR-1)/2;exit}"

It even short-circuits, so converting "two" is quite fast, and even higher numbers are usually decoded in under a second on my box. Here's an example run:
wn@box /tmp> bash unnumber.sh "zero"
0
wn@box /tmp> bash unnumber.sh "fifteen"
15
wn@box /tmp> bash unnumber.sh "ninety"
90
wn@box /tmp> bash unnumber.sh "seven hundred four"
704
wn@box /tmp> bash unnumber.sh "sixty-nine thousand four hundred eleven"
69411
wn@box /tmp> bash unnumber.sh "five hundred twenty thousand two"
520002

Of course, you'll need to have number installed for this to work.

*: Yes, I know, this is not a code-golf challenge, but shortness is pretty much the only discerning quality of my entry, so... :)

+1.  For me, using number in reverse is the most creative thing about this answer.  The golfiness is good too though :)

This is actually quite creative! I like it!

Javascript
(function parse(input) {
  var pat = "ze/on/tw/th.?r/fo/fi/ix/se/ei/ni/ten/ele".split("/");
  var num = "", last = 0, token = input.replace(/-/g, " ").split(" ");
  for(var i in token) {
    var t = token[i];
    for(var p in pat) if(t.match(RegExp(pat[p])) !== null) num += "+" + p;
    if(t.indexOf("een") >= 0) num += "+10";
    if(t.indexOf("lve") >= 0) num += "+10";
    if(t.indexOf("ty") >= 0) num += "*10";
    if(t.indexOf("dr") >= 0) { last = 100; num += "*100"; }
    if(t.indexOf("us") >= 0) {
      if(last < 1000) num = "(" + num + ")"; last = 0;
      num += "*1000";
    }
  }
  alert(eval(num));
})(prompt());

Do you like some eval()?
Run this script on your browser's console.
Edit: Thanks for the feedback. Bugs fixed (again).

really nice code ^^

When you type something like "one hundred sixteen", it'll give 126.

This program fails for some numbers starting at twelve when it returns 23.

Fails on "twenty".

seven thousand three hundred thirty five give me 10335

@ImmerAllein It will work now.

Python
Just to get the ball rolling.
import re
table = {'zero':0,'one':1,'two':2,'three':3,'four':4,'five':5,'six':6,'seven':7,'eight':8,'nine':9,
         'ten':10,'eleven':11,'twelve':12,'thirteen':13,'fourteen':14,'fifteen':15,'sixteen':16,'seventeen':17,'eighteen':18,'nineteen':19,
         'twenty':20,'thirty':30,'forty':40,'fifty':50,'sixty':60,'ninety':90}
modifier = {'hundred':100,'thousand':1000}

while True:
    text = raw_input()
    result = 0
    tmp = 0
    last_multiplier = 1
    for word in re.split('[- ]', text):
        multiplier = modifier.get(word, 1)
        if multiplier > last_multiplier:
            result = (result+tmp)*multiplier
            tmp = 0
        else:
            tmp *= multiplier
        if multiplier != 1:
            last_multiplier = multiplier
        tmp += table.get(word,0)
    print result+tmp

Perl + CPAN
Why reinvent the wheel, when it has been done already?
use feature 'say';
use Lingua::EN::Words2Nums;

say words2nums $_ while <>;

This program reads English strings from standard input (or from one or more files specified as command line arguments), one per line, and prints out the corresponding numbers to standard output.
I have tested this code using both the sample inputs from the challenge, as well as an exhaustive test suite consisting of the numbers from 0 to 999999 converted to text using the bsd-games number utility (thanks, Wander Nauta!), and it correctly parses all of them.  As a bonus, it also understands such inputs as e.g. minus seven (−7), four and twenty (24), four score and seven (87), one gross (144), a baker's dozen (13), eleventy-one (111) and googol (10100).
(Note: In addition to the Perl interpreter itself, this program also requires the CPAN module Lingua::EN::Words2Nums.  Here are some instructions for installing CPAN modules.  Debian / Ubuntu Linux users may also install this module via the APT package manager as liblingua-en-words2nums-perl.)

Python
A general recursive solution, with validity checking. Could be simplified for the range of numbers required, but here's to showing off I guess:
terms = 'zero one two three four five six seven eight nine ten eleven twelve thirteen fourteen fifteen sixteen seventeen eighteen nineteen'.split()
tee  = 'twenty thirty forty fifty sixty seventy eighty ninety'.split()
for t in tee:
    terms.append(t)
    for s in terms[1:10]:
        terms.append(t+'-'+s)

terms = dict(zip(terms, range(100)))

modifiers = [('hundred', 100), ('thousand', 1000), ('million', 10**6), ('billion', 10**9)]

def read_num(words):
    if len(words) == 0: return 0
    elif len(words) == 1:
        if words[0] in terms:
            return terms[words[0]]
        else:
            raise ValueError(words[0]+' is not a valid english number.')
    else:
        for word, value in reversed(modifiers):
            if word in words:
                i = words.index(word)
                return read_num(words[:i])*value+read_num(words[i+1:])

    raise ValueError(' '.join(words)+' is not a valid english number.')

while True:
    try:
        print(read_num(input().split()))
    except ValueError as e:
        print(e)

VBScript 474
This is a fairly routine answer... unfortunately, so routine that @Snack pretty much posted the same process but before me.
i=split(REPLACE(REPLACE(inputbox(""),"lve","een"),"tho","k"))
o=split("z on tw th fo fi si se ei ni ten ele")
y=split("red *100) k )*1000 ty *10) een +10)")
z=""
p=0
for t=0 to UBOUND(i)
    s=split(i(t),"-")
    u=ubound(s)
    r=s(0)
    for x=0 to UBOUND(o)
        IF INSTR(r,o(x)) THEN
            z=z+"+"+CSTR(x)
        END IF
        IF u Then
            IF INSTR(s(1),o(x)) THEN
                z=z+CSTR(x)
            END IF
        END IF
    next
    for m=0 to UBOUND(y)
        IF INSTR(r,y(m))AND u=0 THEN
            z=z+y(m+1)
            p=p+1
        END IF
    next
next
Execute("MSGBOX "+String(p,"(")+z)

Haskell
Similar to other recursive solutions I guess, but I took the time to make it clean.
Here is the complete source with all explanations : http://ideone.com/fc8zcB
-- Define a type for a parser from a list of tokens to the value they represent.
type NParse = [Token] -> Int

-- Map of literal tokens (0-9, 11-19 and tens) to their names.
literals = [
        ("zero", 0), ("one", 1), ("two", 2), ("three", 3), ("four", 4), ("five", 5), ("six", 6), ("seven", 7), ("eight", 8), ("nine", 9),
        ("eleven", 11), ("twelve", 12), ("thirteen", 13), ("fourteen", 14), ("fifteen", 15), ("sixteen", 16), ("seventeen", 17), ("eighteen", 18), ("nineteen", 19),
        ("ten", 10), ("twenty", 20), ("thirty", 30), ("fourty", 40), ("fifty", 50), ("sixty", 60), ("seventy", 70), ("eighty", 80), ("ninety", 90)
    ]

-- Splits the input string into tokens.
-- We do one special transformation: replace dshes by a new token. Such that "fifty-three" becomes "fifty tens three".
prepare :: String -> [Token]

-- Let's do the easy stuff and just parse literals first. We just have to look them up in the literals map.
-- This is our base parser.
parseL :: NParse
parseL [tok] = case lookup tok literals of
    Just x -> x

-- We're going to exploit the fact that the input strings have a tree-like structure like so
--                    thousand
--          hundred             hundred
--      ten       ten       ten         ten
--    lit   lit lit  lit   lit  lit    lit  lit
-- And recursively parse that tree until we only have literal values.
--
-- When parsing the tree
--       thousand
--     h1       h2
-- The resulting value is 1000 * h1 + h2.
-- And this works similarly for all levels of the tree.
-- So instead of writing specific parsers for all levels, let's just write a generic one :

{- genParse ::
    NParse      : the sub parser
    -> Int      : the left part multiplier
    -> Token    : the boundary token
    -> NParse   : returns a new parser -}
genParse :: NParse -> Int -> Token -> NParse
genParse delegate mul tok = newParser where
    newParser [] = 0
    newParser str = case splitAround str tok of
        -- Split around the boundary token, sub-parse the left and right parts, and combine them
        (l,r) -> (delegate l) * mul + (delegate r)

-- And so here's the result:
parseNumber :: String -> Int
parseNumber = parseM . prepare
    where   -- Here are all intermediary parsers for each level
    parseT = genParse   parseL  1       "tens"       -- multiplier is irregular, because the fifty in fifty-three is already multiplied by 10
    parseH = genParse   parseT  100     "hundred"
    parseK = genParse   parseH  1000    "thousand"
    parseM = genParse   parseK  1000000 "million" -- For fun :D

test = (parseNumber "five hundred twenty-three thousand six hundred twelve million two thousand one") == 523612002001

Common Lisp, 94
(write(cdr(assoc(read-line)(loop for i to 999999 collect(cons(format()"~r"i)i)):test #'equalp)))

Number to text conversion is built in to CL, but not the other way around. Builds a reverse mapping for the numbers and checks the input on it.

authors: صالح الرويلي


text:
Determine win in Tictactoe
Let's play some code golf!
Given a tic-tac-toe board state (Example:)
|x|x|o|
|x|o|x|
|o|o|x|

Determine whether a game is a win a lose or cat. Your code should output any of these options given a state. The above game should output lose
Just to be clear: a win is defined as any 3 xs in a row (diagonal, horizontal, vertical). a lose is 3 os in a row, while a cat game in none in a row.
To make things interesting, you get to determine your input structure for the state- which you must then explain. For instance xxoxoxoox is a valid state as seen above where each of the characters is read from left to right, top to bottom. [['x','x','o'],['x','o','x'],['o','o','x']] is the game in multidimensional array read in a similar way. While 0x1a9 which is hex for 110101001 might work as a suitable compression where 1 can be manipulated for xs and 0 can be manipulated for o.
But those are just some ideas, I'm sure you might have many of your own.
Ground rules:

Your program must be able to accept any viable state.
The form of input must be able to represent any state.
The input cannot be redundant, meaning each cell must only appear in one location.
"The win state must be determined from the board"
Assume a complete board
Win before lose for instance in the case 'xxxoooxxx'

Lowest character count wins

Do we write a function? Take in an input? Do we get to choose the output format?

Output should be either win,lose,cat. For input it must be from a human (not randomly generated). Thus using def q(x):#magic code here works just as well as (/*magic code */)(prompt())

I like this input structure: (win|lose|cat) [xo]{9}, where the first word denotes whether the game is a win, lose, or cat (?) for player x. Able to represent any state.

Is it okay if we exit with an exception?

@undergroundmonorail sure

@Runer112 added clause 3 for you. ('win')["oooxxoxxo"] would work in your proposed solution, but give the wrong answer thus not being eligible.

@DylanMadisetti that's why I specified that the first word must denote whether the game is a win, lose, or cat. The example you gave does not match my input structure.

@Runer112 You're right, and that's why it breaks rule 3. My improper state should not be able to work

Can I suggest a rule like "The win state must be determined from the board" or "The input must contain no information except the board state"?

Agreed. Checking the validity makes it more complex

are we to assume a complete board?  otherwise a binary representatiomn wouldn't work great.

Let's assume a complete board

Are we assuming only legal games played?  If so, certain states would be impossible, i.e. XXX OOO XXX but otherwise some full-board states include this as a fourth impossible outcome, where X wins but O also wins.

I think win before lose. If it's becoming too trivial we can throw in some of these stipulations

This question from the math stackexchange may be of relevance: http://math.stackexchange.com/questions/467757/determine-the-winner-of-a-tic-tac-toe-board-with-a-single-matrix-expression

why "cat" out of interest?

@Chris cat is the terminology I learned for a tie. A cat game. No one else?

@DylanMadisetti: never heard it before and googlign for "win lose cat" came up with nothing. I'd have gone with tie or draw personally. Or in the case of this game maybe "inevitability". ;-) I don't much mind as far as the competition goes though. A string is a string. ;-)

@chris not crazy. 3rd line http://en.wikipedia.org/wiki/Tic-tac-toe

Can I number all of the boxes? For example, with numbering 123456789 a board like {x: [1, 2, 3], o: [4, 8, 9]} would be winning for x?

@Cruncher Sure looks like valid input except your example isn't a complete board. Magic square ideas?

@DylanMadisetti it is a complete example. X has won. No need to fill in the rest. But yes, magic square ideas. What language is best at finding a subset of 3 with sum 15? lol

I don't quite understand the last rule. Is it saying that if a board contains both "win" and "lose "conditions it should report "win"? Does the program really have to support such invalid board states?

Why is a tie in Tic-Tac-Toe called a “Cat's Game?”

Ruby 2.0, 85 characters
Here's a simple bitmask-based solution in Ruby:
d=gets.hex
$><<[292,146,73,448,56,7,273,84].map{|m|d&m<1?:lose:d&m<m ?:cat: :win}.max

The board is represented as a hex number, made up of nine bits corresponding to the nine squares.  1 is an X, 0 is an O.  This is just like the 0x1a9 example in the question, though the 0x is optional!
There's probably a better way to do the bitmasks then just hardcoding a big list.  I'll happily take suggestions.
See it running on Ideone here.

Your list contains 273 twice. And I really like the max idea!

Oh @Ventero, always with the obscure optimizations (thanks)

There can be empty spaces on a board.  Your input format does not account for this and therefore cannot represent any viable game state.

@StephenOstermiller rule 4:assume a complete board. You are correct that this rule is perhaps contradicted by rules 1 and 2, however if you read all the comments on the question I think this is within the spirit of the question (incomplete boards are not covered, while complete but illegal boards are.) However I think that octal would be a more user-friendly input format than hex.

There can even be empty spaces on a complete board though.

@StephenOstermiller by definition a complete board has something on every square, even though this may be illegal as you should stop playing once someone has won. Read the full discussion, especially around Riot's comment.

Got it, I thought complete meant something different.

Mathematica, 84 chars
a=Input[];Which[Max@#>2,win,Min@#<1,lose,1>0,cat]&@{Tr@a,Tr@Reverse@a,Tr/@a,Total@a}

Input format: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}

What's happening here?

@TheRare Start from the right. Tr@a is the trace of the field (sum over diagonal), Tr@Reverse@a is the trace of the flipped field (some over anti-diagonal), Tr/@a is Tr applied to each row, which gives you the sum over each row, Total@a gives you the sum over each column. So basically, you've got all 8 lines you need to check. Then the Which thing is applied to that (basically an if/elseif/else statement), where # represents that list of 8 values. if there's a 3 you win, else if there's a 0 you lose, else if 1>0 (true) cat.

Bash: 283 262 258
Featuring a relatively friendly interface.
t(){ sed 's/X/true/g;s/O/false/g'<<<$@;}
y(){ t $(sed 's/X/Q/g;s/O/X/g;s/Q/O/g'<<<$@);}
f(){($1&&$2&&$3)||($1&&$5&&$9)||($1&&$4&&$7)||($2&&$5&&$8)||($3&&$5&&$7)||($3&&$6&&$9)||($4&&$5&&$6)||($7&&$8&&$9)}
f $(t $@)&&echo win||(f $(y $@)&&echo lose)||echo cat

To execute bash tictactoe.sh O X O X O X X O X
Note: the list of 9 positions is a standard matrix representation.  It doesn't matter if the board is represented as column major or row major, read from left to right or top to bottom - games of noughts and crosses (or tic tac toe if you insist) are symmetrical, so input order should be irrelevant to the result in every correct implementation, as long as input is linear.
Edit: Thanks to h.j.k for shorter function syntax suggestion.

Consider t() { ... } instead of function t? Can save some characters there. :)

I'd totally forgotten about the alternative function syntax - thanks!

Spaces are not required around <<< to save another four characters.

Befunge 93 - 375
Takes a binary string as input.
99>~\1-:!!|>v
>0v>v>v   >^$>v
^+ + +    0<:p:
>#+#+#+    ^246
^+ + +    0<265
>#+#+#+    ^pp6
^+ + +    0<2++
 #+#+#+     55p
   0 0      552
  >^>^>0v   +46
v+ + +  <   ppp
>0 + + + v  444
   v!!-3:<< 246
  v_"ni"v   ppp
  0v" w"<   :+:
  \>,,,,@   266
  ->,,,@    555
  !^"cat"_^ 645
  !>:9-! ^  +:+
  >|        p:p
   >"eso"v  6p6
 @,,,,"l"<  246
            p2p
            >^
  v       <^  <

Reads the string. Bruteforce writes it (the right most vertical strip) as a matrix in between the
^+ + +
>#+#+#+
^+ + +
>#+#+#+
^+ + +
 #+#+#+

adding lattice (idk). Determins the sum of the columns, rows, and two diagnals. Compares those values to 3 ("win") or 0 ("lose"), else if all the values equal 1  or 2 then draw ("cat").

Haskell, 146 chars

To make things interesting, you get to determine your input structure for the state- which you must then explain.

OK :). My representation of a board is one of those 126 characters

ĻŃŇŉŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂǅǆǈǏǑǒǕǖǘǝǞǠǤǯǱǲǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌

Here's the solution in 146 chars :
main=interact$(\x->case(head x)of h|elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂǆǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌"->"lose";h|elem h "ƏƝƞƹǁǈǑǝȍȺɆɈɶɾʎʸ"->"cat";h->"win")

And here's how it works, as an haskell script :
import Data.List (subsequences, (\\))
import Data.Char (chr)

-- A set of indexes [0-8] describing where on the board pieces of a single color have been played
-- For example the board "OxO;Oxx;xxO" is indexes [0,2,3,8]
type Play = [Int]

-- There are 126 filled tic tac toe boards when X plays first.
--      (This is a combination of 4 OHs among 9 places : binomial(9 4) = 126)
-- perms returns a list of all such possible boards (represented by the index of their OHs).
perms = filter (\x -> 4 == length x) $ subsequences [0..8]

-- We now create an encoding for plays that brings them down to a single char.
-- The index list can be seen as an 9 bit binary word [0,2,3,8] -> '100001101'
-- This, in turn is the integer 269. The possible boards give integers between 15 and 480.
-- Let's call those PlayInts
type PlayInt = Int

permToInt [] = 0
permToInt (x:xs) = (2 ^ x) + permToInt xs

-- Since the characters in the range 15-480 are not all printable. We offset the chars by 300, this gives the range
-- ĻŃŇŉŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂǅǆǈǏǑǒǕǖǘǝǞǠǤǯǱǲǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌
-- Of all distinct, printable characters
uOffset = 300

-- Transform a PlayInt to its Char representation
pIntToUnicode i = chr $ i + uOffset

-- Helper function to convert a board in a more user friendly representation to its Char
-- This accepts a representation in the form "xooxxxoxo"
convertBoard s = let play = map snd $ filter (\(c, i) -> c == 'o') $ (zip s [0..]) :: Play
    in pIntToUnicode $ permToInt play

--
-- Now let's cook some data for our final result
--

-- All boards as chars
allUnicode = let allInts = map permToInt perms
    in map pIntToUnicode allInts

-- Now let's determine which boards give which outcome.

-- These are all lines, columns, and diags that give a win when filled
wins = [
        [0,1,2],[3,4,5],[6,7,8], -- lines
        [0,3,6],[1,4,7],[2,5,8], -- columns
        [0,4,8],[2,4,6] -- diagonals
    ]

isWin :: Play -> Bool
isWin ps = let triplets = filter (\x -> 3 == length x) $ subsequences ps -- extract all triplets in the 4 or 5 moves played
    in any (\t -> t `elem` wins) triplets -- And check if any is a win line

-- These are OH wins
oWins = filter isWin perms
-- EX wins when the complement board wins
xWins = filter (isWin . complement) perms
    where complement ps = [0..9] \\ ps
-- And it's stalemate otherwise
cWins = (perms \\ oWins) \\ xWins

-- Write the cooked data to files
cookData = let toString = map (pIntToUnicode . permToInt) in do
  writeFile "all.txt" allUnicode
  writeFile "cWins.txt" $ toString cWins
  writeFile "oWins.txt" $ toString oWins
  writeFile "xWins.txt" $ toString xWins

-- Now we know that there are 48 OH-wins, 16 stalemates, and 62 EX wins (they have more because they play 5 times instead of 4).
-- Finding the solution is just checking to which set an input board belongs to (ungolfed :)
main = interact $ \x -> case (head x) of -- Only consider the first input char
    h | elem h "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂǆǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌" -> "lose" -- This string is == oWins
    h | elem h "ƏƝƞƹǁǈǑǝȍȺɆɈɶɾʎʸ" -> "cat" -- And this one == cWins
    h -> "win"

Ruby, 84 characters
$><<(gets.tr("01","10")[r=/0..(0|.0.)..0|000(...)*$|^..0.0.0/]?:win:~r ?:lose: :cat)

Simple, RegExp based solution. The input format is a 9-digit binary string, e.g. 110101001 for the example board given in the question.
Ruby, 78 characters
$><<(gets.tr("ox","xo")[r=/o...(o|.o.)...o|ooo|o_.o._o/]?:win:~r ?:lose: :cat)

Input format: xxo_xox_oox

Python 2 - 214 bytes
b=eval(raw_input())
s=map(sum,b)
w,l='win','lose'
e="if min(s)<1:print l;a\nif max(s)>2:print w;a"
exec e+'\ns=map(sum,zip(*b))\n'+e
m=b[1][1]
for i in 0,2:
 if m==b[0][i]==b[2][abs(i-2)]:print[l,w][m];a
print'cat'

I'm sure there are improvements to be made.
To run:
python2 tictactoe.py <<< '[[1,1,1],[1,0,1],[0,1,0]]'

which represents this board:
X|X|X
-----
X|O|X
-----
0|X|0

Exits with a NameError exception in every case except cat.

Whoa, I never knew about <<<! +1 just for that.

@GregHewgill It's pretty convenient. ./whatever <<< 'blah blah blah' is the same as echo -n 'blah blah blah' | ./whatever but without having a whole separate process for echo.

@undergroundmonorail echo in bash is actually a builtin, so doesn't fork a new process

@GregHewgill it's called a herestring

GolfScript, 63 + 27 = 90 bytes
I originally submitted the following 27-byte entry that exploited a loophole in the rules (as written at the time of submission) allowing a redundant input encoding:
70&.{~"win""lose"if}"cat"if

The input format for this entry is a string consisting of eight octal digits, each (redundantly) encoding three consecutive board squares:

The first three digits each encode a single row of the board, from top down and left to right.
The following three digits each encode a single column of the board, from left to right and top down.
The final two digits each encode one of the diagonals (first from top left to bottom right, then from bottom left to top right).

To encode a sequence (row / column / diagonal) of three squares as an octal digit, replace every x in the sequence with a 1 and every o with a 0, and interpret the resulting sequence of ones and zeros as a binary number between 0 and 7 inclusive.
This input format is quite redundant (all board positions are encoded at least twice, with the center position encoded four times), but it does unambiguously represent any possible state of a completely filled tic-tac-toe board, and does not directly encode the winner into the input.
The input may, optionally, contain spaces or other delimiters between digits.  In fact, all the program really cares about is whether or not the input string contains the digits 7 or 0.
For example, the example board:
|x|x|o|
|x|o|x|
|o|o|x|

may be represented by the input:
651 643 50

To make testing the program above easier, I also provided a 63-byte GolfScript program to convert an ASCII art board layout, as shown above, into an input string suitable for this program:
."XOxo"--[{1&!}/]:a[3/.zip"048642"{15&a=}%3/]{{2base""+}%}%" "*

This converter ignores any characters other than x and o, in either case, in its input.  It produces a single digit string (complete with space delimiters as shown above) suitable for feeding into the win-determining program above, so the concatenation of these two programs can be used to determine the winner directly from the ASCII art board, and thus still qualifies as a valid entry under the current challenge rules:
."XOxo"--[{1&!}/]:a[3/.zip"048642"{15&a=}%3/]{{2base""+}%}%" "*70&.{~"win""lose"if}"cat"if

Try it online!
Of course, the input format converted is not particularly well optimized and the combined program could easily be golfed further.  However, rather than attempting to re-golf a six-year-old solution, I prefer to just keep it as close to its originally submitted form as current rules permit.
Ps. Here's a reverse converter, just to demonstrate that the redundant input format for the 27-byte version indeed does unambiguously represent the board:
.56,48>-- 3<{2base-3>{"ox"=}%n}%"|".@@*+);

The input format seems like bit of a cheat as much of the work happens in producing the input.

@Arkku: Well, yes, it is, but the question explicitly says that "you get to determine your input structure for the state - which you must then explain." It even shows a bit-packed hex string as an example of a valid input format; the only difference between that and my input format is that I reorder and duplicate some bits.

It is exactly the duplication that seems like a cheat. (e.g., it does directly encode the winner as the presence of 7 or 0 in the input)

Still that's a clever encoding, it's redundant, but makes finding the solution much more efficient than any non-redundant encoding !

Redundant IO is explcitly not allowed

@pppery: It was when I posted this answer; the clarifying comment that you refer to was only posted half an hour later. Also, that comment was never actually edited into the challenge. Anyway, if the comment does count as part of the challenge, then the score of this answer (using the ASCII art board input format, and prepending the converter as described above) goes up to 63 + 27 = 90 chars (or bytes).

That rule has now been edited into the question by a moderator.

@pppery: Thanks for the heads-up. I've updated the answer to comply with the current rules.

Python3 - 188 w. different approaches to evaluation
Found the subject yesterday on Reddit and was fascinated. It was a simple code just to determine victory. Same night I made up my own version. Today i found this codegolf thread. [EDIT: 'blabla'] I am amazed about the different answers and possibilities within the other languages! Nice!
188 Python3 Code
EDIT: Now Meeting Requirements 1-5
Input-Style: Player p=0/1 and board b=(1,1,1,0,1,0,1,0,1)
def t(b,p):
    s,c,l,w=0,"cat","loose","win"
    for i in 1,2,3,4:
        u=2*i-1
        a=i*i-5*i+3
        if b[4]==b[4+i]==b[4-i]:
            if p==b[4]:s+=1
            else:s-=1
        if b[u]==b[u+a]==b[u-a]:
            if p==b[u]:s+=1
            else:s-=1
    if s>0:c=w
    if s<0:c=l
    return c

Victory Check Codes
103 Python3 - 'Square-Function'
EDIT1: nicer with "a==b==c==p" instead of "a+b+c==3*p"
def t(b,p):
    for i in 1,2,3,4:
        u=2*i-1
        a=i*i-5*i+3
        if b[4]==b[4+i]==b[4-i]==p or b[u]==b[u+a]==b[u-a]==p:return True

Explanation: Term for a based on f(u=1)=f(u=7)=1 f(u=3)=f(u=5)=3
113 Python3 - 'Magic Square'
Input just with board: Player is „1“, Oponent „0“
def t(b):
    n=[x*y for x,y in zip(b,(2,9,4,7,5,3,6,1,8))]
    if 15 in [x+y+z for x in n for y in n if x!=y for z in n if z!=x and z!=y]:return True

Explanation: Sum has to be 15 in Magic Square
119 Python3 - 'Oneliner'
inspired by Reddit Solution from user 'Xelf'
def t(b,p):
    if 3*p in [b[x]+b[y]+b[z] for x,y,z in [(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)]]:return True

@Ad Hoc Garf Hunter Thank You for the Feedback! Though i am a bit embarassed and sorry i don´t even know what 'stdin' is about. Just want to contribute some ideas and learn. Thank you for the comment on assignment and whitespaces! I just corrected it.
EDIT: Hope to meet the rules now. I understand i could make spaces instead of tabs, but that just looks nasty.

@WheatWizard def q(x): appears to be allowed according to this comment

Using tab indents and 1 instead of True, your "103" snippet uses 117 bytes according to Notepad++.

@CeesTimmerman The post has been edited since that comment.  In fact a function was the format I was suggesting there.  Regardless, I deleted my comments since they are now outdated.

CJam, 39 38 36 characters
"ᔔꉚ굌궽渒䗠脯뗠㰍㔚귇籾〳㎪䬔⹴쪳儏⃒ꈯ琉"2G#b129b:c~

This is a base converted code for
q3/_z__Wf%s4%\s4%]`:Q3'o*#"win"{Q'x3*#"lose""cat"?}?

which is 52 characters long.
The input is simply the string representation of the board starting from top left, going row by row. For example:
oxooxooox

which results in a win output. Or
oxooxoxox

which results in a cat output, etc.
The code simply does the following three things:

q3/_ - Split the string into parts of 3, i.e. per row
_z - Copy the per row array and transpose into per column array.
__Wf%s4% - Reverse each row and get the left to right diagonal. This is the secondary diagonal of the board.
\s4% - Get the main diagonal of the board
]` - Wrap everything in array and stringify the array.

Now we have all possible groups of 3 from the board. We simply check for existence of "ooo" and "xxx" to determine the result.
Try it online here

Python 2, 99 bytes
Similar to the Ruby answer:
def t(b):print['win'if w&b==w else'lose'if w&~b==w else'cat'for w in 448,56,7,292,146,73,273,84][0]

The input is the binary format described in the question: 1 for X, 0 for O, left-to-right, top-to-bottom. For example, 0b101001110 represents
XOX
OOX
XXO

which leads to output: cat

C, 164 bytes
It's midnight here and I haven't done any testing, but I'll post the concept anyway. I'll get back to it tomorrow.
User inputs two octal numbers (I wanted to use binary but as far as I know C only supports octal):
a represents the centre square, 1 for an X, 0 for an O
b is a nine-digit number representing the perimeter squares, circling round the board starting in one corner and finishing in the same corner (with repeat of that corner only), 1 for an X, 0 for an O.
There are two possible ways to win:

centre square is X (a=1) and two opposite squares are also X (b&b*4096 is nonzero)

three adjacent perimeter squares are X (b/8 & b & b*8 is nonzero.) This is only a valid win if the middle square is an edge square, not a corner square, therefore it is necessary to apply the mask m also, to avoid the corner square cases.

Losing is detected using the variable c, which is the inverse of b.
int a,b,c,m=010101010;
main(){
    scanf("%o%o",a,b);c=b^0111111111;
    printf("%s",(a&&b&b*4096)|(b/8&b&b*8&m)?"win":((!a&&c&c*4096)|(c/8&c&c*8)?"lose":"cat"));
}

You forgot to apply the mask m in the "lose" detection - c/8&c&c*8.  I have re-golfed your code (without testing its operation) as follows: int a,b;t(v){return a&&v&v<<12||v/8&v&v*8&0x208208;}main(){scanf("%o%o",a,b);printf("%s",t(b)?"win":t(b^0x1249249)?"lose":"cat");} (130 chars).  The repeated test was long enough to extract into a test function t(); this removes the need for c and m; the constants converted to hex to save one char each.

Just spotted that the printf doesn't need a format string - just supply the result string as the format - or puts it, since the question doesn't ask for a newline after the output!  (saves a further 7 chars).

Bash, 107 103
Generates and runs a sed script.
I/O format: oxo-oox-xoo outputs lose (use a - to separate rows). Input on stdin.
Requires GNU sed for the c command.
I've interpreted rule 5 as "if both win and lose are possible, choose win".
Main Code
This is the actual answer.
Nothing interesting really. It defines $b as /cwin to save characters, then defines the win condition part of the script, then uses sed y/x/o/\;s$b/close/ to convert x to o and cwin to close (thereby generating the lose conditions). It then sends the two things and ccat (which will output cat if no win/lose condition is matched) to sed.
b=/cwin
v="/xxx$b
/x...x...x$b
/x..-.x.-..x$b
/x-.x.-x$b"
sed "$v
`sed y/x/o/\;s$b/close/<<<"$v"`
ccat"

Generated Code
This is the sed script generated and run by the Bash script.
In the regexes, . matches any character and after them cTEXT prints TEXT and exits if the regex is matched.
This can run as a standalone sed script. It's 125 characters long, you can count it as another solution.
/xxx/cwin
/x...x...x/cwin
/x..-.x.-..x/cwin
/x-.x.-x/cwin
/ooo/close
/o...o...o/close
/o..-.o.-..o/close
/o-.o.-o/close
ccat

Haskell, 169
main=interact$(\x->last$"cat":[b|(a,b)<-[("ooo","lose"),("xxx","win")],any(==a)x]).(\x->x++(foldr(zipWith(:))(repeat[])x)++map(zipWith(!!)x)[[0..],[2,1,0]]).take 3.lines

Input format: "X" is represented only by x, "O" only by o. Within each row, characters are simultaneous without spaces, etc. Rows are separated by new lines.
Generates all possible rows/columns/diagonals, then filters [("ooo","lose"),("xxx","win")] by their existence on the board, then selects the second word in the tuple, so we know which players won. We prepend "cat" so that we can take the last element of the list as our winner. If both players won, "win" will be last (list comprehensions maintain order). Since "cat" is always first, if a winner exists, it will be chosen, but otherwise a last element still exists as prepending "cat" guarantees nonemptyness.
EDIT: Shaved 3 characters by changing last list comprehension to map.

Dart - 119
(See dartlang.org).
Original version using RegExp: 151 chars.
main(b,{w:"cat",i,p,z}){
 for(p in["olose","xwin"])
   for(i in[0,2,3,4])
     if(b[0].contains(new RegExp('${z=p[0]}(${'.'*i}$z){2}')))
       w=p.substring(1);
  print(w);
}

Input on the command line is 11 characters, e.g., "xxx|ooo|xxx". Any non-xo character can be used as delimiter.
Leading whitespace and newlines should be omitted before counting characters, but I cut away the internal whitespace where possible.
I wish there was a smaller way to make the substring.
Recusive bit-base version: 119 chars.
Input must be a 9-bit number with 1s representing 'x' and 0s representing 'o'.
main(n){
  n=int.parse(n[0]);
  z(b,r)=>b>0?b&n==b&511?"win":z(b>>9,n&b==0?"lose":r):r;
  print(z(0x9224893c01c01e2254,"cat"));
}

J - 56 (26?) char
Input is given a 3x3 matrix of nine characters, because J can support that as a datatype, LOL.
(win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)

Examples:
   NB. 4 equivalent ways to input the example board
   (3 3 $ 'xxoxoxoox') ; (_3 ]\ 'xxoxoxoox') ; ('xxo','xox',:'oox') ; (];._1 '|xxo|xox|oox')
+---+---+---+---+
|xxo|xxo|xxo|xxo|
|xox|xox|xox|xox|
|oox|oox|oox|oox|
+---+---+---+---+
   (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.) 3 3 $ 'xxoxoxoox'
lose
   wlc =: (win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)
   wlc (3 3 $ 'xoxoxooxo')
cat
   wlc (3 3 $ 'xxxoooxxx')
win

If we are allowed the Golfscriptish encoding of octal digits redundantly representing the state of each row, column, and diagonal, then it's just 26 characters:
   win`lose`cat{::~7 0<./@i.] 6 5 1 6 4 3 5 0
lose
   f=:win`lose`cat{::~7 0<./@i.]
   f  7 0 7 5 5 5 5 5
win

What's there to LOL about?

T-SQL (2012),110
select max(iif(@&m=0,'lose',iif(@&m=m,'win','cat')))from(VALUES(292),(146),(73),(448),(56),(7),(273),(84))z(m)
Input is a hex number. This is pretty much a translation of the ruby solution into T-SQL pretty nice and neat.

Java 7, 260 bytes
String c(int[]s){int a[]=new int[8],x=0,y;for(;x<3;x++){for(y=0;y<3;a[x]+=s[x*3+y++]);for(y=0;y<3;a[x+3]+=s[y++%3]);}for(x=0;x<9;y=s[x],a[6]+=x%4<1?y:0;a[7]+=x%2<1&x>0&x++<8?y:0);x=0;for(int i:a)if(i>2)return"win";for(int i:a)if(i<1)return"loose";return"cat";}

Ungolfed & test cases:
Try it here.
class M{
  static String c(int[] s){
    int a[] = new int[8],
        x = 0,
        y;
    for(; x < 3; x++){
      for(y = 0; y < 3; a[x] += s[x * 3 + y++]);
      for (y = 0; y < 3; a[x + 3] += s[y++ % 3]);
    }
    for(x = 0; x < 9; y = s[x],
                      a[6] += x % 4 < 1
                               ? y
                               : 0,
                      a[7] += x % 2 < 1 & x > 0 & x++ < 8
                               ? y
                               : 0);
    x = 0;
    for(int i : a){
      if(i > 2){
        return "win";
      }
    }
    for(int i : a){
      if(i < 1){
        return "loose";
      }
    }
    return "cat";
  }

  public static void main(String[] a){
    /*  xxo
        xox
        oox  */
    System.out.println(c(new int[]{ 1, 1, 0, 1, 0, 1, 0, 0, 1 }));
    /*  xxx
        ooo
        xxx  */
    System.out.println(c(new int[]{ 1, 1, 1, 0, 0, 0, 1, 1, 1 }));
    /*  xxo
        oox
        xox  */
    System.out.println(c(new int[]{ 1, 1, 0, 0, 0, 1, 1, 0, 1 }));
  }
}

Output:
loose
win
cat

Bash: 208 chars
y(){ tr '01' '10'<<<$@;}
f(){ x=$[($1&$2&$3)|($1&$5&$9)|($1&$4&$7)|($2&$5&$8)|($3&$5&$7)|($3&$6&$9)|($4&$5&$6)|($7&$8&$9)]; }
f $@;w=$x
f $(y $@)
([ $x -eq 1 ]&&echo lose)||([ $w -eq 1 ]&&echo win)||echo cat

To execute bash tictactoe.sh 0 1 0 1 0 1 1 0 1
Inspired by this answer.

183 bytes

PowerShell, 120 116 118 112 106 102 bytes
The more compact pattern inspired by Ventero
Fixed to follow the rule 6.
@(switch -r($args){($x='^(...)*111|^..1.1.1|1..(1|.1.)..1'){'win'}($x-replace1,0){'lose'}.{'cat'}})[0]

Try it online!

J - 97 bytes
Well, the simplest approach available. The input is taken as 111222333, where the numbers represent rows. Read left-to-right. Player is x and enemy is o. Empty squares can be anything except x or o.
f=:(cat`lose>@{~'ooo'&c)`('win'"_)@.('xxx'&c=:+./@(r,(r|:),((r=:-:"1)(0 4 8&{,:2 4 6&{)@,))3 3&$)

Examples: (NB. is a comment)
   f 'xoxxoxxox' NB. Victory from first and last column.
win
   f 'oxxxooxxx' NB. Victory from last row.
win
   f 'ooxxoxxxo' NB. The example case, lost to a diagonal.
lose
   f 'xxooxxxoo' NB. Nobody won.
cat
   f 'xoo xx ox' NB. Victory from diagonal.
win

Ungolfed code an explanation
row   =: -:"1                        Checks if victory can be achieved from any row.
col   =: -:"1 |:                     Checks if victory can be achieved from any column.
diag  =: -:"1 (0 4 8&{ ,: 2 4 6&{)@, Checks if victory can be achieved from diagonals.
check =: +./@(row,col,diag) 3 3&$    Checks all of the above and OR's them.

f     =: (cat`lose >@{~ 'ooo'&check)`('win'"_)@.('xxx'&check)
Check if you have won ........................@.('xxx'&check)
 If yes, return 'win' .............. ('win'"_)
 If not                   (cat`lose >@{~ 'ooo'&check)
  Check if enemy won ................... 'ooo'&check
   If yes, return 'lose'   ---`lose >@{~
   If not, return 'cat'    cat`---- >@{~

JavaScript, 133, 114 characters
r = '/(1){3}|(1.{3}){2}1|(1.{4}){2}1|(1\|.1.\|1)/';alert(i.match(r)?'WIN':i.match(r.replace(/1/g,0))?'LOSS':'CAT')

The input i is a simple string with delimiters for the rows, i.e. 100|001|100
Edit: updated my method to replace the 1s in the regex with zeroes to check for the loss case.

You can remove the spaces around = and the quotes around the regex literal. Also, 1... is one character shorter than 1.{3}.

r.test(i) is also one character shorter than i.match(r).

J : 83
(;:'lose cat win'){::~>:*(-&(+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))-.)3 3$'x'=

Usage: just append a string of x's and o's and watch the magic work. eg. 'xxxoooxxx'.
The inner verb (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:))) basically boxes together the original binary matrix, with the transpose boxed together with the 2 diagonals.
These results are razed together ; row sums are taken to determine wins, and then summed. further I'll call this verb Inner.
For finding the winner, the difference of the scores between the normal and inversed binary matrices is taken by the hook (-&Inner -.).
The rest of the code simply makes the outputs, and selects the right one.

APL(NARS), 69 chars, 138 bytes
{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}

The input should be one 3x3 matrix or one linear array of 9 element that can be only 1 (for X) and 0 (for O), the result will be "cat" if nobody wins, "lose" if O wins, "win" if X wins. There is no check for one invalid board or input is one array has less than 9 element or more or check each element <2.
As a comment: it would convert the input in a 3x3 matrix, and build one array named "x" where elements are the sum each row column and diagonal.
Some test see example showed from others:
  f←{w←3 3⍴⍵⋄x←(+/1 1⍉⊖w),(+/1 1⍉w),(+⌿w),+/w⋄3∊x:'win'⋄0∊x:'lose'⋄'cat'}
  f 1 2 3
win
  f 0 0 0
lose
  f 1 0 1  1 0 1  1 0 1
win
  f 0 1 1  1 0 0  1 1 1
win
  f 0 0 1  1 0 1  1 1 0
lose
  f 1 1 0  0 1 1  1 0 0
cat
  f 1 1 0  0 1 0  0 0 1
win
  f 1 1 0  1 0 1  0 0 1
lose

Jelly, 27 bytes
ŒD,ŒdḢ€;;ZEƇFṀị“ẏż“¡ṇ⁽“Zƙċ»

Try it online!
Input is a list of lists of ints: 0 = nothing, 1 = circle, 2 = cross.
Explanation
ŒD,ŒdḢ€;;ZEƇFṀị“ẏż“¡ṇ⁽“Zƙċ»   Main monadic link
ŒD                            Diagonals
  ,                           Pair with
   Œd                           Antidiagonals
     Ḣ€                       Head (first item) of each
                              [the main diagonal and antidiagonal]
       ;                      Join with the input
        ;                     Join with the input
         Z                      zipped (transposed)
                              [the diagonals, rows and columns]
           Ƈ                  Filter by
          E                     All elements equal?
            F                 Flatten
             Ṁ                Maximum
              ị               Index into (1-indexed)
               “ẏż“¡ṇ⁽“Zƙċ»     ["lose", "win", "cat"]

PowerShell, 174 bytes
param($a,$b,$c,$d,$e,$f,$g,$h,$i)@("$a$b$c","$a$d$g","$a$e$i","$b$e$h","$c$e$g","$c$f$i","$d$e$f","$g$h$i")|%{if($_-eq'XXX'){'win';exit}elseif($_-eq'OOO'){'lose';exit}};'cat'

Try it online!
Trivial solution.
Takes 9 parameters for each key in board.

source: Stack Exchange

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

authors: Евгений Юнин

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

sort: votes