Tictactoe'daki kazancı belirle


19

Biraz kod golf oynayalım!

Tic Tac Toe kurulu durumu verildi (Örnek :)

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

Bir oyunun wina loseveya mı olduğunu belirleyin cat. Durumunuz verildiğinde, kodunuz bu seçeneklerden herhangi birini vermelidir. Yukarıdaki oyun çıktı olmalıdırlose

Açık olmak gerekirse: bir kazanç xarka arkaya 3 s olarak tanımlanır (diyagonal, yatay, dikey). oüst üste 3 s, üst üste cathiçbir oyun yok.

İşleri ilginç hale getirmek için, daha sonra açıklamanız gereken durum için giriş yapınızı belirlersiniz. Örneğin xxoxoxoox, karakterlerin her birinin soldan sağa, yukarıdan aşağıya okunduğu yukarıda görüldüğü gibi geçerli bir durumdur. [['x','x','o'],['x','o','x'],['o','o','x']]benzer şekilde okunan çok boyutlu dizideki oyun. Birlikte 0x1a9bunun için hex 110101001uygun bir sıkıştırma gibi kudreti çalışması 1için manipüle edilebilir xs ve 0manipüle edilebilir o.

Ama bunlar sadece bazı fikirler, eminim kendi fikirlerinize sahip olabilirsiniz.

Temel kurallar:

  1. Programınız geçerli herhangi bir durumu kabul edebilmelidir.
  2. Girdi biçimi herhangi bir durumu temsil edebilmelidir.
  3. "Kazanma durumu kuruldan belirlenmeli"
  4. Komple bir tahta varsayalım
  5. Windaha önce loseörneğin 'xxxoooxxx' davasında

En düşük karakter sayısı kazanır


1
Bu giriş yapısını seviyorum: (win|lose|cat) [xo]{9}ilk kelime oyunun x oyuncusu için bir kazanma, kaybetme veya kedi (?) Olup olmadığını gösterir. Herhangi bir devleti temsil edebilir.
Runer112

2
"Kazanma durumu panodan belirlenmeli" veya "Girdi, pano durumu dışında hiçbir bilgi içermemeli" gibi bir kural önerebilir miyim?
undergroundmonorail

3
Sadece oynanan yasal oyunları mı varsayıyoruz? Eğer öyleyse, bazı devletler imkansız olurdu, yani XXX OOO XXX ama aksi halde bazı tam pansiyon devletler bunu X'in kazandığı ancak O'nun da kazandığı dördüncü imkansız bir sonuç olarak içerir.
Riot

10
neden "kedi" ilgisiz?
Chris

7
@DylanMadisetti: daha önce hiç duymadım ve "win lost cat" için googlign hiçbir şey yapmadı. Kravatla ya da kişisel olarak çizerdim. Ya da bu oyun durumunda belki "kaçınılmazlık". ;-) Rekabet olsa da çok fazla umursamıyorum. Dize bir dizedir. ;-)
Chris

Yanıtlar:


11

Ruby 2.0, 85 karakter

İşte Ruby'de basit bir bitmask tabanlı çözüm:

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

Kart, dokuz kareye karşılık gelen dokuz bitten oluşan bir onaltılık sayı olarak temsil edilir. 1 bir X, 0 bir 'dir O. Bu isteğe bağlı 0x1a9olsa da 0x, sorudaki örnek gibidir !

Muhtemelen bit maskeleri yapmanın daha iyi bir yolu var, o zaman sadece büyük bir listeyi kodlamak. Memnuniyetle öneriler alacağım.

Burada Ideone üzerinde çalıştığını görün .


1
Listeniz 273iki kez içeriyor . Ve bu maxfikri gerçekten seviyorum !
Ventero

1
Oh @Ventero, her zaman belirsiz optimizasyonlarla (teşekkürler)
Paul Prestidge

Tahta üzerinde boş alanlar olabilir. Giriş biçiminiz bu durumu hesaba katmaz ve bu nedenle geçerli bir oyun durumunu temsil edemez.
Stephen Ostermiller

2
@StephenOstermiller kuralı 4: Komple bir kart olduğunu varsayalım. Bu kuralın belki de kural 1 ve 2 ile çeliştiğini haklıyorsunuz, ancak sorudaki tüm yorumları okursanız, bu sorunun ruhu içinde olduğunu düşünüyorum (eksik kurullar kapalı değil, tam değil yasadışı kurullar.) Ancak sekizlinin onaltılıdan daha kullanıcı dostu bir girdi biçimi olacağını düşünüyorum.
Level River St

