Tictactoeで勝利を決める


19

コードゴルフをしましょう!

三目並べボードの状態を指定(例:)

|x|x|o|
|x|o|x|
|o|o|x|

ゲームがあるかどうかを判断しwin、A losecat。コードは、状態を指定してこれらのオプションのいずれかを出力する必要があります。上記のゲームは出力するはずですlose

明確にするために、勝ちとはx、連続する3 秒(対角、水平、垂直)として定義されます。負けは3 o秒連続で、catゲームは連続なしで3 秒です。

物事を面白くするには、状態の入力構造を決定する必要があります。それについて説明する必要があります。たとえばxxoxoxoox、上記の有効な状態では、各文字が左から右、上から下に読み取られます。[['x','x','o'],['x','o','x'],['o','o','x']]同様の方法で読み取られる多次元配列のゲームです。ながら0x1a9そのためヘクスである110101001適切な圧縮としてかもしれない仕事1のために操作することができるxのと0のために操作することができますo

しかし、これらは単なるアイデアであり、あなたはあなた自身の多くを持っていると確信しています。

基本ルール:

  1. プログラムは、実行可能な状態を受け入れることができる必要があります。
  2. 入力の形式は、あらゆる状態を表すことができなければなりません。
  3. 「勝利の状態は、ボードから決定する必要があります」
  4. 完全なボードを想定
  5. Win前にloseインスタンスの場合の「xxxoooxxx」

最小の文字数が勝つ


1
この入力構造が好きです:(win|lose|cat) [xo]{9}、最初の単語は、ゲームがプレイヤーxの勝ち負けか猫(?)かを示します。あらゆる状態を表現できます。
Runer112 14年

2
「ボードから勝ち状態を判断する必要がある」や「ボード状態以外の情報を入力に含めることはできません」などのルールを提案できますか?
地下

3
合法的なゲームのみがプレイされると想定していますか?その場合、特定の状態、つまりXXX OOO XXXが不可能になりますが、それ以外の場合、一部のフルボード状態には、Xが勝つがOも勝つ4番目の不可能な結果として含まれます。
暴動14年

10
なぜ「猫」は興味がないのですか?
クリス14年

7
@DylanMadisetti:これまで聞いたことがないし、「猫に勝つ」のgooglignは何も思いつきませんでした。私は自分でネクタイをしたり絵を描いたりしていました。または、このゲームの場合は「不可避」かもしれません。;-)競争に関してはあまり気にしません。文字列は文字列です。;-)
クリス14年

回答:


11

Ruby 2.0、85文字

Rubyでの簡単なビットマスクベースのソリューションを次に示します。

d=gets.hex
$><<[292,146,73,448,56,7,273,84].map{|m|d&m<1?:lose:d&m<m ?:cat: :win}.max

ボードは、9つの正方形に対応する9ビットで構成される16進数で表されます。1はX0、0はOです。これは0x1a9質問の例と同じ0xですが、オプションです!

ビットマスクを実行するよりも、大きなリストをハードコーディングするよりも良い方法がおそらくあります。喜んで提案します。

こちらでIdeoneで実行ています


1
リストには2732回含まれています。そして、私はmaxアイデアが本当に好きです!
Ventero 14年

1
ああ@Ventero、常にあいまいな最適化(感謝)
Paul Prestidge 14年

ボード上に空きスペースがある場合があります。入力フォーマットはこれを考慮していないため、実行可能なゲームの状態を表すことはできません。
スティーブンオステルミラー14年

2
@StephenOstermillerルール4:ボード全体を想定します。このルールはおそらくルール1と2に矛盾することは間違いありませんが、質問に対するすべてのコメントを読んだ場合、これは質問の精神の範囲内だと思います(不完全なボードはカバーされませんが、完全なボードは違法です)ただし、8進数は16進数よりもユーザーフレンドリな入力形式になると思います。
レベルリバーセント

1
わかりました、完全とは何か違うことを意味すると思いました。
スティーブンオステルミラー14年

10

Mathematica、84文字

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

入力形式: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}


ここで何が起こっていますか?
seequ 14年

