Skip to main content
5 of 8
added 15 characters in body
Jonah
  • 34.1k
  • 4
  • 41
  • 95

J, 90 87 85 78 bytes

((|:-:&([:+/="1)1,:#\)@#~*/@,&,[:g+/@])(,:&(-/~)0j1&*)(g=.+./ .*^:_~)"[email protected]:@1 

Try it online!

argument encoding

We take the list positions (encoded as complex numbers) as the right arg, and the list of pieces as the left arg. For example, for the board:

rc,gc,bc __,gs,__ __,gf,__ 

the left and right arguments would like like this (boxed for clarity):

┌──┬─────────────────┐ │rc│0 0j1 0j2 1j1 2j1│ │gc│ │ │bc│ │ │gs│ │ │gf│ │ └──┴─────────────────┘ 

idea

The high-level idea is the interesting part, so I'll focus on that.

  1. Find all horizontally connected pieces. To do this, we create an adjacency matrix of all the positions, where adjacency is defined by the distance between two elements being in the set _1 0 1:

     0 0j1 0j2 1j1 2j1 +----------------------- 0 |1 1 0 0 0 0j1 |1 1 1 0 0 0j2 |0 1 1 0 0 1j1 |0 0 0 1 0 2j1 |0 0 0 0 1 

    And then take the transitive closure of that matrix "or-multiplied" by itself until a fixed point. The result shows all the horizontal connections:

     1 1 1 0 0 <- 0 is connected to 0, 0j1, 0j2 1 1 1 0 0 <- 0j1 is connected to 0, 0j1, 0j2 1 1 1 0 0 <- 0j2 is connected to 0, 0j1, 0j2 0 0 0 1 0 <- 1j1 is only connected to itself 0 0 0 0 1 <- 2j1 is only connected to itself 
  2. Find all vertically connected pieces. To do this, we reuse the logic in step 1, by first multiplying every position by 0j1, which has the effect of rotating the entire board 45 degress left. Now vertical connections will be horizontal ones. The resulting final matrix this time is:

     1 0 0 0 0 0 1 0 1 1 0 0 1 0 0 0 1 0 1 1 0 1 0 1 1 
  3. Next, we use the rows from the previous steps as masks to define the groups of pieces we need to validate:

     ┌──┬──┬──┬──┬──┐ │rc│gc│bc│gc│gc│ <- Vertically connected pieces │ │gs│ │gs│gs│ │ │gf│ │gf│gf│ ├──┼──┼──┼──┼──┤ │rc│rc│rc│gs│gf│ <- Horizontally connected pieces │gc│gc│gc│ │ │ │bc│bc│bc│ │ │ └──┴──┴──┴──┴──┘ 
  4. For each group, we validate that one property is all the same, and that the other property is all different. This part should have been easier to golf but the best approach I came up with was (|:-:&([:+/="1)1,:#\). This first creates a matrix like:

     1 1 1 1 2 3 

    and compares it to the transpose of the input:

     ggg csf 

    "under" the "self-classify" of each row. What does this mean?

     1 1 1 <- the self classify of 1 1 1 0 0 0 0 0 0 1 0 0 <- the self classify of 0 1 2 0 1 0 which is just the identity matrix 0 0 1 

    Finally we add these two together elementwise:

     2 1 1 0 1 0 0 0 1 

    The transpose of the input will have this same "signature" iff it has the properties we need.

  5. Finally, we check that all elements are connected. Here we use our adjacency matrix trick a third time, except now adjacency is defined as a horizontal or vertical connection:

     1 1 0 0 0 1 1 1 1 0 0 1 1 0 0 0 1 0 1 1 0 0 0 1 1 

    and we check that its transitive closure becomes the matrix consisting of all ones:

     1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 
Jonah
  • 34.1k
  • 4
  • 41
  • 95