1
Anladım, tamamlamanın farklı bir şey ifade ettiğini düşündüm.
Stephen Ostermiller

10

Mathematica, 84 karakter

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

Giriş biçimi: {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}


Burada neler oluyor?
seequ

3
@TheRare Sağdan başlayın. Tr@aalan (çapraz üzerinde toplam) izidir, Tr@Reverse@aters çevrilmiş alan iz (bazı anti çapraz üzerinde), Tr/@abir Tr, her satır üzerinde size toplamı veren her satır, uygulanan Total@aher bir sütun üzerinde size toplamını verir. Temel olarak, kontrol etmeniz gereken 8 hattın hepsi var. Daha sonra Whichşey (temelde bir if/elseif/elseifade) üzerine uygulanır, burada #8 değer listesini temsil eder. ifBir var 3kazanmak, else ifbir var 0, kaybedecek else if 1>0(doğru) cat.
Martin Ender

6

Bash: 283 262 258

Nispeten samimi bir arayüze sahiptir.

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

Yürütmek bash tictactoe.sh O X O X O X X O X

Not: 9 konumlu liste standart bir matris temsilidir. Tahtanın sütun ana veya satır ana olarak gösterilmesi, soldan sağa veya yukarıdan aşağıya okunması önemli değildir - noughts ve crosses oyunları (veya ısrar ederseniz tic tac toe) simetriktir, bu nedenle giriş sırası alakasız olmalıdır girdi doğrusal olduğu sürece her doğru uygulamada sonuca götürür.

Düzenleme: Daha kısa işlev sözdizimi önerisi için hjk sayesinde.


Düşünün t() { ... }yerine function t? Orada bazı karakterler kaydedebilir. :)
hjk

Alternatif işlev sözdizimini tamamen unutmuştum - teşekkürler!
Riot

<<<Dört karakter daha kaydetmek için boşluklara gerek yoktur .
Michael Mior

4

Befunge 93-375

İkili bir dizeyi girdi olarak alır.

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

Dizeyi okur. Bruteforce (en sağdaki dikey şerit) arasında bir matris olarak yazar

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

kafes ekleme (idk). Sütunların, satırların ve iki tanının toplamını belirler. Bu değerleri 3 ("kazan") veya 0 ("kaybet") ile karşılaştırır, aksi takdirde tüm değerler 1 veya 2'ye eşitse çizin ("kedi").


4

GolfScript, 27 karakter

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

Giriş formatı, her biri (art arda) üç ardışık tahta kareyi kodlayan sekiz sekizli rakamdan oluşan bir dizedir:

  • İlk üç basamak, yukarıdan aşağıya ve soldan sağa doğru tek bir satır satırını kodlar.
  • Aşağıdaki üç hane soldan sağa ve yukarıdan aşağıya doğru tek bir sütunu kodlar.
  • Son iki hane, diyagonallerden birini kodlar (önce soldan sağa, sonra soldan sağa).

Üç kareden oluşan bir diziyi (satır / sütun / diyagonal) sekizlik bir rakam olarak kodlamak için, dizideki her birini x1 ve her birini o0 ile değiştirin ve sonuçta olanların ve sıfırların dizisini 0 ile 7 arasında bir ikili sayı olarak yorumlayın. kapsayıcı.

Bu giriş biçimi (bütün kartı pozisyonları orta konumda dört kez kodlanmış ile iki kez, en azından kodlanır) oldukça fazladır, fakat bu etmez açıkça tamamen dolu bir tic tac ayak kurulu bir olası durumunu temsil eder ve etmez , doğrudan kodlayan kazanan.

Giriş, isteğe bağlı olarak, rakamlar arasında boşluklar veya başka sınırlayıcılar içerebilir. Aslında, tüm program gerçekten umurunda, giriş dizesi basamak 7veya içeriyor olup olmadığıdır 0.

Örneğin, örnek yönetim kurulu:

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

girdi ile temsil edilebilir:

651 643 50

Kolaylık sağlamak için, yukarıdaki meydan okumada gösterildiği gibi ASCII sanat panosu düzenini bu program için uygun bir giriş dizesine dönüştürmek için bir GolfScript programı:

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

