Все одиночные восьмерки

24

Учитывая непустой прямоугольный массив целых чисел от 0до 9, выведите количество ячеек, которые есть 8и не имеют соседа, который есть 8. Соседство здесь понимается в смысле Мура , то есть включает диагонали. Таким образом, каждая ячейка имеет 8соседей, за исключением ячеек по краям массива.

Например, учитывая вход

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

выход должен быть 3. Следующие три ячейки будут отмечены звездочкой (но должно быть выведено только количество таких записей):

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

Дополнительные правила

Контрольные примеры

  1. Входные данные:

    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
    

    Выход: 3

  2. вход

    8 8
    2 3
    

    Выход: 0

  3. Входные данные:

    5 3 4
    2 5 2
    

    Выход: 0

  4. Входные данные:

    5 8 3 8
    

    Выход: 2

  5. Входные данные:

    8
    0
    8
    

    Выход: 2.

  6. Входные данные:

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

    Выход: 1

  7. Входные данные:

    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
    

    Выход 3.

  8. Входные данные:

    8
    

    Выход: 1

  9. Входные данные:

    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
    

    Выход: 4.

  10. Входные данные:

    8 1 8
    2 5 7
    8 0 1
    

    Выход: 3.

Входы в формате 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]

Входные данные в формате 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]]

Выходы:

3, 0, 0, 2, 2, 1, 3, 1, 4, 3
Луис Мендо
источник
17
Если вам это нравится, то вам следовало бы проголосовать за него
Луис Мендо
Когда я читал «ячейки, которые равны 8», я на мгновение подумал, что вы имеете в виду, что ячейка может быть больше, чем патрон 1x1 (NxN) сетки. Вероятно, следует перефразировать это в "ячейки, которые 8", чтобы уточнить математику не нужно. = P
Tezra
@ Тезра Отредактировано. Я нахожу новую формулировку немного менее естественной, но я не являюсь носителем языка, поэтому я буду доверять вашему критерию
Луис Мендо

Ответы:

2

MATL , 21 17 10 байт

8=t3Y6Z+>z

Попробуйте онлайн!

Спасибо Луису Мендо за помощь в чате и за предложение 2D свертки.

Объяснение:

	#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
источник
Вы можете сэкономить немало байтов, используя (2D-) свертку, если вы знакомы с этой концепцией
Луис Мендо
1
@LuisMendo 2D свертка - это одна из тех вещей, где я тоже не понимаю 1D свертки, так что для меня там нет надежды ... звучит как возможность изучить оба!
Джузеппе
1
Если вам нужна помощь, дайте мне знать в чате. Свертка - очень полезная операция. Если вы хотите изучать свертку, начните с 1D. Обобщение в 2D немедленно
Луис Мендо
9

R , 117 63 59 байт

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

Попробуйте онлайн!

distвычисляет расстояния (по умолчанию - евклидово) между строками матрицы. whichсо вторым аргументом TRUEвозвращает координаты, где предикат является истинным.

Координаты являются соседями, если расстояние между ними не превышает квадратный корень из 2, но внутренняя часть <2достаточно хорошая, потому что возможное расстояние прыгает от sqrt(2)ro 2.

НГМ
источник
обидно, числовая неточность не позволяет colSums()^2<=2работать.
Джузеппе
@Giuseppe, конечно, есть только несколько возможных расстояний и sqrt(2)прыжков 2(например sort(c(dist(expand.grid(1:6,1:6))), decreasing = TRUE))), поэтому мы были слишком умны там.
НГМ
7

APL (Dyalog Classic) , 29 28 25 байт

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

Попробуйте онлайн!

СПП
источник
Примечание: нулевое происхождение индекса даже не требуется.
Захари
@ Zacharý Я всегда использую его по умолчанию, чтобы избежать неожиданностей.
НГН
Ах, так как другие с 1(кроме явно не установлен). В этом есть смысл.
Захари
Удивлен, что это не использует трафарет. Есть ли что-то, что делает трафарет неудобным здесь?
lirtosiast
@lirtosiast это просто дольше с ним :)
НГН
5

Желе , 18 15 байт

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

Попробуйте онлайн!

Как это работает

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

Предыдущее решение, 18 байт

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

Попробуйте онлайн!

Хотел поделиться другим подходом, хотя это на 1 байт длиннее решения Джонатана Аллана .

Как это работает

æ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
фонтанчик для питья
источник
4

J , 43, 40 37 байт

-3 байта благодаря Bubbler

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

Попробуйте онлайн!

Объяснение:

