Gibt es mehr harte oder weiche Objekte?

19

Tangential inspiriert von der Eröffnung des What-If-Buches.

Die Eingabe ist ein Rechteck aus Leerzeichen als Zeichenfolge, Liste der Zeichenfolge usw. mit Objekten, die aus #den folgenden Elementen bestehen:

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

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

Die Objekte sind immer sich nicht überschneidende, sich nicht berührende Rechtecke. Ein weiches Objekt ist definiert als ein Objekt, das nicht mit #'s in der Mitte gefüllt ist und nur einen Rand darstellt. Ein hartes Objekt ist ein Objekt, das gefüllt ist. Ein Objekt mit Breite oder Höhe <=2wird als hart angesehen. Alle Objekte sind entweder hart oder weich.

Befinden sich mehr harte Objekte in der Eingabe, werden sie ausgegeben "Hard", wenn sie weicher sind "Soft", werden sie ausgegeben , wenn sie gleich sind "Equal".

Das ist , also gewinnt der kürzeste Code in Bytes !

Testfälle

Diese Fälle sind keine vollständigen Eingaben, sondern vielmehr das, als was jedes Objekt charakterisiert werden sollte. Der eigentliche Input wird wie die ASCII-Kunst am Anfang der Frage sein.

Hart

#

####

##
##

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

Weich

###
# #
###

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

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

Aktuelle Testfälle

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

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

Hard

###                
###                
###                

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

Equal

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


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

Soft
Maltysen
quelle
2
Sind die Ausgänge streng oder können 3 eindeutige Ausgänge verwendet werden (z. B. H / S / E oder -1/0/1)?
Trichoplax
@ Trichoplax sie sind streng
Maltysen
3
Meta-Antwort zu umständlichen E / A-Formaten (um nicht zu sagen, dass Sie nicht das tun können, was Sie wählen, sondern nur, um Leuten einen Ort zu geben, an dem sie eine feinkörnigere Meinung äußern können, wenn sie dies wünschen).
Trichoplax
@ DLosc sicher, das ist in Ordnung, Hinzufügen.
Maltysen
@ LuisMendo nein, Hinzufügen.
Maltysen

Antworten:

8

MATL , 105 104 58 50 49 Bytes

Vielen Dank an @Neil für einen Vorschlag, mit dem ich 46 Bytes entfernen konnte!

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

Die Eingabe ist ein 2D-Zeichen-Array mit durch getrennten Zeilen ;. Das Beispiel in der Herausforderung ist

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

Hier ist ein weiteres Beispiel:

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

Das entspricht

###                
###                
###                

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

und sollte so geben 'Equal'.

Als drittes Beispiel, entsprechend 'Soft',

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

das ist,

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


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

Probieren Sie es online!

Erläuterung

Dies verwendet 2D-Faltung, um Formen zu erkennen. Die Eingabe wird in ein 2D-Array mit 1Angabe #und -1für Leerzeichen konvertiert . und ist mit einem Rahmen von -1Werten aufgefüllt . Dies stellt sicher, dass auch Formen am Rand des ursprünglichen Feldes erkannt werden.

Ein weiches Objekt wird von der Maske erkannt

 1   1
 1  -1

Dies entspricht der linken oberen Ecke des Objekts mit einem leeren Innenpunkt. Beachten Sie, dass die Faltung die Maske invertiert, sodass sie wie [-1 1; 1 1]im Code definiert ist. Die Anzahl S der Positionen, an denen die Faltung gleich 4ist, ist die Gesamtzahl der weichen Objekte.

Ein Objekt (weich oder hart) wird von der Maske erkannt

-1  -1
-1   1

Dies entspricht der oberen linken Ecke des Objekts zusammen mit einigen leeren äußeren Punkten. Diese Maske ist die negierte Version der vorherigen, sodass das vorherige Faltungsergebnis wiederverwendet werden kann. Insbesondere ist die Anzahl T von Positionen, an denen dieses Ergebnis gleich -4ist, die Gesamtzahl von Objekten.

Die Anzahl H der harten Gegenstände ist T - S . Die Ausgabezeichenfolge wird durch das Vorzeichen der ermittelten 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
quelle
1
Ich habe also keine Ahnung, was eine Faltung ist, aber können Sie nicht einfach alle Objekte zählen (indem Sie z. B. die obere linke Ecke finden) und mit der doppelten Anzahl weicher Objekte vergleichen?
Neil
@Neil das sieht sehr vielversprechend aus, danke! Auf diese Weise konnte ich von 5 auf 2 Windungen reduzieren. (Bei einer Faltung wird im Wesentlichen geprüft, ob ein bestimmtes Muster an einer bestimmten Position übereinstimmt.) Ich werde es später versuchen
Luis Mendo
... oder auch nur 1 Faltung! Vielen Dank! 46 Bytes frei :-) @Neil
Luis Mendo
3
Es war fast auf Augenhöhe mit JS ... @Neil auf welcher Seite bist du
;-)
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"