Bu dönüştürücü dışında herhangi karakterleri yok sayar xve obunun girişteki, her iki durumda da,. Yukarıdaki kazanç belirleme programına beslemek için uygun tek haneli bir dize (yukarıda gösterildiği gibi boşluk sınırlayıcılarla birlikte) üretir, bu nedenle bu iki programın birleşimi, kazananı doğrudan ASCII sanat tahtasından belirlemek için kullanılabilir.

Ayrıca, burada bir ters dönüştürücü, sadece girişin gerçekten de tahtayı açıkça temsil ettiğini göstermek için:

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

Ps. İşte bu çözümün çevrimiçi bir demosu.


2
Girdi üretilirken işin çoğu gerçekleştiğinden girdi biçimi hile gibi görünüyor.
Arkku

@Arkku: Evet, öyle, ama soru açıkça "devlet için girdi yapınızı belirleyeceksiniz - ki daha sonra açıklamanız gerekir" diyor. Geçerli bir giriş biçimine örnek olarak biraz paketlenmiş onaltılık bir dize bile gösterir; Bu ve benim giriş formatı arasındaki tek fark, bazı bitleri yeniden sıralayıp çoğaltmam.
Ilmari Karonen

6
Tam bir kopya gibi görünüyor. (örneğin, bu etmez , doğrudan giriş, 7 veya 0 varlığı olarak kazanan kodlayan)
Arkku

Yine de bu akıllı bir kodlamadır, gereksizdir, ancak çözümü bulmayı gereksiz olmayan kodlamalardan çok daha verimli hale getirir!
ARRG

3

Python 2 - 214 bayt

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'

Eminim yapılacak iyileştirmeler var.

Koşmak:

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

bu kurulu temsil eder:

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

NameErrorDışında her durumda bir istisna dışında çıkar cat.


Vay, hiç bilmiyordum <<<! Sadece bunun için +1.
Greg Hewgill

@GregHewgill Oldukça kullanışlı. ./whatever <<< 'blah blah blah'için echo -n 'blah blah blah' | ./whateverayrı bir süreç olmadan aynıdır echo.
undergroundmonorail

@undergroundmonorail echoiçinde bashbir yerleşik aslında, bu yüzden yeni bir süreç çatal değil
Bob

@GregHewgill buna bir soykırım deniyor

3

Haskell, 146 karakter

İşleri ilginç hale getirmek için, daha sonra açıklamanız gereken durum için giriş yapınızı belirlersiniz.

TAMAM :). Bir tahtayı temsil etmem şu 126 karakterden biri

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

146 karakterden oluşan çözüm:

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

İşte bir haskell betiği olarak şu şekilde çalışır:

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 karakter

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'

Bu sürümde, soyun tahtasının durumunu temsil eden bir tam sayı içerir. İki bitin karttaki her kareyi temsil ettiği bir değer dizisidir:

  • 10 - X
  • 11 - Ö
  • 00 - Boş kare

Bu çözüm, olası sekiz "arka arkaya üç" konfigürasyonun her birini test etmek için bit manipülasyonu kullanır (her birini iki kez, bir kez X için ve bir kez O için test eder).

Bunu , bu fonksiyonun gerçek bir Tic-Tac-Toe oyununun bir parçası olarak kullanıldığı Tic-Tac-Toe web sitemden küçük bir küçültme ile sunuyorum detectWin.


6
Buna kaba kuvvet denebilir.
seequ

2

Ruby, 84 karakter

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

Basit, RegExp tabanlı çözüm. Giriş formatı, örneğin 110101001soruda verilen örnek kart için 9 basamaklı bir ikili dizedir .

Ruby, 78 karakter

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

Giriş biçimi: xxo_xox_oox


1

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

Giriş biçimi: "X" yalnızca x, "O" ile gösterilir o. Her satırda karakterler, boşluklar olmadan eşzamanlıdır. Satırlar yeni satırlarla ayrılır.

Tüm olası satırları / sütunları / köşegenleri oluşturur, daha sonra [("ooo","lose"),("xxx","win")]tahtadaki varlıklarına göre filtreler , daha sonra gruptaki ikinci kelimeyi seçer, böylece hangi oyuncuların kazandığını biliyoruz. Biz prepend "cat"bizim kazanan listenin son öğe alabilir böylece. Her iki oyuncu da kazanırsa, "win"sonuncusu olur (liste kavrayışları düzeni korur). Yana "cat"ilk daima kazanır varsa, bu seçilecektir, ama aksi bir son öğe hala prepending olarak var "cat"garanti nonemptyness.

