Erkennen Sie rechteckigen Text mit rechteckigem Code


19

Bei einer Zeichenfolge aus druckbarem ASCII-Text (einschließlich Zeilenumbrüchen und Leerzeichen), die mindestens ein Zeichen enthält, bei dem es sich weder um eine neue Zeile noch um ein Leerzeichen handelt, wird ein wahrer Wert ausgegeben, wenn die Zeichenfolge rechteckig ist, andernfalls ein falscher Wert. Darüber hinaus muss der Quellcode für Ihre Lösung rechteckig sein .

Eine Zeichenfolge ist rechteckig, wenn alle folgenden Bedingungen erfüllt sind:

  1. Die erste und die letzte Zeile enthalten keine Leerzeichen.
  2. Das erste und letzte Zeichen jeder Zeile ist kein Leerzeichen.
  3. Alle Zeilen haben die gleiche Anzahl von Zeichen.

Der folgende Text ist beispielsweise rechteckig:

abcd
e fg
hijk

Dieser Text ist jedoch nicht rechteckig (Anforderung 3):

1234
567
8900

Testfälle

Wahrheit:

sdghajksfg
asdf
jkl;
qwerty
u i op
zxcvbn
1234
5  6
7890
abcd
e fg
hijk

Falsey:

a b c
123
456
7 9
12
345
qwerty
 uiop
zxcvnm
1234
567
8900

Das ist , also gewinnt die kürzeste Lösung in Bytes.




9
Ein Einzeiler ohne Leerzeichen ist also eine gültige Einsendung, richtig?
Arnauld


1
Können wir Eingaben als ein Array von Zeichenfolgen annehmen, eine für jede Zeile? Oder müssen wir eine einzelne lange Zeichenfolge eingeben, die die Zeilenumbrüche enthält?
BradC

Antworten:


12

C (GCC) , 127 125 124 118 Bytes

  • Zwei Bytes durch Golfen r*=!e&(!t|t==c);zu gespeichert r>>=e||t&&t-c;. (Dieser Golf war die Inspiration für meine letzten C-Tipps zum Inverse Flag-Update .)
  • Ein Byte durch Golfen *(_-2)auf gespeichert _[~1].
  • Es wurden sechs Bytes gespart *_++-10||(...), *_++<11?...:0indem ...:0das c++Inkrement mit dem Platzhalter Null (der nicht konstruktiv verwendet wird) abgegolft und verwendet wurde. Diese Golfplätze erlaubten ein weiteres Ummischen der Loops.
  • Wenn man mehrere Falsey-Werte verwenden kann, könnten 114 Bytes möglich sein.
r,e,c,t;_(char*_){for(r=1,t=c=0;*_;*_++<11?r*=(t||(t=c,!e))&*_>32&_[~1]>32&t==c,c=e=0:c++)*_-32||(e=1);r>>=e||t&&t-c;}

Probieren Sie es online!

Quelllayout für ein größeres Rechteck.

Erläuterung

Im Folgenden wird die 124 Byte lange Version erläutert.

r,e,c,t;_(char*_){     // `r` is the boolean result flag, `e` a boolean flag if the current line contains
                       //  a space, `t` the first line's width, `c` the current line's current width
 for(r=1,t=c=0;*_;c++) // initialize, loop through entire string
  *_-32||              // if the current char is a space,
   (e=1),              //  the current line contains a space
  *_++-10||            // if the current char is a newline (char pointer `_` now incremented)
   (r*=(t||(t=c,!e))   // if t is not yet set, the current line is the first line; set it
                       //  to this line's length, check that no spaces where found
    &*_>32             // the next line's first char should not be a space
    &_[~1]>32          // this line's last char should not have been a space
    &t==c,c=~0,e=0);   // the line lengths should match, reset `c` and `e` to zero
                       //  (`~0 == -1`, countering the loop's increment of `c`)
 r>>=e||t&&t-c;}       // return boolean flag, check that the last line does not contain spaces,
                       //  there was either no newline or line lengths match
                       //  (here) equivalent to `r*=!e&(!t|t==c)`

