Ci sono più oggetti duri o oggetti morbidi


19

Tangenzialmente ispirato dall'apertura al libro What-If.

L'input è un rettangolo di spazi come stringa, elenco di stringhe, ecc., Con oggetti fatti #all'interno:

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

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

Gli oggetti saranno sempre rettangoli non intersecanti, non toccanti. Un oggetto morbido è definito come un oggetto che non è riempito con quello #al centro ed è solo un bordo, un oggetto duro è uno che viene riempito. Un oggetto con larghezza o altezza <=2è considerato duro. Tutti gli oggetti sono duri o morbidi.

Se ci sono più oggetti duri nell'input, output "Hard", se più soft, output "Soft", se sono uguali, output "Equal".

Questo è , quindi vince il codice più breve in byte !

Casi test

Questi casi non sono input completi, ma piuttosto ciò che ogni oggetto dovrebbe essere caratterizzato come. L'input reale sarà come l'arte ascii nella parte superiore della domanda.

Difficile

#

####

##
##

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

morbido

###
# #
###

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

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

Casi di prova reali

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

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

Hard

###                
###                
###                

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

Equal

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


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

Soft

2
Le uscite sono rigorose o possono essere utilizzate 3 uscite non ambigue (come H / S / E o -1/0/1)?
trichoplax,

@trichoplax sono severi
Maltysen,

3
Meta risposta su ingombranti formati I / O (non per dire che non puoi fare ciò che scegli, ma solo per dare un posto affinché le persone possano esprimere un'opinione più fine se lo desiderano).
trichoplax,

@DLosc sicuramente va bene, aggiungendo.
Maltysen,

@LuisMendo no, aggiungendo.
Maltysen,

Risposte:


8

MATL , 105 104 58 50 49 byte

Grazie a @Neil per un suggerimento che mi ha permesso di rimuovere 46 byte!

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

L'input è un array di caratteri 2D, con le righe separate da ;. L'esempio nella sfida è

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

Ecco un altro esempio:

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

Questo corrisponde a

###                
###                
###                

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

e quindi dovrebbe dare 'Equal'.

Come terzo esempio, corrispondente a 'Soft',

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

questo è,

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


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

Provalo online!

Spiegazione

Questo utilizza la convoluzione 2D per rilevare le forme. L'input viene convertito in un array 2D con 1indicazione #e -1spazio; ed è riempito con una cornice di -1valori. Questo assicura che vengano rilevate anche forme ai margini del campo originale.

Un oggetto morbido viene rilevato dalla maschera

 1   1
 1  -1

che corrisponde all'angolo superiore sinistro dell'oggetto con un punto interno vuoto. Si noti che la convoluzione inverte la maschera, quindi è definita come [-1 1; 1 1]nel codice. Il numero S di posizioni in cui 4è uguale la convoluzione è il numero totale di oggetti morbidi.

Un oggetto (morbido o duro) viene rilevato dalla maschera

-1  -1
-1   1

che corrisponde all'angolo superiore sinistro dell'oggetto insieme ad alcuni punti esterni vuoti. Questa maschera è la versione negata di quella precedente, quindi il risultato della convoluzione precedente può essere riutilizzato. In particolare, il numero T di posizioni in cui quel risultato -4è uguale è il numero totale di oggetti.

Il numero H di oggetti duri è T - S . La stringa di uscita è determinato dal segno di 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
Quindi, non ho idea di cosa sia una convoluzione, ma non potresti semplicemente contare tutti gli oggetti (trovando ad esempio l'angolo in alto a sinistra) e confrontando con il doppio del numero di oggetti morbidi?
Neil,

@Neil che sembra molto promettente, grazie! In questo modo potrei ridurre da 5 a 2 convoluzioni. (Una convoluzione sta essenzialmente vedendo se un modello specifico corrisponde in una certa posizione). Ci proverò più tardi
Luis Mendo,

... o anche solo 1 convoluzione! Molte grazie! 46 byte di sconto :-) @Neil
Luis Mendo,

3
Era quasi alla pari con JS ... @Neil da che parte stai ;-)
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"

Salvato 2 byte grazie a @ edc65!

Accetta input come una stringa multilinea riempita con spazi per formare una griglia.

Spiegazione / Test

Molto vicino alla lunghezza del MATL! Fondamentalmente, cerca la linea superiore di #s di ciascun oggetto e se la lunghezza della linea superiore è inferiore a 2 o i primi 2 caratteri sotto la linea superiore sono uguali, è difficile, altrimenti morbido.

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


Sembra esserci un problema con l'input a linea singola; ###ritorna Equal.
Dennis,

@Dennis, hai ragione. Sembra che per l'input a riga singola il mio codice precedente si basasse sul bug che ho corretto. Riparato ora.
user81655

IMHO ~g.search(/$/m)è leggermente più leggibile di ~g.search`\n`||-1.
Neil,

@Neil True. C'era un bug, quindi mi sono affrettato ||-1a risolverlo, ma il tuo suggerimento mi ha fatto capire che l'aggiunta |$al regex avrebbe comunque salvato 2 byte. Grazie!
user81655

Puoi usare solo 1 countern=l=... n>l?...:n<l?...:...
edc65

4

Gelatina, 50 49 46 43 38 34 33 32 byte

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

Provalo online! o verifica tutti i casi di test .

sfondo

Ce ne sono 16 diversi schemi 2 × 2 di blocchi e spazi:

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

Di questi, poiché due oggetti non si toccheranno mai,

| #|# |
|# | #|

non si verificherà mai nell'input, lasciandoci con 14 possibili schemi.

Assegnando    un valore di 0 e #un valore di 1 , possiamo codificare un 2 × 2 modello

|ab|
|cd|

come 2 (2a + c) + (2b + d) = 4a + 2b + 2c + d , lasciando i seguenti valori per il 14 motivi.

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

Per motivi parziali 2 × 1 , 1 × 2 o 1 × 1 sul bordo inferiore e / o destro, li tratteremo come se fossero riempiti di spazi, codificandoli come 4a + 2b , 4a + 2c e 4a , rispettivamente .

In questo modo, ogni oggetto (morbido o duro) avrà esattamente un 4 modello (il suo angolo in basso a destra); ogni oggetto morbido avrà esattamente due 7 motivi (il suo angolo in basso a sinistra e il suo angolo in alto a destra).

Pertanto, sottraendo la quantità di 4 pattern dal numero di 7 pattern riscontrati nell'input si otterrà (s + h) - 2s = h - s: = d , dove h e s sono la quantità di oggetti duri e morbidi che formano.

Stampiamo duro se d> 0 , morbido se d <0 e uguale se d = 0 .

Come funziona

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

!si aspetta un array Char bidimensionale come argomento. Provalo online!

Come funziona

Questo utilizza quasi esattamente la stessa idea della mia risposta Jelly , con un miglioramento:

Invece di contare la quantità di 4 e 7 , rimuoviamo tutti gli altri numeri, quindi sottraggiamo 5,5 per mappare (4, 7) a (-1,5, 1,5) . In questo modo, il segno della somma delle differenze risultanti determina l'output corretto.


0

TSQL, 328 249 byte

Dichiarazione di variabili e dati di test:

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)

Codice:

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)

Codice sgonfiato:

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)

spiegazione:

Lo script sta eseguendo la scansione del testo per il modello:

      space
space x

Ognuno di questi è l'inizio di una scatola

Per quelle posizioni, lo script sta quindi controllando il modello, non è necessario controllare la prima x:

  x
x space 

Quando esiste, è un oggetto morbido, altrimenti è un oggetto duro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.