Wykryj tekst prostokątny za pomocą kodu prostokątnego

19

Biorąc pod uwagę ciąg drukowalnego tekstu ASCII (w tym znaki nowej linii i spacje), który zawiera co najmniej jeden znak, który nie jest ani nową linią, ani spacją, wypisz prawdziwą wartość, jeśli ciąg jest prostokątny, a w przeciwnym razie wartość falsey. Dodatkowo kod źródłowy twojego rozwiązania musi być prostokątny .

Ciąg jest prostokątny, jeśli spełnia wszystkie następujące warunki:

  1. Pierwszy wiersz i ostatni wiersz nie zawierają spacji.
  2. Pierwszy i ostatni znak każdej linii nie jest spacją.
  3. Wszystkie linie mają tę samą liczbę znaków.

Na przykład następujący tekst jest prostokątny:

abcd
e fg
hijk

Ten tekst nie jest jednak prostokątny (wymaganie nr 3):

1234
567
8900

Przypadki testowe

Prawda:

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

To jest , więc wygrywa najkrótsze rozwiązanie w bajtach.

Mego
źródło
2
Związane .
AdmBorkBork
9
Tak więc jednowarstwowa bez miejsca jest prawidłowym przesłaniem, prawda?
Arnauld
1
powiązane
Rod
1
Czy możemy brać dane wejściowe jako tablicę ciągów, po jednej dla każdej linii? Czy też musimy wprowadzić pojedynczy długi ciąg znaków, który zawiera podział wiersza?
BradC

Odpowiedzi:

12

C (gcc) , 127 125 124 118 bajtów

  • Zaoszczędzono dwa bajty, grając r*=!e&(!t|t==c);w golfa r>>=e||t&&t-c;. (Ten golf był inspiracją dla mojej ostatniej odpowiedzi na C w odpowiedzi na aktualizację flagi odwrotnej ).
  • Zapisano bajt, grając *(_-2)w golfa _[~1].
  • Zaoszczędzono sześć bajtów, grając *_++-10||(...)w golfa *_++<11?...:0i wykorzystując symbol zastępczy zero ...:0(który nie jest używany konstruktywnie), aby c++zwiększyć przyrost. Te pola golfowe umożliwiły dalsze przetasowania w pętli.
  • Gdy można użyć wielu wartości falsey, możliwe jest 114 bajtów .
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;}

Wypróbuj online!

Układ źródłowy osiąga wyższy prostokąt.

Wyjaśnienie

Poniżej wyjaśniono wersję o długości 124 bajtów.

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

Wypróbuj online!

Jonathan Frech
źródło
10
+1 zar,e,c,t
Urna Magicznej Ośmiornicy
4

Java 10, 214 176 169 152 144 139 bajtów

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 bajtów dzięki @Neil .

Używa String[]azamiast var a; return-r<0;zamiast return r>0;; i dodał komentarz //na samym końcu, więc nie ma spacji w pierwszym i ostatnim wierszu.

Zauważ, że ten prostokąt jest krótszy niż wejście jednowierszowe, ponieważ int r=1,...;należy go zastąpić int[]v{1,...};, a wtedy wszystkie zastosowania liczb całkowitych stają się v[n](gdzie n jest indeksem zmiennej w tablicy v).

Wypróbuj online.

Wyjaśnienie:

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

Oto ten sam program podstawowy ze spacjami ( 128 126 bajtów ):

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 bajty dzięki @Neil .

Wypróbuj online.

Kevin Cruijssen
źródło
1
tio.run/…
Neil
3

T-SQL, 237 207 bajtów

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

Wyjścia 1 dla prostokąta, w przeciwnym razie 0. Musiałem użyć ton dodatkowych parens i wsporników, aby wyeliminować spacje, jestem pewien, że jest wiele miejsca na ulepszenia.

Objaśnienie :

Zgodnie z naszymi dozwolonymi opcjami We / Wy i wyjaśnieniem w komentarzach do pytań dane wejściowe są traktowane jako osobne wiersze w istniejącej tabeli t . Ponieważ dane w SQL są z natury nieuporządkowane, ta tabela zawiera pole tożsamości „numer wiersza” i :

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

Zasadniczo mój SQL wykonuje 3 podkwerendy, z których każde zwraca 0lub 1bazuje na 3 kryteriach kodu „prostokątnego”. Te 3 wartości są mnożone razem, zwracając tylko 1kod, który spełnia wszystkie 3.

EDYCJA : Połącz kryteria 2 i 3 w ten sam WYBÓR, aby zaoszczędzić miejsce

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