3
@TheRare右から開始します。Tr@aフィールド(対角を超える合計)の跡があり、Tr@Reverse@a反転したフィールドの痕跡がある(一部は抗対角線上)、Tr/@aされTr、各列の上にあなたの合計を与える各行に適用されるTotal@a各列の上にあなたの合計を提供します。基本的に、確認する必要がある8行すべてがあります。次に、そのWhichことを(基本的にはif/elseif/elseステートメント)に適用し#ます。ここで、8つの値のリストを表します。ifあります3あなたが勝った、else ifあります0、あなたが失うelse if 1>0(真)cat
マーティンエンダー

6

バッシュ:283 262 258

比較的使いやすいインターフェイスを備えています。

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

実行する bash tictactoe.sh O X O X O X X O X

注:9つの位置のリストは、標準のマトリックス表現です。ボードが列メジャーまたは行メジャーで表され、左から右または上から下に読まれるかどうかは関係ありません-Noughts and Crosses(またはあなたが主張する場合は三目並べ)のゲームは対称的であるため、入力順序は無関係です入力が線形である限り、すべての正しい実装の結果に。

編集:より短い関数構文の提案をしてくれたhjkに感謝します。


t() { ... }代わりに検討しfunction tますか?そこにいくつかのキャラクターを保存できます。:)
hjk

代替関数の構文を完全に忘れていました-ありがとう!
暴動14年

<<<さらに4文字を保存するためにスペースは不要です。
マイケルミオール

4

Befunge 93-375

入力としてバイナリ文字列を受け取ります。

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       <^  <

文字列を読み取ります。ブルーテフォースは、(右端の垂直ストリップ)を、

^+ + + 
>#+#+#+
^+ + + 
>#+#+#+
^+ + + 
 #+#+#+

ラティス(idk)を追加します。列、行、および2つのダイアグナルの合計を決定します。これらの値を3( "win")または0( "lose")と比較します。そうでなければ、すべての値が1または2に等しい場合は描画( "cat")します。


4

GolfScript、27文字

70&.{~"win""lose"if}"cat"if

入力形式は8桁の8進数で構成される文字列で、それぞれが(冗長的に)3つの連続したボードの正方形をエンコードします。

  • 最初の3桁は、それぞれ上から下、左から右に向かって、ボードの1行をエンコードします。
  • 次の3桁はそれぞれ、左から右、上から下に向かってボードの1列をエンコードします。
  • 最後の2桁はそれぞれ対角線の1つをエンコードします(最初は左上から右下へ、次に左下から右上へ)。

3つの正方形のシーケンス(行/列/対角線)を8進数としてエンコードするには、シーケンスのxすべてoを1に、すべてを0に置き換え、1と0の結果のシーケンスを0と7の間の2進数として解釈します包括的。

この入力形式は、(すべてのボードの位置が中心位置が4回符号化して、二回以上で符号化された)非常に冗長であるが、それはない明確に完全に充填された三目並べボードの任意の可能な状態を表し、ない直接エンコード入力に勝者。

入力には、オプションで、数字の間にスペースまたはその他の区切り文字を含めることができます。実際、プログラムが本当に気にするのは、入力文字列に数字7またはが含まれているかどうか0です。

たとえば、サンプルボード:

|x|x|o|
|x|o|x|
|o|o|x|

入力で表すことができます:

651 643 50

便宜上、上記の課題で示したASCIIアートボードレイアウトをこのプログラムに適した入力文字列に変換するGolfScriptプログラムを以下に示します。

."XOxo"--[{1&!}/]:a[3/.zip"048642"{15&a=}%3/]{{2base""+}%}%" "*

このコンバータは、入力のいずれの場合でも、xおよび以外の文字を無視oします。上記の勝利決定プログラムへの入力に適した1桁の文字列(上記のスペース区切り文字を含む)を生成するため、これら2つのプログラムの連結を使用して、ASCIIアートボードから直接勝者を決定できます。

また、入力が実際にボードを明確に表していることを示すために、逆変換器を示します。

.56,48>-- 3<{2base-3>{"ox"=}%n}%"|".@@*+);

追伸 このソリューションのオンラインデモはこちらです。


2
入力フォーマットは、入力の生成で多くの作業が発生するため、ちょっとしたごまかしのように見えます。
Arkku

@Arkku:ええ、そうです。しかし、質問は「状態の入力構造を決定することができます-次に説明する必要があります」と明示的に述べています。有効な入力形式の例として、ビットパックされた16進文字列も表示されます。それと私の入力形式の唯一の違いは、いくつかのビットを並べ替えて複製することです。
イルマリカロネン

