Aufgabe
Suchen Sie bei einer gegebenen Booleschen Matrix eine (oder optional mehrere) Teilmenge (n) von Zeilen, die in jeder Spalte genau ein True enthalten. Sie können einen beliebigen Algorithmus verwenden , müssen jedoch sehr große Matrizen unterstützen, wie im letzten Beispiel.
Ein möglicher Algorithmus ( Knuths Algorithmus X )
Dieser Algorithmus muss zwar nicht verwendet werden, ist jedoch möglicherweise die beste Option.
- Wenn die Matrix A keine Spalten enthält, ist die aktuelle Teillösung eine gültige Lösung. erfolgreich beenden.
- Andernfalls wählen Sie eine Spalte c .
- Wählen Sie * eine Zeile r so, dass A r , c = 1 ist.
- Fügen Sie die Zeile r in die Teillösung ein.
- Für jede Spalte j , so daß A r , j = 1,
für jede Zeile i , so dass A i , j = 1,
Zeile löschen i von Matrix A .
Spalte j aus Matrix A löschen . - Wiederholen Sie diesen Algorithmus rekursiv auf der reduzierten Matrix A .
* Schritt 3 ist nicht deterministisch und muss zurückverfolgt werden, wenn bei einem späteren Aufruf von Schritt 3 keine Zeile gefunden wird.
Eingang
Beliebige gewünschte Darstellung der minimalen 2 × 2-Matrix A , z. B. als numerisches oder boolesches Array
1 0 0 1 0 0 1
1 0 0 1 0 0 0
0 0 0 1 1 0 1
0 0 1 0 1 1 0
0 1 1 0 0 1 1
0 1 0 0 0 0 1
oder als Universe + Set Sammlung
U = {1, 2, 3, 4, 5, 6, 7}
S = {
A = [1, 4, 7],
B = [1, 4],
C = [4, 5, 7],
D = [3, 5, 6],
E = [2, 3, 6, 7],
F = [2, 7]
}
oder als 0 oder 1 indizierte Mengen;
{{1, 4, 7}, {1, 4}, {4, 5, 7}, {3, 5, 6}, {2, 3, 6, 7}, {2, 7}}
.
Ausgabe
Beliebige gewünschte Darstellung einer (oder optional mehrerer / aller) der Lösungen, z. B. als numerisches oder boolesches Array der ausgewählten Zeilen
1 0 0 1 0 0 0
0 0 1 0 1 1 0
0 1 0 0 0 0 1
oder als Boolesche Liste, die ausgewählte Zeilen angibt, {0, 1, 0, 1, 0, 1}
oder als numerische (0 oder 1 indizierte) Liste ausgewählter Zeilen {2, 4, 6}
oder als Liste von Satznamen ['B', 'D', 'F']
.
Mehr Beispiele
Im:
1 0 1
0 1 1
0 1 0
1 1 1
Out: 1 3
oder 4
oder 1 0 1 0
oder 0 0 0 1
oder [[1,3],[4]
etc.
Im:
1 0 1 0 1
0 1 0 1 0
1 1 0 0 1
0 1 0 1 1
Out: 1 1 0 0
etc.
Im:
0 1 0 1 1 0 1
1 1 0 0 1 1 1
0 1 0 0 1 0 0
1 1 1 0 0 0 1
0 0 0 1 1 1 0
Out: 0 0 0 1 1
etc.
Im:
0 1 1
1 1 0
Out: Nichts oder Fehler oder fehlerhafte Lösung, dh Sie müssen keine Eingaben ohne Lösung verarbeiten.
In: http://pastebin.com/raw/3GAup0fr
Aus: 0 10 18 28 32 38 48 61 62 63 68 86 90 97 103 114 120 136 148 157 162 174 177 185 186 194 209 210 218 221 228 243 252 255 263 270 271 272 273 280 291 294 295 309 310 320 323 327 339 345 350 353 355 367 372 373 375 377 382 385 386 389 397 411 417 418 431 433 441 451 457 458 459 466 473 479 488 491 498 514 517
In: https://gist.github.com/angs/e24ac11a7d7c63d267a2279d416bc694
Aus: 553 2162 2710 5460 7027 9534 10901 12281 12855 13590 14489 16883 19026 19592 19834 22578 25565 27230 28356 29148 29708 30818 31044 34016 34604 36806 36918 39178 43329 43562 45246 46307 47128 47906 48792 50615 51709 53911 55523 57423 59915 61293 62087 62956 64322 65094 65419 68076 70212 70845 71384 74615 76508 78688 79469 80067 81954 82255 84412 85227
Antworten:
Haskell,
1009392878380 BytesKnuths Algorithmus:
Berechnet alle Cover nicht deterministisch mit der Tiefe zuerst in der Listenmonade. Verwenden Sie
head
diese Option , um nur eine zu berechnen, da Haskell faul ist. Verwendungszweck:Verwenden Sie Folgendes, um mehr Geschwindigkeit zu erzielen, indem Sie Knuths Vorschlag verwenden, die Spalte mit den kleinsten auszuwählen: (115 Byte, flache Liste für das Universum). Findet beim Kompilieren in weniger als einer Minute die erste Lösung für das Problem der großen Pentomino-Abdeckung .
Vielen Dank an @Zgarb für das Speichern von 1 + 3 Bytes!
Vielen Dank an @ChristianSievers für seinen weisen Rat und das Einsparen von 5 Bytes und einigen.
Ungolfed (mit flachem Listenuniversum):
quelle
filter
in ein Listenverständnis ändern und eine Hilfsfunktion definierenh!x=h(`elem`(x>>=id))
.(!)=elem
, daher diea
's. Und ja, f kann dort definitiv verwendet werden. Vielen Dank! Die verschiedenen Kombinationen vonfilter … elem
betteln darum, vereinheitlicht zu werden ...w%a=[c:s|(u:_)<-[sortOn length.group.sort$w++concat a],c<-id&u$a,s<-(w\\c)%(not&c$a)]
. Beachten Sie, dass es sich jetztu
um eine Liste handelt, die die ausgewählte Spalte möglicherweise wiederholt enthält, die jedoch für die Richtigkeit keine Rolle spielt.u
inline war, da sie einmal pro Element berechnet wurdea
, aber wir streben eine Golfgeschwindigkeit an, nicht eine optimale Geschwindigkeit.c\\b==c
wahrscheinlich ist es nicht so schlimm, da es träge aufhören kann. Nicht zu inlinierenu
und zu verwenden,Data.Map.Strict
um das seltenste Element zu finden, wäre auf einer ganz anderen Ebene.Python, 482 Bytes
r
ist die Funktion, die mit der Universe + Set-Sammlung aufgerufen werden soll.Von dieser Seite ein wenig Golf gespielt
Verwendungszweck:
quelle
list
in der ersten for-Schleife und die Ausbeute zu entfernen undreversed(...)
zu...[::-1]
S.append(x)
, können Sie dies tunS+=x,
(mit dem nachgestellten Komma): zum BeispielC+=X.pop(j),
.R,
124117115113 BytesSehr ineffizient, aber nicht so lange im Code. Versucht alle möglichen Teilmengen von Zeilen und prüft, ob alle Zeilen 1 ergeben.
Nimmt eine Matrix als Eingabe. Gibt die Rownummern der ersten gefundenen Lösung zurück. Gibt nichts zurück, wenn es keine Lösungen gibt, kann aber lange dauern, bis der Vorgang abgeschlossen ist, wenn die Eingabe groß ist.
Ungolfed:
7 Bytes dank Billywob gespart
Weitere 2 Bytes dank Billywob gespart
quelle
drop=F
Anweisung löschen, funktioniert sie auch nicht für Teilmengen von nur einer Zeile. Ich habe noch nie mit gearbeitetscan
und nur angenommen, dass es so funktionieren würde, mein schlechtes. Ändern in eine benannte Funktion.function(x,n=nrow(x))for(i in 1:n)for(j in 1:ncol(z<-combn(n,i)))if(all(colSums(x[k<-z[,j],,drop=F])==1))cat(k)
n
aber irgendwie ist es mir durch den Kopf gegangen.APL (Dyalog) , 81 Bytes
Probieren Sie es online aus!
{
anonyme Funktion::
wenn…⍵
Wenn das Argument⍉
wenn transponiert≢
hat eine Zeilenanzahl×
das ist positivdann
⍵∇{
… Wenden Sie diese Funktion dann mit dem rechten Argument als linkes Argument (Einschränkungsmatrix) an, jedoch erst, nachdem sie vom folgenden anonymen Operator (Funktion höherer Ordnung) geändert wurde::
Wenn…1∊⍵
das rechte Argument~
NICHT vorhanden ist,dann…
0
geben Sie Null zurück (dh fehlgeschlagen)⋄
sonst::
wenn…<\⍵
das erste wahre des rechten Arguments (wörtlich kumulativ kleiner als; erste Zeile)f←
das zu f zuweisen, um⍺⌿⍨
die Zeilen des linken Arguments zu filtern,
ravel (abflachen)~
negierenc←
, das zu c~
negieren⍺/⍨
Verwenden Sie dies, um die Spalten des linken Arguments zu filtern. Welche∨/
Zeilen haben eine wahre? (ODER Reduktion)~
negieren das⍺⌿⍨
Verwenden Sie das, um die Zeilen des linken Arguments zu filtern.c/
Verwenden Sie c , um die Spalten zu filtern,⍺⍺
die die ursprüngliche äußere Funktion anwenden (der linke Operand; Submatrix-Cover).s←
Weisen Sie zu, dass s0≡
… mit Null identisch ist (Fehler). Dann (versuchen Sie a andere Zeile):f<⍵
rechts Argument UND NICHT f⍺∇
recurse auf , dass (das ursprüngliche linke Argument Erhaltung)⋄
sonst:r\s
Verwendung Nullen in r Null gefüllten Spalten einfügen sf∨
Rückkehr f OR dass (Erfolg; Zeile f enthalten)}
... ... auf+⌿⍵
die Summe des Argumentsn←
ordne das n zu⌊/
das Minimum davonn=
Boolescher Wert, wobei n gleich dem ist<\
der erste von diesen (wörtlich kumulativ kleiner als)⍵/⍨
Verwenden Sie dies, um die Spalten des Arguments zu filtern (gibt die erste Spalte mit den wenigsten an),
ravel das (abflachen)⋄
sonst∧/⍵
Zeilen, die alle Einsen sind (keine, daher ergibt dies für jede Zeile eine Null)}
Ende der anonymen Funktionquelle