Counting generalized polyominoes This challenge will have you count pseudo-polyforms on the snub square tiling.

I think that this sequence does not yet exist on the OEIS, so this challenge exists to compute as many terms as possible for this sequence.

Update: this is now on the OEIS as A309159: Number of generalized polyforms on the snub square tiling with n cells.

Definitions

The snub square tiling is a semiregular tiling of the plane that consists of equilateral triangles and squares.



A pseudo-polyform on the snub square tiling is a plane figure constructed by joining together these triangles and squares along their shared sides, analogous to a polyomino. Here is an example of a six-cell and an eight-cell pseudo-polyform:



Examples

For n = 1 there are two 1-cell pseudo-polyforms, namely the square and the triangle:



For n = 2 there are two 2-cell pseudo-polyforms, namely a square with a triangle and two triangles.



For n = 3 there are four 3-cell pseudo-polyforms.



Challenge

The goal of this challenge is to compute as many terms as possible in this sequence, which begins 2, 2, 4, ... and where the n-th term is the number of n-cell pseudo-polyforms up to rotation and reflection.

Run your code for as long as you'd like. The winner of this challenge will be the user who posts the most terms of the sequence, along with their code. If two users post the same number of terms, then whoever posts their last term earliest wins.

(Once there are enough known terms to prove that this sequence does not already exist in the OEIS, I'll create an entry in the OEIS and list the contributor as a co-author if he or she desires.)
Haskell

Now that not only the comments document that Peter Taylor was the first one to give enough terms to search on OEIS, I can give my results.

( 1 - 10) 2, 2, 4, 10, 28, 79, 235, 720, 2254, 7146,
(11 - 15) 22927, 74137, 241461, 790838, 2603210,
(16 - 18) 8604861, 28549166, 95027832,
(19 - 22) 317229779, 1061764660, 3562113987, 11976146355


Earlier, I counted hexagonal polyominoes. Except for some optimizations, what I'm doing here is very similar.

The elements of the tiling are represented like this:
You can go in an almost straight line from left to right
(in the first picture), alternating between squares and
rectangles. There are almost parallel further lines,
wiggling in opposite directions. Together, they miss
some triangles.
There are similar almost straight parallel lines from
bottom to top, containing the missing triangles.
Now ignore the wiggling and use a Cartesian coordinate
system, but only use odd numbers for the coordinates of the squares.
Then the triangles naturally get coordinate pairs with one even
and one odd coordinate. Pairs with both coordinates even
don't represent elements of the tiling.

(You could as well use even numbers for the coordinates
of the squares. I guess I decided this way because I thought
about reflection before rotation.)

Save the program in a file with a name like cgp.hs and compile with ghc -O2 -o cgp cgp.hs. It takes either one numeric command line argument and computes the number of polyominoes of that size, or none, in which case it computes values until stopped.



{-# LANGUAGE BangPatterns #-}

import Data.List(sort)
import qualified Data.Set as S
import System.Environment(getArgs)

data Point = P !Int !Int deriving (Eq,Ord)

start :: Point
start = P 1 1

redsq :: Point -&gt; Bool
redsq (P x y) = (x+y) `mod` 4 == 2

neighs :: Point -&gt; [Point]
neighs (P x y) =
  case (even x, even y) of
    (False,False) -&gt; [P x (y+1), P (x+1) y, P x (y-1), P (x-1) y]
    (True, False) -&gt; (P x (c y (x+y+1))) : opt [P (x-1) y, P (x+1) y]
    (False,True ) -&gt; (P (c x (x+y-1)) y) : opt [P x (y-1), P x (y+1)]
  where
    opt = filter ok
    ok p = p&gt;start || not (redsq p)
    c z m = if m `mod` 4 == 0 then z+2 else z-2

count :: S.Set Point -&gt; S.Set Point -&gt; [Point] -&gt; Int -&gt; Int -&gt; Int -&gt; Int -&gt; Int
count use _    _            0 c r y =
  if check (S.toAscList use) (y==r)
    then c+1
    else c
count _   _    []           _ c _ _ = c
count use seen (p:possible) n c r y =
  let !c' = count use seen possible n c r y
      new = filter (`S.notMember` seen) $ neighs p
      !r' = if redsq p then r+1 else r
      !y' = if redsq (mirror p) then y+1 else y
      !n' = n-1
  in if r'+n' &lt; y'&#32;
       then c'
       else count (S.insert p use) (foldr S.insert seen new) (new++possible)
                  n' c' r' y'

class Geom g where
  translate :: Int -&gt; Int -&gt; g -&gt; g
  rot :: g -&gt; g
  mirror :: g -&gt; g

instance Geom Point where
  translate dx dy (P x y) = P (dx+x) (dy+y)
  rot (P x y) = P (2-y) x    -- rotate around (1,1)
  mirror (P x y) = P x (-y)

instance (Geom g, Ord g) =&gt; Geom [g] where
  translate x y = map $ translate x y
  rot = sort . map rot
  mirror = sort . map mirror

normalize :: [Point] -&gt; [Point]
normalize pol = let (P x y) = head (filter redsq pol)
                in translate (1-x) (1-y) pol

check :: [Point] -&gt; Bool -&gt; Bool
check pol !cm = let rotated = take 4 $ iterate rot pol
                    mirrored = if cm then map mirror rotated else []
                    alts = map normalize (tail rotated ++ mirrored)
                in all (pol&lt;=) alts

f :: Int -&gt; Int
f 0 = 1; f 1 = 2; f 2 = 2
f n = count S.empty S.empty [start] n 0 0 0

output :: Int -&gt; IO ()
output n = putStrLn $ show n ++ ": " ++ show (f n)

main = do args &lt;- getArgs
          case args of
            []  -&gt; mapM_ output [1..]
            [n] -&gt; output (read n)



Try it online!