Có nhiều vật cứng hay vật mềm hơn không


19

Lấy cảm hứng từ việc mở đầu cho cuốn sách What-If.

Đầu vào là một hình chữ nhật của các khoảng trắng dưới dạng một chuỗi, danh sách các chuỗi, v.v., với các đối tượng được tạo từ #bên trong:

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

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

Các đối tượng sẽ luôn luôn không giao nhau, không chạm vào, hình chữ nhật. Một đối tượng mềm được định nghĩa là một đối tượng không được lấp đầy #ở giữa và chỉ là một đường viền, một đối tượng cứng là một đối tượng được lấp đầy. Một đối tượng có chiều rộng hoặc chiều cao <=2được coi là cứng. Tất cả các đối tượng là cứng hoặc mềm.

Nếu có nhiều đối tượng cứng hơn trong đầu vào, đầu ra "Hard", nếu mềm hơn, đầu ra "Soft", nếu chúng bằng nhau, đầu ra "Equal".

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng!

Các trường hợp thử nghiệm

Những trường hợp này không phải là đầu vào đầy đủ, mà là những gì mỗi đối tượng nên được đặc trưng là. Đầu vào thực tế sẽ giống như nghệ thuật ascii ở đầu câu hỏi.

Cứng

#

####

##
##

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

Mềm mại

###
# #
###

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

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

Các trường hợp thử nghiệm thực tế

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

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

Hard

###                
###                
###                

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

Equal

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


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

Soft

2
Các đầu ra có nghiêm ngặt không, hoặc có thể sử dụng bất kỳ 3 đầu ra rõ ràng nào (như H / S / E hoặc -1/0/1) không?
trichoplax

@trichoplax họ rất nghiêm ngặt
Maltysen

3
Meta answer trên các định dạng I / O cồng kềnh (không nói rằng bạn không thể làm những gì bạn chọn, mà chỉ để tạo một nơi để mọi người bày tỏ ý kiến ​​chi tiết hơn nếu họ muốn).
trichoplax

@DLosc chắc chắn là ổn, thêm vào.
Maltysen

@LuisMendo không, thêm.
Maltysen

Câu trả lời:


8

MATL , 105 104 58 50 49 byte

Cảm ơn @Neil về một đề xuất cho phép tôi xóa 46 byte!

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

Đầu vào là một mảng char 2D, với các hàng được phân tách bằng ;. Ví dụ trong thử thách là

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

Đây là một ví dụ khác:

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

Điều này tương ứng với

###                
###                
###                

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

và do đó nên cho 'Equal'.

Như một ví dụ thứ ba, tương ứng với 'Soft',

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

đó là,

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


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

Hãy thử trực tuyến!

Giải trình

Điều này sử dụng tích chập 2D để phát hiện hình dạng. Đầu vào được chuyển đổi thành một mảng 2D với 1chỉ thị #-1không gian; và được đệm với một khung các -1giá trị. Điều này đảm bảo rằng các hình dạng ở rìa của trường ban đầu cũng được phát hiện.

Một vật thể mềm được phát hiện bởi mặt nạ

 1   1
 1  -1

tương ứng với góc trên bên trái của đối tượng với một điểm bên trong trống. Lưu ý rằng tích chập đảo ngược mặt nạ, vì vậy nó được định nghĩa như [-1 1; 1 1]trong mã. Số S của các vị trí trong đó tích chập bằng 4là tổng số vật thể mềm.

Một đối tượng (mềm hoặc cứng) được phát hiện bởi mặt nạ

-1  -1
-1   1

mà xác định đến góc trên bên trái của đối tượng cùng với một số điểm bên ngoài trống rỗng. Mặt nạ này là phiên bản phủ định của mặt trước, vì vậy kết quả tích chập trước đó có thể được sử dụng lại. Cụ thể, số T của các vị trí mà kết quả đó bằng -4với tổng số đối tượng.

Số H của các đối tượng khó khăn là T - S . Chuỗi đầu ra được xác định bởi các dấu hiệu của 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

1
Vì vậy, tôi không biết thế nào là tích chập, nhưng bạn không thể đếm tất cả các đối tượng (bằng cách tìm ví dụ góc trên cùng bên trái) và so sánh với hai lần số lượng vật thể mềm?
Neil

@Neil có vẻ rất hứa hẹn, cảm ơn! Bằng cách đó tôi có thể giảm từ 5 xuống còn 2 kết quả. (Một tích chập về cơ bản là nhìn thấy nếu một mẫu cụ thể phù hợp ở một vị trí nào đó). Tôi sẽ thử sau
Luis Mendo

