Підключення 4: Знайдіть підробку!


35

Банк був розбитий, і всі місцеві мафіозні злодії мають незвичайне алібі: вони вдома грали в Connect 4! Для того, щоб допомогти в розслідуванні, вас просять написати програму для перевірки всіх дощок Connect 4, які були вилучені, щоб перевірити, чи справді позиції є дійсними грою Connect 4, і їх не було спішно складено як тільки поліція постукала у двері.

Правила підключення 4: гравці Rі Yпо черзі відкидати плитки їх кольору в стовпчики сітки 7х6. Коли гравець опускає плитку в колонку, він падає вниз, щоб зайняти найнижчу незаповнену позицію в цій колонці. Якщо гравцеві вдається отримати горизонтальний, вертикальний або діагональний пробіг з чотирьох плиток їх кольору на дошці, вони виграють і гра закінчується негайно.

Наприклад (із Rзапуском), наступне неможливе положення Connect 4.

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | |
| | |Y| | | | |
|R| |Y| | | | |

Ваша програма чи функція повинні взяти плату Connect 4 і повернути її

  • Неправдиве значення, що вказує на неможливість позиції або
  • Рядок чисел від 1 до 7, що вказує на одну можливу послідовність ходів , що ведуть до цієї позиції (стовпці пронумеровані , 1щоб 7зліва направо, і так послідовності 112, наприклад, вказує на червоний рух в колонці 1, а потім жовтий хід у стовпці з 1подальшим червоним переміщенням у стовпці 2). Якщо ви хочете, ви можете обрати нумерацію стовпців, крім 1234567, якщо ви хочете вказати у своєму рішенні. Якщо ви хочете повернути список у якомусь іншому форматі; наприклад, як масив, [2, 4, 3, 1, 1, 3]то це теж добре, доки легко зрозуміти, які рухаються.

Ви можете прочитати дошку в будь-якому розумному форматі, в тому числі, використовуючи букви, відмінні від Rта Yдля гравців, але ви повинні вказати, хто з гравців буде першим. Можна припустити, що на дошці завжди буде 6x7 з двома гравцями.

Ви можете припустити, що отримані вами позиції принаймні фізично можливо створити на стандартній платі Connect 4; тобто, що не буде "плаваючих" шматків. Можна припустити, що дошка буде порожньою.

Це кодовий гольф, тому найкоротша відповідь виграє. Застосовуються стандартні лазівки.

Приклади

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | | --> 1234567 (one possible answer)
| | | | | | | |
|R|Y|R|Y|R|Y|R|

| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |R| | | | | --> false
| | |Y| | | | |
|R| |Y| | | | |

| | | | | | | |
| | |Y| | | | |
| | |R| | | | |
| | |Y| | | | | --> 323333 (only possible answer)
| | |R| | | | |
| |Y|R| | | | |

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> false (this is the position arising after
| |Y|Y|Y|Y| | |     the moves 11223344, but using those moves
| |R|R|R|R| | |     the game would have ended once R made a 4)

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> 2134231211 (among other possibilities)
|R|R|Y| | | | |
|Y|R|R|Y| | | |

| | | | | | | |
| | | | | | | |
|Y| | | | | | |     
|R|Y| | | | | | --> false (for example, 21342312117 does not
|R|R|Y| | | | |     work, because Y has already made a diagonal 4)
|Y|R|R|Y| | |R|

| | | | | | | |
| | | | | | | |
| | | | | | | |     
| | | | | | | | --> 112244553 or similar
|Y|Y| |Y|Y| | |
|R|R|R|R|R| | |

Джон, з цікавості, чи знаєш ти, чи існує алгоритм без грубої сили?
Йона

Відповіді:


9

Желе , 57 байт

ŒṪŒ!µ0ịŒṬ¬a³ZU,Ɗ;ŒD$€Ẏṡ€4Ḅo1%15;Ḋ€ṢṚ$Ƒƙ$Ȧȧœị³$2R¤ṁ$ƑµƇṪṪ€

Бере матрицю, де 0вона не заповнена, 1відтворюється перша, а 2відтворюється друга. Виходить список 1-індексованих стовпців, порожній, якщо виявлено підробку.

Спробуйте в Інтернеті! (занадто неефективний, щоб пробігти більше 7 штук)

Примітка:

  1. Передбачає, що "плаваючих" частин немає (виправте це, попередньо додавши ZṠṢ€Ƒȧ+6 байт)
  2. Припускає, що порожня дошка - підробка

11

JavaScript (ES6),  202 194 187  183 байт

240

m=>(p=[...'5555555'],g=(c,s=o='')=>/2|4/.test(m)?['',0,2,4].some(n=>m.join``.match(`(1|3)(.{1${n}}\\1){3}`))?o:p.map((y,x)=>m[m[y][x]--^c||p[g(c^6,s+x,p[x]--),x]++,y][x]++)&&o:o=s)(2)

Спробуйте в Інтернеті!

Як?

г2413

Роблячи це, він гарантує, що у нас не буде жодного запуску чотирьох послідовних непарних значень, поки всі парні значення не зникнуть (тобто, якщо сторона виграє, це повинен бути останній крок).

ухp[х] .

Прокоментував

m => (                            // m[] = input matrix
  p = [...'5555555'],             // p[] = next row for each column
  g = (c,                         // g = recursive function taking c = color,
          s = o = '') =>          //     s = current solution, o = final output
    /2|4/.test(m) ?               // if the matrix still contains at least a 2 or a 4:
      ['', 0, 2, 4]               //   see if we have four consecutive 1's or 3's
      .some(n =>                  //   by testing the four possible directions
        m.join``                  //   on the joined matrix, using
        .match(                   //   a regular expression where the number of characters
          `(1|3)(.{1${n}}\\1){3}` //   between each occurrence is either 1, 10, 12 or 14
        )                         //   (horizontal, diagonal, vertical, anti-diagonal)
      ) ?                         //   if we have a match:
        o                         //     abort and just return the current value of o
      :                           //   else:
        p.map((y, x) =>           //     for each cell at (x, y = p[x]):
          m[                      // 
            m[y][x]--             //       decrement the value of the cell
            ^ c ||                //       compare the original value with c
            p[                    //       if they're equal:
              g(                  //         do a recursive call with:
                c ^ 6,            //           the other color
                s + x,            //           the updated solution
                p[x]--            //           the updated row for this column
              ),                  //         end of recursive call
              x                   //         then:
            ]++,                  //         restore p[x]
            y                     //         and restore m[y][x]
          ][x]++                  //         to their initial values
        ) && o                    //     end of map(); yield o
    :                             // else:
      o = s                       //   we've found a solution: copy s to o
)(2)                              // initial call to g() with c = 2

Примітка. Я запитав "Чи можна вважати, що порожня дошка не буде надана як вхід?" - якщо нам доведеться це впоратися, то ваш код потребує налаштування.
Джонатан Аллан

я не знаю чому, f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [0,2,2,0,2,2,0], [1,1,1,1,1,1,1] ])закінчується 0 і f([ [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,0,0,0,0,0], [0,0,2,0,2,0,0], [2,2,2,0,2,2,1], [1,1,1,1,1,1,1] ])повинно бути правдою
Нахуель Фуле,

@NahuelFouilleul Дякую за повідомлення про це. Я виправив код, додав ці тестові випадки.
Арнольд

2

Python 2 , 295 285 байт

def f(a):
 if 1-any(a):return[]
 p=sum(map(len,a))%2
 for i in R(7):
	if a[i][-1:]==`p`:
	 b=a[:];b[i]=b[i][:-1];L=f(b)
	 if L>1>(`1-p`*4in','.join([J((u[j]+' '*14)[n-j]for j in R(7))for n in R(12)for u in[b,b[::-1]]]+b+map(J,zip(*[r+' '*7for r in b])))):return L+[i]
R=range;J=''.join

Спробуйте в Інтернеті!

-10 thx для Джо Кінга .

Введення - це список рядків, що представляють стовпці; з «1» для червоного та «0» для жовтого. Рядки не вставлені ''. Отже (фальсифікація):

| | | | | | | |
| | | | | | | |
|Y| | | | | | |
|R|Y| | | | | |
|R|R|Y| | | | |
|Y|R|R|Y| | |R|

вводиться як:

[
  '0110',
  '110',
  '10',
  '0',
  '',
  '',
  '1'
]

Вихід - це список індексів стовпців, 0-індексованих, які можуть скласти дошку; або Noneякщо він недійсний.

Приймає порожню дошку як дійсну (повертає порожній список []замість None).

Цей підхід є рекурсивним від останнього до першого кроку: виходячи з паритету загальної кількості зроблених рухів, ми видаляємо або останній крок Червоного, або останній Жовтий хід (або відмовляємо, якщо це неможливо); перевірте отриману дошку, щоб побачити, чи є у опонента 4-у-ряду (в такому випадку не вдасться, тому що гра повинна була вже припинитися); в іншому випадку повторіть курсор, поки дошка не буде порожньою (що є дійсним).

Код 4-у-рядку - це найпотужніша частина. Усі діагональні рядки для матриці bпороджуються:

[
    ''.join(
        (u[j]+' '*14)[n-j] for j in range(7)
    )
    for u in[b,b[::-1]]for n in range(12) 
]

який спочатку перераховує діагоналі "вниз-похилі", а потім - "похилі".

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.