Phát hiện văn bản hình chữ nhật với mã hình chữ nhật


19

Đưa ra một chuỗi văn bản ASCII có thể in (bao gồm cả dòng mới và dấu cách) có chứa ít nhất một ký tự không phải là dòng mới cũng như khoảng trắng, xuất ra giá trị trung thực nếu chuỗi là hình chữ nhật và giá trị falsey khác. Ngoài ra, mã nguồn cho giải pháp của bạn phải là hình chữ nhật .

Một chuỗi là hình chữ nhật nếu nó đáp ứng tất cả các điều kiện sau:

  1. Dòng đầu tiên và dòng cuối cùng không chứa khoảng trắng.
  2. Ký tự đầu tiên và cuối cùng của mỗi dòng không phải là khoảng trắng.
  3. Tất cả các dòng có cùng số lượng ký tự.

Ví dụ: văn bản sau là hình chữ nhật:

abcd
e fg
hijk

Tuy nhiên, văn bản này không phải là hình chữ nhật (yêu cầu số 3):

1234
567
8900

Các trường hợp thử nghiệm

Sự thật:

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

Đây là , vì vậy giải pháp ngắn nhất tính bằng byte sẽ thắng.




9
Vì vậy, một lót mà không có bất kỳ không gian là một đệ trình hợp lệ, đúng không?
Arnauld


1
Chúng ta có thể lấy đầu vào là một chuỗi các chuỗi, một cho mỗi dòng không? Hoặc chúng ta phải nhập một chuỗi dài duy nhất bao gồm các ngắt dòng?
BradC

Câu trả lời:


12

C (gcc) , 127 125 124 118 byte

  • Lưu hai byte bằng cách chơi golf r*=!e&(!t|t==c);để r>>=e||t&&t-c;. (Golf này là nguồn cảm hứng cho lời khuyên C gần đây của tôi trả lời cập nhật cờ Inverse .)
  • Lưu một byte bằng cách chơi golf *(_-2)để _[~1].
  • Lưu Sáu byte bằng cách chơi golf *_++-10||(...)đến *_++<11?...:0và sử dụng các placeholder zero ...:0(mà không được sử dụng một cách xây dựng) để golf c++increment. Những sân golf cho phép một số cải tổ vòng lặp thêm.
  • Khi một người có thể sử dụng nhiều giá trị falsey, có thể có 114 byte .
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;}

Hãy thử trực tuyến!

Bố trí nguồn đạt được một hình chữ nhật cao hơn.

Giải trình

Phần sau đây giải thích phiên bản dài 124 byte.

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

Hãy thử trực tuyến!


10

4

Java 10, 214 176 169 152 144 139 byte

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 byte nhờ @Neil .

Sử dụng String[]athay vì var a; return-r<0;thay vì return r>0;; và thêm một nhận xét //ở cuối, vì vậy không có khoảng trắng trên hàng đầu tiên và cuối cùng.

Lưu ý rằng hình chữ nhật này ngắn hơn đầu vào một dòng, vì int r=1,...;phải được thay thế bằng int[]v{1,...};và tất cả việc sử dụng các số nguyên sau đó sẽ trở thành v[n](trong đó n là chỉ số của biến trong mảng v).

Hãy thử trực tuyến.

Giải trình:

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

Đây là cùng một chương trình cơ sở với khoảng trắng ( 128 126 byte ):

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 byte nhờ @Neil .

Hãy thử trực tuyến.



3

T-SQL, 237 207 byte

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

Đầu ra 1 cho hình chữ nhật, 0 khác. Tôi đã phải sử dụng hàng tấn dấu ngoặc và dấu ngoặc bổ sung để loại bỏ khoảng trắng, tôi chắc chắn có rất nhiều chỗ để cải thiện.

Giải thích :

Theo các tùy chọn I / O được phép của chúng tôi và làm rõ trong các nhận xét câu hỏi, đầu vào được lấy dưới dạng các hàng riêng biệt trong bảng t có sẵn . Vì dữ liệu trong SQL vốn không có thứ tự, nên bảng đó bao gồm trường nhận dạng "số hàng" i :

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

Về cơ bản, SQL của tôi thực hiện 3 truy vấn con, mỗi truy vấn trả về 0hoặc 1dựa trên 3 tiêu chí của mã "hình chữ nhật". 3 giá trị này được nhân với nhau, chỉ trả về 1mã thỏa mãn cả 3.