... Hoặc thậm chí chỉ 1 chập! Cảm ơn rất nhiều! Tắt 46 byte :-) @Neil
Luis Mendo

3
Nó gần như ngang hàng với JS ... @ Bạn đang ở bên nào ;-)
edc65

6

JavaScript (ES6), 123 121 118 byte

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"

Đã lưu 2 byte nhờ @ edc65!

Đưa đầu vào dưới dạng một chuỗi nhiều dòng được đệm bằng khoảng trắng để tạo thành lưới.

Giải thích / Kiểm tra

Rất gần với chiều dài MATL! Về cơ bản, nó tìm kiếm dòng trên cùng #của mỗi đối tượng và nếu độ dài của dòng trên cùng nhỏ hơn 2 hoặc 2 ký tự đầu tiên bên dưới dòng trên cùng là giống nhau, thì cứng, nếu không thì mềm.

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


Dường như có một vấn đề với đầu vào một dòng; ###trả lại Equal.
Dennis

@Dennis Bạn nói đúng. Có vẻ như đối với đầu vào dòng đơn, mã trước đó của tôi đã dựa vào lỗi tôi đã sửa. Đã sửa bây giờ.
dùng81655

IMHO ~g.search(/$/m)dễ đọc hơn một chút ~g.search`\n`||-1.
Neil

@Neil Đúng. Có một lỗi nên tôi đã nhanh chóng ||-1khắc phục để sửa nó, nhưng đề nghị của bạn khiến tôi nhận ra rằng việc thêm |$vào regex sẽ tiết kiệm được 2 byte. Cảm ơn!
dùng81655

Bạn có thể sử dụng chỉ 1 bộ đếmn=l=... n>l?...:n<l?...:...
edc65

4

Thạch, 50 49 46 43 38 34 33 32 byte

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

Hãy thử trực tuyến! hoặc xác minh tất cả các trường hợp thử nghiệm .

Lý lịch

16 mẫu khối và không gian 2 × 2 khác nhau :

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

Trong số này, vì hai vật sẽ không bao giờ chạm vào,

| #|# |
|# | #|

sẽ không bao giờ xảy ra trong đầu vào, để lại cho chúng ta 14 mẫu có thể.

Gán    giá trị 0#giá trị là 1 , chúng ta có thể mã hóa một 2 × 2 mẫu

|ab|
|cd|

as 2 (2a + c) + (2b + d) = 4a + 2b + 2c + d , để lại các giá trị sau cho 14 mẫu.

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

Đối với phần 2 × 1 , 1 × 2 hoặc 1 × 1 mô hình tại biên giới thấp hơn và / hoặc phải, chúng tôi sẽ đối xử với họ như thể được đệm bằng không gian, mã hóa chúng như 4a + 2b , 4a + 2c4a , tương ứng .

Bằng cách này, mỗi đối tượng (mềm hoặc cứng) sẽ có chính xác một mẫu 4 (góc dưới bên phải của nó); mỗi đối tượng mềm sẽ có chính xác hai 7 mẫu (góc dưới bên trái và góc trên bên phải của nó).

Do đó, trừ đi số lượng 4 mẫu từ số 7 mẫu gặp phải trong đầu vào sẽ mang lại (s + h) - 2s = h - s: = d , trong đó hs là số lượng vật cứng và mềm mà chúng tạo thành.

Chúng tôi in Cứng nếu d> 0 , Mềm nếu d <0Bằng nếu d = 0 .

Làm thế nào nó hoạt động

Ḥ+Ḋ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

Julia, 99 95 93 byte

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

!mong đợi một mảng Char hai chiều làm đối số. Hãy thử trực tuyến!

Làm thế nào nó hoạt động

Điều này sử dụng gần như chính xác ý tưởng tương tự như câu trả lời Jelly của tôi , với một cải tiến:

Thay vì đếm số lượng 47 , chúng tôi xóa tất cả các số khác, sau đó trừ 5,5 để ánh xạ (4, 7) thành (-1,5, 1,5) . Bằng cách này, dấu của tổng của sự khác biệt kết quả xác định đầu ra chính xác.


0

TSQL, 328 249 byte

Khai báo các biến và dữ liệu thử nghiệm:

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)

Mã số:

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)

Mã xì hơi:

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)

Giải thích:

Script đang quét văn bản cho mẫu:

      space
space x

Mỗi cái là bắt đầu của một cái hộp

Đối với các vị trí đó, tập lệnh sau đó đang kiểm tra mẫu, không cần kiểm tra lần đầu tiên x:

  x
x space 

Khi tồn tại nó là một vật thể mềm, nếu không nó là một vật thể cứng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.