EDIT: Son liste kavrama değiştirerek 3 karakter traş map.


1

C, yaklaşık 150

Burada gece yarısı ve hiç test yapmadım , ama yine de konsepti yayınlayacağım. Yarın buna geri döneceğim.

Kullanıcı iki sekizli sayı girer (Ben ikili kullanmak istedim ama bildiğim kadarıyla C sadece sekizli destekler):

a merkezi kareyi temsil eder, X için 1, O için 0

b bir köşeden başlayarak ve aynı köşede biten (sadece o köşenin tekrarı ile), X için 1, O için 0 olmak üzere çevre karelerini temsil eden dokuz haneli bir sayıdır.

Kazanmanın iki yolu vardır:

  1. orta kare X ( a= 1) ve iki karşıt kare de X ( b&b*4096sıfırdan farklı)

  2. Üç bitişik çevre karesi b/8 & b & b*8X'tir ( sıfır değildir.) Bu, yalnızca orta kare bir köşe karesi değil, bir köşe karesi ise geçerli bir kazançtır, bu nedenle mköşe karesi durumlarından kaçınmak için maskeyi de uygulamak gerekir .

Kayıp, b'nin tersi olan c değişkeni kullanılarak tespit edilir.

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"Kayıp" tespitinde maskeyi uygulamayı unuttun c/8&c&c*8. Kodunuzu (çalışmasını test etmeden) aşağıdaki gibi yeniden golf oynadım: 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 karakter). Tekrarlanan test, bir test fonksiyonuna ekstrakte edilecek kadar uzundu t(); bu cve m; sabitler her biri bir karakter kaydetmek için hex'e dönüştürülür.
Toby Speight

Sadece printfbir biçim dizesine ihtiyaç duymadığını fark ettim - sonuç dizesini biçim olarak sağlayın - ya putsda soru çıktıdan sonra yeni bir satır istemediğinden! (7 karakter daha kaydeder).
Toby Speight

1

Bash, 107 103

Bir sed komut dosyası oluşturur ve çalıştırır.

G / Ç formatı: oxo-oox-xooçıkışlar lose( -satırları ayırmak için a kullanın). Standart giriş. cKomut için GNU sed gerektirir .

Kural 5'i "hem kazan hem de kaybet mümkünse kazan'ı seç" şeklinde yorumladım.

Ana kod

Asıl cevap bu.

Gerçekten ilginç bir şey yok. Bu tanımlar $bolarak /cwinkarakterleri kaydetmek için, o zaman script kazanma koşulu parçasını tanımlayan sonra, kullanır sed y/x/o/\;s$b/close/dönüştürmek xiçin ove cwiniçin close(dolayısıyla kaybetmek koşulları üreten). Sonra iki şeyi gönderir veccat ( catkazan / kaybet koşulu eşleşmezse çıktı alır) sed'e .

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"

Oluşturulan Kod

Bu, Bash betiği tarafından oluşturulan ve çalıştırılan sed betiğidir.

Normal ifadelerde, .cTEXT ifadelerde, herhangi bir karakterle eşleşir ve ondan sonra METİN yazdırır ve normal ifadeyle eşleşirse çıkar.

Bu bağımsız bir sed komut dosyası olarak çalışabilir. 125 karakter uzunluğunda, başka bir çözüm olarak sayabilirsiniz.

/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

Giriş, ioyun tahtasının her bir satırını, sütununu ve köşegenini temsil eden sayıların bir listesi olan örn.

X X O
O X O
O O X

ile temsil edilir [6, 2, 1, 4, 6, 1, 7, 4].

Kod :('cat','lose','win')[2 if 7 in i else 0 in i]


1

Dart - 119

(Bkz. Dartlang.org ).

RegExp kullanan orijinal sürüm: 151 karakter.

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

Komut satırındaki giriş 11 karakterdir, örneğin "xxx | ooo | xxx". Herhangi bir xo olmayan karakter sınırlayıcı olarak kullanılabilir.

Karakter sayılmadan önce önde gelen boşluklar ve yeni satırlar atlanmalıdır, ancak mümkünse dahili boşlukları keserim. Alt dize yapmanın daha küçük bir yolu olsaydı.

Tekrarlayan bit tabanlı versiyon: 119 karakter. Giriş 9 bitlik bir sayı olmalı ve 1'ler 'x' ve 0'lar 'o' temsil eder.

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 karakter

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

Bu, için temel dönüştürülmüş bir koddur.

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

