Czy jest więcej twardych przedmiotów lub miękkich przedmiotów?

19

Stycznie zainspirowany otwarciem książki What-If.

Dane wejściowe to prostokąt spacji jako ciąg znaków, lista ciągów znaków itp., W których znajdują się obiekty #:

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

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

Obiekty zawsze będą się nie przecinały, nie dotykały prostokątów. Miękki obiekt jest zdefiniowany jako obiekt, który nie jest wypełniony #s na środku i jest tylko ramką, twardy obiekt to taki, który jest wypełniony. Obiekt o szerokości lub wysokości <=2jest uważany za twardy. Wszystkie przedmioty są twarde lub miękkie.

Jeśli na wejściu znajduje się więcej twardych obiektów, wyjście "Hard", jeśli jest bardziej miękkie, wyjście "Soft", jeśli są równe, wyjście "Equal".

To jest , więc wygrywa najkrótszy kod w bajtach !

Przypadki testowe

Te przypadki nie są pełnymi danymi wejściowymi, ale raczej tym, jak każdy obiekt powinien być scharakteryzowany. Rzeczywisty wkład będzie jak ascii-art na górze pytania.

Ciężko

#

####

##
##

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

Miękki

###
# #
###

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

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

Rzeczywiste przypadki testowe

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

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

Hard

###                
###                
###                

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

Equal

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


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

Soft
Maltysen
źródło
2
Czy wyjścia są surowe, czy można zastosować 3 jednoznaczne wyjścia (takie jak H / S / E lub -1/0/1)?
trichoplax
@trichoplax są surowe
Maltysen 18.04.16
3
Meta odpowiedź na kłopotliwe formaty I / O (nie mówiąc, że nie możesz robić tego, co wybierzesz, ale po to, aby dać ludziom miejsce do wyrażenia bardziej szczegółowej opinii, jeśli chcą).
trichoplax
@DLosc na pewno w porządku, dodając.
Maltysen 18.04.16
@LuisMendo nie, dodawanie.
Maltysen,

Odpowiedzi:

8

MATL , 105 104 58 50 49 bajtów

Dzięki @Neil za sugestię, która pozwoliła mi usunąć 46 bajtów!

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

Dane wejściowe to tablica znaków 2D z wierszami oddzielonymi ;. Przykładem wyzwania jest

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

Oto inny przykład:

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

To odpowiada

###                
###                
###                

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

i dlatego powinien dać 'Equal'.

W trzecim przykładzie, odpowiadające 'Soft',

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

to jest,

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


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

Wypróbuj online!

Wyjaśnienie

Wykorzystuje splot 2D do wykrywania kształtów. Dane wejściowe są konwertowane na tablicę 2D ze 1wskazaniem #i -1dla przestrzeni; i jest wypełniony ramką -1wartości. Zapewnia to wykrycie kształtów na krawędzi pierwotnego pola.

Miękki przedmiot jest wykryty przez maskę

 1   1
 1  -1

co odpowiada lewemu górnemu narożnikowi obiektu z jednym pustym punktem wewnętrznym. Zauważ, że splot odwraca maskę, więc jest zdefiniowany jak [-1 1; 1 1]w kodzie. Liczba S pozycji, w których splot 4jest równy, jest całkowitą liczbą miękkich obiektów.

Obiekt (miękkie lub twarde) zostanie wykryty przez maskę

-1  -1
-1   1

który odpowiada lewy górny róg obiektu wraz z pewnymi pustymi punktami zewnętrznymi. Ta maska ​​jest zaprzeczoną wersją poprzedniej, więc poprzedni wynik splotu można ponownie wykorzystać. W szczególności liczba T pozycji, w których wynik ten -4jest równy, to całkowita liczba obiektów.

Liczba H twardych przedmiotów jest T - S . Ciąg wyjściowy określa znak S - H = 2 * S - T .

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
Luis Mendo
źródło
1
Więc nie mam pojęcia, co to jest splot, ale czy nie mógłbyś po prostu policzyć wszystkich obiektów (znajdując np. Lewy górny róg) i porównać z podwójną liczbą miękkich obiektów?
Neil,
@ Neil, który wygląda bardzo obiecująco, dzięki! W ten sposób mogłem zmniejszyć z 5 do 2 zwojów. (Splot polega zasadniczo na sprawdzeniu, czy określony wzór pasuje do określonej pozycji). Spróbuję później
Luis Mendo,
... lub nawet tylko 1 splot! Wielkie dzięki! 46 bajtów off :-) @Neil
Luis Mendo
3
To było prawie na równi z JS ... @Neil, po której jesteś stronie ;-)
edc65
6

