Есть ли более твердые или мягкие объекты?

19

Тангенциально вдохновлен открытием книги «Что если».

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

########          
#      #          
########          

   ###        ####
   ###        ####
   ###             

Объекты всегда будут непересекающимися, не соприкасающимися прямоугольниками. Мягкий объект определяется как объект, который не заполнен #символами в середине и является только границей, а жесткий объект - это объект, который заполнен. Объект с шириной или высотой <=2считается сложным. Все объекты жесткие или мягкие.

Если на входе больше твердых объектов, выведите "Hard", если более мягкий, выведите "Soft", если они равны, выведите "Equal".

Это , поэтому выигрывает самый короткий код в байтах !

Тестовые случаи

Эти случаи - не полные входные данные, а то, как должен характеризоваться каждый объект. Фактический вклад будет похож на ascii-art в верхней части вопроса.

Жесткий

#

####

##
##

##########
##########
##########

Мягкий

###
# #
###

###################
#                 #
#                 #
#                 #
###################

####
#  #
#  #
#  #
#  #
#  #
#  #
#  #
####

Актуальные тестовые случаи

########          
#      #          
########          

   ###        ####
   ###        ####
   ###             

Hard

###                
###                
###                

###################
#                 #
#                 #
#                 #
###################

Equal

   ######    
   #    #    
   ######    
          ###
   ##  #  # #
          ###


 ########    
 #      #    
 ########  

Soft
Maltysen
источник
2
Являются ли выходы строгими или могут быть использованы любые 3 однозначных выхода (например, H / S / E или -1/0/1)?
Трихоплакс
@trichoplax они строгие
Малтысен
3
Мета-ответ на громоздкие форматы ввода / вывода (не говоря уже о том, что вы не можете делать то, что выбираете, а просто дать людям возможность выразить более детальное мнение, если они того пожелают).
trichoplax
@DLosc уверен, что все в порядке, добавив.
Maltysen
@ LuisMendo нет, добавление.
Maltysen

Ответы:

8

MATL , 105 104 58 50 49 байтов

Спасибо @Neil за предложение, которое позволило мне удалить 46 байт!

2\TTYaEq4:HeqgEqZ+K/Zot0>+ss'Soft Hard Equal'Ybw)

Ввод - это двумерный массив символов, разделенный строками ;. Пример в вызове

['########          ';'#      #          ';'########          ';'                  ';'   ###        ####';'   ###        ####';'   ###            ']

Вот еще один пример:

['###                ';'###                ';'###                ';'                   ';'###################';'#                 #';'#                 #';'#                 #';'###################']

Это соответствует

###                
###                
###                

###################
#                 #
#                 #
#                 #
###################

и таким образом должен дать 'Equal'.

В качестве третьего примера, что соответствует 'Soft',

['   ######    ';'   #    #    ';'   ######    ';'          ###';'   ##  #  # #';'          ###';'             ';'             ';' ########    ';' #      #    ';' ########    ']

то есть,

   ######    
   #    #    
   ######    
          ###
   ##  #  # #
          ###


 ########    
 #      #    
 ########  

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

объяснение

Это использует 2D свертку для обнаружения фигур. Входные данные преобразуются в двумерный массив с 1указанием #и -1для пробела; и дополнен рамкой -1значений. Это гарантирует, что формы на краю исходного поля также обнаружены.

Мягкий объект обнаружен с помощью маски

 1   1
 1  -1

который соответствует верхнему левому углу объекта с одной пустой внутренней точкой. Обратите внимание, что свертка инвертирует маску, поэтому она определяется как [-1 1; 1 1]в коде. Число S позиций, в которых равна свертка, 4является общим числом мягких объектов.

Объект (мягкий или жесткий) детектируют с помощью маски

-1  -1
-1   1

который соответствует верхнему левому углу объекта вместе с некоторыми пустыми внешними точками. Эта маска является отрицательной версией предыдущей, поэтому результат предыдущей свертки можно использовать повторно. В частности, количество позиций T, в которых этот результат равен, -4является общим количеством объектов.

Число Н твердых объектов Т - S . Строка вывода определяется знаком S - Н = 2 * S - Т .

