Hadi saklambaç oynayalım!


12

Kullanıcı gizlenir ve bilgisayar onları bulmaya çalışır.

İlk olarak, program ızgaranın boyutu için bir giriş alacaktır. 5x5, 10x10, 15x15 vb. Gibi. Izgara her zaman mükemmel bir kare olmaz.

Izgara bir satranç tahtası gibidir:

_______________________________
|     |     |     |     |     |
| A1  |     |     |     |     | A
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     | B2  |     |     |     | B
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     |     | C3  |     |     | C
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     |     |     | D4  |     | D
|_____|_____|_____|_____|_____|
|     |     |     |     |     |
|     |     |     |     | E5  | E
|_____|_____|_____|_____|_____|
   1     2     3     4     5

Şimdi, kullanıcı B2(bilgisayara söylemeden) gibi bir kare seçecektir

Bilgisayar kareleri tahmin etmeye başlayacaktır. Doğru kareyi seçerse, kullanıcı yanıt verecektir y. Değilse, döşemelerinin seçtiği yönden (N, NE, E, SE, S, SW, W) giriş yaparlar.

Yani kullanıcı aldı eğer B2ve bilgisayar tahmin C3kullanıcı girişi olur, NW.

İşte çıktıların ve girişlerin bir örneği:

Grid?
5x5

C3?
NW

C2?
N

B2?
y

puanlama:

Bu normal bir meydan okumadan biraz farklı puanlanacaktır.

Kazanan, doğru kareyi tahmin etmek için en az sayıda (ortalama) tahmin alan programdır. Ortalamalandırılacak test senaryoları, 5x5 ve ardından 10x10'da olası tüm kareler olacaktır.

Bununla birlikte, 26 satıra kadar olan her ızgara deseniyle de çalışmalıdır (yani 5x8, 6x2, 20x5 vb.).

Lütfen test edilmesi için bir JSFiddle gibi bir yol ekleyin.

Ve son olarak, bir beraberlik durumunda, en kısa program kazanır.


1
Saklanıyorsam A1ve bilgisayar tahmin ederse B9, uygun yanıt NWW?
Greg Martin

@GregMartin NW olurdu .... N, W, S, E düz olmalı, farklı bir satır / sütundaki herhangi bir şey NW, NE, SW, SE olmalıdır
JKonowitz

Belirli girdi ve çıktı biçiminde esneklik var mı? 26'dan fazla satır varsa, bunlara ne denir?
Greg Martin

@GregMartin Çıktı ile esnek olabilirsiniz ancak basit tutmaya çalışabilirsiniz. Tam olarak aynı olmak zorunda değildir, ancak benzer bir stile sahip olmalıdır. 26 yaşın üzerindeki herhangi bir şeyi hesaba katmanıza gerek yok, bunu düzenleyeceğim.
JKonowitz