EDIT : Kết hợp tiêu chí 2 và 3 vào cùng một CHỌN để tiết kiệm dung lượng

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

Các TRIM(v)chức năng chỉ được hỗ trợ bởi SQL 2017 trở lên. Các phiên bản trước sẽ cần LTRIM(RTRIM(v)), sẽ yêu cầu cân bằng lại các hàng.

Một lưu ý ngẫu nhiên: LEN()hàm trong SQL bỏ qua dấu cách, vì vậy LEN('foo ') = 3. Để có được độ dài "thật", bạn phải giải quyết một ký tự cho đến hết rồi trừ đi một: P


3

C ++, 199 183 181 175 byte

Hàm mẫu này chấp nhận các dòng dưới dạng một tập hợp các chuỗi (có thể là các chuỗi rộng), được truyền dưới dạng một cặp các vòng lặp.

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

Cảm ơn là do người dùng Erroneous đã nhắc nhở tôi về back()thành viên std::stringvà chỉ ra rằng đó npos+1là con số không.

Tương đương

Việc chơi golf thực sự duy nhất là nối các dòng đầu tiên và cuối cùng để chúng ta có thể thực hiện một lần duy nhất findcho các không gian trong đó.

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

Chương trình kiểm tra

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

Điều này có thể được đánh gôn thêm tới 183 byte với độ rộng dòng là 22, sử dụng .find(' ')+1==0s.back()thay vì *s.rbegin().
Sai lầm




2

Haskell , 79 byte

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

Hãy thử trực tuyến! Lấy đầu vào là một danh sách các dòng.

Mẫu g(x:r)= ...liên kết dòng đầu tiên xvà danh sách (có thể trống) của các dòng còn lại đến r. Sau đó all((==(0<$x)).(0<$))rkiểm tra xem tất cả các dòng rcó cùng độ dài với x(Sử dụng mẹo này ).

Nếu không, thì kết hợp &&ngắn mạch và trả về False, nếu không thì phía bên tay phải được ước tính. Có một chuỗi được xây dựng bao gồm xcho dòng đầu tiên, last(x:r)cho dòng cuối cùng của r(hoặc dòng đầu tiên trong trường hợp rtrống) và (head<$>r)cho dòng đầu tiên và (last<$>r)cho ký tự cuối cùng của mỗi dòng. Đối với chuỗi này, all(>='!')kiểm tra xem nó không chứa bất kỳ khoảng trắng nào (chúng tôi không thể sử dụng (>' ')do hạn chế mã nguồn).


Lỗi trên "\ n \ n"
Angs

@Angs Bắt tốt. May mắn thay, OP làm rõ rằng đầu vào contains at least one character that is neither a newline nor a space, cũng cho phép bỏ trường hợp danh sách trống.
Laikoni

Ôi thật tuyệt, không để ý rằng nó đã được thêm vào
Angs

2

MATL , 13 byte

ctgF6Lt&()32>

Đầu vào là một chuỗi các chuỗi, trong định dạng {'abc' 'de'}.

Đầu ra là một mảng chỉ chứa các mảng, là sự thật hoặc một mảng chứa ít nhất là 0, là falsey .

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp kiểm tra , bao gồm kiểm tra tính trung thực / giả.