2\                 % Input. Modulo 2: '#' gives 1, ' ' gives 0
TTYa               % Add a frame of zeros
Eq                 % Convert 0 to -1
4:HeqgEq           % Generate mask [-1 1; 1 1], for soft objects
Z+                 % 2D convolution, preserving size
K/Zo               % Divide by 4 and round towards 0. Gives 1 or -1 for 4 or -4
t0>                % Duplicate. 1 for positive entries (soft objects), 0 otherwise
+                  % Add. This corresponds to the factor 2 that multiplies number S
ss                 % Sum of 2D array. Gives 2*S-T
'Soft Hard Equal'  % Push this string
Yb                 % Split by spaces. Gives cell array
w)                 % Swap. Apply (modular) index to select one string
Луис Мендо
источник
1
Итак, я понятия не имею, что такое свертка, но не могли бы вы просто посчитать все объекты (найдя, например, верхний левый угол) и сравнить с двойным числом мягких объектов?
Нил
@ Нейл, это выглядит очень многообещающе, спасибо! Таким образом, я мог бы уменьшить с 5 до 2 извилин. (Свертка, по сути, видит, соответствует ли конкретный шаблон в некоторой позиции). Я попробую это позже
Луис Мендо
... или даже просто 1 свертка! Большое спасибо! 46 байт :-) @Neil
Луис Мендо,
3
Это было почти наравне с JS ... @Neil, на чьей ты стороне ;-)
edc65
6

JavaScript (ES6), 123 121 118 байт