2 Bytes gespart dank @ edc65!

Nimmt Eingaben als mehrzeilige Zeichenfolge auf, die mit Leerzeichen aufgefüllt ist, um ein Raster zu bilden.

Erklärung / Test

Ganz in der Nähe von MATL Länge! Grundsätzlich wird nach der obersten Zeile von #s jedes Objekts gesucht, und wenn die Länge der obersten Zeile kleiner als 2 ist oder die ersten 2 Zeichen unter der obersten Zeile gleich sind, ist es hart, ansonsten weich.

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

user81655
quelle
Es scheint ein Problem mit der Einzeileneingabe zu geben. ###kehrt zurück Equal.
Dennis
@ Tennis Du hast recht. Es scheint, dass sich mein vorheriger Code bei der Eingabe einer einzelnen Zeile auf den Fehler stützte, den ich behoben hatte. Jetzt behoben.
User81655
IMHO ~g.search(/$/m)ist etwas lesbarer als ~g.search`\n`||-1.
Neil
@ Neil True. Es gab einen Fehler, den ich hastig behoben ||-1habe, aber Ihr Vorschlag hat mir klar gemacht, dass das Hinzufügen |$zum regulären Ausdruck trotzdem 2 Bytes einspart. Vielen Dank!
user81655
Sie könnten nur 1 Zähler verwendenn=l=... n>l?...:n<l?...:...
edc65
4

Jelly, 50 49 46 43 38 34 33 32 Bytes

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

Probieren Sie es online! oder überprüfen Sie alle Testfälle .

Hintergrund

Es gibt 16 verschiedene 2 × 2- Muster von Blöcken und Zwischenräumen:

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

Von diesen, da zwei Objekte nie berühren werden,

| #|# |
|# | #|

wird nie in der Eingabe auftreten und uns mit 14 möglichen Mustern verlassen.

Wenn Sie    einen Wert von 0 und #einen Wert von 1 zuweisen, können Sie ein 2 × 2- Muster codieren

|ab|
|cd|

als 2 (2a + c) + (2b + d) = 4a + 2b + 2c + d , wobei die folgenden Werte für die 14 Muster belassen werden.

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

Für partielle 2 × 1 , 1 × 2 oder 1 × 1- Muster am unteren und / oder rechten Rand werden sie so behandelt, als ob sie mit Leerzeichen aufgefüllt wären, und als 4a + 2b , 4a + 2c und codiert 4a , jeweils .

Auf diese Weise hat jedes Objekt (weich oder hart) genau ein 4- Muster (seine untere rechte Ecke); Jedes weiche Objekt hat genau zwei 7 Muster (seine untere linke und seine obere rechte Ecke).

Das Subtrahieren der Anzahl von 4 Mustern von der Anzahl von 7 Mustern in der Eingabe ergibt (s + h) - 2s = h - s: = d , wobei h und s die Anzahl von harten und weichen Objekten sind, die sie bilden.

Wir drucken Hart, wenn d> 0 , Weich, wenn d <0 und Gleich, wenn d = 0 .

Wie es funktioniert

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

Julia, 99 95 93 Bytes

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

!erwartet ein zweidimensionales Char-Array als Argument. Probieren Sie es online!

Wie es funktioniert

Dies verwendet fast genau die gleiche Idee wie meine Gelee-Antwort , mit einer Verbesserung:

Anstatt die Anzahl der 4er und 7er zu zählen, entfernen wir alle anderen Zahlen und subtrahieren dann 5.5 , um (4, 7) auf (-1.5, 1.5) abzubilden . Auf diese Weise bestimmt das Vorzeichen der Summe der resultierenden Differenzen die korrekte Ausgabe.

Dennis
quelle
0

TSQL, 328 249 Bytes

Variablen und Testdaten deklarieren:

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)

Code:

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)

Code entleert:

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)

Erklärung:

Das Skript durchsucht den Text nach dem Muster:

      space
space x

Jedes davon ist der Anfang einer Kiste

Für diese Positionen sucht das Skript nach dem Muster und muss nicht erst nach x suchen:

  x
x space 

Wenn das existiert, ist es ein weiches Objekt, sonst ist es ein hartes Objekt.

t-clausen.dk
quelle