Ta TRIM(v)funkcja jest obsługiwana tylko przez SQL 2017 i nowsze wersje. Potrzebne byłyby wcześniejsze wersje LTRIM(RTRIM(v)), które wymagałyby ponownego zrównoważenia wierszy.

Jedna losowa uwaga: LEN()funkcja SQL ignoruje końcowe spacje, więc LEN('foo ') = 3. Aby uzyskać „prawdziwą” długość, musisz przypiąć postać do końca, a następnie odjąć jedną: P

BradC
źródło
3

C ++, 199 183 181 175 bajtów

Ta funkcja szablonu akceptuje wiersze jako zbiór ciągów (które mogą być ciągami szerokimi) przekazywanymi jako para iteratorów.

#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();});}

Podziękowania należą się użytkownikowi Błędnemu za przypomnienie mi back()członka std::stringi wskazanie, że npos+1wynosi zero.

Ekwiwalent nie golfa

Jedynym prawdziwym golfem jest połączenie pierwszej i ostatniej linii, abyśmy mogli wykonać jeden finddla miejsc w nich.

#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(); });
}

Program testowy

#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();});}",})
        ;
}
Toby Speight
źródło
Można to dodatkowo pograć w golfa do 183 bajtów o szerokości linii 22, używając .find(' ')+1==0i s.back()zamiast *s.rbegin().
Błędny
2

JavaScript (Node.js) , 85 bajtów

x=>(x=x.split`\n`).some(s=>s.length-x[0].length|s.trim()!=s)<!/\s/.test(x[0]+x.pop())

Wypróbuj online!