s=>s.replace(/#+/g,(m,i)=>s[i+l]>" "?0:n+=!m[1]|s[i-l+1]==s[i-l]||-1,n=l=~s.search`
|$`)|n>l?"Hard":n<l?"Soft":"Equal"

Сохранено 2 байта благодаря @ edc65!

Принимает ввод в виде многострочной строки, дополненной пробелами для формирования сетки.

Объяснение / Тест

Очень близко к длине MATL! По сути, он ищет верхнюю строку #s каждого объекта, и если длина верхней строки меньше 2 или первые 2 символа под верхней строкой одинаковы, это сложно, в противном случае - мягкий.

var solution =

s=>
  s.replace(/#+/g,(m,i)=>        // for each run of consecutive # characters
    s[i+l]>" "?                  // if the position above the match contains a #
      0                          // do nothing (this object has already been counted)
    :n+=                         // add 1 to the counter (hard) if
      !m[1]                      // the match is only 1 # wide
      |s[i-l+1]==s[i-l]          // or the characters below are the same
      ||-1,                      // else decrement the counter (soft)
    n=                           // n = counter, hard objects increase n, soft decrease
    l=~s.search`\n|$`            // l = (negative) line length
  )
  |n>l?"Hard":n<l?"Soft":"Equal" // return the result string

// Test
document.write("<pre>" + [`

########          
#      #          
########          
                  
   ###        ####
   ###        ####
   ###            

`,`

###                
###                
###                
                   
###################
#                 #
#                 #
#                 #
###################

`,`

   ######    
   #    #    
   ######    
          ###
   ##  #  # #
          ###
             
             
 ########    
 #      #    
 ########    

`,`

########          
#      #          
########          
                  
   ###        ####
   # #        ####
   ###            

`,`

########          
#      #          
########          
                  
   ###  ###   ####
   ###  # #   ####
   ###  ###       

`,`

#

`,`

##

`,`

#
#

`,`

###
# #
###

`].map((test) => solution(test.slice(2, -2))).join("\n")
)

user81655
источник
Кажется, есть проблема с однострочным вводом; ###возвращается Equal.
Деннис
@ Денис Ты прав. Кажется, что для однострочного ввода мой предыдущий код основывался на исправленной мной ошибке. Исправлено сейчас.
user81655
ИМХО ~g.search(/$/m)чуть более читабельно, чем ~g.search`\n`||-1.
Нил
@ Нейл Правда. Была ошибка, поэтому я поспешно попытался ||-1ее исправить, но ваше предложение заставило меня понять, что добавление |$к регулярному выражению в любом случае сэкономит 2 байта. Благодарность!
user81655
Вы можете использовать только 1 счетчикn=l=... n>l?...:n<l?...:...
edc65
4

Желе, 50 49 46 43 38 34 33 32 байта

Ḥ+ḊZ
>⁶ÇÇFµċ7_ċ4$Ṡị“¤Ỵf“¢*ɦ“¡⁺ƒ»

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

Фон

Есть 16 различных 2 × 2 шаблонов блоков и пробелов:

|  |  |  | #|  | #| #|# | #|# |# |##|# |##|##|##|
|  | #|# |  |##| #|# |  |##| #|# |  |##| #|# |##|

Из них, поскольку два объекта никогда не будут касаться,

| #|# |
|# | #|

никогда не произойдет на входе, оставляя нам с 14 возможных моделей.

Присваивая    значение 0 и #значение 1 , мы можем кодировать шаблон 2 × 2

|ab|
|cd|

как 2 (2a + c) + (2b + d) = 4a + 2b + 2c + d , оставляя следующие значения для 14 шаблонов.

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

Для частичных шаблонов 2 × 1 , 1 × 2 или 1 × 1 на нижней и / или правой границе мы будем обрабатывать их, как если бы они были заполнены пробелами, кодируя их как 4a + 2b , 4a + 2c и 4a соответственно ,

Таким образом, каждый объект (мягкий или жесткий) будет иметь ровно один шаблон 4 (его правый нижний угол); каждый мягкий объект будет иметь ровно два 7 рисунка (его левый нижний и правый верхний угол).

Таким образом, вычитая количество 4 шаблонов из числа 7 шаблонов, обнаруженных во входных данных, получим (s + h) - 2s = h - s: = d , где h и s - количество твердых и мягких объектов, которые они образуют.

Мы печатаем Hard, если d> 0 , Soft, если d <0, и Equal, если d = 0 .

Как это устроено

Ḥ+ḊZ                         Helper link. Input: M (n×m matrix)

Ḥ                            Unhalve; multiply all entries of M by 2.
  Ḋ                          Dequeue; remove the first row of M.
 +                           Perform vectorized addition.
                             This returns 2 * M[i] + M[i + 1] for each row M[i].
                             Since the M[n] is unpaired, + will not affect it,
                             as if M[n + 1] were a zero vector.
   Z                         Zip; transpose rows with columns.


>⁶ÇÇFµċ7_ċ4$Ṡị“¤Ỵf“¢*ɦ“¡⁺ƒ»  Main link. Input: G (character grid)

>⁶                           Compare each character with ' ', yielding 1 for '#'
                             and 0 for ' '.
  Ç                          Call the helper link.
                             This will compute (2a + c) for each pattern, which is
                             equal to (2b + d) for the pattern to its left.
   Ç                         This yields 2(2a + c) + (2b + d) for each pattern.
    F                        Flatten; collect all encoded patterns in a flat list.

     µ                       Begin a new, monadic link. Argument: A (list)
      ċ7                     Count the amount of 7's.
         ċ4$                 Count the amount of 4's.
        _                    Subtract the latter from the former.
            Ṡ                Yield the sign (1, -1 or 0) of the difference.
              “¤Ỵf“¢*ɦ“¡⁺ƒ»  Yield ['Hard', 'Soft', Equal'] by indexing into a
                             built-in dictionary.
             ị               Retrieve the string at the corresponding index.
Деннис
источник
1

Юлия, 99 95 93 байта

~=t->2t'+[t[2:end,:];0t[1,:]]'
!x=("Hard","Equal","Soft")[sign(~~(x.>32)∩(4,7)-5.5|>sum)+2]

!ожидает двухмерный массив Char в качестве аргумента. Попробуйте онлайн!

Как это устроено

Это использует почти ту же идею, что и мой ответ Jelly , с одним улучшением:

Вместо того, чтобы считать количество 4 и 7 , мы удаляем все остальные числа, затем вычитаем 5,5, чтобы отобразить (4, 7) в (-1,5, 1,5) . Таким образом, знак суммы полученных разностей определяет правильный результат.

Деннис
источник
0

TSQL, 328 249 байт

Объявление переменных и тестовых данных:

DECLARE @l int = 20
DECLARE @ varchar(max)=''
SELECT @+=LEFT(x + replicate(' ', @l), @l)
FROM (values
(' xxxx'),
(' xxxx'),
(' xxxx'),
('x'),
(''),
('xxx'),
('x x  xxx'),
('xxx  x x'),
('     xxx    ')) x(x)

Код:

SELECT substring('Soft EqualHard',sign(sum(iif(substring(@,N,@l+2)like'xx'+replicate('_', @l-2)+'x ',-1,1)))*5+6,5)FROM(SELECT row_number()OVER(ORDER BY Type)N FROM sys.all_objects)x WHERE n<=len(@)AND' x'=substring(@,N-1,2)AND''=substring(@,N-@l,1)

Код дефлирован:

SELECT
  substring('Soft EqualHard',
    sign(sum(iif(substring(@,N,@l+2)like'xx'+replicate('_', @l-2)+'x ',-1,1)))*5+6,5)
FROM(SELECT row_number()OVER(ORDER BY Type)N FROM sys.all_objects)x
WHERE n<=len(@)AND' x'=substring(@,N-1,2)AND''=substring(@,N-@l,1)

Explaination:

Скрипт сканирует текст по шаблону:

      space
space x

Каждый из них является началом коробки

Для этих позиций скрипт затем проверяет шаблон, не нужно проверять сначала x:

  x
x space 

Когда это существует, это мягкий объект, в противном случае это жесткий объект.

t-clausen.dk
источник