6
不正行為のように見えるのは、まさに複製です。(例えば、それはない直接入力7または0の存在として勝者をコードする)
Arkku

それでもそれは賢いエンコーディングですが、冗長ですが、ソリューションを見つけることは非冗長エンコーディングよりもはるかに効率的です!
ARRG 14年

3

Python 2-214バイト

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'

改善すべき点があると確信しています。

走る:

python2 tictactoe.py <<< '[[1,1,1],[1,0,1],[0,1,0]]'

このボードを表します:

X|X|X
-----
X|O|X
-----
0|X|0

で終了NameErrorを除くすべての場合に例外cat


おっ、私は知らなかった<<<!そのためだけに+1。
グレッグヒューギル14年

@GregHewgillとても便利です。./whatever <<< 'blah blah blah'はと同じですecho -n 'blah blah blah' | ./whateverが、の完全な個別のプロセスはありませんecho
地下

@undergroundmonorail echobash組み込み、実際にあるので、新しいプロセスフォークしない
ボブ・

それがherestringと呼ばれています@GregHewgill

3

Haskell、146文字

物事を面白くするには、状態の入力構造を決定する必要があります。それについて説明する必要があります。

OK :)。ボードの私の表現は、これらの126文字の1つです。

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

146文字のソリューションを次に示します。

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

haskellスクリプトとしての仕組みは次のとおりです。

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 
-- ĻŃŇʼnŊœŗřŚşšŢťŦŨųŷŹźſƁƂƅƆƈƏƑƒƕƖƘƝƞƠƤƳƷƹƺƿǁǂDždžLjǏǑǒǕǖǘǝǞǠǤǯDZDzǵǶǸǽǾȀȄȍȎȐȔȜȳȷȹȺȿɁɂɅɆɈɏɑɒɕɖɘɝɞɠɤɯɱɲɵɶɸɽɾʀʄʍʎʐʔʜʯʱʲʵʶʸʽʾˀ˄ˍˎː˔˜˭ˮ˰˴˼̌
-- 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 "ĻŃœťŦŨųŷŹƁƂƅƈƕƠƤƳƿǂdžǞǤǵǾȀȳȿɁɅɑɒɘɝɠɤɵɽʀʐʽʾː˭ˮ˰˴˼̌" -> "lose" -- This string is == oWins
    h | elem h "ƏƝƞƹǁLjǑǝȍȺɆɈɶɾʎʸ" -> "cat" -- And this one == cWins
    h -> "win"

3

JavaScript、420文字

if((s&0x3F000)==0x3F000||(s&0x00FC0)==0x00FC0||(s&0x0003F)==0x0003F||(s&0x030C3)==0x030C3||(s&0x0C30C)==0x0C30C||(s&0x30C30)==0x30C30||(s&0x03330)==0x03330||(s&0x30303)==0x30303)return 'win'
if((s&0x3F000)==0x2A000||(s&0x00FC0)==0x00A80||(s&0x0003F)==0x0002A||(s&0x030C3)==0x02082||(s&0x0C30C)==0x08208||(s&0x30C30)==0x20820||(s&0x03330)==0x02220||(s&0x30303)==0x20202)return 'lose'
if((s&0x2AAAA)==0x2AAAA)return 'cat'

このバージョンでsは、ゲームボードの状態を表す整数が含まれます。これは、2ビットがボード上の各正方形を表す値のビット配列です。

  • 10 - バツ
  • 11 -O
  • 00 -空の広場

このソリューションでは、ビット操作を使用して、8つの可能な「連続した3つの」構成のそれぞれをテストします(Xに対して1回、Oに対して1回、それぞれ2回テストします)。

この機能が実際の三目並べゲームの一部として使用されている三目並べのウェブサイトから、これを少し縮小して紹介しdetectWinます。


6
まあ、これは総当たり攻撃と呼ばれる可能性があります。
seequ 14年

2

ルビー、84文字

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

シンプルなRegExpベースのソリューション。入力形式は、9桁のバイナリ文字列です。たとえば110101001、質問で与えられたボードの例です。

ルビー、78文字

$><<(gets.tr("ox","xo")[r=/o...(o|.o.)...o|ooo|o_.o._o/]?:win:~r ?:lose: :cat)

入力形式: xxo_xox_oox


1

ハスケル、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

入力形式:「X」はでのみx、「O」はでのみ表されoます。各行内で、文字はスペースなしなどで同時に存在します。行は改行で区切られます。

すべての可能な行/列/対角線を生成[("ooo","lose"),("xxx","win")]し、ボード上のそれらの存在によってフィルタリングし、タプル内の2番目の単語を選択するため、どのプレーヤーが勝ったかがわかります。"cat"リストの最後の要素を勝者とするために、先頭に追加します。両方のプレイヤーが勝った場合、"win"最後になります(リストの理解度は順序を維持します)。"cat"常に最初なので、勝者が存在する場合、それが選択されますが、そうでない場合は、先頭に追加"cat"することで空でないことが保証されるため、最後の要素がまだ存在します。

編集:最後のリストの理解度をに変更して、3文字を削りましたmap


1

C、約150

ここは真夜中で、テストは行っていませんが、とにかくコンセプトを投稿します。明日また戻ってきます。

ユーザーは2つの8進数を入力します(バイナリを使用したかったのですが、Cが8進数のみをサポートしていることを知っている限り)。

a 中央の正方形を表します。Xは1、Oは0です。

b 境界の正方形を表す9桁の数字で、1つの角で始まり、同じ角で終わるボードの周りを一周します(その角の繰り返しのみ)。Xは1、Oは0です。

勝つには2つの方法があります。

  1. 中央の正方形はX(a= 1)であり、2つの向かい合う正方形もX(b&b*4096非ゼロ)です

  2. 3つの隣接する周囲の正方形はX(b/8 & b & b*8ゼロ以外)です。これは、真ん中の正方形がコーナー正方形ではなくエッジ正方形である場合にのみ有効な勝ちです。したがってm、コーナー正方形の場合を避けるためにマスクも適用する必要があります。

損失は​​、変数c(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"));
}

m「失われた」検出でマスクを適用するのを忘れました- c/8&c&c*8。次のように、コードを(操作をテストせずに)再ゴルフしました: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文字)。繰り返されたテストは、テスト関数に抽出するのに十分な長さでしたt()。これにより、cand が不要になりmます。それぞれ1文字を節約するために16進数に変換された定数。
トビースパイト

printf書式文字列が必要ないことを発見しました-結果文字列を書式として提供するだけです-またはputs、質問は出力後に改行を要求しないためです!(さらに7文字を保存します)。
トビースパイト

1

バッシュ、 107 103

sedスクリプトを生成して実行します。

I / O形式:oxo-oox-xoo出力lose-行を区切るにはa を使用)。標準入力。cコマンドにGNU sedが必要です。

ルール5は、「勝ち負けが可能な場合は勝ちを選択する」と解釈しました。

メインコード

これが実際の答えです。

本当に面白いことは何もありません。これは、定義$bとして/cwin文字を保存するために、スクリプトの勝利条件部を定義し、その後、使用してsed y/x/o/\;s$b/close/変換することxoしてcwinまでclose(それによって失う条件を生成します)。次に、2つのものとccatcat勝ち/負けの条件が一致しない場合に出力される)を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"

生成されたコード

これは、Bashスクリプトによって生成および実行されるsedスクリプトです。

正規表現では、.任意の文字に一致し、その後にcTEXTTEXTを出力し、正規表現に一致すると終了します。

これは、スタンドアロンのsedスクリプトとして実行できます。長さは125文字です。別のソリューションとしてカウントできます。

/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

1

Python 3、45

入力はでi、ゲームボードの各行、列、および対角線を表す数字のリストです。例:

X X O
O X O
O O X

はで表され[6, 2, 1, 4, 6, 1, 7, 4]ます。

コード('cat','lose','win')[2 if 7 in i else 0 in i]


1

ダーツ-119

dartlang.orgを参照)。

RegExpを使用した元のバージョン:151文字。

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);
}

コマンドラインでの入力は11文字です(例: "xxx | ooo | xxx")。任意の非XO文字を区切り文字として使用できます。

先頭の空白と改行は、文字を数える前に省略する必要がありますが、可能な限り内部の空白を削除します。部分文字列を作成するより小さな方法があればいいのにと思います。

Recusiveビットベースバージョン:119文字。入力は9ビットの数値でなければならず、1は「x」を表し、0は「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"));
}

1

CJam、39 38 36文字

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

