Apakah Ada Lebih Banyak Objek Keras atau Objek Lunak


19

Terinspirasi oleh pembukaan oleh buku What-If.

Input adalah persegi panjang spasi sebagai string, daftar string, dll., Dengan objek yang terbuat dari #dalamnya:

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

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

Objek akan selalu non-berpotongan, tidak menyentuh, persegi panjang. Objek lunak didefinisikan sebagai objek yang tidak diisi dengan #'s di tengah dan hanya perbatasan, objek keras adalah yang diisi. Objek dengan lebar atau tinggi <=2dianggap keras. Semua benda itu keras atau lunak.

Jika ada lebih banyak objek keras di input, output "Hard", jika lebih lunak, output "Soft", jika mereka sama, output "Equal".

Ini adalah , jadi kode terpendek dalam byte menang!

Uji Kasus

Kasing-kasing ini bukan input penuh, melainkan apa yang harus dicirikan oleh setiap objek. Masukan yang sebenarnya akan seperti ascii-art di bagian atas pertanyaan.

Keras

#

####

##
##

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

Lembut

###
# #
###

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

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

Kasus Uji Aktual

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

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

Hard

###                
###                
###                

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

Equal

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


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

Soft

2
Apakah outputnya ketat, atau bisakah 3 output yang ambigu digunakan (seperti H / S / E atau -1/0/1)?
trichoplax

@trichoplax mereka ketat
Maltysen

3
Meta menjawab pada format I / O yang rumit (bukan untuk mengatakan Anda tidak dapat melakukan apa yang Anda pilih, tetapi hanya untuk memberikan tempat bagi orang-orang untuk mengekspresikan pendapat yang lebih halus jika mereka mau).
trichoplax

@Dosc yakin tidak apa-apa, menambahkan.
Maltysen

@LuisMendo no, menambahkan.
Maltysen

Jawaban:


8

MATL , 105 104 58 50 49 byte

Terima kasih kepada @Neil untuk saran yang memungkinkan saya menghapus 46 byte!

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

Input adalah array char 2D, dengan baris dipisahkan oleh ;. Contoh dalam tantangannya adalah

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

Ini contoh lain:

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

Ini sesuai dengan

###                
###                
###                

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

dan karenanya harus memberi 'Equal'.

Sebagai contoh ketiga, terkait dengan 'Soft',

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

itu adalah,

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


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

Cobalah online!

Penjelasan

Ini menggunakan konvolusi 2D untuk mendeteksi bentuk. Input dikonversi ke array 2D dengan 1menunjukkan #dan -1untuk ruang; dan diisi dengan bingkai -1nilai. Ini memastikan bahwa bentuk-bentuk di tepi bidang asli juga terdeteksi.

Sebuah objek yang lembut terdeteksi oleh topeng

 1   1
 1  -1

yang sesuai dengan sudut kiri atas objek dengan satu titik interior kosong. Perhatikan bahwa konvolusi membalikkan mask, sehingga didefinisikan seperti [-1 1; 1 1]dalam kode. Jumlah S dari posisi di mana konvolusi sama dengan 4adalah jumlah total objek lunak.

Sebuah objek (lunak atau keras) terdeteksi oleh topeng

-1  -1
-1   1

yang sesuai dengan sudut kiri atas objek bersama-sama dengan beberapa titik eksterior kosong. Topeng ini adalah versi yang dinegasikan dari yang sebelumnya, sehingga hasil konvolusi sebelumnya dapat digunakan kembali. Secara khusus, jumlah T dari posisi di mana hasil yang sama dengan itu -4adalah jumlah total objek.

Jumlah H dari benda keras adalah T - S . Output string ditentukan oleh tanda 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
Jadi, saya tidak tahu apa konvolusi itu, tetapi tidak bisakah Anda menghitung semua benda (dengan menemukan misalnya sudut kiri atas) dan membandingkan dengan dua kali jumlah objek lunak?
Neil

@ Neil yang terlihat sangat menjanjikan, terima kasih! Dengan begitu saya bisa mengurangi 5 hingga 2 konvolusi. (Konvolusi pada dasarnya melihat apakah pola tertentu cocok pada beberapa posisi). Saya akan mencobanya nanti
Luis Mendo