Probieren Sie es online!


10
+1 fürr,e,c,t
Magic Octopus Urn

4

Java 10, 214 176 169 152 144 139 Bytes

s->{String[]a=s.split("\n")
;int r=1,i=0,R=a.length;for
(;i<R;i++)if(i<1|i>R-2?a[i]
.contains(" "):a[i].trim( )
!=a[i])r=0;return-r<0;}////

-5 Bytes dank @Neil .

Verwendet String[]aanstelle von var a; return-r<0;statt return r>0;; und //am Ende einen Kommentar hinzugefügt , sodass in der ersten und letzten Zeile keine Leerzeichen vorhanden sind.

Beachten Sie, dass dieses Rechteck kürzer als eine einzeilige Eingabe ist, da int r=1,...;es durch ersetzt werden sollte int[]v{1,...};, und alle Verwendungen der ganzen Zahlen dann werden v[n](wobei n der Index der Variablen im Array ist v).

Probieren Sie es online aus.

Erläuterung:

s->{                        // Method with String parameter and boolean return-type
  String[]a=s.split("\n");  //  Input split by new-lines
  int r=1,                  //  Result-integer, starting at 1
      i=0,                  //  Index `i`, starting at 0
      R=a.length;           //  Amount of rows `R`
  for(;i<R;i++)             //  Loop `i` over the rows
    if(i<1                  //   If it's the first row,
       |i>R-2?              //   or the last row:
        a[i].contains(" ")  //   And the current row contains a space
       :a[i].trim()!=a[i])  //   Or either column of the current row contains a space
      r=0;                  //    Set the result `r` to 0
   return-r<0;}             //  Return whether `r` is still 1
////                        // Comment to comply to the rules of the challenge

Hier ist das gleiche Basisprogramm mit Leerzeichen ( 128 126 Bytes ):

s->{var a=s.split("\n");int r=1,i=0,R=a.length;for(;i<R;i++)if(i<1|i>R-2?a[i].contains(" "):a[i].trim()!=a[i])r=0;return r>0;}

-2 Bytes dank @Neil .

Probieren Sie es online aus.



3

T-SQL, 237 207 Bytes

SELECT(SELECT(IIF(max(len(v))=min(len(v)),1,0)*IIF(SUM(len(v+'x')-len
(trim(v))-1)=0,1,0))FROM t)*(SELECT(IIF(SUM(charindex(' ',v))=0,1,0))
FROM[t]WHERE[i]IN(SELECT(min(i))FROM[t]UNION(SELECT(max(i))FROM[t])))

Ausgang 1 für Rechteck, sonst 0. Ich musste Tonnen von zusätzlichen Parens und Klammern verwenden, um Leerzeichen zu entfernen. Ich bin sicher, es gibt viel Raum für Verbesserungen.

Erklärung :

Gemäß unseren zulässigen E / A-Optionen und der Erläuterung in den Fragenkommentaren werden die Eingaben als separate Zeilen in einer bereits vorhandenen Tabelle t verwendet . Da Daten in SQL von Natur aus ungeordnet sind, enthält diese Tabelle das Identitätsfeld "Zeilennummer" i :

CREATE TABLE t (i INT IDENTITY(1,1), v VARCHAR(999))

Grundsätzlich führt mein SQL 3 Unterabfragen aus, von denen jede die 3 Kriterien des "rechteckigen" Codes zurückgibt 0oder auf diesen 1basiert. Diese 3 Werte werden miteinander multipliziert und nur 1für Code zurückgegeben, der alle 3 erfüllt.

BEARBEITEN : Kombinieren Sie die Kriterien 2 und 3 in einem SELECT, um Platz zu sparen

SELECT(
SELECT(IIF(max(len(v))=min(len(v)),1,0)                  --All rows same length
      *IIF(SUM(len(v+'x')-len(trim(v))-1)=0,1,0))FROM t) --no leading or trailing spaces
