Давайте пограємо в ховати і шукати!


12

Користувач сховатиметься, а комп'ютер спробує їх знайти.

По-перше, програма візьме вхід для розміру сітки. Як і 5х5, 10х10, 15х15 тощо. Сітка не завжди буде ідеальним квадратом.

Сітка на зразок шахової дошки:

_______________________________
|     |     |     |     |     |
| 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, чи належна відповідь NWчи W?
Грег Мартін

@GregMartin Це було б NW .... N, W, S, E всі повинні бути прямими, а все, що в іншому рядку / стовпці повинно бути NW, NE, SW, SE
JKonowitz

Чи є гнучкість у конкретному форматі введення та виведення? Якщо є більше 26 рядів, як вони називаються?
Грег Мартін

@GregMartin Ви можете бути гнучкими з результатами, але намагайтеся робити це просто. Це не повинно бути абсолютно однаковим, але повинен мати схожий стиль. Вам не потрібно обліковувати нічого вище 26, я це відредагую.
JKonowitz

Я не знаю, що означає "подібний стиль". Чи можемо ми взяти введення як упорядковану пару цілих чисел (рядок №, коло #)? (PS: Ці питання є причинами, чому перед публікацією викликів у « Пісочниці» - чудова ідея.)
Грег Мартін

Відповіді:


3

Python 3.6 , 466 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

Математика, оптимальна поведінка в тестових випадках, 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 . (Проте тестуйте швидко: я думаю, що для кожного запуску програми існує обмеження часу.) Припущення програми виглядають як 2 cзамість цього C2, але в іншому випадку воно працює відповідно до наведених вище специфікацій. Сітка повинна бути введена як упорядкована пара цілих чисел, наприклад {26,100}, а відповіді на здогадки програми повинні бути введені у вигляді рядків, як "NE"або "y".

Програма відслідковує найменший і найбільший номер рядка та номер стовпця, який відповідає вхідним досі, і завжди вгадує центральну точку підрешітки можливостей (округлення NW). Програма є детермінованою, тому легко обчислити кількість здогадок, які вона вимагає в середньому за фіксованою сіткою. На сітці 10х10 програма вимагає 1 здогадки для одного квадрата, 2 здогадів на вісім квадратів, 3 здогадів на 64 квадрати та 4 здогадів на інші 27 квадратів, в середньому 3,17; і це теоретичний мінімум, враховуючи, скільки послідовностей з 1 догадкою, 2 здогадок тощо може призвести до правильних здогадів. Дійсно, програма повинна досягти теоретичного мінімуму на будь-якій розмірній сітці з аналогічних причин. (На сітці 5х5 середня кількість здогадок становить 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циклом у маскуванні, тож ей, на два менших байти. Можливі діапазони номерів рядків та номерів стовпців у будь-який момент зберігаються {{a, c}, {f, h}}, а відгадування по центру в цій підмережі обчислюється функціями, {b, g}визначеними у рядку 2. Рядок 3 ініціалізує максимальний рядок cта максимальний стовпець 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.