... atau bahkan hanya 1 belitan! Terima kasih banyak! Diskon 46 byte :-) @Neil
Luis Mendo

3
Itu hampir setara dengan JS ... @Neil sisi mana Anda berada ;-)
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"

Disimpan 2 byte berkat @ edc65!

Mengambil input sebagai string multiline yang diisi dengan spasi untuk membentuk kisi.

Penjelasan / Tes

Sangat dekat dengan panjang MATL! Pada dasarnya, ia mencari garis atas #s dari setiap objek, dan jika panjang garis atas kurang dari 2 atau 2 karakter pertama di bawah garis atas adalah sama, itu sulit, jika tidak lembut.

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


Tampaknya ada masalah dengan input baris tunggal; ###kembali Equal.
Dennis

@ Dennis Kamu benar. Tampaknya untuk input satu baris kode saya sebelumnya mengandalkan bug yang saya perbaiki. Diperbaiki sekarang
user81655

IMHO ~g.search(/$/m)sedikit lebih mudah dibaca daripada ~g.search`\n`||-1.
Neil

@Neil Benar. Ada bug jadi saya buru-buru ||-1memasang untuk memperbaikinya, tetapi saran Anda membuat saya menyadari bahwa menambahkan |$ke regex akan menghemat 2 byte. Terima kasih!
user81655

Anda bisa menggunakan hanya 1 countern=l=... n>l?...:n<l?...:...
edc65

4

Jelly, 50 49 46 43 38 34 33 32 byte

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

Cobalah online! atau verifikasi semua kasus uji .

Latar Belakang

Ada 16 pola blok dan spasi 2 × 2 yang berbeda :

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

Dari jumlah tersebut, karena dua benda tidak akan pernah menyentuh,

| #|# |
|# | #|

tidak akan pernah terjadi pada input, meninggalkan kita dengan 14 pola yang mungkin.

Menetapkan    nilai 0 dan #nilai 1 , kita dapat mengkodekan 2 × 2 pola

|ab|
|cd|

sebagai 2 (2a + c) + (2b + d) = 4a + 2b + 2c + d , meninggalkan nilai berikut untuk 14 pola.

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

Untuk pola parsial 2 × 1 , 1 × 2 atau 1 × 1 di batas bawah dan / atau kanan, kami akan memperlakukannya seolah-olah diisi dengan spasi, masing-masing dikodekan sebagai 4a + 2b , 4a + 2c dan 4a . .

Dengan cara ini, setiap objek (lunak atau keras) akan memiliki tepat satu 4 pola (sudut kanan bawahnya); setiap objek lunak akan memiliki tepat dua pola 7 (kiri bawah dan sudut kanan atas).

Jadi, mengurangkan jumlah 4 pola dari jumlah 7 pola yang ditemui dalam input akan menghasilkan (s + h) - 2s = h - s: = d , di mana h dan s adalah jumlah benda keras dan lunak yang mereka bentuk.

Kami mencetak Hard jika d> 0 , Soft jika d <0 dan Equal jika d = 0 .

Bagaimana itu bekerja

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

!mengharapkan array Char dua dimensi sebagai argumen. Cobalah online!

Bagaimana itu bekerja

Ini menggunakan ide yang hampir sama persis dengan jawaban Jelly saya , dengan satu peningkatan:

Alih-alih menghitung jumlah 4 dan 7 , kami menghapus semua angka lainnya, lalu kurangi 5,5 untuk memetakan (4, 7) menjadi (-1,5, 1,5) . Dengan cara ini, tanda jumlah perbedaan yang dihasilkan menentukan keluaran yang benar.


0

TSQL, 328 249 byte

Mendeklarasikan variabel dan data uji:

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)

Kode:

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)

Kode kempes:

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)

Penjelasan:

Script memindai teks untuk polanya:

      space
space x

Masing-masing adalah awal dari sebuah kotak

Untuk posisi itu, skrip kemudian memeriksa polanya, tidak perlu memeriksa x pertama:

  x
x space 

Ketika yang ada itu adalah objek yang lunak, kalau tidak itu adalah objek yang keras.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.