Первая часть алгоритма гарантирует, что мы можем применить скользящее окно 3x3 для ввода. Это достигается путем добавления ряда нулей и поворота на 90 градусов, повторяется 4 раза.

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
Гален Иванов
источник
1
37 байт используя @:и перемещаясь|. . Обратите внимание, что @вместо @:не работает.
Bubbler
@Bubbler Спасибо!
Гален Иванов
Это хорошо. Вероятно, стоит добавить хотя бы высокоуровневое объяснение того, как это работает, если не разбивка кода. Мне понадобилось около 10 метров, чтобы понять это. Также интересно, насколько короче версия APL (в которой используется тот же подход). Похоже, это в основном результат орграфов, а не одиночных символов символов ...
Иона
@ Джона, я добавлю объяснение. Для сравнения с APL вы можете посмотреть ревизии решения ngn , особенно 28-байтовую версию
Гален Иванов
1
@Jonah Объяснение добавлено
Гален Иванов
3

Сетчатка 0.8.2 , 84 байта

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

Попробуйте онлайн! Объяснение:

.+
_$&_

Оберните каждую строку не 8символами, чтобы все 8s имели хотя бы один символ с каждой стороны.

m`

Это последний этап, поэтому подсчет матчей подразумевается. mМодификатор делает ^и $символы совпадают в начале или в конце каждой строки.

(?<!...|8)

Не сопоставляйте персонажа сразу после 8 или ...

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

... символ ниже 8; (?(1).)^(?<-1>.)*совпадает с тем же столбце, что и ¶(.)*на следующей строке, но .?.?позволяет 8быть 1 слева или справа от символа после того , как .на следующей строке.

8

Матч 8с.

(?!8|...)

Не сопоставляйте 8 непосредственно перед 8, или ...

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

... персонаж с цифрой 8 в строке ниже; опять же , (?<-2>.)*$(?(2).)совпадает с тем же столбце, что и (.)*¶на предыдущей строке, но .?.?позволяет 8быть 1 влево или вправо из 8прежде , чем .на предыдущей строке.

Нил
источник
3

Желе , 17 байт

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

Попробуйте онлайн! Или посмотрите набор тестов .

Как?

=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)
Джонатан Аллан
источник
3

J, 42 байта

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

Попробуйте онлайн!

объяснение

Высокоуровневый подход здесь аналогичен подходу, используемому в классическом APL-решении игры жизни: https://www.youtube.com/watch?v=a9xAKttWgP4. .

В этом решении мы сдвигаем нашу матрицу в 8 возможных соседних направлениях, создавая 8 дубликатов входных данных, складываем их вместе, а затем складываем «плоскости» вместе, чтобы получить количество соседей.

Здесь мы используем трюк «умножение на бесконечность», чтобы адаптировать решение для этой проблемы.

[: +/@, 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
Ион
источник
1
Вы забыли убрать пробел между ~а>
Гален Иванов
@GalenIvanov Исправлено сейчас. Спасибо.
Иона
3

Java 8, 181 157 156 байт

(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 байта благодаря @ OlivierGrégoire .

Принимает размеры в качестве дополнительных параметров R(количество строк) и C(количество столбцов).

Ячейки проверены очень похоже, как я сделал в моем ответе симулятора Fryer .

Попробуйте онлайн.

Объяснение:

(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
Кевин Круйссен
источник
2

Python 2 , 130 байт

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

Попробуйте онлайн!

Час Браун
источник
Кажется короче, если взять длину от args
l4m2
2

Powershell, 121 байт

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

Менее гольф тестовый скрипт:

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

Выход:

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 : 

Объяснение:

Сначала скрипт рассчитывает длину первой строки.

Во-вторых, это добавляет дополнительную границу к строкам. Строка дополненной реальности :

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

представляет многострочную строку:

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

Примечание 1: количество = достаточно для строки любой длины.

Примечание 2: большое количество = не влияет на поиск восьмерок.

Затем регулярное выражение (?<=[^8]{3}.{$l}[^8])8(?=[^8].{$l}[^8]{3})ищет цифру 8с предыдущими не-восьмыми (?<=[^8]{3}.{$l}[^8])и следующими не-восьмыми (?=[^8].{$l}[^8]{3}):

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

Наконец, количество совпадений возвращается в результате.

Mazzy
источник
2

Желе , 12 байт

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

Попробуйте онлайн!

Как это работает

œẹ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.
Деннис
источник
1

JavaScript (ES6), 106 байт

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

Попробуйте онлайн!


Побитовый подход, 110 байтов

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

Попробуйте онлайн!

Arnauld
источник
Побитовое сбой сбой[[7]]
l4m2
@ lm42 О, спасибо. Сейчас исправлено.
Арно
1

Clojure , 227 198 байт

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

Уч. Определенно не самый короткий здесь, во всяком случае. 54 байта скобки - убийца. Я все еще относительно доволен, хотя.

-29 байт пути создания вспомогательной функции , которая генерирует диапазон , так как я делал это дважды, меняя reduceк (count (filterустановке, и избавиться от заправочного макроса после игры в гольфе.

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

Где test-casesнаходится массив, содержащий все «тестовые примеры Python»

Попробуйте онлайн!

Carcigenicate
источник