Problema na caixa mágica


15

Você tem uma matriz de entrada do tamanho m * n. Cada célula da matriz é preenchida com P ou T. A única operação que você pode executar na matriz é inverter colunas. Quando você inverte uma coluna, as letras em todas as células dessa coluna mudam (P se torna T e vice-versa). Se você tiver o número 'x' de linhas com a mesma letra (por exemplo, PPPP), receberá um ponto. Projete um algoritmo que capte a matriz e retorne uma solução (que colunas virar), para que a matriz resultante tenha o número máximo de pontos possível.

Nota: Caso haja várias soluções que produzam a pontuação mais alta, escolha aquela com o menor número de lançamentos. Exemplo:

Matriz de entrada:

PPTPP
PPTPP
PPTTP
PPPTT
PPPTT

Resultado:

3

Explicação:
Uma solução que gera os pontos mais altos: Inverter a coluna no. 3
Então a matriz original seria:

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

//Total: 2 points

Observe que também é possível virar as colunas 4 e 5 para obter uma pontuação de dois, mas isso precisa de uma virada adicional.

Você pode usar qualquer formato de entrada conveniente para representar a matriz bidimensional e também dois valores distintos, mas fixos, para representar Pe T.

Isso é código de golfe, então a resposta mais curta (em bytes) vence.


6
Bem-vindo ao PPCG. Este é um grande desafio, mas ele precisa de um critério de vitória para estar no tópico.
Ypnypn

Posso controlar o formato de entrada? Posso dizer que P é falso e T é verdadeiro? Caso contrário, qual é o formato de entrada?
proud haskeller

Claro, o formato de entrada não importa. Digamos que você tenha uma matriz bidirecional de caracteres, ints ou booleanos ou qualquer outro tipo que você escolher.
bruhhhhh

3
Você precisa de um critério vencedor para decidir qual das respostas válidas é a melhor. Supondo que uma resposta válida tenha que fornecer o máximo de pontos para a grade de entrada (você deve indicar isso), deve ser possível aplicar força bruta em uma grade de 32 colunas em tempo razoável. Portanto, sugiro que você faça um codegolf (o menor código vence) #
Level River St

1
Eu trabalhei na primeira sugestão de Peter. Sinta-se livre para alterar as palavras, se você não gostar.
Martin Ender

Respostas:


3

APL, 37

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

Exemplo:

{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

Testado aqui.


1

Pyth , 28

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

Recebe entrada na forma de uma lista aninhada, por exemplo

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

Dá saída indexada 0, por exemplo

[2]

^U2lhQ: Gera todas as listas possíveis de 0s e 1s do comprimento certo.

_osZ: Ordena essas listas da maioria dos 1s para a menor.

+/QN/Qm!dN: Conta quantas vezes cada lista ( N) e seu inverso, 0s e 1s trocados ( m!dN) ocorrem na entrada. O primeiro corresponde a uma série de movimentos que deixam todos os zeros, e o último a todos.

eo: Ordena a lista pela chave acima e pega seu último elemento, que será o resultado com as colunas mais correspondentes e, entre elas, a com as menos.

f@ ... TUhQ: Converte essa lista de 1s e 0s em uma lista de índices a serem invertidos.

Para a indexação 1, altere dpara a ke coloque mhdno início.


0

CJam, 53 51 bytes

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

Isso lê uma matriz bidimensional de 0s e 1s de STDIN. Por exemplo, o exemplo na pergunta seria

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

Teste aqui.

Isso primeiro obtém todos os subconjuntos possíveis de colunas, em ordem crescente de comprimento, depois executa os lançamentos para cada subconjunto e os classifica por quantas linhas ainda possuem 0 e 1 s. Finalmente, apenas retornamos o primeiro subconjunto. Isso depende da classificação ser estável, de modo que a ordem inicial de aumento de comprimento cuide do desempate.


0

Haskell, 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]

formato de entrada é uma lista de lista de entradas. você pode usar uma versão em cadeia para testar:

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

oh não os espaços! isso dói!

isso funciona iterando sobre as linhas e calculando o número de pontos que obteremos se invertermos as colunas de uma maneira que essa linha ganhe um ponto.

A primeira coisa a notar é que inverter a linha para todos Trueou para todos Falsenão importa, porque as grades serão exatamente o inverso uma da outra e, portanto, terão exatamente a mesma pontuação.

é assim que calculamos a contagem quando uma determinada linha ganha um ponto: iteramos as linhas novamente e somamos os pontos que cada linha nos fornece, usando o fato de que eles fazem exatamente quando as linhas são idênticas ou exatamente inversas.

por exemplo, se a linha que estamos lançando TPPTPe a linha atual sobre a qual estamos iterando são PTTPTou TPPTPentão a linha ganha um ponto, mas quando é qualquer outra linha, ela não ganha pontos.


@ MartinBüttner Sim, eu fixá-lo em breve (espero)
haskeller orgulhoso

0

CJam, 37

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

Formato de entrada:

[[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

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

Entrada é uma lista de listas:

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

Saída é uma tupla de inversões usando a indexação python de 0:

(2,)

Se a saída precisar ser indexada a partir de 1, o código terá 272 caracteres com 0 indicando que não há inversões:

print 0 if len(S[1])==0 else [p+1 for p in S[1]]
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.