21
\$\begingroup\$

Input

A non-empty binary matrix consisting of 3x3 sub-matrices put side by side.

Task

Your task is to identify valid dice patterns (as described below) among the 3x3 sub-matrices. Each valid pattern is worth the value of the corresponding dice. Invalid patterns are worth 0.

Output

The sum of the valid dice values.

Dice patterns

$$\begin{align} &1:\pmatrix{\color{gray}0,\color{gray}0,\color{gray}0\\\color{gray}0,1,\color{gray}0\\\color{gray}0,\color{gray}0,\color{gray}0} &&2:\pmatrix{1,\color{gray}0,\color{gray}0\\\color{gray}0,\color{gray}0,\color{gray}0\\\color{gray}0,\color{gray}0,1}\text{or}\pmatrix{\color{gray}0,\color{gray}0,1\\\color{gray}0,\color{gray}0,\color{gray}0\\1,\color{gray}0,\color{gray}0}\\ &3:\pmatrix{1,\color{gray}0,\color{gray}0\\\color{gray}0,1,\color{gray}0\\\color{gray}0,\color{gray}0,1}\text{or}\pmatrix{\color{gray}0,\color{gray}0,1\\\color{gray}0,1,\color{gray}0\\1,\color{gray}0,\color{gray}0} &&4:\pmatrix{1,\color{gray}0,1\\\color{gray}0,\color{gray}0,\color{gray}0\\1,\color{gray}0,1}\\ &5:\pmatrix{1,\color{gray}0,1\\\color{gray}0,1,\color{gray}0\\1,\color{gray}0,1} &&6:\pmatrix{1,\color{gray}0,1\\1,\color{gray}0,1\\1,\color{gray}0,1}\text{or}\pmatrix{1,1,1\\\color{gray}0,\color{gray}0,\color{gray}0\\1,1,1} \end{align}$$

Example

The expected output for the following matrix is 14 because it contains the dice 5, 6 and 3, followed by an invalid pattern (from left to right and from top to bottom).

$$\pmatrix{1,0,1,1,1,1\\ 0,1,0,0,0,0\\ 1,0,1,1,1,1\\ 1,0,0,0,0,0\\ 0,1,0,0,1,0\\ 0,0,1,0,1,0}$$

Rules

  • Both the width and the height of the matrix are guaranteed to be multiples of 3.
  • You must ignore sub-matrices that are not properly aligned on the grid (see the 3rd test case). More formally and assuming 0-indexing: the coordinates of the top-left cell of each sub-matrix to be considered are of the form \$(3x, 3y)\$.
  • This is .

Test cases

// 0
[ [ 1,0,0 ],
  [ 0,0,1 ],
  [ 1,0,0 ] ]

// 2
[ [ 0,0,1 ],
  [ 0,0,0 ],
  [ 1,0,0 ] ]

// 0 (0 + 0)
[ [ 0,0,1,0,1,0 ],
  [ 0,0,0,1,0,0 ],
  [ 0,0,1,0,1,0 ] ]

// 9 (3 + 3 + 3)
[ [ 1,0,0,0,0,1,1,0,0 ],
  [ 0,1,0,0,1,0,0,1,0 ],
  [ 0,0,1,1,0,0,0,0,1 ] ]

// 6 (6 + 0)
[ [ 1,0,1 ],
  [ 1,0,1 ],
  [ 1,0,1 ],
  [ 1,0,1 ],
  [ 1,0,0 ],
  [ 1,0,1 ] ]

// 14 (5 + 6 + 3 + 0)
[ [ 1,0,1,1,1,1 ],
  [ 0,1,0,0,0,0 ],
  [ 1,0,1,1,1,1 ],
  [ 1,0,0,0,0,0 ],
  [ 0,1,0,0,1,0 ],
  [ 0,0,1,0,1,0 ] ]

// 16 (1 + 2 + 3 + 4 + 0 + 6)
[ [ 0,0,0,1,0,0,1,0,0 ],
  [ 0,1,0,0,0,0,0,1,0 ],
  [ 0,0,0,0,0,1,0,0,1 ],
  [ 1,0,1,1,1,1,1,0,1 ],
  [ 0,0,0,1,0,1,1,0,1 ],
  [ 1,0,1,1,1,1,1,0,1 ] ]
\$\endgroup\$
5
\$\begingroup\$

Python 3, 195 189 bytes

-6 bytes thanks to @Jo King