*(SELECT(IIF(SUM(charindex(' ',v))=0,1,0))               --No spaces at all in
FROM[t]WHERE[i]IN(SELECT(min(i))FROM[t]                  --   first row or
            UNION(SELECT(max(i))FROM[t])))               --   last row

Die TRIM(v)Funktion wird nur von SQL 2017 und höher unterstützt. Frühere Versionen würden benötigen LTRIM(RTRIM(v)), was ein erneutes Ausgleichen der Zeilen erfordern würde.

Eine zufällige Anmerkung: Die LEN()Funktion in SQL ignoriert also nachfolgende Leerzeichen LEN('foo ') = 3. Um eine "wahre" Länge zu erhalten, müssen Sie ein Zeichen bis zum Ende anheften und dann eins subtrahieren: P


3

C ++, 199 183 181 175 Bytes

Diese Vorlagenfunktion akzeptiert Zeilen als Sammlung von Zeichenfolgen (bei denen es sich um breite Zeichenfolgen handeln kann), die als Iteratorenpaar übergeben werden.

#include<algorithm>//
template<class I>bool
f(I a,I b){return!~+(
*a+b[-1]).find(' ')&&
std::all_of(a,b,[&a](
auto&s){return' '+-s.
back()&&s[0]-' '&&a->
size()==s.size();});}

Vielen Dank an den Benutzer Erroneous , der mich an das back()Mitglied von erinnert std::stringund darauf hingewiesen hat, dass npos+1es null ist.

Ungolfed-Äquivalent

Das einzige wirkliche Golfspiel besteht darin, die erste und die letzte Zeile zu verketten, damit wir eine einzelne Zeile findfür Leerzeichen in diesen Zeilen ausführen können .

#include <algorithm>
template<class It>
bool f(It a, It b)
{
    return (*a+b[-1]).find(' ') == a->npos
        && std::all_of(a, b,
                       [=](auto s) {
                           return s.back() != ' '
                               && s.front() != ' '
                               && s.size() == a->size(); });
}

Testprogramm

#include <iostream>
#include <string>
#include <vector>
int expect(const std::vector<std::string>& v, bool expected)
{
    bool actual = f(v.begin(), v.end());
    if (actual == expected) return 0;
    std::cerr << "FAILED " << (expected ? "truthy" : "falsey") << " test\n";
    for (auto const& e: v)
        std::cerr << "  |" << e << "|\n";
    return 1;
}
int expect_true(const std::vector<std::string>& v) { return expect(v, true); }
int expect_false(const std::vector<std::string>& v) { return expect(v, false); }
int main()
{
    return
        // tests from the question
        + expect_true({"sdghajksfg"})
        + expect_true({"asdf", "jkl;",})
        + expect_true({"qwerty", "u i op", "zxcvbn",})
        + expect_true({"1234", "5  6", "7890",})
        + expect_true({"abcd", "e fg", "hijk",})
        + expect_false({"a b c",})
        + expect_false({"123", "456", "7 9",})
        + expect_false({"12", "345",})
        + expect_false({"qwerty", " uiop", "zxcvnm",})
        + expect_false({"1234", "567", "8900",})
        // extra tests for leading and trailing space
        + expect_false({"123", " 56", "789"})
        + expect_false({"123", "45 ", "789"})
        // the function source
        + expect_true({"#include<algorithm>//",
                       "template<class I>bool",
                       "f(I a,I b){return!~+(",
                       "*a+b[-1]).find(' ')&&",
                       "std::all_of(a,b,[&a](",
                       "auto&s){return' '+-s.",
                       "back()&&s[0]-' '&&a->",
                       "size()==s.size();});}",})
        ;
}

Dies kann mit .find(' ')+1==0und s.back()anstelle von auf 183 Bytes mit einer Linienbreite von 22 weiter golfen werden *s.rbegin().
Fehlerhafte



