# How much is my dice matrix worth?

## Input

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

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 ] ]


# 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))


# 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

• 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 – Easton Bornemeier Aug 3 '18 at 16:07
• – Jonathan Frech Aug 3 '18 at 16:30
• Get rid of both instances of //3 and use '0'+''.join... to save two bytes :) – Jonathan Allan Aug 3 '18 at 16:44
• ...combine that with enumerate to save two more: here – Jonathan Allan Aug 3 '18 at 16:49
• – Jonathan Frech Aug 3 '18 at 17:09

# 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ŅŕǇŭ");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!

# Perl 6, 113 105 97 94 bytes

{sum (|@_[*;^3+3*$_]for ^@_[0]).rotor(9).map:{"@āđŅŕǇ@@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 "@āđŅŕǇ@@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
}
}


# Jelly,  29 28 bytes

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

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


### 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:
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
“°€⁼-Ḍ?‘    -     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)

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

# 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!

# Retina 0.8.2, 90 bytes

+(...)(.+¶)(...)(.+¶)(...)
$1¶$3¶$5¶$2$4 ¶ M!.{9} G111000111|(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.

G111000111|(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.

# Ruby, 151 bytes

->m{m.each_slice(3).flat_map{|r|r.transpose.each_slice(3).map{|d|" \x10āđŅŕǇ  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āđŅŕǇ  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
}


## 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.

# Python 2, 159 bytes

f=lambda a:a>[]and sum(u'ȀāDđTŅȀŕȀǇŭ'.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.