lambda m:sum({16:1,257:2,68:2,273:3,84:3,325:4,341:5,455:6,365:6}.get(int(''.join(str(e)for c in m[3*i:][:3]for e in c[3*j:][:3]),2),0)for i in range(len(m)//3)for j in range(len(m[0])//3))

Try it online! (189) Try it online! (195)

Human readable version:

# 3x3 part matrix to dice, beginning at coordinates 3*i, 3*j
def single_matrix_to_dice(matrix, i, j):
    # Example: matrix = [[0, 0, 0], [0, 1, 0], [0, 0, 0]], i=0, j=0 (result is 1)

    matrix_string = ''.join(
        str(e) for column in matrix[3*i:3*i+3] 
        for entry in column[3*j:3*j+3]
    ) # Slicing the matrix so that only the valid entries remain, here '000010000'

    # Interpreting the matrix string as binary number, here 16
    binary_number = int(matrix_string,2)

    # binary representations of all valid dice rolls
    dct = {16:1,257:2,68:2,273:3,84:3,325:4,341:5,455:6,365:6}

    return dct.get(binary_number, 0)

def f(matrix):
    return sum(
        single_matrix_to_dice(matrix, i, j) for i in range(len(m)//3) 
        for j in range(len(m[0])//3))
    ) # len(m)/3 would generate a float, so len(m)//3 is used
\$\endgroup\$
  • \$\begingroup\$ I wonder if you could shorten this slightly by doing the same operation on the transpose of the matrix as well. That way you could remove all of the duplicate entries in your map that add 6 bytes each. Just need to add the transpose step in <18 bytes \$\endgroup\$ – Easton Bornemeier Aug 3 '18 at 16:07
  • \$\begingroup\$ 188 bytes. \$\endgroup\$ – Jonathan Frech Aug 3 '18 at 16:30
  • \$\begingroup\$ Get rid of both instances of //3 and use '0'+''.join... to save two bytes :) \$\endgroup\$ – Jonathan Allan Aug 3 '18 at 16:44
  • \$\begingroup\$ ...combine that with enumerate to save two more: here \$\endgroup\$ – Jonathan Allan Aug 3 '18 at 16:49
  • 2
    \$\begingroup\$ 165 bytes. \$\endgroup\$ – Jonathan Frech Aug 3 '18 at 17:09
5
\$\begingroup\$

R, 134 bytes

function(m,d=dim(m)/3-1){for(a in 0:d)for(b in 0:d[2])F=F+sum(y<-m[1:3+a*3,1:3+b*3])*sum(y*2^(8:0))%in%utf8ToInt("āDđTŅŕLJŭ");F}

Try it online!

I noticed I had the same idea of @Heteira

History :

  • 171 : -10 bytes thanks to @JayCe !
  • 161 : -3 bytes thanks to @Giuseppe !
  • 158 : -13 bytes saved !
  • 145 : -2 bytes thanks to @Giuseppe!
  • 143 : -6 bytes saved !
  • 137 : -3 bytes thanks to @JayCe!
\$\endgroup\$
4
\$\begingroup\$

Perl 6, 113 105 97 94 bytes

{sum (|@_[*;^3+3*$_]for ^@_[0]).rotor(9).map:{"@āđŅŕLJ@@DT@@ŭ".ords.first(:2[$_],:k)%7}}

Try it online!

Splits up the matrix into sub matrices of 3x3, converts the nine 1s and 0s to base 2 and then indexes it into a list of integers for the value.

Explanation:

{  #Start anonymous code block
  sum   # Sum of all
     (|@_[*;^3+3*$_]   # Get the n*3 to n*3+3th elements in every sub-list
           for ^@_[0]) # For n in the range 0 to width (divide by 3 to avoid warnings)
     .rotor(9)  # Split this list into groups of 9 (split the dice up)
     .map:{     # And map each die to 
        "@āđŅŕLJ@@DT@@ŭ".ords  # In the list of integers
           .first(      # The first appearance of 
               :2[$_],  # The dice converted from a list of 0s and 1s to base 2
                 :k     # Returning the index
             )%7        # And modulo by 7 to get the alternate versions of 2, 3 and 6
          }
}
\$\endgroup\$
4
\$\begingroup\$

Jelly,  29 28 bytes

-1 thanks to Mr. Xcoder (use to replace ṢṪ)

s€3ZẎs3µZU,ƊṀṙ1FḄ“°€⁼-Ḍ?‘i)S

A monadic link.

Try it online! Or run the tests.

How?

s€3ZẎs3µZU,ƊṀṙ1FḄ“°€⁼-Ḍ?‘i)S - Link: list of lists of 1s and 0s
s€3                          - split each into threes
   Z                         - transpose
    Ẏ                        - tighten
     s3                      - split into threes -> the sub-matrices in column-major order
       µ                  )  - for each sub-matrix, say D:
           Ɗ                 -   last three links as a monad:
        Z                    -     transpose D
         U                   -     reverse each -> D rotated a quarter turn clockwise
          ,                  -     pair with D
            Ṁ                -   get the maximum of the two orientations
             ṙ1              -   rotate left by one (to ensure FḄ will yield integers <256 for all non-zero valued D)
               F             -   flatten
                Ḅ            -   convert from binary
                         i   -   first 1-based index in (0 if not found):
                 “°€⁼-Ḍ?‘    -     code-page indices list = [128,12,140,45,173,63]
                           S - sum

For example when a sub-matrix is:

[[1,0,1],
 [1,0,1],
 [1,0,1]]

Then ZU,Ɗ yields:

[[[1, 1, 1],
  [0, 0, 0],
  [1, 1, 1]],   ...which has maximum (Ṁ):    ...and after ṙ1:
 [[1, 0, 1],                   [[1, 1, 1],         [[0, 0, 0],
  [1, 0, 1],                    [0, 0, 0],          [1, 1, 1],
  [1, 0, 1]]]                   [1, 1, 1]]          [1, 1, 1]]

...which flattens to [0, 0, 0, 1, 1, 1, 1, 1, 1], which, converting from binary, is 63 which is the sixth entry in the code-page index list “°€⁼-Ḍ?‘ (? being byte 3F in Jelly's code-page)

\$\endgroup\$
  • \$\begingroup\$ might work instead of ṢṪ for -1. \$\endgroup\$ – Mr. Xcoder Aug 3 '18 at 15:47
  • \$\begingroup\$ ...yes it will (I thought I was saving over using M >.<). Can something clever be done with ŒṪ I wonder... \$\endgroup\$ – Jonathan Allan Aug 3 '18 at 15:52
3
\$\begingroup\$

Japt -x, 36 bytes

Now it's getting interesting. I'm sure can be golfed down even more

ò3 ®®ò3Ãy f@"0ıtŵġdťƍǧ"øºXm¬¬Í+H)d
c

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Retina 0.8.2, 90 bytes

+`(...)(.+¶)(...)(.+¶)(...)
$1¶$3¶$5¶$2$4
¶

M!`.{9}
G`111000111|(101){3}|(.)0(.0).0\3\2
1

Try it online! Explanation:

+`(...)(.+¶)(...)(.+¶)(...)
$1¶$3¶$5¶$2$4

Repeatedly remove \$3\times 3\$ blocks from each \$3\times n\$ row until all rows have 3 columns.

¶

M!`.{9}

Join all the blocks together and then split back up into rows of 9 columns.

G`111000111|(101){3}|(.)0(.0).0\3\2

Only keep valid dice patterns (two patterns for 6, then one matches any number from 0 to 5, although 0 of course will not contribute to the count below.)

1

Count the pips on the valid dice.

\$\endgroup\$
1
\$\begingroup\$

Ruby, 151 bytes

->m{m.each_slice(3).flat_map{|r|r.transpose.each_slice(3).map{|d|" \x10āđŅŕLJ  DT  ŭ".chars.map(&:ord).index(d.flatten.join.to_i 2)&.%7}-[p]}.sum}

Try it online!

A lambda accepting a 2d array of ints (or strings, I guess). Takes inspiration from Jo King's answer. I feel like slicing the dice out of the input matrix took a lot of space, so I may well be outgolfed. Fortunately, dealing with nils only cost me a handful of bytes.

Ungolfed:

->m{
  m.each_slice(3).flat_map{|r|             # Split into groups of 3 rows
    r.transpose.each_slice(3).map{|d|      # Split into groups of 3 columns
      " \x10āđŅŕLJ  DT  ŭ".chars.map(&:ord) # [0,16,257,273,325,341,455,0,0,68,84,0,0,365]
        .index(                            # Find in that array
          d.flatten.join.to_i 2            #   the die flattened into a bitstring (nil if not found)
        )&.%7                              # Safe-modulo 7 (leaves nils as nil)
    }-[p]                                  # Remove nils
  }.sum                                    # Add 'em up
}
\$\endgroup\$
1
\$\begingroup\$

Clojure, 197 bytes

#(apply +(for[R[range]i(R 0(count %)3)j(R 0(count(% 0))3)](case(apply +(map *(iterate(partial * 2)1)(for[x(R 3)y(R 3)]((%(+ i x))(+ j y)))))16 1 257 2 68 2 273 3 84 3 325 4 3 4 1 5 455 6 365 6 0)))

I should have come up with something smarter.

\$\endgroup\$
1
\$\begingroup\$

Python 2, 159 bytes

f=lambda a:a>[]and sum(u'ȀāDđTŅȀŕȀLJŭ'.find(unichr(int(J(J(map(str,r[i:i+3]))for r in a[:3]),2)))/2+1for i in range(0,len(a[0]),3))+f(a[3:])
J=''.join

Try it online!

Hat tip to Jonathan Frech for the unicode encoding approach.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.