2

Haskell , 106 102 98 110 109 102 Bytes

(\a->all(==[])a||and(e((1<$)<$>a):map(all(>='!').($a))[head,last,map$last,map$head]));e(a:s)=all(==a)s

Vielen Dank an @nimi und @Laikoni für jeweils ein Byte!

Probieren Sie es online!


2

Haskell , 79 Bytes

g(x:r)=all((==(0<$x)).(0<$))r&&all(>='!')(x++last(x:r)++(head<$>r)++(last<$>r))

Probieren Sie es online! Nimmt die Eingabe als eine Liste von Zeilen.

Das Muster g(x:r)= ...bindet die erste Zeile an xund die (möglicherweise leere) Liste der verbleibenden Zeilen an r. all((==(0<$x)).(0<$))rÜberprüfen Sie dann , ob alle Zeilen in rderselben Länge wie x(mit diesem Tipp ) sind.

Wenn nicht, dann schließt die Verbindung &&kurz und kehrt zurück False, andernfalls wird die rechte Seite ausgewertet. Dort wird ein String gebildet, der aus xder ersten Zeile, last(x:r)der letzten Zeile r(oder der ersten Zeile, falls diese rnoch leer ist) und (head<$>r)dem ersten und (last<$>r)dem letzten Zeichen jeder Zeile besteht. all(>='!')Überprüft für diese Zeichenfolge, ob sie keine Leerzeichen enthält (wir können sie (>' ')aufgrund der Quellcodeeinschränkung nicht verwenden ).


Fehler auf "\ n \ n"
Angs

@Angs Guter Fang. Zum Glück hat OP klargestellt, dass die Eingabe contains at least one character that is neither a newline nor a space, die auch das Löschen der leeren Liste Fall ermöglicht.
Laikoni

Oh schön, habe nicht bemerkt, dass das hinzugefügt wurde
Angs

2

MATL , 13 Bytes

ctgF6Lt&()32>

Die Eingabe ist ein Array von Zeichenfolgen im Format {'abc' 'de'}.

Die Ausgabe ist ein Array, das nur Einsen enthält, was der Wahrheit entspricht , oder ein Array, das mindestens eine Null enthält, was falsch ist .

Probieren Sie es online! Oder überprüfen Sie alle Testfälle , einschließlich des Wahrheits- / Falschheitstests.

Erläuterung

c       % Implicit input. Convert to char. This concatenates the
        % strings of the input cell array as rows of a rectangular
        % char array, right-padding with spaces as needed
tg      % Duplicate, convert to logical. Gives a logical array with
        % the same size containing true in all its entries
F       % Push false
6L      % Push the array [2, j-1], where j is the imaginary unit.
        % When used as an index, this is interpreted as 2:end-1
t       % Duplicate
&(      % Assignment indexing with 4 inputs: original array, new
        % value, two indexing arrays. This writes false at the inner
        % rectangle (2:end-1)×(2:end-1) of the logical array that
        % initially only contained true. This will be used as a
        % logical index (mask) into the rectangular char array
)       % Reference indexing. This selects the border of the char
        % array. The result is a column vector of chars
32>     % Is each entry greater than 32? (ASCII code for space)
        % Implicit display

11 Bytes: cO6Lt&(32=~ Probieren Sie es online! Löscht einfach die nicht umrandeten Teile und prüft dann, ob Leerzeichen vorhanden sind.
Sundar - Reinstate Monica

@ Sundar Gute Idee! Das ist schon anders, poste es selbst
Luis Mendo

1
Nee, fühlt sich deiner Antwort zu ähnlich, besonders wenn ich sie als schreibe cF6Lt&(32=~. Fühlen Sie sich frei, es zu bearbeiten, oder wenn nicht, können wir es einfach in den Kommentaren belassen.
Sundar - Reinstate Monica


1

Leinwand , 17 15 Bytes

4[↷K;}┐){SL]∑4≡

Probieren Sie es hier aus!

Erklärung (ASCII-fähig für Monospace):

4[↷K;}┐){SL]∑4=  full program; pushes the input to the stack.
4[   }           repeat 4 times
  ↷                rotate ToS clockwise. This also pads the input with spaces
   K;              take off the last line and put it below the item
      ┐          pop the remaining of the input (the center)
       )         and wrap the rest (the sides) in an array
        {  ]     map over those
         S         split on spaces - should result to one item in the array
          L        and get the length
            ∑    sum those lengths together
             4=  check if equal 4

