I wrote the following Haskell program which generates polyplets of size n and checks them forfinds vanishing cases. Currently it ignores the symmetries of possible solutionspolyplets.
data Polyplet = Polyplet {
members :: [(Int,Int)]
}
,
instance Eqnonmembers Polyplet:: where[(Int,Int)]
} (Polypletderiving a)Show
eq ==:: (PolypletEq ba) ==> filter(`notElem`a)b[a] ++-> filter(`notElem`b)a[a] ==-> []Bool
eq [] [] = True
(Polypleteq a) ![] (Polyplet = False
eq [] b) = filterFalse
eq (`notElem`at:a) b ++= eq a (filter (`notElem`b/=t)a == []b)
instance ShowEq Polyplet where
show (Polyplet pa _) === unlines(Polyplet [[ifb elem_) = any (x,yeq a) p[zero then$ f $ '*'g else$ 'b|f<-[id,syma,syma.syma,syma.syma.syma],g<-[id,symb]]
syma '|x<p = [(b,-rangify[x|a)|(xa,_b)<-p]]|y<p]
symb p = [(-rangify[y|a,b)|(_a,yb)<-p]]p]
childrensize :: Polyplet -> [Polyplet]Int
childrensize polyplet@(Polyplet p _) = [zero $ Polyplet $length cp
zero :: [(Int,Int)] -> [(Int,Int)]
zero p |= cdo
let mx = minimum [x|(x,_)<-p];
uniquifylet $my allDeads= polyplet]minimum [y|(_,y)<-p];
[(x-mx,y-my)|(x,y)<-p];
zerozeroPolyplet :: Polyplet -> Polyplet
zerozeroPolyplet (Polyplet p np) = do
let mx = minimum [x|(x,_)<-p];
let my = minimum [y|(_,y)<-p];
Polyplet[Polyplet [(x-mx,y-my)|(x,y)<-p];p] [(x-mx,y-my)|(x,y)<-np]
rangify l = [minimum l..maximum l]
deadsAt :: Polyplet -> (Int,Int) -> [(Int,Int)]
deadsAt (Polyplet p _) x = filter(`notElem`p) $ adjacents x
-- Maybe rename? --
allDeads :: Polyplet -> [(Int,Int)]
allDeads polyplet@(Polyplet p np) = uniquify $$ filter (`notElem` np) $ p >>= deadsAt polyplet
maxLive :: Polyplet -> (Int,Int) -> Int
maxLive (Polyplet _ np) x = sum [1|u<-adjacents x,notElem u np]
minLive :: Polyplet -> (Int,Int) -> Int
minLive (Polyplet p _) x = 8 - sum [1|u<-adjacents x,notElem u p]
-- Could this be made faster? --
uniquify :: (Eq a) => [a] -> [a]
uniquify u = [a|(a,b) <- zip u [0..],notElem a $ take b u]
adjacents :: (Int,Int) -> [(Int,Int)]
adjacents (a,b) = [(a+x,b+y)|x<-[-1..1],y<-[-1..1],(x,y)/=(0,0)]
sizeNpolyplets :: Int -> [Polyplet]
sizeNpolyplets 1 = [Polyplet [(0,0)]]
sizeNpolyplets n = uniquify $ sizeNpolyplets (n-1) >>= children
vanishingforbiddenMinor :: Polyplet -> Bool
vanishingforbiddenMinor polyplet@(Polyplet p) = all ((`notElem`[5,6]np).length.deadsAt polyplet)= [1|lCell<-p && all ((/=5).length.deadsAt,maxLive polyplet) (allDeadslCell<4,minLive polyplet)
You can envoke it like so in ghci
mapM_ print $ filter vanishing $ sizeNpolypletslCell>1] 7
This will make a nice little ascii diagram of the found polyplets. If you want the raw data you can use
mapM_++ (print.members)[1|dCell<-np,maxLive $ filter vanishing $polyplet sizeNpolypletsdCell 7
instead.
The program is not very fast but I have been able to confirm that there are no solutions of size $2\leq n\leq 8$ using my laptop. Perhaps better techniques/more powerful computers can exhaust larger cases.
Here is an alternative version of the program that takes into account symmetry when calculating values. It may be slower than the above implementation especially for smaller inputs.
data== Polyplet3,minLive =polyplet PolypletdCell {
== members3] ::== [(Int,Int)]
}[]
eqpartitions :: (Num a,Eq a) => [a]a -> [a][b] -> Bool[([b],[b])]
eqpartitions []_ [] = True
eq a [([] = False
eq ,[] b = False
eq (t:a) b]
partitions =0 eqx a (filter= [(/=t) b[],x)
instance Eq Polyplet where]
(Polyplet a)partitions ==n (Polyplet bx:xs) = any (eq a) [zero $ f $ g $ b|f<-[id,syma,syma.syma,syma.syma.syma],g<-[id,symb]]
syma p =map [(b,-a)|\(a,b)<-p]
symb p = [(-a,b)|> (x:a,b)<-p]
instance Show Polyplet where
show (Polyplet p) = unlines [[if elem (x,y) p then '*'$ partitions (n-1) xs) ++ (map (\(a,b) -> (a,x:b)) $ elsepartitions 'n '|x<-rangify[x|(x,_)<-p]]|y<-rangify[y|(_,yxs)<-p]]
childrensubPolyplets :: Int -> Polyplet -> [Polyplet]
childrensubPolyplets max polyplet@(Polyplet p np) = [Polyplet $ zero $ c(addingLive :++ p) |(addingDead c++ np)|(addingLive,addingDead) <- uniquifyinit $$ partitions max $ allDeads polyplet]
zerozipCat :: [(Int,Int)][[a]] -> [(Int,Int)]
zero p[[a]] =-> do[[a]]
zipCat let[] mxb = minimum [x|(x,_)<-p];b
zipCat leta my[] = minimuma
zipCat [y|(_,ya:as)<-p];
[(x-mx,y-myb:bs)| = (x,y)<-p];
rangifya l++ =b): [minimumzipCat l..maximumas l]bs
deadsAtregroup :: Polyplet[Polyplet] -> (Int,Int)[[Polyplet]]
regroup ->[] [(Int,Int)]= []
deadsAtregroup (Polyplet p) x:xs) = filterzipCat (`notElem`pregroup xs) $ adjacents x
allDeads :: Polyplet ->replicate [(Int,Int)]
allDeadslength polyplet@(Polypletmembers px) = uniquify $- p1) >>=[] deadsAt++ polyplet[[x]]
uniquifyfillPolyplets :: (Eq a)Int =>-> [a]Int -> [a][[Polyplet]]
uniquifyfillPolyplets u1 n = [a|[Polyplet [(a0,b0) <- zip u [0..],notElem a[]] $: takereplicate b(n-1) u]
[]
adjacentsfillPolyplets ::x (Int,Int)n ->= [(Int,Int)]do
adjacents (a,b)let previous = [fillPolyplets (a+x,b+y)|x<-[-1..1],y<-[x-1..1],(x,y)/=(0,0)]
n
sizeNpolyplets ::zipCat Intprevious ->$ map (filter forbiddenMinor . uniquify . map zeroPolyplet) $ [Polyplet]
sizeNpolypletsregroup 1$ =(previous [Polyplet!! [(0,0x-2)]]
sizeNpolyplets n = uniquify) $>>= sizeNpolypletssubPolyplets (n-1x+1) >>= children
noChildrenvanishing :: Polyplet -> Bool
noChildrenvanishing polyplet@(Polyplet p np) = all ((/=5`notElem`[5,6]).length.deadsAt polyplet) (allDeads polyplet)
noSurvivors :: Polyplet -> Bool
noSurvivors polyplet@(Polyplet p) =&& all ((`notElem`[5,6]/=5).length.deadsAt polyplet) p(allDeads polyplet ++ np)
vanishinggetVanishingPolyplets :: PolypletInt -> Bool[Polyplet]
vanishinggetVanishingPolyplets pn = noChildrenfillPolyplets pn &&n noSurvivors>>= p(filter vanishing)
You can envoke it like so in ghci
mapM_ (print.members) $ getVanishingPolyplets 7
The program is not very fast but I have been able to get a complete classification for vanishing polyplets of size $n \leq 12$. Perhaps better techniques/more powerful computers can exhaust larger cases.
Here are the results of running it on $n=12$:
$$ \substack{ \displaystyle{◻◻◻} \cr \displaystyle{◻◼◻} \cr \displaystyle{◻◻◻} \cr } \quad \quad \quad \substack{ \displaystyle{◻◻◻◻} \cr \displaystyle{◻◼◼◻} \cr \displaystyle{◻◻◻◻} \cr } \quad \quad \quad \substack{ \displaystyle{◻◻◻◻} \cr \displaystyle{◻◻◼◻} \cr \displaystyle{◻◼◻◻} \cr \displaystyle{◻◻◻◻} \cr } \quad \quad \quad \substack{ \displaystyle{◻◻◻◻◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻} \cr \displaystyle{◻◼◼◼◼◼◻} \cr \displaystyle{◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◻◻◻◻} \cr } \quad \quad \quad \substack{ \displaystyle{◻◻◻◻◻◻◻} \cr \displaystyle{◻◻◻◻◼◻◻} \cr \displaystyle{◻◼◻◼◻◻◻} \cr \displaystyle{◻◻◼◼◼◻◻} \cr \displaystyle{◻◻◻◼◻◼◻} \cr \displaystyle{◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◻◻◻◻} \cr } $$ $$ \substack{ \displaystyle{◻◻◻◻◻◻◻◻} \cr \displaystyle{◻◻◻◼◼◻◻◻} \cr \displaystyle{◻◼◼◼◼◼◼◻} \cr \displaystyle{◻◻◻◼◼◻◻◻} \cr \displaystyle{◻◻◻◻◻◻◻◻} \cr } \quad \quad \quad \substack{ \displaystyle{◻◻◻◻◻◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◼◼◼◼◻} \cr \displaystyle{◻◼◼◼◼◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◻◻◻◻◻} \cr } \quad \quad \quad \substack{ \displaystyle{◻◻◻◻◻◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◼◼◼◼◻} \cr \displaystyle{◻◼◼◼◼◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◻◻◻◻◻} \cr } \quad \quad \quad \substack{ \displaystyle{◻◻◻◻◻◻◻◻} \cr \displaystyle{◻◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◻◼◻◻◻} \cr \displaystyle{◻◻◻◼◼◼◼◻} \cr \displaystyle{◻◼◼◼◼◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◼◻◻◻◻} \cr \displaystyle{◻◻◻◻◻◻◻◻} \cr } $$
All of these were previously found by others, however now we can be certain that there are no other vanishing polyplets of size less than $12$ that we are unaware of.
There also seems to be an issue that some polyplets show up in the output more times than they should. I think this is a problem with the way I handle symmetries but I can't nail it down for sure. Fixing this problem would probably make things considerably faster.