Проблема з магічною коробкою


15

У вас є вхідний масив розміром m * n. Кожна комірка масиву заповнена або P, або T. Єдина операція, яку ви можете зробити на масиві, - це перевернути стовпці. Коли ви перегортаєте стовпець, літери у всіх комірках цього стовпця перемикаються (P стає T і viceversa). Якщо у вас є "x" рядків з однаковою літерою (наприклад, PPPP), ви отримуєте крапку. Створіть алгоритм, який приймає масив і повертає рішення (які стовпчики перевертати) таким чином, щоб в результаті масиву була максимальна кількість точок.

Примітка. Якщо існує декілька рішень, які дають найвищий бал, виберіть той, який має найменшу кількість сальто. Приклад:

Вхідний масив:

PPTPP
PPTPP
PPTTP
PPPTT
PPPTT

Вихід:

3

Пояснення:
Рішення, яке дає найвищі бали: стовпчик "Перевернути" №. 3
Тоді початковий масив буде таким:

PPPPP // 1 point
PPPPP // 1 point
PPPTP
PPTTT
PPTTT

//Total: 2 points

Зауважте, що можна також перевернути стовпці 4 і 5, щоб отримати дві оцінки, але для цього потрібен додатковий фліп.

Ви можете використовувати будь-який зручний формат введення для представлення двовимірного масиву, а також ви можете будь-які два різних, але фіксованих, значення для представлення Pта T.

Це кодовий гольф, тому найкоротша відповідь (у байтах) виграє.


6
Ласкаво просимо до PPCG. Це велике завдання, але для того, щоб бути темою, потрібен критерій виграшу.
Ypnypn

Чи можна контролювати формат введення? Чи можу я сказати, що P - помилково, а T - правда? Якщо ні, то який вхідний формат?
гордий haskeller

Звичайно, формат введення не має значення. Скажімо, у вас є двонаправлений масив символів, ints або booleans або будь-який тип, який ви обрали.
bruhhhhh

3
Вам потрібно виграти критерій, щоб вирішити, який із вагомих відповідей найкращий. Якщо припустимо, що відповідь має надати максимальну кількість балів для вхідної сітки (BTW, ви повинні це вказати), слід забезпечити обробку сітки з 32 стовпчиками в розумний час. Тому я пропоную вам зробити ia codegolf (найкоротший виграш коду)
Level River St

1
Я працював над першою пропозицією Петра. Не соромтеся змінювати формулювання, якщо вам це не подобається.
Мартін Ендер

Відповіді:


3

APL, 37

{x/1+⍳⍴x←y[↑⍋(+/∘.≠⍨2⊥⍉y),¨+/y←⍵⍪~⍵]}

Приклад:

{x/1+⍳⍴x←y[↑⍋(+/∘.≠⍨2⊥⍉y),¨+/y←⍵⍪~⍵]} 5 5⍴0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 1 1

Тестували тут.


1

Піт , 28

f@eo+/QN/Qm!dN_osZ^U2lhQTUhQ

Вводиться у вигляді вкладеного списку, наприклад

[[0,0,1,0,0],[0,0,1,0,0],[0,0,1,1,0],[0,0,0,1,1],[0,0,0,1,1]]

Дає вихід 0-індексований, напр

[2]

^U2lhQ: Створює всі можливі списки 0 і 1 правильної довжини.

_osZ: Упорядковує ці списки від більшості найменш від 1.

+/QN/Qm!dN: Підраховує, скільки разів кожен список ( N) та його зворотна, 0s та 1s swap ( m!dN) трапляються на вході. Перший відповідає серії фліп, залишаючи всі нулі, останній залишаючи всі нулі.

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

f@ ... TUhQ: Перетворює цей список 1 і 0 в список індексів, які слід перевернути.

Для 1-індексації змініть dна a k, а потім поставте mhdна початку.


0

CJam, 53 51 байт

l~z:X,,La\{1$f++}/{,}${X\{_X=:!t}/z{_&,(},,}$0=:)S*

Це зчитує двовимірний масив 0s та 1s від STDIN. Наприклад, приклад у питанні був би

[[0 0 1 0 0] [0 0 1 0 0] [0 0 1 1 0] [0 0 0 1 1] [0 0 0 1 1]]

Тестуйте це тут.

При цьому спочатку отримуються всі можливі підмножини стовпців у порядку збільшення довжини, потім виконується фліп для кожної підмножини та сортується за тим, скільки рядків у них ще є 0 і 1. Нарешті, ми просто повертаємо перший такий підмножина. Це спирається на стабільність сортування, так що початковий порядок збільшення довжини піклується про перемикач краватки.


0

Хаскелл, 98

g s=snd$maximum[((sum[1|o<-s,o==r||o==map(1-)r],-sum r),[i|(i,1)<-zip[1..]r])|r<-s++map(map(1-))s]

Формат введення - це список списку входів. ви можете використовувати версію рядка для тестування:

gg = g . map (map (\c -> case c of 'T' -> 0 ; _ -> 1) ) . lines

о, ні пробіли! боляче!

це працює, повторюючи рядки та обчислюючи кількість очок, які ми отримаємо, якщо перегорнути стовпці таким чином, що цей рядок набере нам крапку.

Перше, що потрібно помітити, це те, що перевертає рядок будь-яким True або всі Falseне має значення, оскільки сітки будуть точно зворотними один до одного, і, таким чином, буде мати точно такий же бал.

як ми обчислюємо кількість підрахунків, коли заданий рядок набирає крапку, так: ми повторюємо повторення між рядками і підсумовуємо точки, які дає нам кожен ряд, використовуючи той факт, що вони роблять саме тоді, коли рядки однакові або точні зворотні.

Наприклад, якщо рядок, який ми перегортаємо, TPPTPі поточний рядок, який ми повторюємо, є PTTPTабо TPPTPтоді рядок отримує нам крапку, але коли це будь-який інший рядок, він не отримує нам жодних очок.


@ MartinBüttner Так, я скоро це
виправлю

0

CJam, 37

q~_{:!}%+:T{T1$a-,\0-+}$0={U):U*}%0-`

Формат введення:

[[0 0 1 0 0] [0 0 1 0 0] [0 0 1 1 0] [0 0 0 1 1] [0 0 0 1 1]]


0

Пітон 2, 234

from itertools import *
A=input()
n=len(A[0])
R=range(n)
S=(0,)
for p in[q for i in R[:-1] for q in combinations(R,i)]:
    s=[sum([(l[q]+(q in p))%2 for q in R])for l in A]
    m=s.count(n)+s.count(0)
    if m>S[0]:S=(m,p)
print S[1]

Введення - це список списків:

[[0,0,1,0,0],[0,0,1,0,0],[0,0,1,1,0],[0,0,0,1,1],[0,0,0,1,1]]

Вихід - це набір фліп, використовуючи індексацію пітона від 0:

(2,)

Якщо вихід повинен бути проіндексований від 1, то код становить 272 символи, 0 не позначає фліп:

print 0 if len(S[1])==0 else [p+1 for p in S[1]]
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.