4
Ich finde es ironisch, dass diese UTF8-Zeichen in einer Monospace-ähnlichen Schriftart das Gefühl vermitteln, dass es in der Quelle viele Leerzeichen gibt. (Zumindest in meinem Browser.)
Arnauld

1
@Arnauld Zeichen mit voller Breite machen das. Und deshalb habe ich eine Schrift für meinen Dolmetscher gemacht, um sie hübscher zu machen: p
dzaima


1

Rot , 216 191 Bytes

func[s][d:(length?(first(s:(split(s)"^/"))))sp:
func[a][none = find a" "]b: on foreach c s[b: b
and(d = length? c )and(c/1 <>" ")and(" "<> last
c)]res:(sp(first(s)))and(sp(last(s)))and(b)res]

Probieren Sie es online!

Ich habe in die erste und letzte Reihe eine Menge ansonsten nicht notwendiger Klammern gesetzt.


0

Gelee , 17 Bytes

Ỵµ.ịЀ;ịɗẎ⁶e<L€E$

Probieren Sie es online!


@ JonathanFrech Ah, behoben. > _>
Erik der Outgolfer

@MagicOctopusUrn Huh? Können Sie bitte auf einen Eingang verlinken, bei dem sich dieser nicht korrekt verhält?
Erik der Outgolfer

Oh, nein, du hast meine auch gerufen, das Does not seem to enforce equal line lengthist alles, was ich gesagt habe.
Magic Octopus Urn

Scheint nicht für " \n " Try it online
Angs

1
@Angs Versuchen Sie es zu zitieren. Es wird anscheinend als nichts analysiert, wenn Sie es so ausdrücken.
Erik der Outgolfer

0

Gelee , 15 Bytes

Verwendet eine von Mnemonic entwickelte Methode in einer (derzeit - aufgrund eines Edge-Case-Fehlers) gelöschten Pyth-Übermittlung. (Wenn es jetzt repariert ist, geben Sie etwas Kredit !)

ỴµL€Eȧt€⁶ZUƊ4¡⁼

Eine monadische Verknüpfung, die eine Liste von Zeichen akzeptiert, die 1 oder 0 zurückgibt.

Probieren Sie es online!

Wie?

ỴµL€Eȧt€⁶ZUƊ4¡⁼ - Link: list of characters
Ỵ               - split at newlines (making a list of lists - the rows)
 µ              - start a new monadic chain, call that ROWS
  L€            - length of €ach row in ROWS
    E           - all equal? (an integer: 1 if so, otherwise 0)
            4¡  - repeat four times:
           Ɗ    -   last three links as a monad:
      t€⁶       -     trim spaces (⁶) from €ach row in current ROWS
         Z      -     transpose that result
          U     -     upend (reverse each new row)
     ȧ          - logical AND (0 if L€E was 0 else the result of the repeated transform)
              ⁼ - equal to X? (the integer 0 is not equal to any listy of characters)

@Mnemonic - Jelly-fied :)
Jonathan Allan

0

Japt , 22 Bytes

Nicht konkurrierende Antwort: Es gibt einen bekannten Fehler in Japt , bei dem zweidimensionale Array-Rotationen die Ergebnisse abschneiden. Aufgrund dieses Fehlers funktioniert der folgende Code nur bei Eingaben, die quadratisch sind. Wenn der Fehler jedoch nicht vorhanden war, sollte der folgende Code vollständig korrekt funktionieren.

