Ile jest warta moja matryca kości?


21

Wkład

Niepusta macierz binarna składająca się z podmacierzy 3x3 umieszczonych obok siebie.

Zadanie

Twoim zadaniem jest zidentyfikowanie prawidłowych wzorów kości (jak opisano poniżej) wśród podmacierzy 3x3. Każdy prawidłowy wzór jest wart wartości odpowiednich kości. Nieprawidłowe wzory są warte 0.

Wydajność

Suma prawidłowych wartości kości.

Wzory kości

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

Przykład

Oczekiwany wynik dla następnej macierzy wynosi 14, ponieważ zawiera ona kości 5 , 6 i 3 , po których następuje nieprawidłowy wzór (od lewej do prawej i od góry do dołu).

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

Zasady

  • Zarówno szerokość, jak i wysokość matrycy są gwarantowane jako wielokrotności 3.
  • Musisz zignorować podmacierze, które nie są odpowiednio wyrównane na siatce (patrz 3. przypadek testowy). Bardziej formalnie i zakładając 0 indeksowanie: współrzędne górnego rogu każdej komórki macierzy sub należy uwzględnić w postaci .(3)x,3)y)
  • To jest .

Przypadki testowe

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

Odpowiedzi:


5

Python 3 , 195 189 bajtów

-6 bajtów dzięki @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))

Wypróbuj online! (189) Wypróbuj online! (195)

Wersja czytelna dla człowieka:

# 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

Zastanawiam się, czy można to nieco skrócić, wykonując tę ​​samą operację również w przypadku transpozycji macierzy. W ten sposób możesz usunąć wszystkie zduplikowane wpisy z mapy, które dodają po 6 bajtów. Wystarczy dodać krok transpozycji w <18 bajtach
Easton Bornemeier


Pozbądź się obu przypadków //3i użyj, '0'+''.join...aby zaoszczędzić dwa bajty :)
Jonathan Allan

... połącz to z wyliczeniem, aby uratować jeszcze dwa: tutaj
Jonathan Allan


5

R , 134 bajty

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}

Wypróbuj online!

Zauważyłem, że mam taki sam pomysł na @Heteira

Historia:

  • 171 : -10 bajtów dzięki @JayCe!
  • 161 : -3 bajty dzięki @Giuseppe!
  • 158 : -13 bajtów zapisanych!
  • 145 : -2 bajty dzięki @Giuseppe!
  • 143 : -6 zapisanych bajtów!
  • 137 : -3 bajty dzięki @JayCe!

1
zaoszczędź 5 bajtów, kompresując listę liczb - link z przykładami za długimi, aby opublikować jako komentarz
JayCe

1
dim
Jeszcze


1
Istnieje dodatkowa para nawiasów, wokół (2^(8:0))których można usunąć.
Giuseppe,

1
catintToUtf8
Dodałem

4

Perl 6 , 113 105 97 94 bajtów

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

Wypróbuj online!

Dzieli macierz na podmacierze 3x3, konwertuje dziewięć 1 i 0 na bazę 2, a następnie indeksuje ją na listę liczb całkowitych wartości.

Wyjaśnienie:

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

Galaretka ,  29 28 bajtów

-1 dzięki Mr. Xcoder (użyj do zastąpienia ṢṪ)

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

Link monadyczny.

Wypróbuj online! Lub uruchom testy .

W jaki sposób?

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

Na przykład, gdy macierz podrzędna to:

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

Następnie ZU,Ɗdaje:

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

... który spłaszcza się do [0, 0, 0, 1, 1, 1, 1, 1, 1], który, konwertując z pliku binarnego, jest 63szóstym wpisem na liście indeksów stron kodowych “°€⁼-Ḍ?‘( ?bajt 3Fna stronie kodowej Jelly )


może działać zamiast ṢṪ-1.
Pan Xcoder,

... tak to zrobi (myślałem, że oszczędzam, używając M>. <). ŒṪZastanawiam się, czy można zrobić coś sprytnego ...
Jonathan Allan


2

Retina 0.8.2 , 90 bajtów

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

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

Wypróbuj online! Wyjaśnienie:

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

3)×3)3)×n

¶

M!`.{9}

Połącz wszystkie bloki razem, a następnie podziel z powrotem na rzędy po 9 kolumn.

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

Zachowaj tylko prawidłowe wzory kości (dwa wzory dla 6, a następnie jeden pasuje do dowolnej liczby od 0do 5, chociaż 0oczywiście nie przyczyni się do liczenia poniżej).

1

Policz pipsy na prawidłowych kostkach.


1

Rubin , 151 bajtów

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

Wypróbuj online!

Lambda akceptuje tablicę 2d ints (lub ciągów, jak sądzę). Inspiruje się odpowiedzią Jo Kinga . Wydaje mi się, że wycięcie kości z matrycy wejściowej zajęło dużo miejsca, więc mogę zostać obezwładniony. Na szczęście radzenie sobie z zerami kosztuje tylko garść bajtów.

Nie golfowany:

->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 bajtów

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

Powinienem był wymyślić coś mądrzejszego.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.