これは、ベース変換されたコードです

q3/_z__Wf%s4%\s4%]`:Q3'o*#"win"{Q'x3*#"lose""cat"?}?

長さは52文字です。

入力は、単に左上から行ごとに進むボードの文字列表現です。例えば:

oxooxooox

結果がwin出力されます。または

oxooxoxox

cat出力などになります。

コードは次の3つのことを単純に行います。

  • q3/_ -文字列を3つの部分、つまり行ごとに分割します
  • _z -行ごとの配列をコピーし、列ごとの配列に転置します。
  • __Wf%s4%-各行を逆にして、左から右の対角線を取得します。これは、ボードの2番目の対角線です。
  • \s4% -ボードの主な対角線を取得します
  • ]` -すべてを配列でラップし、配列を文字列化します。

これで、ボードから3つのグループがすべて可能になりました。「ooo」と「xxx」の存在を確認して、結果を判断します。

こちらからオンラインでお試しください


1

GNU sed、25バイト

入力が、他の回答でも使用されているように、列、行、および対角線の個別のビューを備えたボードの冗長表現である場合、sedは最小バイトでゲームの終了状態を確認するのに非常に適しています。

入力形式: xxx ooo xxx xox xox xox xox xox(OPの質問から取得したボードの状態)

/xxx/cwin
/ooo/close
ccat

入力形式が非冗長(xxx ooo xxx)の場合、上記のsedコードは、以下の行が先頭に追加された場合にのみ機能し、プログラムの長さは96バイトになります(必要なrフラグがカウントされます)。

s/(.)(.)(.) (.)(.)(.) (.)(.)(.)/& \1\4\7 \2\5\8 \3\6\9 \1\5\9 \3\5\7/

1

Bash:208文字

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

実行する bash tictactoe.sh 0 1 0 1 0 1 1 0 1

この答えに触発されました


0

VB.net

この例では、provideは次のビットパターンとしてエンコードされます

q  = &B_100101_100110_011010 ' 00 Empty, 01 = O, 10 = X

これで、以下を実行して結果(または勝者)を決定できます。

Dim g = {21, 1344, 86016, 66576, 16644, 4161, 65379, 4368}
Dim w = If(g.Any(Function(p)(q And p)=p),"Lose",If(g.Any(Function(p)(q And p*2)=p*2),"Win","Cat"))

0

J-97バイト

まあ、利用可能な最も簡単なアプローチ。入力はとして取得され111222333、数字は行を表します。左から右に読んでください。プレイヤーはx、敵はo。空の四角は除く何もすることができますxo

f=:(cat`lose>@{~'ooo'&c)`('win'"_)@.('xxx'&c=:+./@(r,(r|:),((r=:-:"1)(0 4 8&{,:2 4 6&{)@,))3 3&$)

例:(NB。はコメントです)

   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