e_ʶUÌÊéUeº4o)r_z)mx}U
e_                      // Check if every line in the input array
  ʶUÌÊ                 // has the same length as the last item.
       é               // Also,
               r_z)mx}U // check if rotating and trimming the input array
           º4o)         // four times
         Ue             // is equal to the input array.

Nimmt Eingaben als ein Array von Zeichenfolgen. Durch die Verwendung von Klammern anstelle von Leerzeichen wird das Erfordernis eines Rechteckcodes recht einfach.
Probieren Sie es hier aus .


0

Ruby 2.5+, 63 Bytes

->a{!a.uniq(&:size)[1]&&a.none?(/^\s|\s$/)&&!(a[0]+a[-1])[?\s]}

Nimmt Eingaben als ein Array von Zeichenfolgen. Kein Testlink, da die Version auf TIO (2.4) für diesen zu alt ist. Stattdessen ist hier eine etwas längere (69 Byte) Version zum Testen:

->a{!a.uniq(&:size)[1]&&a.none?{|l|l=~/^\s|\s$/}&&!(a[0]+a[-1])[?\s]}

Probieren Sie es online!

Der Unterschied besteht darin, dass 2.5 Ruby die direkte Übergabe eines Regex-Musters an all?, any?, none?Methoden unterstützt, wodurch einige Bytes eingespart werden. Die Methode selbst ist selbsterklärend - wir testen:

  1. Wenn es nur 1 eindeutige Zeilengröße gibt
  2. Gibt es Leerzeichen an den Zeilengrenzen?
  3. Gibt es Leerzeichen in der ersten und letzten Zeile?

0

C (gcc) , 119 Bytes

Übernimmt die Eingabe als Liste (n) von n Zeichenfolgen.

f(s,n,m,r,p)char**s,*p;{for(r=m=n;m--;r*=strlen(*s)==strlen(s[m])&(!p||m&&m^n-1&&p!=s[m]&&p[1]))p=strchr(s[m],32);n=r;}

Probieren Sie es online!


0

C # (.NET Core) , 145 167 Bytes

S[0].Length>1&&S[0].IndexOf
(" ") + S[ S.Count() - 1 ].
IndexOf(" ")<-1&Array.Find(
S,x=>x[0]==' '| x [x.Length
-1]  ==  ' '  | S[0].Length
!=x.Length)==null?11>0:0>1;

Probieren Sie es online!

S[0].Length>1&                                    // And if the lenght of the first argument is more than 1 char
Array.Find(                                       // Find a string in an array
    S,                                            // The array which will be searched in
    x=>                                           // For x as the current string from the array
    x.Length!=S[0].Length|                        // If the string lenght match not the first argument lenght
    x[0]==' '|                                    // Or if the string begins with a spacer
    x[x.Length-1]==' '                            // Or if the string ends with a spacer
)==null&                                          // And if there was no string found which matched the conditions
S[0].IndexOf(" ")+S[S.Count()-1].IndexOf(" ")<-1  // And if the first and last string doesn't have a spacer
?                                                 // If all above is true do
1>0                                               // Return True
:                                                 // Else
0>1                                               // Return False

Keine Leerzeichen in der ersten Zeile.
FrownyFrog

@FrownyFrog S[0].IndexOf(" ")sucht nach einem Leerzeichen in der ersten und S[S.Count()-1].IndexOf(" ")in der letzten Zeile. Wenn in der ersten und letzten Zeile kein Leerzeichen vorhanden ist, ist es -2, was dann bei zutrifft -2 < -1.
Hille

2
Ich meine die Herausforderung, Ihr Code hat die gleiche Einschränkung, so dass Sie keine Leerzeichen in der ersten Zeile haben können.
FrownyFrog

1
Ihr Code muss zurückgegeben werden, Truewenn er an Ihr Programm übergeben wird. Dies ist eine zusätzliche Einschränkung bei dieser Herausforderung.
FrownyFrog

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.