Чи є більш жорсткі об'єкти або м'які об'єкти


19

Натхненно натхненний відкриттям книги «Що робити».

Вхід - це прямокутник пробілів у вигляді рядка, списку рядків тощо, з об'єктами, виготовленими з #'' s всередині:

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

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

Об'єкти завжди будуть прямокутниками, що не перетинаються, не торкаються. М'який об'єкт визначається як об'єкт, який не заповнений #'s в середині і є лише рамкою, жорсткий об'єкт - тим, що заповнюється. Предмет шириною чи висотою <=2вважається важким. Всі об'єкти або тверді, або м'які.

Якщо на вході є більше твердих об'єктів, виходять "Hard", якщо більш м'які, виводяться "Soft", якщо вони рівні, виводяться "Equal".

Це , тому найкоротший код у байтах виграє!

Випробування

Ці випадки не є повними вхідними даними, а, як слід характеризувати кожен об'єкт. Фактичний вклад буде подібний до мистецтва ascii-art у верхній частині питання.

Важко

#

####

##
##

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

М’який

###
# #
###

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

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

Фактичні випробування

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

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

Hard

###                
###                
###                

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

Equal

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


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

Soft

2
Чи чіткі результати, чи можна використовувати будь-які 3 однозначні виходи (наприклад, H / S / E або -1/0/1)?
трихоплакс

@trichoplax вони суворі
Малтісен

3
Мета-відповідь на громіздкі формати вводу-виводу (не кажучи, що ви не можете робити те, що ви вибрали, а просто дати місце людям для висловлення більш тонкої думки, якщо вони бажають).
трихоплакс

@DLosc впевнений, що це добре, додаючи.
Мальтісен

@LuisMendo немає, додаючи.
Мальтісен

Відповіді:


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
Отже, я поняття не маю, що таке згортка, але чи не могли ви просто порахувати всі об'єкти (знайшовши, наприклад, верхній лівий кут) та порівнявши вдвічі більше м'яких об’єктів?
Ніл

@Neil, що виглядає дуже перспективно, дякую! Таким чином я міг зменшити з 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")
)


Здається, є проблема з однорядним введенням; ###повертає Equal.
Денніс

@Dennis Ти маєш рацію. Здається, що для введення одного рядка мій попередній код покладався на помилку, яку я виправив. Виправлено зараз.
користувач81655

ІМХО ~g.search(/$/m)трохи читабельніший ніж ~g.search`\n`||-1.
Ніл

@Neil True. Виникла помилка, тому я поспіхом вирішив ||-1її виправити, але ваша пропозиція дала мені зрозуміти, що додавання |$в регулярний вираз врятує 2 байти. Спасибі!
користувач81655

Ви можете використовувати лише 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 - кількість твердих і м'яких предметів, які вони утворюють.

Друкуємо важко, якщо d> 0 , м'яким, якщо d <0, і рівним, якщо 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)

Пояснення:

Сценарій сканує текст на зразок:

      space
space x

Кожен із них - це початок коробки

Потім для цих позицій скрипт перевіряє шаблон, не потрібно перевіряти перший x:

  x
x space 

Коли це існує, це м'який предмет, інакше це важкий предмет.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.