"Benzer tarzın" ne anlama geldiğini bilmiyorum. Girdiyi sıralı bir tam sayı çifti olarak alabilir miyiz (satır #, sütun #)? (Not: ön gönderme zorluklar neden, bu tür sorular nedenleri Sandbox harika bir fikir.)
Greg Martin

Yanıtlar:


3

Python 3.6 , 466 398 392 bayt, minimaks

x, y = 1, 1
w, h = [int(x) for x in input('Grid?\n').split('x')]


def split_factor(a, b):
    N = b-y
    W = a-x
    S = h+~N
    E = w+~W
    return max(1, N, W, S, E, N*W, S*W, S*E, N*E)


def move(a, b):
    *Z, = zip([a, x, a, a+1, x, x, a+1, a+1],
              [y, b, b+1, b, y, b+1, b+1, y],
              [1, a-x, 1, w+x+~a, a-x, a-x, w+x+~a, w+x+~a],
              [b-y, 1, h+y+~b, 1, b-y, h+y+~b, h+y+~b, b-y])
    return Z[['N', 'W', 'S', 'E', 'NW', 'SW', 'SE', 'NE'].index(d)]

d = ''
while d != 'y':
    print()
    splits = {(a, b): split_factor(a, b) for a in range(x, x+w) for b in range(y, y+h)}
    a, b = min(splits, key=splits.get)
    d = input(f'{a}{"ABCDEFGHIJKLMNOPQRSTUVWXYZ"[b]}?\n')
    x, y, w, h = move(a, b)

Girdi ve çıktı örnekte gösterilen biçimde olmalıdır. Bu, oyuncunun cevabından (yani KB, E, y, vb.) Kaynaklanabilecek en büyük kalan alan olan minimum "bölünme faktörü" olan kareyi bulur ve bunu tahmin eder. Evet, bu her zaman bu oyunda kalan alanın merkezi, ancak en kötü durumu en aza indirgeme tekniği farklı kurallara sahip benzer oyunlarda daha genel olarak çalışacaktır.

Okunamayan sürüm:

x=y=d=1
w,h=map(int,input('Grid?\n').split('x'))
while d!='y':print();s={(a,b):max(b-y,h+y+~b)*max(w+x+~a,a-x)for a in range(x,x+w)for b in range(y,y+h)};a,b=min(s,key=s.get);d=input(f'{a}{chr(64+b)}?\n');*z,=zip([a+1,x,a+1,x,a,a,a+1,x],[b+1,b+1,y,y,b+1,y,b,b],[w+x+~a,a-x,w+x+~a,a-x,1,1,w+x+~a,a-x],[h+y+~b,h+y+~b,b-y,b-y,h+y+~b,b-y,1,1]);x,y,w,h=z[~'WENS'.find(d)or-'NWNESWSE'.find(d)//2-5]

2

Mathematica, test senaryolarında optimal davranış, 260 bayt

For[a=f=1;{c,h}=Input@Grid;z=Characters;t=<|Thread[z@#->#2]|>&;r="";v=Floor[+##/2]&;b:=a~v~c;g:=f~v~h,r!="y",r=Input[g Alphabet[][[b]]];{{a,c},{f,h}}={t["NSu",{{a,b-1},{b+1,c},{b,b}}]@#,t["uWX",{{g,g},{f,g-1},{g+1,h}}]@#2}&@@Sort[z@r/.{c_}:>{c,"u"}/."E"->"X"]]

Bu program, yukarıdaki kodu kesip Wolfram Cloud'a yapıştırarak test edilebilir . (Yine de hızlı bir şekilde test edin: Her program çalıştırması için bir zaman sınırı olduğunu düşünüyorum.) Programın tahminleri 2 cbunun yerine benziyor C2, ancak aksi takdirde yukarıdaki özelliklere göre çalışıyor. Izgara, sıralı bir tamsayı çifti gibi {26,100}girilmeli ve programın tahminlerine verilen yanıtlar, "NE"veya gibi dizeler olarak girilmelidir "y".

Program, şimdiye kadar girdilerle tutarlı olan en küçük ve en büyük satır numarasını ve sütun numarasını izler ve her zaman olasılıkların alt ızgarasının merkez noktasını (yuvarlama KB) tahmin eder. Program deterministiktir, bu nedenle sabit bir ızgara üzerinden ortalama olarak ihtiyaç duyduğu tahmin sayısını hesaplamak kolaydır. 10x10 ızgarada, program tek bir kare için 1 tahmin, sekiz kare için 2 tahmin, 64 kare için 3 tahmin ve kalan 27 kare için 4 tahmin, ortalama 3.17 gerektirir; ve kaç tane tahmin, 2 tahmin vb. dizinin doğru tahminlere yol açabileceği düşünüldüğünde teorik minimumdur. Aslında, program benzer nedenlerle herhangi bir boyut ızgarasında teorik minimum seviyeye ulaşmalıdır. (5x5'lik bir ızgarada, ortalama tahmin sayısı 2.6'dır.)

Biraz kod açıklaması, golfing dışında oldukça basit olmasına rağmen. (Bazı başlangıç ​​ifadelerinin sırasını açıklama amacıyla değiştirdim; bayt sayısı üzerinde bir etkisi yok.)

1  For[a = f = 1; z = Characters; t = <|Thread[z@# -> #2]|> &;
2      v = Floor[+##/2] &; b := a~v~c; g := f~v~h;
3      r = ""; {c, h} = Input@Grid, 
4    r != "y", 
5    r = Input[g Alphabet[][[b]]];
6      {{a, c}, {f, h}} = {t["NSu", {{a, b - 1}, {b + 1, c}, {b, b}}]@#, 
7        t["uWX", {{g, g}, {f, g - 1}, {g + 1, h}}]@#2} & @@ 
8        Sort[z@r /. {c_} :> {c, "u"} /. "E" -> "X"]
   ]

1-3 satırları For, aslında sadece Whilekılık değiştirmiş bir döngü olan döngüyü başlatır , bu yüzden hey, iki daha az bayt. Herhangi bir anda olası satır numarası ve sütun numarası aralıkları saklanır {{a, c}, {f, h}}ve bu alt ızgaradaki ortalanmış tahmin {b, g}, satır 2'de tanımlanan işlevlerle hesaplanır . Satır 3 , kullanıcı girişinden cmaksimum satırı ve maksimum sütunu başlatır hve ayrıca rloop test edilmiş değişken olanı ve sonraki kullanıcı girişlerini de başlatır .

Hat 4'teki test yerine getirilirken, hat 5 kullanıcıdan bilgi alır, burada bilgi istemi geçerli tahminden gelir {b, g}( Alphabet[][[b]]]satır numarasını bir harfe dönüştürür). Sonra 6-8 satırları olasılıkların alt ızgarasını günceller (ve dolayısıyla dolaylı olarak bir sonraki tahminde bulunur). Örneğin, t["NSu", {{a, b - 1}, {b + 1, c}, {b, b}}]( tsatır 1'in tanımı verildiğinde )

<| "N" -> {a, b - 1}, "S" -> {b + 1, c}, "u" -> {b, b}|>

burada min. satır ve maks. satır sayılarının kullanıcının son girdisine göre güncellendiğini görebilirsiniz. Satır 8, olası tüm girişleri formun sıralı karakter çiftine dönüştürür { "N" | "S" | "u", "u" | "W" | "X"}; burada "u"doğru bir satır veya sütun "X"anlamına gelir ve Doğu anlamına gelir (sadece Sortgüzel çalışmasına izin vermek için). Kullanıcı sonunda girdiğinde "y", bu satırlar bir hata atar, ancak daha sonra döngü testi başarısız olur ve hata asla propogasyona tabi tutulmaz (program yine de durur).


0

Toplu, böl ve fethet

@echo off
set z = ABCDEFGHIJKLMNOPQRSTUVWXYZ
set /p g = Grid?
set /a w = 0, n = 0, e = %g :x= + 1, s = % + 1
:l
set /a x = (w + e) / 2, y = (n + s) / 2
call set c = %%z :~%y%,1%%
set /p g = %c %%x%?
if %g :w=.% == %g % set /a w = x
if %g :n=.% == %g % set /a n = y
if %g :e=.% == %g % set /a e = x
if %g :s=.% == %g % set /a s = y
if %g :y=.% == %g % goto l

Hala aranacak alanın sınırlayıcı kutusunu oluşturarak çalışır. Bir sonraki tahmin her zaman kutunun merkezidir. Yanıtta yer almayan pusula noktaları için, kutu bu yönde azaltılır. Örneğin, bir yanıt Niçin kutunun sol, sağ ve alt kısmı tahmin edilen kareye ayarlanır.

369 baytta kimseyi dövmeyi beklemiyorum, bu yüzden boşlukları okunabilirlik için bıraktım.


Peki, böl ve fethet genellikle büyük testcasları için yararlıdır, ancak küçük vakalar için değil, daha iyi algoritmalar var mı?
Matthew Roh

@SIGSEGV Ne demek istediğinizden emin değilim; Greg ve Ben'in cevapları da kutu yönteminin merkezini kullanıyor.
Neil

Hala daha iyi bir algoritmaya ihtiyacımız var.
Matthew Roh

@SIGSEGV Kutu merkezi yöntemi en uygunudur. Daha iyi bir algoritma yoktur.
TheNumberOne
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.