JavaScript (ES6), 123 121 118 bajtów

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"

Zaoszczędzono 2 bajty dzięki @ edc65!

Pobiera dane wejściowe jako ciąg wielowierszowy wypełniony spacjami, aby utworzyć siatkę.

Wyjaśnienie / test

Bardzo blisko długości MATL! Zasadniczo szuka górnej linii #s każdego obiektu, a jeśli długość górnej linii jest mniejsza niż 2 lub pierwsze 2 znaki poniżej górnej linii są takie same, jest to trudne, w przeciwnym razie miękkie.

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

użytkownik 81655
źródło
Wydaje się, że występuje problem z wprowadzaniem jednowierszowym; ###zwraca Equal.
Dennis
@Dennis Masz rację. Wygląda na to, że w przypadku wprowadzania w jednym wierszu mój poprzedni kod polegał na naprawionym przeze mnie błędzie. Naprawiono teraz.
user81655 19.04.16
IMHO ~g.search(/$/m)jest nieco bardziej czytelny niż ~g.search`\n`||-1.
Neil,
@Neil True. Wystąpił błąd, więc pospiesznie ||-1postanowiłem go naprawić, ale twoja sugestia uświadomiła mi, że dodanie |$wyrażenia regularnego pozwoli zaoszczędzić 2 bajty. Dzięki!
user81655 19.04.2016
Możesz użyć tylko 1 countern=l=... n>l?...:n<l?...:...
edc65 19.04.16
4

Galaretka, 50 49 46 43 38 34 33 32 bajty

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

Wypróbuj online! lub zweryfikuj wszystkie przypadki testowe .

tło

Istnieje 16 różnych wzorów bloków i spacji 2 × 2 :

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

Spośród nich, ponieważ dwa przedmioty nigdy się nie dotykają,

| #|# |
|# | #|

nigdy nie pojawi się na wejściu, pozostawiając nam 14 możliwych wzorców.

Przypisanie    wartości 0 , a #wartość 1 , można kodować 2 x 2 wzór

|ab|
|cd|

jako 2 (2a + c) + (2b + d) = 4a + 2b + 2c + d , pozostawiając następujące wartości dla 14 wzorów.

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

Częściowych 2 x 1 , 1 x 2 i 1 x 1 wzorców na dolnej i / lub prawej krawędzi, to je traktować tak, jakby były spacjami kodujących je jako 4a + 2b , 4a + 2c i 4a , odpowiednio .

W ten sposób każdy obiekt (miękki lub twardy) będzie miał dokładnie jeden wzór 4 (jego prawy dolny róg); każdy miękki obiekt będzie miał dokładnie dwa 7 wzorów (jego lewy dolny i prawy górny róg).

Zatem odjęcie liczby 4 wzorów od liczby 7 wzorów napotkanych na wejściu da (s + h) - 2s = h - s: = d , gdzie h i s to ilość twardych i miękkich obiektów, które tworzą.

Drukujemy Hard, jeśli d> 0 , Soft jeśli d <0 i Equal, jeśli d = 0 .

Jak to działa

Ḥ+Ḋ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.
Dennis
źródło
1

Julia, 99 95 93 bajtów

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

!oczekuje dwuwymiarowej tablicy Char jako argumentu. Wypróbuj online!

Jak to działa

To używa prawie dokładnie tego samego pomysłu, co moja odpowiedź Jelly , z jedną poprawką:

Zamiast zliczać liczby 4 i 7 , usuwamy wszystkie inne liczby, a następnie odejmujemy 5,5, aby mapować (4, 7) na (-1,5, 1,5) . W ten sposób znak sumy różnic wynikowych określa prawidłowy wynik.

Dennis
źródło
0

TSQL, 328 249 bajtów

Deklarowanie zmiennych i danych testowych:

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)

Kod:

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)

Deflowany kod:

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)

Wyjaśnienie:

Skrypt skanuje tekst w poszukiwaniu wzorca:

      space
space x

Każdy z nich jest początkiem pudełka

W przypadku tych pozycji skrypt sprawdza następnie wzorzec, nie trzeba sprawdzać pierwszego x:

  x
x space 

Gdy istnieje, jest to obiekt miękki, w przeciwnym razie jest to obiekt twardy.

t-clausen.dk
źródło