Quanto vale minha matriz de dados?


21

Entrada

Uma matriz binária não vazia que consiste em sub-matrizes 3x3 colocadas lado a lado.

Tarefa

Sua tarefa é identificar padrões de dados válidos (conforme descrito abaixo) entre as sub-matrizes 3x3. Cada padrão válido vale o valor dos dados correspondentes. Padrões inválidos valem 0.

Saída

A soma dos valores válidos dos dados.

Padrões de dados

1:(0 0,0 0,0 00 0,1,0 00 0,0 0,0 0)2:(1,0 0,0 00 0,0 0,0 00 0,0 0,1)ou(0 0,0 0,10 0,0 0,0 01,0 0,0 0)3:(1,0 0,0 00 0,1,0 00 0,0 0,1)ou(0 0,0 0,10 0,1,0 01,0 0,0 0)4:(1,0 0,10 0,0 0,0 01,0 0,1)5:(1,0 0,10 0,1,0 01,0 0,1)6:(1,0 0,11,0 0,11,0 0,1)ou(1,1,10 0,0 0,0 01,1,1)

Exemplo

O resultado esperado para a matriz a seguir é 14 porque contém os dados 5 , 6 e 3 , seguidos por um padrão inválido (da esquerda para a direita e de cima para baixo).

(1,0 0,1,1,1,10 0,1,0 0,0 0,0 0,0 01,0 0,1,1,1,11,0 0,0 0,0 0,0 0,0 00 0,1,0 0,0 0,1,0 00 0,0 0,1,0 0,1,0 0)

Regras

  • A largura e a altura da matriz são garantidas como múltiplos de 3.
  • Você deve ignorar as sub-matrizes que não estão alinhadas corretamente na grade (consulte o terceiro caso de teste). Mais formalmente e assumindo a indexação 0: as coordenadas da célula superior esquerda de cada sub-matriz a ser considerada têm a forma .(3x,3y)
  • Isso é .

Casos de teste

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

Respostas:


5

Python 3 , 195 189 bytes

-6 bytes graças a @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))

Experimente online! (189) Experimente online! (195)

Versão legível por humanos:

# 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

Gostaria de saber se você poderia encurtar isso levemente, fazendo a mesma operação na transposição da matriz também. Dessa forma, você pode remover todas as entradas duplicadas do seu mapa que adicionam 6 bytes cada. Só precisa adicionar a etapa de transposição em <18 bytes
Easton Bornemeier


Livrar-se de ambas as instâncias do //3e uso '0'+''.join...para salvar dois bytes :)
Jonathan Allan

... combine isso com enumerar para economizar mais dois: aqui #
Jonathan Allan


5

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}

Experimente online!

Percebi que tinha a mesma ideia da @Heteira

História:

  • 171 : -10 bytes graças a @JayCe!
  • 161 : -3 bytes graças a @ Giuseppe!
  • 158 : -13 bytes salvos!
  • 145 : -2 bytes graças a @ Giuseppe!
  • 143 : -6 bytes salvos!
  • 137 : -3 bytes graças a @JayCe!

1
salvar 5 bytes por comprimir a lista de números - ligação com exemplos muito tempo para cargo de um comentário
Jayce



1
Há um par extra de parênteses em torno do (2^(8:0))qual pode ser removido.
Giuseppe

1
I adicionar esquecido catda saída de intToUtf8: save 3 bytes
Jayce

4

Perl 6 , 113 105 97 94 bytes

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

Experimente online!

Divide a matriz em sub-matrizes de 3x3, converte os nove 1s e 0s na base 2 e depois a indexa em uma lista de números inteiros para o valor.

Explicação:

{  #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
          }
}

4

Geléia ,  29 28 bytes

-1 graças a Mr. Xcoder (use para substituir ṢṪ)

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

Um link monádico.

Experimente online! Ou execute os testes .

Quão?

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

Por exemplo, quando uma sub-matriz é:

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

Então ZU,Ɗproduz:

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

... que simplifica [0, 0, 0, 1, 1, 1, 1, 1, 1], que, convertendo do binário, é 63a sexta entrada na lista de índices da página de códigos “°€⁼-Ḍ?‘( ?sendo byte 3Fna página de códigos de Jelly )


pode funcionar em vez de ṢṪpara -1.
Mr. Xcoder

... sim (pensei que estava economizando usando M>. <). Pode algo inteligente ser feito com ŒṪPergunto-me ...
Jonathan Allan


2

Retina 0.8.2 , 90 bytes

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

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

Experimente online! Explicação:

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

3×33×n

¶

M!`.{9}

Junte todos os blocos e divida-os novamente em linhas de 9 colunas.

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

Mantenha apenas padrões de dados válidos (dois padrões para 6, então um corresponde a qualquer número de 0até 5, embora, é 0claro, não contribua para a contagem abaixo.)

1

Conte os pips nos dados válidos.


1

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}

Experimente online!

Um lambda aceitando uma matriz 2D de entradas (ou cordas, eu acho). Inspira-se na resposta de Jo King . Sinto que cortar os dados para fora da matriz de entrada ocupava muito espaço, por isso posso ser superado. Felizmente, lidar com nils só me custou um punhado de 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
}

1

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

Eu deveria ter pensado em algo mais inteligente.


1

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

Experimente online!

Dica para Jonathan Frech pela abordagem de codificação unicode.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.