l4m2
źródło
@KevinCruijssen przepraszam :(
DanielIndie
Kocham twojego NORoperatora!
Neil
2

Python 2 , 82 bajty

lambda*s:len(set(map(len,s)))<2<'!'<=min(tuple(s[0]+s[-1])+zip(*s)[0]+zip(*s)[-1])

Wypróbuj online!

Wywołaj jako f("abcd", "e fg", "hijk").

Lynn
źródło
2

Haskell , 106 102 98 110 109 102 bajtów

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

Dzięki @nimi i @Laikoni za bajt każdy!

Wypróbuj online!

Angs
źródło
2

Haskell , 79 bajtów

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

Wypróbuj online! Pobiera dane wejściowe jako listę linii.

Wzór g(x:r)= ...wiąże pierwszą linię xz (ewentualnie pustą) listą pozostałych linii r. Następnie all((==(0<$x)).(0<$))rsprawdza, czy wszystkie linie rmają taką samą długość jak x(Korzystanie z tej wskazówki ).

Jeśli nie, to połączenie &&zwiera i wraca False, w przeciwnym razie oceniana jest prawa strona. Tam budowany jest ciąg znaków, który składa się z xpierwszego wiersza, last(x:r)ostatniego wiersza r(lub pierwszego wiersza ponownie, jeśli rjest pusty) oraz (head<$>r)pierwszego i (last<$>r)ostatniego znaku każdego wiersza. W przypadku tego ciągu all(>='!')sprawdza, czy nie zawiera spacji (nie możemy go użyć z (>' ')powodu ograniczeń kodu źródłowego).

Laikoni
źródło
Błędy w „\ n \ n”
Angs
@Angs Good catch. Na szczęście OP wyjaśnił, że dane wejściowe contains at least one character that is neither a newline nor a space, które pozwalają również na upuszczenie pustej listy.
Laikoni
Och, nieźle, nie zauważyłem, że to zostało dodane
Angs
2

MATL , 13 bajtów

ctgF6Lt&()32>

Dane wejściowe to tablica ciągów w formacie {'abc' 'de'}.

Dane wyjściowe to tablica zawierająca tylko te, które są zgodne z prawdą , lub tablica zawierająca co najmniej zero, czyli falsey .

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe , w tym test na prawdziwość / fałszerstwo.

Wyjaśnienie

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
Luis Mendo
źródło
11 bajtów: cO6Lt&(32=~ Wypróbuj online! Po prostu zeruje nieprzygraniczne części, a następnie sprawdza, czy są jakieś spacje.
Sundar - Przywróć Monikę
@sundar Dobry pomysł! To wystarczająco inne, opublikuj to sam
Luis Mendo
1
Nie, wydaje się zbyt podobny do twojej odpowiedzi, zwłaszcza jeśli napiszę to jako cF6Lt&(32=~. Możesz go edytować, a jeśli nie, możemy zostawić go w komentarzach.
Sundar - Przywróć Monikę
1

JavaScript (ES6), 88 bajtów

s=>!s.split`\n`.some((s,i,a)=>s[L='length']-a[0][L]|(++i%a[L]>1?/^\s|\s$/:/\s/).test(s))

Wypróbuj online!

Arnauld
źródło
1

Płótno , 17 15 bajtów

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

Wypróbuj tutaj!

Objaśnienie (ASCII-fied for 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
dzaima
źródło
4
Ironiczne jest dla mnie, że te znaki UTF8 czcionką monospace dają wrażenie, że w źródle jest wiele spacji. (Przynajmniej robią to w mojej przeglądarce).
Arnauld
1
Robią to znaki @Arnauld o pełnej przepustowości. I dlatego stworzyłem czcionkę dla mojego tłumacza, aby były ładniejsze: p
dzaima
1

Perl 5 , 70 bajtów

$f||=$_;$l||=y///c;$,||=/^\s|\s$/||$l-y///c;$e=$_}{$\="$f$e"=~/\s/||$,

Wypróbuj online!

Wyjścia 0dla prawdy, każda inna liczba dla falsey.

Xcali
źródło
1

Czerwony , 216 191 bajtów

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]

Wypróbuj online!

W pierwszym i ostatnim rzędzie umieściłem wiele niepotrzebnych nawiasów.

Galen Iwanow
źródło
0

Galaretka , 17 bajtów

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

Wypróbuj online!

Erik the Outgolfer
źródło
@JonathanFrech Ah, naprawiony. > _>
Erik the Outgolfer
@MagicOctopusUrn Huh? Czy możesz podać link do danych wejściowych, w których nie zachowuje się to poprawnie?
Erik the Outgolfer
Och, nie, wołałeś mój, bo Does not seem to enforce equal line lengthto wszystko, co mówiłem.
Magic Octopus Urn
Wygląda na to, że nie działa dla " \n " Wypróbuj online!
Angs
1
@Angs Spróbuj zacytować. Najwyraźniej jest to parsowane, jeśli się tak wyrazi.
Erik the Outgolfer
0

Galaretka , 15 bajtów

Korzysta z metody opracowanej przez Mnemonic w (obecnie - z powodu błędu krawędzi) usuniętym pytaniu. (jeśli teraz jest to naprawione, daj kredyt !)

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

Link monadyczny przyjmujący listę znaków, która zwraca 1 lub 0.

Wypróbuj online!

W jaki sposób?

Ỵµ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)
Jonathan Allan
źródło
@Mnemonic - Jelly-fied :)
Jonathan Allan
0

Japt , 22 bajty

Odpowiedź niekonkurencyjna: w Japt znany jest błąd, w którym dwuwymiarowe obroty tablicy obcinają wyniki. Z powodu tego błędu poniższy kod działa tylko na wejściach, które są kwadratowe. Jeśli błąd nie był obecny, poniższy kod powinien działać całkowicie poprawnie.

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.

Pobiera dane wejściowe jako tablicę ciągów. Używanie nawiasów zamiast spacji sprawia, że ​​wymagania dotyczące kodu prostokątnego są dość łatwe.
Wypróbuj tutaj .

Gnida
źródło
0

Ruby 2.5+, 63 bajty

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

Pobiera dane wejściowe jako tablicę ciągów. Brak linku testowego, ponieważ wersja na TIO (2.4) jest na to za stara. Zamiast tego jest tu nieco dłuższa (69 bajtów) wersja do testowania:

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

Wypróbuj online!

Różnica polega na tym, że ponieważ 2.5 Ruby obsługuje bezpośrednie przekazywanie wzorca Regex do all?, any?, none?metod, co oszczędza nam kilka bajtów. Sama metoda jest dość oczywista - testujemy:

  1. Jeśli jest tylko 1 unikalny rozmiar linii
  2. Jeśli na granicach linii znajdują się spacje
  3. Jeśli w pierwszej i ostatniej linii są spacje.
Kirill L.
źródło
0

C (gcc) , 119 bajtów

Pobiera dane wejściowe jako listę (y) n ciągów.

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;}

Wypróbuj online!

gastropner
źródło
0

C # (.NET Core) , 145 167 bajtów

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;

Wypróbuj 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
Hille
źródło
Brak spacji w pierwszym wierszu.
FrownyFrog
@FrownyFrog S[0].IndexOf(" ")szuka spacji w pierwszym wierszu i S[S.Count()-1].IndexOf(" ")szuka w ostatnim wierszu. Jeśli nie ma spacji w pierwszym i ostatnim wierszu, to -2, co jest prawdą w -2 < -1.
Hille
2
Mam na myśli wyzwanie, twój kod ma takie same ograniczenia, więc nie możesz mieć spacji w pierwszym wierszu.
FrownyFrog
1
Kod musi zostać zwrócony Truepo przekazaniu do programu. To dodatkowe ograniczenie w tym wyzwaniu.
FrownyFrog