Skip to content

Instantly share code, notes, and snippets.

@chaoxu
Last active December 22, 2015 13:19
Show Gist options
  • Save chaoxu/6478677 to your computer and use it in GitHub Desktop.
Save chaoxu/6478677 to your computer and use it in GitHub Desktop.
⍝ The canonical representation.
⍝ The matrix with width <= height and has
⍝ the smalelst value if expressed as a binary number.
CanonPoly←{
⍝ Remove zero rows
rm←{(⍵∨.≠0)⌿⍵}
allMatrix←{
⍝ Every mutation of the matrix(reflection and rotation)
allHorMat←{(⍵)(⍉⊖⍉⊖⍵)(⊖⍵)(⍉⊖⍉⍵)}
allVerMat←{(⍉⊖⍵)(⊖⍉⍵)(⍉⍵)(⊖⍉⊖⍵)}
⍝ We don't have to compute half of the matrices if
⍝ height doesn't equal to width.
>/⍴⍵:allHorMat ⍵
</⍴⍵:allVerMat ⍵
(allHorMat ⍵),allVerMat ⍵
}
m←allMatrix rm⍉rm ⍵
⍝ Represent the matrices as a binary number, and pick the smallest.
⊃m[⊃⍒{2⊥,⍵}¨m]
}
⍝ match a matrix in every direction.
⍝ Implemented by rotate the matrix in each direction, do the match, and rotate back.
Match ← {(⍺⍷⍵)∨(⊖⍉⍺⍷⍉⊖⍵)∨(⊖⍉⊖⍉⍺⍷⍉⊖⍉⊖⍵)∨(⍉⊖⍺⍷⊖⍉⍵)}
⍝ Two polyominoes are smiliar if and only if
⍝ they have the same canonical representation.
SimilarPoly ← {(CanonPoly ⍺) ≡ CanonPoly ⍵}
ValidPoly ← {
⍝ Expected input MUST BE a boolean matrix, otherwise undefined behavior.
⍝ First set a 1 to 2, then expand the area of 2 by BFS.
bfs ← {({(1 2 Match ⍵)+⍵}⍣(+/+/⍵))⍵}
⍝ The matrix represents a polyominoes if there is no 1 in the resulting matrix.
~(1 ∊ bfs ⍵+((⍴⍵)⍴<\,⍵))
}
PolyGen←{
⍝ Add a border of 0's.
br←{¯1⊖(⍵⍪0)⍪0}
⍝ remove duplicates.
nub←{((⍵⍳⍵)≡¨⍳⍴⍵)/⍵}
⍝ matrix with exactly one 1.
basis←{((×/⍵),⍵)⍴(1,(×/⍵)⍴0)}
⍝ Possible positions to add a new cell.
deltas←{(,(0 1 Match ⍵))⌿basis(⍴⍵)}
⍝ all possible polyominoes within one move from input polyomino
NextPoly←{nub CanonPoly¨⊂[2,3](deltas ⍵)+[2,3]⍵}
⍝ The set of polyominoes generated by adding one more cell to them
NextPolys←{nub⊃,/NextPoly¨br¨⍉¨br¨⍵}
⍝ Iterate NextPolys, starting from a set of monomino.
(NextPolys⍣(⍵-1)),⊂(1 1⍴1)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment