Todos os oitos únicos

24

Dada uma matriz retangular não-vazia de números inteiros de 0para 9, produza a quantidade de células que são 8e não têm um vizinho 8. Vizinho é aqui entendido no sentido de Moore , isto é, incluindo diagonais. Portanto, cada célula tem 8vizinhos, exceto as células nas bordas da matriz.

Por exemplo, dada a entrada

8 4 5 6 5
9 3 8 4 8
0 8 6 1 5
6 7 9 8 2
8 8 7 4 2

a saída deve ser 3. As três células qualificadas seriam as seguintes, marcadas com um asterisco (mas apenas a quantidade dessas entradas deve ser impressa):

* 4 5 6 5
9 3 8 4 *
0 8 6 1 5
6 7 9 * 2
8 8 7 4 2

Regras adicionais

  • Opcionalmente, você pode pegar dois números que definem o tamanho da matriz como entradas adicionais.

  • A entrada pode ser obtida por qualquer meio razoável . O formato é flexível, como de costume. Por exemplo, pode ser uma matriz de caracteres 2D, ou uma lista de listas de números ou uma lista simples.

  • Programas ou funções são permitidos, em qualquer linguagem de programação . As brechas padrão são proibidas.

  • O menor código em bytes vence.

Casos de teste

  1. Entrada:

    8 4 5 6 5
    9 3 8 4 8
    0 8 6 1 5
    6 7 9 8 2
    8 8 7 4 2
    

    Saída: 3

  2. Entrada

    8 8
    2 3
    

    Saída: 0

  3. Entrada:

    5 3 4
    2 5 2
    

    Saída: 0

  4. Entrada:

    5 8 3 8
    

    Saída: 2

  5. Entrada:

    8
    0
    8
    

    Saída: 2.

  6. Entrada:

    4 2 8 5
    2 6 1 8
    8 5 5 8
    

    Saída: 1

  7. Entrada:

    4 5 4 3 8 1 8 2
    8 2 7 7 8 3 9 3
    9 8 7 8 5 4 2 8
    4 5 0 2 1 8 6 9
    1 5 4 3 4 5 6 1
    

    Saída 3.

  8. Entrada:

    8
    

    Saída: 1

  9. Entrada:

    8 5 8 1 6 8 7 7
    9 9 2 8 2 7 8 3
    2 8 4 9 7 3 2 7
    9 2 9 7 1 9 5 6
    6 9 8 7 3 1 5 2
    1 9 9 7 1 8 8 2
    3 5 6 8 1 4 7 5
    

    Saída: 4.

  10. Entrada:

    8 1 8
    2 5 7
    8 0 1
    

    Saída: 3.

Entradas no formato MATLAB:

[8 4 5 6 5; 9 3 8 4 8; 0 8 6 1 5; 6 7 9 8 2; 8 8 7 4 2]
[8 8; 2 3]
[5 3 4; 2 5 2]
[5 8 3 8]
[8; 0; 8]
[4 2 8 5; 2 6 1 8; 8 5 5 8]
[4 5 4 3 8 1 8 2; 8 2 7 7 8 3 9 3; 9 8 7 8 5 4 2 8; 4 5 0 2 1 8 6 9; 1 5 4 3 4 5 6 1]
[8]
[8 5 8 1 6 8 7 7; 9 9 2 8 2 7 8 3; 2 8 4 9 7 3 2 7; 9 2 9 7 1 9 5 6; 6 9 8 7 3 1 5 2; 1 9 9 7 1 8 8 2; 3 5 6 8 1 4 7 5]
[8 1 8; 2 5 7; 8 0 1]

Entradas no formato Python:

[[8, 4, 5, 6, 5], [9, 3, 8, 4, 8], [0, 8, 6, 1, 5], [6, 7, 9, 8, 2], [8, 8, 7, 4, 2]]
[[8, 8], [2, 3]]
[[5, 3, 4], [2, 5, 2]]
[[5, 8, 3, 8]]
[[8], [0], [8]]
[[4, 2, 8, 5], [2, 6, 1, 8], [8, 5, 5, 8]]
[[4, 5, 4, 3, 8, 1, 8, 2], [8, 2, 7, 7, 8, 3, 9, 3], [9, 8, 7, 8, 5, 4, 2, 8], [4, 5, 0, 2, 1, 8, 6, 9], [1, 5, 4, 3, 4, 5, 6, 1]]
[[8]]
[[8, 5, 8, 1, 6, 8, 7, 7], [9, 9, 2, 8, 2, 7, 8, 3], [2, 8, 4, 9, 7, 3, 2, 7], [9, 2, 9, 7, 1, 9, 5, 6], [6, 9, 8, 7, 3, 1, 5, 2], [1, 9, 9, 7, 1, 8, 8, 2], [3, 5, 6, 8, 1, 4, 7, 5]]
[[8, 1, 8], [2, 5, 7], [8, 0, 1]]

Saídas:

3, 0, 0, 2, 2, 1, 3, 1, 4, 3
Luis Mendo
fonte
17
Se você gosta dele, então você deveria ter colocado uma votação sobre isso
Luis Mendo
Quando li "células iguais a 8", por um momento pensei que você quisesse dizer que uma célula poderia ser maior que um mandril 1x1 (NxN) da grade. Provavelmente deve reformular isso para "células com 8" para esclarecer que não é necessário fazer matemática. = P
Tezra 12/11/1918
@Tezra Edited. Acho que a nova redação um pouco menos natural, mas eu não sou um falante nativo, então eu vou confiar em seu critério
Luis Mendo

Respostas:

2

MATL , 21 17 10 bytes

8=t3Y6Z+>z

Experimente online!

Agradecemos a Luis Mendo pela ajuda no bate-papo e por sugerir convolução 2D.

Explicação:

	#implicit input, m
8=	#equal to 8? matrix of 1 where m is 8, 0 otherwise
t	#duplicate
3Y6	#push [1 1 1; 1 0 1; 1 1 1], "neighbor cells" for convolution
Z+	#2D convolution; each element is replaced by the number of neighbors that are 8
>	#elementwise greater than -- matrix of 1s where an 8 is single, 0s otherwise
z	#number of nonzero elements -- number of single eights
	#implicit output
Giuseppe
fonte
Você pode economizar muito poucos bytes usando convolução (2D), se você é famiiar com o conceito
Luis Mendo
11
A convolução 2D do @LuisMendo é uma daquelas coisas em que também não entendo a convolução 1D, então não há esperança para mim lá ... parece uma oportunidade para aprender as duas coisas!
21818 Giuseppe #:
11
Se precisar de ajuda, informe-me na sala de bate-papo. Convolução é uma operação muito útil. Se você quiser aprender convolução, comece com 1D. A generalização para 2D é imediato
Luis Mendo
9

R , 117 63 59 bytes

function(m)sum(colSums(as.matrix(dist(which(m==8,T)))<2)<2)

Experimente online!

distcalcula distâncias (o padrão é euclidiano) entre as linhas de uma matriz. whichcom o segundo argumento TRUEretorna as coordenadas em que o predicado é verdadeiro.

As coordenadas são vizinhas se a distância entre elas não for maior que a raiz quadrada de 2, mas a interna <2for boa o suficiente porque a distância possível salta de sqrt(2)ro 2.

ngm
fonte
é uma pena que a imprecisão numérica não permita colSums()^2<=2que funcione.
Giuseppe
@ Giuseppe, é claro, existem apenas algumas distâncias e sqrt(2)saltos possíveis para 2(por exemplo sort(c(dist(expand.grid(1:6,1:6))), decreasing = TRUE))), então estávamos sendo espertos demais por lá.
ngm
7

APL (Dyalog Classic) , 29 28 25 bytes

≢∘⍸16=2⊥¨3,⌿3,/8=(⍉0,⌽)⍣4

Experimente online!

ngn
fonte
Nota: nem a origem do índice 0 é necessária.
Zachary
@ Zacharý Eu sempre o uso como padrão, para evitar surpresas.
NGN
Ah, assim como outros com 1(exceto não definido explicitamente). Isso faz sentido.
Zachary
Surpreendeu que isso não use o estêncil. Existe algo que torne o estêncil inconveniente aqui?
lirtosiast
@lirtosiast é apenas mais com ele :)
NGN
5

Geléia , 18 15 bytes

8=µ+Ż+ḊZµ⁺ỊṖḋµS

Experimente online!

Como funciona

8=µ+Ż+ḊZµ⁺ỊṖḋµS    Main link (monad). Input: digit matrix
8=              1) Convert elements by `x == 8`
  µ             2) New chain:
   +Ż+Ḋ              x + [0,*x] + x[1:] (missing elements are considered 0)
                     Effectively, vertical convolution with [1,1,1]
       Z             Transpose
        µ⁺      3) Start new chain, apply 2) again
          ỊṖ       Convert elements by `|x| <= 1` and remove last row
            ḋ      Row-wise dot product with result of 1)
             µS 4) Sum

Solução anterior, 18 bytes

æc7B¤ZḊṖ
8=µÇÇỊḋµS

Experimente online!

Queria compartilhar outra abordagem, embora este seja 1 byte mais longo que a solução de Jonathan Allan .

Como funciona

æc7B¤ZḊṖ    Auxiliary link (monad). Input: integer matrix
æc7B¤       Convolution with [1,1,1] on each row
     ZḊṖ    Zip (transpose), remove first and last elements

8=µÇÇỊḋµS    Main link (monad). Input: digit matrix
8=           Convert 8 to 1, anything else to 0 (*A)
  怀        Apply aux.link twice (effective convolution with [[1,1,1]]*3)
     Ịḋ      Convert to |x|<=1, then row-wise dot product with A
       µS    Sum the result
Bubbler
fonte
4

J , 43, 40 37 bytes

-3 bytes graças ao Bubbler

1#.1#.3 3(16=8#.@:=,);._3(0|:@,|.)^:4

Experimente online!

Explicação:

A primeira parte do algoritmo garante que podemos aplicar uma janela deslizante 3x3 à entrada. Isso é obtido anexando uma linha de zeros e rotação de 90 graus, repetida 4 vezes.

1#.1#.3 3(16=8#.@:=,);._3(0|:@,|.)^:4
                         (       )^:4 - repeat 4 times
                          0|:@,|.     - reverse, prepend wit a row of 0 and transpose
                     ;._3             - cut the input (already outlined with zeroes)
      3 3                             - into matrices with size 3x3
         (          )                 - and for each matrix do
                   ,                  - ravel (flatten)
             8    =                   - check if each item equals 8
              #.@:                    - and convert the list of 1s and 0s to a decimal
          16=                         - is equal to 16?
   1#.                                - add (the result has the shape of the input)
1#.                                   - add again
Galen Ivanov
fonte
11
37 bytes usando @:e movendo|. . Observe que @no lugar de @:não funciona.
quer
@Bubbler Obrigado!
Galen Ivanov
Isso é legal. Provavelmente vale a pena adicionar pelo menos uma explicação de alto nível de como funciona, se não uma quebra de código. Levei 10m ou mais para descobrir. Além disso, é interessante quanto menor a versão do APL (que usa a mesma abordagem). Parece que é principalmente o resultado de dígrafos em vez de símbolos de char único ...
Jonah
@ Jonah eu vou adicionar uma explicação. Para comparação com o APL, você pode examinar as revisões da solução da ngn , especialmente a versão de 28 bytes
Galen Ivanov
11
@Jonah Explanation added
Galen Ivanov
3

Retina 0.8.2 , 84 bytes

.+
_$&_
m`(?<!(?(1).)^(?<-1>.)*.?.?8.*¶(.)*.|8)8(?!8|.(.)*¶.*8.?.?(?<-2>.)*$(?(2).))

Experimente online! Explicação:

.+
_$&_

Quebra cada linha em não- 8caracteres, para que todos os 8s tenham pelo menos um caractere de cada lado.

m`

Esta é a última etapa, portanto, a contagem de partidas está implícita. O mmodificador faz com que os caracteres ^e $correspondam no início ou no final de qualquer linha.

(?<!...|8)

Não combine um personagem diretamente após um 8, ou ...

(?(1).)^(?<-1>.)*.?.?8.*¶(.)*.

... um personagem abaixo de 8; o (?(1).)^(?<-1>.)*corresponde à mesma coluna como ¶(.)*na linha seguinte, mas o .?.?permite a 8para ser uma esquerda ou à direita do caractere após o .na linha seguinte.

8

Correspondência 8s.

(?!8|...)

Não combine um 8 imediatamente antes de um 8, ou ...

.(.)*¶.*8.?.?(?<-2>.)*$(?(2).)

... um personagem com um 8 na linha abaixo; novamente, (?<-2>.)*$(?(2).)corresponde à mesma coluna que a (.)*¶da linha anterior, mas .?.?permite 8que seja 1 à esquerda ou à direita da 8anterior .na linha anterior.

Neil
fonte
3

Geléia , 17 bytes

=8ŒṪµŒcZIỊȦƲƇẎ⁸ḟL

Experimente online! Ou veja a suíte de testes .

Quão?

=8ŒṪµŒcZIỊȦƲƇẎ⁸ḟL - Link: list of lists of integers (digits)
=8                - equals 8?
  ŒṪ              - multidimensional truthy indices (pairs of row & column indices of 8s)
    µ             - start a new monadic chain
     Œc           - all pairs (of the index-pairs) 
            Ƈ     - filter keep if:  (keep those that represent adjacent positions)
           Ʋ      -   last four links as a monad:
       Z          -     transpose
        I         -     incremental differences
         Ị        -     insignificant? (abs(x) <= 1)
          Ȧ       -     all?
             Ẏ    - tighten (to a list of all adjacent 8's index-pairs, at least once each)
              ⁸   - chain's left argument (all the index-pairs again)
               ḟ  - filter discard (remove those found to be adjacent to another)
                L - length (of the remaining pairs of indices of single 8s)
Jonathan Allan
fonte
3

J, 42 bytes

[:+/@,8=]+[:+/(<:3 3#:4-.~i.9)|.!.0(_*8&=)

Experimente online!

explicação

A abordagem de alto nível aqui é semelhante à usada na solução clássica de APL para o jogo da vida: https://www.youtube.com/watch?v=a9xAKttWgP4 .

Nessa solução, mudamos nossa matriz nas 8 direções possíveis vizinhas, criando 8 duplicatas da entrada, empilhando-as e adicionando os "planos" juntos para obter a contagem de vizinhos.

Aqui, usamos o truque "multiplicar pelo infinito" para adaptar a solução para esse problema.

[: +/@, 8 = ] + [: +/ (neighbor deltas) (|.!.0) _ * 8&= NB. 
                                                        NB.
[: +/@,                                                 NB. the sum after flattening
        8 =                                             NB. a 0 1 matrix created by
                                                        NB. elmwise testing if 8
                                                        NB. equals the matrix
            (the matrix to test for equality with 8   ) NB. defined by...
            ] +                                         NB. the original input plus
                [: +/                                   NB. the elmwise sum of 8
                                                        NB. matrices defined by
                                                _ *     NB. the elmwise product of 
                                                        NB. infinity and
                                                    8&= NB. the matrix which is 1
                                                        NB. where the input is 8
                                                        NB. and 0 elsewhere, thus
                                                        NB. creating an infinity-0
                                                        NB. matrix
                                        (|.!.0)         NB. then 2d shifting that 
                                                        NB. matrix in the 8 possible
                                                        NB. "neighbor" directions
                      (neighbor deltas)                 NB. defined by the "neighbor
                                                        NB. deltas" (see below)
                                                        NB. QED.
                                                        NB. ***********************
                                                        NB. The rest of the
                                                        NB. explanation merely
                                                        NB. breaks down the neighbor
                                                        NB. delta construction.


                      (neighbor deltas  )               NB. the neighbor deltas are
                                                        NB. merely the cross product
                                                        NB. of _1 0 1 with itself,
                                                        NB. minus "0 0"
                      (<: 3 3 #: 4 -.~ i.9)             NB. to create that...
                       <:                               NB. subtract one from
                          3 3 #:                        NB. the base 3 rep of
                                       i.9              NB. the numbers 0 - 8
                                 4 -.~                  NB. minus the number 4
                                                        NB.
                                                        NB. All of which produces
                                                        NB. the eight "neighbor"
                                                        NB. deltas:
                                                        NB. 
                                                        NB.       _1 _1
                                                        NB.       _1  0
                                                        NB.       _1  1
                                                        NB.        0 _1
                                                        NB.        0  1
                                                        NB.        1 _1
                                                        NB.        1  0
                                                        NB.        1  1
Jonah
fonte
11
Você esqueceu de remover um espaço entre ~e>
Galen Ivanov
@GalenIvanov Corrigido agora. Obrigado.
Jonah #
3

Java 8, 181 157 156 bytes

(M,R,C)->{int z=0,c,f,t;for(;R-->0;)for(c=C;c-->0;z+=f>1?0:f)for(f=0,t=9;M[R][c]==8&t-->0;)try{f+=M[R+t/3-1][c+t%3-1]==8?1:0;}catch(Exception e){}return z;}

-24 bytes graças a @ OlivierGrégoire .

Toma as dimensões como parâmetros adicionais R(quantidade de linhas) e C(quantidade de colunas).

As células são verificadas de maneira semelhante à da resposta do meu simulador de fritadeira .

Experimente online.

Explicação:

(M,R,C)->{                    // Method with integer-matrix as parameter & integer return
  int z=0,                    //  Result-counter, starting at 0
      c,f,t;                  //  Temp-integers, starting uninitialized
  for(;R-->0;)                //  Loop over the rows:
    for(c=C;c-->0             //   Inner loop over the columns:
           ;                  //     After every iteration:
            z+=f==1?          //      If the flag-integer is larger than 1:
                0             //       Leave the result-counter the same by adding 0
               :              //      Else:
                f)            //       Add the flag-integer (either 0 or 1)
      for(f=0,                //    Reset the flag to 0
          t=9;M[R][c]==8&     //    If the current cell contains an 8:
              t-->0;)         //     Inner loop `t` in the range (9, 0]:
        try{f+=               //      Increase the flag by:
               M[R+t/3-1]     //       If `t` is 0, 1, or 2: Look at the previous row
                              //       Else-if `t` is 6, 7, or 8: Look at the next row
                              //       Else (`t` is 3, 4, or 5): Look at the current row
                [c+t%3-1]     //       If `t` is 0, 3, or 6: Look at the previous column
                              //       Else-if `t` is 2, 5, or 8: Look at the next column
                              //       Else (`t` is 1, 4, or 7): Look at the current column
                ==8?          //       And if the digit in this cell is 8:
                 1            //        Increase the flag-integer by 1
                :0;           //       Else: leave it the same
        }catch(Exception e){} //      Catch and ignore ArrayIndexOutOfBoundsExceptions
                              //      (try-catch saves bytes in comparison to if-checks)
  return z;}                  //  And finally return the counter
Kevin Cruijssen
fonte
2

Python 2 , 130 bytes

lambda a:sum(sum(u[~-c*(c>0):c+2].count(8)for u in a[~-r*(r>0):r+2])*8==8==a[r][c]for r in range(len(a))for c in range(len(a[0])))

Experimente online!

Chas Brown
fonte
Parece mais curto se o comprimento for de args
l4m2
2

Powershell, 121 bytes

param($a)(($b='='*4*($l=($a|% Le*)[0]))+($a|%{"!$_!"})+$b|sls "(?<=[^8]{3}.{$l}[^8])8(?=[^8].{$l}[^8]{3})" -a|% m*).Count

Script de teste com menos golfe:

$f = {

param($a)

$length=($a|% Length)[0]
$border='='*4*$length
$pattern="(?<=[^8]{3}.{$length}[^8])8(?=[^8].{$length}[^8]{3})"
$matches=$border+($a|%{"!$_!"})+$border |sls $pattern -a|% Matches
$matches.count

}

@(

,(3,"84565","93848","08615","67982","88742")
,(0,"88","23")
,(0,"534","252")
,(2,"5838")
,(2,"8","0","8")
,(1,"4285","2618","8558")
,(3,"45438182","82778393","98785428","45021869","15434561")
,(1,"8")
,(4,"85816877","99282783","28497327","92971956","69873152","19971882","35681475")
,(3,"818","257","801")
,(0,"")

) | % {
    $expected,$a = $_
    $result = &$f $a
    "$($result-eq$expected): $result : $a"
}

Saída:

True: 3 : 84565 93848 08615 67982 88742
True: 0 : 88 23
True: 0 : 534 252
True: 2 : 5838
True: 2 : 8 0 8
True: 1 : 4285 2618 8558
True: 3 : 45438182 82778393 98785428 45021869 15434561
True: 1 : 8
True: 4 : 85816877 99282783 28497327 92971956 69873152 19971882 35681475
True: 3 : 818 257 801
True: 0 : 

Explicação:

Primeiro, o script calcula o comprimento da primeira string.

Segundo, ele adiciona borda extra às strings. Realidade aumentada gosta de:

....=========!84565! !93848! !08615! !67982! !88742!===========....

representa a sequência multilinha:

...=====
=======
!84565!
!93848!
!08615!
!67982!
!88742!
=======
========...

Nota 1: o número de = é suficiente para uma sequência de qualquer comprimento.

Nota 2: um grande número de = não afeta a pesquisa por oito.

Em seguida, a expressão regular (?<=[^8]{3}.{$l}[^8])8(?=[^8].{$l}[^8]{3})procura o dígito 8com os não-oito anteriores (?<=[^8]{3}.{$l}[^8])e os seguintes não-oito (?=[^8].{$l}[^8]{3}):

.......
<<<....
<8>....
>>>....
.......

Finalmente, o número de correspondências é retornado como resultado.

confuso
fonte
2

Gelatina , 12 bytes

œẹ8ạṀ¥þ`’Ạ€S

Experimente online!

Como funciona

œẹ8ạṀ¥þ`’Ạ€S  Main link. Argument: M (matrix)

œẹ8           Find all multidimensional indices of 8, yielding an array A of pairs.
      þ`      Table self; for all pairs [i, j] and [k, l] in A, call the link to the
              left. Return the results as a matrix.
   ạ              Absolute difference; yield [|i - k|, |j - l|].
    Ṁ             Take the maximum.
        ’     Decrement all the maxmima, mapping 1 to 0.
         Ạ€   All each; yield 1 for each row that contains no zeroes.
           S  Take the sum.
Dennis
fonte
1

JavaScript (ES6), 106 bytes

a=>a.map((r,y)=>r.map((v,x)=>k+=v==8&[...'12221000'].every((d,i,v)=>(a[y+~-d]||0)[x+~-v[i+2&7]]^8)),k=0)|k

Experimente online!


Abordagem bit a bit, 110 bytes

a=>a.map(r=>r.map(v=>x=x*2|v==8,x=k=0)|x).map((n,y,b)=>a[0].map((_,x)=>(n^1<<x|b[y-1]|b[y+1])*2>>x&7||k++))&&k

Experimente online!

Arnauld
fonte
[[7]]
Falha
@ lm42 Oh, obrigado. Agora consertado.
Arnauld
1

Clojure , 227 198 bytes

(fn[t w h](let[c #(for[y(range %3 %4)x(range % %2)][x y])e #(= 8(get-in t(reverse %)0))m(fn[[o p]](count(filter e(c(dec o)(+ o 2)(dec p)(+ p 2)))))](count(filter #(= 1(m %))(filter e(c 0 w 0 h))))))

Ai. Definitivamente não é o mais curto aqui, por qualquer meio. 54 bytes de parênteses são matadores. Ainda estou relativamente feliz com isso.

-29 bytes , criando uma função auxiliar que gera um intervalo desde que eu fazia isso duas vezes, alterando reducepara uma (count (filterconfiguração e removendo a macro de segmentação após jogar golfe.

(defn count-single-eights [td-array width height]
  ; Define three helper functions. One generates a list of coords for a given range of dimensions, another checks if an eight is
  ; at the given coord, and the other counts how many neighbors around a coord are an eight
  (letfn [(coords [x-min x-max y-min y-max]
            (for [y (range y-min y-max)
                  x (range x-min x-max)]
              [x y]))
          (eight? [[x y]] (= 8 (get-in td-array [y x] 0)))
          (n-eights-around [[cx cy]]
            (count (filter eight?
                           (coords (dec cx) (+ cx 2), (dec cy) (+ cy 2)))))]

    ; Gen a list of each coord of the matrix
    (->> (coords 0 width, 0 height)

         ; Remove any coords that don't contain an eight
         (filter eight?)

         ; Then count how many "neighborhoods" only contain 1 eight
         (filter #(= 1 (n-eights-around %)))
         (count))))

(mapv #(count-single-eights % (count (% 0)) (count %))
      test-cases)
=> [3 0 0 2 2 1 3 1 4 3]

Onde test-casesestá uma matriz contendo todos os "casos de teste Python"

Experimente online!

Carcinigenicado
fonte