かくれんぼをしましょう!


12

ユーザーは非表示になり、コンピューターはそれらを見つけようとします。

まず、プログラムはグリッドのサイズの入力を受け取ります。5x5、10x10、15x15など。グリッドは常に完全な正方形とは限りません。

グリッドはチェス盤のようなものです。

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

これで、ユーザーは次のような正方形を選択しますB2(コンピューターに通知せずに)

コンピューターは正方形の推測を開始します。正しい正方形が選択されると、ユーザーはで応答しyます。そうでない場合は、選択したタイルからの方向(N、NE、E、SE、S、SW、W)を入力します。

したがって、ユーザーが選択B2し、コンピューターが推測したC3場合、ユーザーは入力しますNW

出力と入力の例を次に示します。

Grid?
5x5

C3?
NW

C2?
N

B2?
y

得点:

これは、通常のチャレンジとは少し異なります。

勝者は、正しい平方を推測するために必要な推測の平均数が最も少ないプログラムです。平均化されるテストケースは、5x5のすべての可能な正方形であり、10x10の正方形です。

ただし、最大26行のグリッドのすべてのパターン(5x8、6x2、20x5など)でも機能する必要があります。

JSFiddleなど、テストする方法を含めてください。

そして最後に、同点の場合、最短のプログラムが勝ちます。


1
私が上で隠れていた場合はA1、コンピュータの推測B9、適切な応答ですNWW
グレッグマーティン

@GregMartin NWになります。...N、W、S、Eはすべて直線である必要がありますが、異なる行/列にあるものはNW、NE、SW、SEでなければなりません
JKonowitz

入力および出力の特定の形式に柔軟性はありますか?26行を超える場合、それらは何と呼ばれますか?
グレッグマーティン

@GregMartin出力は柔軟にできますが、シンプルに保つようにしてください。まったく同じである必要はありませんが、同様のスタイルが必要です。26を超えるものを考慮する必要はありません。編集します。
JKonowitz

「類似スタイル」の意味がわかりません。入力を整数のペア(行番号、列番号)として受け取ることはできますか?(PS:質問のこれらのタイプは、中、なぜ事前に掲載の課題の理由ですサンドボックス。素晴らしいアイデアです)
グレッグ・マーティン

回答:


3

Pythonの3.6466 398 392バイト、ミニマックス

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)

入力と出力は、例に示す形式にする必要があります。これにより、最小の「スプリットファクター」(プレイヤーの回答(NW、E、yなど)から生じる可能性のある最大の残りの領域)を持つ正方形が検出され、それが推測されます。はい、それは常にこのゲームの残りの領域の中心ですが、最悪のケースを最小化するこの手法は、ルールが異なる同様のゲームでより一般的に機能します。

読めないバージョン:

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、テストケースの最適な動作、260バイト

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"]]

このプログラムは、上記のコードを切り取り、Wolfram Cloudに貼り付けることでテストできます。(ただし、すばやくテストしてください。各プログラムの実行には時間制限があると思います。)プログラムの推測はの2 c代わりに似ていますがC2、それ以外は上記の仕様に従って実行されます。グリッドは、などの整数の順序付きペアとして入力する必要があり{26,100}、プログラムの推測に対する応答は、"NE"またはなどの文字列として入力する必要があります"y"

プログラムは、これまでの入力と一致する最小および最大の行番号と列番号を追跡し、常に可能性のあるサブグリッドの中心点を推測します(丸めNW)。このプログラムは決定論的であるため、固定グリッド上で平均的に必要な推測の数を簡単に計算できます。10x10グリッドでは、プログラムは1つの正方形に対して1つの推測、8つの正方形に対して2つの推測、64の正方形に対して3つの推測、残りの27の正方形に対して4つの推測を必要とします(平均3.17)。そして、これは理論上の最小値であり、1推測、2推測などのシーケンスが正しい推測につながる可能性があることを考えます。実際、プログラムは同様の理由で、あらゆるサイズのグリッドで理論上の最小値を達成する必要があります。(5x5グリッドでは、推測の平均数は2.6です。)

少しコードを説明しますが、ゴルフ以外のかなり簡単な説明です。(説明のためにいくつかの初期化ステートメントの順序を交換しました。バイトカウントには影響しません。)

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行目はForループを初期化しますが、これは実際にはWhile変装したループであるため、2バイト少なくなっています。いつでも可能な行番号と列番号の範囲はに保存され{{a, c}, {f, h}}、そのサブグリッドの中央推測は{b, g}2行目で定義された関数によって計算されます。3行目はユーザー入力からmax-row cとmax-column hを初期化します。またr、ループテストされた変数である初期化、および後続のユーザー入力も初期化します。

4行目のテストが満たされている間、5 行目はユーザーからの入力を受け取ります。この場合、プロンプトは現在の推測に基づいています{b, g}Alphabet[][[b]]]行番号を文字に変換します)。次に、6〜8行目でサブグリッドの可能性を更新します(したがって、暗黙的に次の推測を更新します)。たとえば、t["NSu", {{a, b - 1}, {b + 1, c}, {b, b}}]t行1の定義が与えられた場合)は、

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

ユーザーの最後の入力に応じて更新される最小行数と最大行数を確認できます。行8は、可能な入力を次の形式の文字の順序付きペアに変換します{ "N" | "S" | "u", "u" | "W" | "X"}。ここ"u"は正しい行または列を"X"表し、東を表します(Sortうまく機能するようにするためです)。ユーザーが最終的に入力すると"y"、これらの行はエラーをスローしますが、ループテストは失敗し、エラーは伝播されません(プログラムはとにかく停止します)。


0

バッチ、分割統治

@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

検索する領域の境界ボックスを作成することにより機能します。次の推測は常にボックスの中心です。応答に含まれないコンパスポイントの場合、ボックスはその方向に縮小されます。たとえば、の応答のN場合、ボックスの左、右、および下は推測された正方形に設定されます。

369バイトでは、誰かに勝つことを期待していないので、読みやすくするためにスペースを残しました。


まあ、分割統治は一般に大きなテストケースには役立ちますが、小さなケースではなく、より良いアルゴリズムですか?
マシュー

@SIGSEGV意味がわからない。グレッグとベンの答えは、ボックス中心法も使用しています。
ニール

さらに優れたアルゴリズムが必要です。
マシュー盧

@SIGSEGV中心点法が最適です。より良いアルゴリズムはありません。
TheNumberOne
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.