非ゴルフコードの説明

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`---- >@{~

0

Python 2、120バイト

b=0b101001110
l=[448,56,7,292,146,73,273,84]
print(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

または、Python、 Pythonシェルからの115バイト(2または3):

b=0b101001110;l=[448,56,7,292,146,73,273,84];(['Win'for w in l if w&b==w]+['Lose'for w in l if w&~b==w]+['Cat'])[0]

ボード変数は、質問で説明されているバイナリ形式に設定されます:1Xの場合0、Oの場合、左から右、上から下。この場合、101001110表します

XOX
OOX
XXO

出力につながる: Cat


入力形式は何ですか?
seequ 14年

0

パイソン(73 62文字)

入力は、同じボードの4つの異なるビューを表す4つの小文字の文字列であり、すべて行、列、右対角、左対角の1つの文字列に連結されます。

更新

良い反例でこれを指摘してくれたtheRareに感謝します! ボードの各ビューは、ボード内の各セグメント(行または列)とともに、連結後もボードの構造が保持されるように、「x」でも「o」でもない文字で区切る必要があります。ボードの各ビューの周囲の境界線は角括弧( "["および "]")になり、行/列間のセパレータはパイプ文字 "|"になります。

これにより、アルゴリズムが単純になります。勝ち負けをそれぞれ「xxx」または「ooo」で探すだけです。それ以外の場合は、ネクタイ(猫)です。

例えば、ボード(左から右、上から下へ読む)...

X | X | X X | O | X O | X | O

...「[xxx | xox | oxo]」(行ごと)+「[xxo | xox | xxo]」(列ごと)+「[xoo]」(右の診断)+ [xoo]」(左のように表示) diag)= "[xxx | xox | oxo] [xxo | xox | xxo] [xoo] [xoo]"。

このPythonステートメントは、変数sを指定してゲーム結果を出力しますを入力としてを出力します。

print 'win' if 'xxx' in s else 'lose' if 'ooo' in s else 'cat'

これはボードで機能しますかOXX XOO XOX(猫でなければなりません)?
seequ

いいえ...違います。良いキャッチ!私の解決策は少し単純すぎると思います...おっと!
ボブ14年

この種の解決策が私の頭をよぎったとは言えません。:)
seequ 14年

0

Haskell(69文字)

i x=take 4$(x>>=(\y->case y of{'7'->"win";'0'->"lose";_->""}))++"cat"

これは、 この回答でます。より具体的には、入力は8つの8進数値であり、各行、列、および対角線のバイナリ値を表します。このコードは、7のすべてのインスタンスを「勝つ」、0のすべてのインスタンスを「失う」ようにし、他のすべてを削除します。次に、最後に「cat」を追加し、結果から最初の4文字を取得します。

4つの可能な回答があります:「lose」、「cat」、「win」の後に「l」、「win」の後に「c」があります。これらはルールで禁止されていません:)

使用例:

i "65153806" --outputs "lose"

0

J:83

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

使用法:xとoの文字列を追加するだけで、魔法のように動作します。例えば。「xxxoooxxx」。

内側の動詞は、(+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))基本的に元のバイナリマトリックスをボックスで囲み、転置は2つの対角線で囲まれます。これらの結果は一緒に破壊されます。行の合計は勝ちを決定するために取得され、合計されます。さらにこの動詞を呼び出しますInner

勝者を見つけるために、正規バイナリ行列と逆バイナリ行列の間のスコアの差がフックによって取得されます (-&Inner -.)ます。

残りのコードは単に出力を作成し、正しいものを選択します。


0

JavaScript、133、114文字

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')

入力iは、行の区切り文字を持つ単純な文字列です。つまり、100|001|100

編集:メソッドを更新して、正規表現の1をゼロに置き換えて、損失ケースを確認しました。


=正規表現リテラルの前後のスペースと引用符を削除できます。また、1...は1文字よりも短いです1.{3}
nyuszika7h

1
r.test(i)は、よりも1文字短くなっていi.match(r)ます。
nyuszika7h 14

0

J-56(26?)文字

Jはデータ型LOLとしてサポートできるため、入力には9文字の3x3マトリックスが与えられます。

(win`lose`cat{::~xxx`ooo<./@i.<"1,<"1@|:,2 7{</.,</.@|.)

例:

   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

各行、列、および対角線の状態を冗長に表す8進数のGolfscriptishエンコードが許可されている場合、それはわずか26文字です。

   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

0

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)

入力は16進数です。これは、ルビーソリューションをT-SQLに変換したものです。


0

Javascript 1.6、71文字

入力は、game各行、各列、および各文字列を3文字の文字列として含む配列として想定しています。bobのanswerに似ていますが、連結された文字列としてではなく、配列に入っています。

alert(game.indexOf("xxx")>=0?"win":game.indexOf("ooo")>=0?"lose":"cat")

EDIT @ nyuszika7hのコメント(67文字)

alert(~game.indexOf("xxx")?"win":~game.indexOf("ooo")?"lose":"cat")

~game.indexOf("xxx")代わりにを使用できますgame.indexOf("xxx")>=0が、もう一方の場合も同じです。
nyuszika7h 14

0

Java 7、260バイト

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";}

未ゴルフ&テストケース:

ここで試してみてください。

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 }));
  }
}

出力:

loose
win
cat

0

APL(NARS)、69文字、138バイト

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

入力は、1つ(Xの場合)と0(Oの場合)のみである9要素の1つの3x3行列または1つの線形配列である必要があります。 "Xが勝った場合。1つの無効なボードのチェックはありません。または、1つの配列の要素が9個未満であるか、各要素が<2であるかをチェックします。

コメントとして:入力を3x3行列に変換し、「x」という名前の1つの配列を作成します。ここで、要素は各行列と対角線の合計です。

いくつかのテストは他から示された例を見る:

  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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.