Problème de boîte magique

15

Vous avez un tableau d'entrée de taille m * n. Chaque cellule du tableau est remplie de P ou de T. La seule opération que vous pouvez faire sur le tableau est de retourner les colonnes. Lorsque vous retournez une colonne, les lettres de toutes les cellules de cette colonne changent (P devient T et vice versa). Si vous avez «x» nombre de lignes avec la même lettre (par exemple PPPP), vous obtenez un point. Concevez un algorithme qui prend le tableau et renvoie une solution (quelles colonnes retourner) de telle sorte que le tableau résultant ait le nombre maximum de points possible.

Remarque: dans le cas où plusieurs solutions donnent le score le plus élevé, choisissez celle qui a le plus petit nombre de flips. Exemple:

Tableau d'entrée:

PPTPP
PPTPP
PPTTP
PPPTT
PPPTT

Production:

3

Explication:
Une solution qui rapporte les points les plus élevés: Flip colonne no. 3 Le
tableau d'origine serait alors:

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

//Total: 2 points

Notez que l'on pourrait également inverser les colonnes 4 et 5 pour obtenir un score de deux, mais cela nécessite un basculement supplémentaire.

Vous pouvez utiliser n'importe quel format d'entrée pratique pour représenter le tableau bidimensionnel, et vous pouvez également choisir deux valeurs distinctes, mais fixes, pour représenter Pet T.

Il s'agit du code golf, donc la réponse la plus courte (en octets) l'emporte.

bruhhhhh
la source
6
Bienvenue chez PPCG. C'est un grand défi, mais il faut un critère gagnant pour être sur le sujet.
Ypnypn
Puis-je contrôler le format d'entrée? Puis-je dire que P est faux et T est vrai? Sinon, quel est le format d'entrée?
fier haskeller
Bien sûr, le format d'entrée n'a pas d'importance. Supposons que vous ayez un tableau bidirectionnel de caractères, de caractères ou de booléens ou tout autre type que vous choisissez.
bruhhhhh
3
Vous avez besoin d'un critère gagnant pour décider laquelle des réponses valides est la meilleure. En supposant qu'une réponse valide doit donner le maximum de points pour la grille d'entrée (BTW vous devez le dire), il devrait être possible de forcer une grille de 32 colonnes en un temps raisonnable. Par conséquent, je vous suggère de faire ia codegolf (les victoires de code les plus courtes)
Level River St
1
J'ai travaillé dans la première suggestion de Peter. N'hésitez pas à changer la formulation si vous ne l'aimez pas.
Martin Ender

Réponses:

3

APL, 37

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

Exemple:

{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

Testé ici.

jimmy23013
la source
1

Pyth , 28

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

Prend la saisie sous la forme d'une liste imbriquée, par exemple

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

Donne la sortie indexée 0, par exemple

[2]

^U2lhQ: Génère toutes les listes possibles de 0 et 1 de la bonne longueur.

_osZ: Ordonne ces listes du plus 1 au moins.

+/QN/Qm!dN: Compte le nombre de fois où chaque liste ( N) et son inverse, 0 et 1 échangés (m!dN ) se produisent dans l'entrée. Le premier correspond à une série de flips laissant tous les zéros, le second à tous les zéros.

eo: Ordonne la liste par la clé ci-dessus, et prend son dernier élément, qui sera le résultat avec les colonnes les plus correspondantes, et parmi elles celle avec le moins.

f@ ... TUhQ: Convertit cette liste de 1 et de 0 en une liste d'indices à retourner.

Pour l'indexation 1, changez le den a k, puis mettez mhdau début.

isaacg
la source
0

CJam, 53 51 octets

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

Cela lit un tableau bidimensionnel de 0 et 1 à partir de STDIN. Par exemple, l'exemple de la question serait

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

Testez-le ici.

Cela obtient d'abord tous les sous-ensembles de colonnes possibles, par ordre croissant de longueur, puis effectue les retournements pour chaque sous-ensemble et les trie en fonction du nombre de lignes contenant à la fois des 0 et des 1. Enfin, nous renvoyons simplement le premier sous-ensemble de ce type. Cela repose sur le fait que le tri est stable, de sorte que l'ordre initial de longueur croissante s'occupe du bris d'égalité.

Martin Ender
la source
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]

le format d'entrée est une liste de liste d'entiers. vous pouvez utiliser une version chaîne pour tester:

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

oh non les espaces! ça fait mal!

cela fonctionne en itérant sur les lignes et en calculant le nombre de points que nous obtiendrons si nous inversons les colonnes de manière à ce que cette ligne nous rapporte un point.

La première chose à noter est que le basculement de la ligne vers tous Trueou tous Falsen'a pas d'importance, car les grilles seront exactement l'inverse les unes des autres et auront donc exactement le même score.

La façon dont nous calculons le nombre lorsqu'une ligne donnée gagne un point est la suivante: nous itérons à nouveau sur les lignes et additionnons les points que chaque ligne nous donne, en utilisant le fait qu'ils le font exactement lorsque les lignes sont identiques ou inverses.

par exemple, si la ligne que nous inversons est TPPTPet que la ligne actuelle sur laquelle nous itérons est PTTPTou TPPTPalors la ligne nous rapporte un point, mais quand c'est une autre ligne, elle ne nous rapporte aucun point.

fier haskeller
la source
@ MartinBüttner Oui, je vais le réparer sous peu (avec un peu de
chance
0

CJam, 37

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

Format d'entrée:

[[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]]
jimmy23013
la source
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]

L'entrée est une liste de listes:

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

La sortie est un tuple de flips utilisant l'indexation python à partir de 0:

(2,)

Si la sortie doit être indexée à partir de 1, alors le code est de 272 caractères avec 0 dénotant aucun flip:

print 0 if len(S[1])==0 else [p+1 for p in S[1]]
user2487951
la source