Giải trình

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 byte: cO6Lt&(32=~ Hãy thử trực tuyến! Chỉ cần loại bỏ các phần không biên giới, sau đó kiểm tra xem có bất kỳ khoảng trắng nào không.
- Phục hồi lại

@sundar Ý kiến ​​hay! Điều đó đủ khác biệt, hãy tự đăng nó
Luis Mendo

1
Không, cảm thấy quá giống với câu trả lời của bạn, đặc biệt nếu tôi viết nó như cF6Lt&(32=~ . Vui lòng chỉnh sửa nó trong, hoặc nếu không chúng ta có thể để nó trong phần bình luận.
- Phục hồi Monica


1

Canvas , 17 15 byte

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

Hãy thử nó ở đây!

Giải thích (ASCII-fied cho 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
Tôi thấy thật trớ trêu khi những ký tự UTF8 này trong một phông chữ giống như không gian đơn cho cảm giác rằng có nhiều khoảng trống trong nguồn. (Ít nhất, họ làm trong trình duyệt của tôi.)
Arnauld

1
@Arnauld nhân vật toàn băng thông làm điều đó. Và đó là lý do tại sao tôi tạo một phông chữ cho trình thông dịch của mình để làm cho chúng đẹp hơn: p
dzaima


1

Màu đỏ , 216 191 byte

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]

Hãy thử trực tuyến!

Tôi đặt rất nhiều dấu ngoặc đơn không cần thiết ở hàng đầu tiên và cuối cùng.


0

Thạch , 17 byte

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

Hãy thử trực tuyến!


@JonathanFrech À, đã sửa. > _>
Erik the Outgolfer

@MagicOctopusUrn Huh? Bạn có thể vui lòng liên kết đến một đầu vào trong đó điều này không hoạt động chính xác?
Erik the Outgolfer

Ồ, không, bạn gọi tôi Does not seem to enforce equal line lengthlà vì tất cả những gì tôi đang nói.
Bạch tuộc ma thuật Urn

Dường như không hoạt động cho " \n " Thử trực tuyến!
Angs

1
@Angs Hãy thử trích dẫn nó. Nó rõ ràng được phân tích cú pháp như không có gì nếu bạn đặt nó như thế.
Erik the Outgolfer

0

Thạch , 15 byte

Sử dụng một phương thức được Mnemonic phát triển trong một (hiện tại - do lỗi trường hợp cạnh) đã xóa đệ trình Pyth. (nếu bây giờ đã được sửa chữa, hãy cung cấp một số tín dụng !)

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

Một liên kết đơn âm chấp nhận danh sách các ký tự trả về 1 hoặc 0.

Hãy thử trực tuyến!

Làm sao?

Ỵµ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 byte

Câu trả lời không thể xóa: có một lỗi đã biết trong Japt , trong đó các phép quay mảng hai chiều cắt ngắn kết quả. Do lỗi đó, mã dưới đây chỉ hoạt động trên các đầu vào là hình vuông. Tuy nhiên, nếu lỗi không xuất hiện, mã bên dưới sẽ hoạt động hoàn toàn chính xác.

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.

Đưa đầu vào như một mảng của chuỗi. Sử dụng dấu ngoặc đơn thay vì dấu cách làm cho yêu cầu mã hình chữ nhật khá dễ dàng.
Hãy thử nó ở đây .


0

Ruby 2.5+, 63 byte

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

Đưa đầu vào như một mảng của chuỗi. Không có liên kết kiểm tra, vì phiên bản trên TIO (2.4) quá cũ cho phiên bản này. Thay vào đó, đây là phiên bản dài hơn (69 byte) để thử nghiệm:

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

Hãy thử trực tuyến!

Sự khác biệt là vì 2.5 Ruby hỗ trợ trực tiếp truyền mẫu Regex cho all?, any?, none?các phương thức, giúp chúng ta tiết kiệm được một vài byte. Phương pháp này khá tự giải thích - chúng tôi kiểm tra:

  1. Nếu chỉ có 1 kích thước dòng duy nhất
  2. Nếu có bất kỳ khoảng trắng nào trên đường biên
  3. Nếu có khoảng trắng trên dòng đầu tiên và cuối cùng.

0

C (gcc) , 119 byte

Lấy đầu vào dưới dạng một danh sách của n chuỗi.

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

Hãy thử trực tuyến!


0

C # (.NET Core) , 145 167 byte

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;

Hãy thử trực tuyến!

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

Không có khoảng trắng trong dòng đầu tiên.
FrownyFrog

@FrownyFrog S[0].IndexOf(" ")đang tìm kiếm một khoảng trắng ở dòng đầu tiên và S[S.Count()-1].IndexOf(" ")đang tìm kiếm ở dòng cuối cùng. Nếu không có khoảng trắng ở dòng đầu tiên và cuối cùng, thì đó là -2, điều đó đúng -2 < -1.
Hille

2
Ý tôi là thách thức, mã của bạn có cùng hạn chế, vì vậy bạn không thể có khoảng trắng ở dòng đầu tiên.
FrownyFrog

1
Mã của bạn phải trở lại Truekhi được chuyển đến chương trình của bạn. Đó là một hạn chế bổ sung trong thử thách này.
FrownyFrog

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.