52 karakter uzunluğunda.

Giriş, satırın sol üstünden başlayarak satır satır olacak şekilde dize temsilidir. Örneğin:

oxooxooox

bu da bir winçıktı ile sonuçlanır . Veya

oxooxoxox

catçıktı, vb. ile sonuçlanır .

Kod basitçe aşağıdaki üç şeyi yapar:

  • q3/_ - İpi 3'lü parçalara ayırın, yani sıra başına
  • _z - Satır başına diziyi kopyalayın ve sütun dizisine dönüştürün.
  • __Wf%s4%- Her satırı tersine çevirin ve soldan sağa diyagonal olsun. Bu, tahtanın ikincil köşegenidir.
  • \s4% - Tahtanın ana köşegenini al
  • ]` - Her şeyi diziye sarın ve diziyi dizginleyin.

Şimdi tahtadan tüm olası 3 grup var. Sadece sonucu belirlemek için "ooo" ve "xxx" in varlığını kontrol ediyoruz.

Buradan çevrimiçi deneyin


1

GNU sed, 25 bayt

Giriş, diğer yanıtlarda da kullanıldığı gibi, sütunlar, satırlar ve köşegenler için ayrı görünümlere sahip bir panonun yedekli bir temsiliyse, sed, oyunun son durumunu en az bayt ile kontrol etmek için çok uygundur.

Giriş formatı: xxx ooo xxx xox xox xox xox xox (yönetim kurulu durumu OP sorusundan alınmıştır)

/xxx/cwin
/ooo/close
ccat

Giriş formatı yedekli değilse ( xxx ooo xxx), yukarıdaki sed kodu yalnızca aşağıdaki satırın başındaysa çalışır ve programı 96 bayt uzunluğunda yapar (gerekli rbayrak sayılmış olarak).

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

1

Bash: 208 karakter

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

Yürütmek bash tictactoe.sh 0 1 0 1 0 1 1 0 1

Bu cevaptan esinlenildi .


0

VB.net

Örnek ile aşağıdaki bit örüntüsü olarak kodlanır

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

Şimdi sonucu (veya kazanan) aşağıdakileri yaparak belirleyebiliriz.

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 bayt

Peki, mevcut en basit yaklaşım. Giriş, 111222333sayıların satırları temsil ettiği şekilde alınır . Soldan sağa okuyun. Oyuncu xve düşman o. Boş kareler xveya dışında herhangi bir şey olabilir o.

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

Örnekler: (Not. Bir yorumdur)

   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

Açıklanamayan kod açıklama

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 bayt

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]

Veya Python, Python kabuğundan 115 bayt (2 veya 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]

Board değişkeni, soruda açıklanan ikili biçime ayarlanır: 1X 0için, O için, soldan sağa, yukarıdan aşağıya. Bu durumda, 101001110temsil

XOX
OOX
XXO

Hangi çıkış yol açar: Cat


Giriş formatı nedir?
seequ

0

Python ( 73 62 karakter)

Giriş, tümü aynı panonun dört ayrı görünümünü temsil eden dört küçük harfli dizgidir ve tümü tek bir dizeye birleştirilir: satır, sütun, sağ çapraz, sol çapraz.

GÜNCELLEME

Buna iyi bir karşı örnekle işaret ettiği için teşekkürler! Kartın her görünümü ve bir kart içindeki her bölüm (satır veya sütun), "x" veya "o" olmayan bir karakterle ayrılmalıdır, böylece kartın yapısı birleştirme işleminden sonra bile korunur. Tahtanın her görünümünün etrafındaki kenarlıklar köşeli parantez ("[" ve ​​"]") olacak ve satırlar / sütunlar arasındaki ayırıcı bir çizgi karakteri "|" olacaktır.

Bu algoritmayı basitleştirir - sadece bir kazanç veya kayıp için "xxx" veya "ooo" yı arayın. Aksi takdirde bir kravat (kedi).

Örneğin tahta (soldan sağa, yukarıdan aşağıya okuma) ...

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

... "[xxx | xox | oxo]" (satırlarla) + "[xxo | xox | xxo]" (sütunlarla) + "[xoo]" (sağ diag) + [xoo] "(solda) ile temsil edilir diag) = "[xxx | xox | okso] [xxo | xox | xxo] [xoo] [xoo]".

Bu Python deyimi, s değişkenine göre oyun sonucunu yazdırır girdi :

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

Bu tahta için işe yarıyor mu OXX XOO XOX(kedi olmalı)?
seequ

Hayır ... hayır değil. İyi yakalama! Sanýrým çözümüm biraz fazla basitti ... Hata!
bob

Bu tür bir çözümün aklımdan geçmediğini söyleyemem. :)
seequ

0

Haskell (69 karakter)

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

Bu, bu cevapta açıklananla aynı girdiyi alır . Daha spesifik olarak, girdi her bir satır, sütun ve diyagonalin ikili değerini açıklayan 8 sekizlik değerdir. Kod, her 7 "kazanma" örneğini, 0 "kaybetme" örneğini oluşturur ve diğer her şeyi kaldırır. Sonra sonuna "kedi" ekler ve sonuçtan ilk 4 karakter alır.

4 olası cevap olacaktır: "kaybetmek", "kedi", "kazanmak" ve ardından "l" ve "kazanmak" ve ardından "c", kuralların yasaklamadığı :)

Örnek kullanım:

i "65153806" --outputs "lose"

0

J: 83

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

Kullanımı: sadece bir dizi x's ve o's ekleyin ve sihirli işi izleyin. Örneğin. 'Xxxoooxxx'.

İç fiil (+/@:(*./"1)@;@(;((<0 1)&|:&.>@(;|.)(,<)|:)))temel olarak orijinal ikili matrisi bir araya getirir, devrik 2 çapraz ile birlikte kutlanır. Bu sonuçlar birlikte ortaya çıkar; kazançları belirlemek için sıra toplamları alınır ve sonra toplanır. ayrıca ben bu fiili arayacağım Inner.

Kazanı bulmak için, normal ve ters ikili matrisler arasındaki puanların farkı kanca tarafından alınır (-&Inner -.).

Kodun geri kalanı çıkışları yapar ve doğru olanı seçer.


0

JavaScript, 133 , 114 karakter

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

Giriş i, satırlar için sınırlayıcılara sahip basit bir dizedir;100|001|100

Düzenleme: kayıp durumda kontrol etmek için regex 1s sıfır ile değiştirmek için yöntemimi güncellendi.


Normal boşlukların çevresindeki boşlukları =ve tırnak işaretlerini kaldırabilirsiniz . Ayrıca, 1...bir karakter daha kısadır 1.{3}.
nyuszika7h

1
r.test(i)aynı zamanda bir karakterden daha kısadır i.match(r).
nyuszika7h

0

J - 56 (26?) Karakter

Girdi, dokuz karakterli 3x3'lük bir matris verilir, çünkü J bunu bir veri türü LOL olarak destekleyebilir.

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

Örnekler:

   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

Her satırın, sütunun ve diyagonalin durumunu temsil eden sekizli basamakların Golfscriptish kodlamasına izin verilirse, bu sadece 26 karakterdir:

   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)

Giriş onaltılık bir sayıdır. Bu oldukça yakut çözümün T-SQL'e oldukça güzel ve düzenli bir çevirisidir.


0

Javascript 1.6, 71 karakter

Ben game3 char dize olarak her satır, her sütun ve her diag içeren bir dizi olarak girdi varsayıyorum . Bob'un cevabına benzer , ancak bir dizide gelir, birleştirilmiş bir dize olarak değil.

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

DÜZENLEME @ nyuszika7h adlı kullanıcının yorumunu (67 karakter)

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

Diğeri için aynı ~game.indexOf("xxx")yerine kullanabilirsiniz game.indexOf("xxx")>=0.
nyuszika7h

0

Java 7, 260 bayt

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

Test edilmemiş ve test durumları:

Burada deneyin.

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

Çıktı:

loose
win
cat

0

APL (NARS), 69 karakter, 138 bayt

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

Giriş bir 3x3 matris veya sadece 1 (X için) ve 0 (O için) olabilen 9 elemanlı bir lineer dizi olmalıdır, hiç kimse kazanmazsa sonuç "cat", O kazanırsa "kaybet", win "X kazanırsa. Bir geçersiz devre kartı için giriş yoktur veya giriş, bir dizinin 9 veya daha az öğe içerdiğinden veya her öğenin <2 olduğundan emin olun.

Yorum olarak: 3x3'lük bir matristeki girdiyi dönüştürür ve "x" adında bir dizi oluşturur; burada elemanlar, her satır sütununun ve diyagonalin toplamıdır.

Bazı testler diğerlerinden gösterilen örneğe bakınız:

  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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.