Giochiamo a nascondino!


12

L'utente si nasconderà e il computer proverà a trovarli.

Innanzitutto, il programma prenderà un input, per le dimensioni della griglia. Come 5x5, 10x10, 15x15, ecc. La griglia non sarà sempre un quadrato perfetto.

La griglia è un po 'come una scacchiera:

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

Ora, l'utente sceglierà un quadrato, come B2(senza dirlo al computer)

Il computer inizierà a indovinare i quadrati. Se sceglie il quadrato corretto, l'utente risponderà con y. In caso contrario, inseriranno la direzione della loro tessera rispetto a quella selezionata (N, NE, E, SE, S, SW, W).

Quindi, se l'utente ha scelto B2e il computer ha indovinato C3, l'utente avrebbe inserito NW.

Ecco un esempio delle uscite e degli ingressi:

Grid?
5x5

C3?
NW

C2?
N

B2?
y

punteggio:

Questo sarà segnato in modo leggermente diverso rispetto a una normale sfida.

Il vincitore è il programma che richiede il minor numero di ipotesi (in media) per indovinare il quadrato corretto. I casi di test da calcolare in media saranno tutti i quadrati possibili in un 5x5 e quindi in un 10x10.

Tuttavia, deve funzionare anche con ogni modello di griglia fino a 26 righe (ovvero 5x8, 6x2, 20x5, ecc.).

Includere un modo per testarlo, ad esempio un JSFiddle.

E infine, in caso di pareggio, vince il programma più corto.


1
Se mi nascondo A1e il computer indovina B9, è la risposta corretta NWo W?
Greg Martin,

@GregMartin Sarebbe NW .... N, W, S, E devono essere tutti dritti mentre qualsiasi cosa su una riga / colonna diversa deve essere NW, NE, SW, SE
JKonowitz

C'è flessibilità nel formato specifico di input e output? Se ci sono più di 26 righe, come vengono chiamate?
Greg Martin,

@GregMartin Puoi essere flessibile con l'output ma cerca di mantenerlo semplice. Non deve essere esattamente lo stesso, ma dovrebbe avere uno stile simile. Non è necessario tenere conto di nulla al di sopra di 26, lo modificherò.
JKonowitz

Non so cosa significhi "stile simile". Possiamo prendere input come una coppia ordinata di numeri interi (riga #, col #)? (PS: questi tipi di domande sono le ragioni per cui pre-postare sfide nella Sandbox è una grande idea.)
Greg Martin

Risposte:


3

Python 3.6 , 466 398 392 byte, minimax

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)

L'input e l'output dovrebbero essere nella forma mostrata nell'esempio. Questo trova il quadrato con il "fattore di divisione" minimo - che è la più grande area rimanente che può derivare dalla risposta del giocatore (cioè NW, E, y, ecc.) - e indovina. Sì, questo è sempre il centro dell'area rimanente in questo gioco, ma questa tecnica per ridurre al minimo il caso peggiore funzionerà più in generale in giochi simili con regole diverse.

Versione illeggibile:

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, comportamento ottimale su casi di test, 260 byte

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

Questo programma può essere testato tagliando e incollando il codice sopra nel Wolfram Cloud . (Prova rapidamente, però: penso che ci sia un limite di tempo per ogni programma eseguito.) Le ipotesi del programma sembrano 2 cinvece di C2, ma altrimenti funziona secondo le specifiche sopra. La griglia deve essere inserita come una coppia ordinata di numeri interi, come {26,100}, e le risposte alle ipotesi del programma devono essere inserite come stringhe, come "NE"o "y".

Il programma tiene traccia del numero di riga e del numero di colonna più piccolo e più grande che è coerente con gli input finora e indovina sempre il punto centrale della griglia secondaria delle possibilità (arrotondamento NW). Il programma è deterministico, quindi è facile calcolare il numero di ipotesi che richiede in media su una griglia fissa. Su una griglia 10x10, il programma richiede 1 ipotesi per un singolo quadrato, 2 ipotesi per otto quadrati, 3 ipotesi per 64 quadrati e 4 ipotesi per i restanti 27 quadrati, per una media di 3,17; e questo è il minimo teorico, dato quante sequenze 1-ipotesi, 2-ipotesi, ecc. possono portare a ipotesi corrette. In effetti, il programma dovrebbe raggiungere il minimo teorico su qualsiasi griglia di dimensioni per ragioni simili. (Su una griglia 5x5, il numero medio di ipotesi è 2.6.)

Una piccola spiegazione del codice, anche se è abbastanza semplice oltre al golf. (Ho scambiato l'ordine di alcune istruzioni di inizializzazione a fini espositivi - nessun effetto sul conteggio dei byte.)

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

Le righe 1-3 inizializzano il Forloop, che in realtà è solo un Whileloop sotto mentite spoglie, quindi ehi, due byte in meno. I possibili intervalli di numeri di riga e numeri di colonna in qualsiasi momento vengono archiviati in {{a, c}, {f, h}}, e l'ipotesi centrata in quella sottogriglia viene calcolata dalle funzioni {b, g}definite nella riga 2. La riga 3 inizializza la riga cmassima e la colonna massima hdall'input dell'utente e inizializza anche rqual è la variabile testata in loop e anche i successivi input dell'utente.

Mentre il test sulla riga 4 è soddisfatto, la riga 5 riceve input dall'utente, in cui il prompt proviene dall'ipotesi corrente {b, g}( Alphabet[][[b]]]converte il numero di riga in una lettera). Quindi le righe 6-8 aggiornano la sottogriglia delle possibilità (e quindi implicitamente la prossima ipotesi). Ad esempio, t["NSu", {{a, b - 1}, {b + 1, c}, {b, b}}](data la definizione della triga 1) si espande in

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

dove puoi vedere i numeri di riga minima e massima aggiornati in base all'ultimo input dell'utente. La riga 8 converte qualsiasi possibile input in una coppia ordinata di caratteri del modulo { "N" | "S" | "u", "u" | "W" | "X"}; qui "u"sta per una riga o colonna corretta e "X"sta per est (solo per consentire Sortdi lavorare bene). Quando l'utente inserisce finalmente "y", queste righe generano un errore, ma poi il loop test fallisce e l'errore non viene mai propagato (il programma si ferma comunque).


0

Lancia, dividi e conquista

@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

Funziona creando il rettangolo di selezione dell'area ancora da cercare. L'ipotesi successiva è sempre al centro della scatola. Per quei punti cardinali che non sono inclusi nella risposta, la casella è ridotta in quella direzione. Ad esempio, per una risposta di N, il lato sinistro, destro e inferiore della casella sono impostati sul quadrato indovinato.

A 369 byte non mi aspetto di battere nessuno, quindi ho lasciato gli spazi per la leggibilità.


Bene, divide-and-conquer è generalmente utile per grandi test ma non per piccoli casi, qualche algoritmo migliore?
Matthew Roh,

@SIGSEGV Non sono sicuro di cosa intendi; Le risposte di Greg e Ben usano anche il metodo al centro della scatola.
Neil

Abbiamo ancora bisogno di un algoritmo migliore.
Matthew Roh,

@SIGSEGV Il metodo del centro del riquadro è ottimale. Non esiste un algoritmo migliore.
TheNumberOne
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.