Deteksi Teks Persegi Panjang dengan Kode Persegi Panjang


19

Diberikan string teks ASCII yang dapat dicetak (termasuk baris baru dan spasi) yang berisi setidaknya satu karakter yang bukan baris baru atau spasi, mengeluarkan nilai kebenaran jika string berbentuk persegi panjang, dan nilai falsey sebaliknya. Selain itu, kode sumber untuk solusi Anda harus empat persegi panjang .

String berbentuk persegi panjang jika memenuhi semua kondisi berikut:

  1. Baris pertama dan baris terakhir tidak mengandung spasi.
  2. Karakter pertama dan terakhir dari setiap baris bukanlah spasi.
  3. Semua baris memiliki jumlah karakter yang sama.

Misalnya, teks berikut berbentuk persegi panjang:

abcd
e fg
hijk

Teks ini, bagaimanapun, bukan persegi panjang (persyaratan # 3):

1234
567
8900

Uji Kasus

Benar:

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

Ini adalah , jadi solusi terpendek dalam byte menang.




9
Jadi, one-liner tanpa spasi adalah pengiriman yang valid, benar?
Arnauld


1
Bisakah kita mengambil input sebagai array string, satu untuk setiap baris? Atau haruskah kita memasukkan string panjang tunggal yang mencakup jeda baris?
BradC

Jawaban:


12

C (gcc) , 127 125 124 118 byte

  • Disimpan dua byte oleh golf r*=!e&(!t|t==c);ke r>>=e||t&&t-c;. (Golf ini adalah inspirasi untuk tips C saya baru-baru ini menjawab pembaruan bendera Inverse .)
  • Disimpan satu byte dengan bermain golf *(_-2)ke _[~1].
  • Disimpan enam byte dengan golf *_++-10||(...)ke *_++<11?...:0dan memanfaatkan placeholder nol ...:0(yang tidak digunakan secara konstruktif) untuk golf ituc++ menambah . Mereka golf memungkinkan beberapa perulangan loop lebih lanjut.
  • Ketika seseorang dapat menggunakan beberapa nilai falsey, 114 byte bisa dimungkinkan.
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;}

Cobalah online!

Tata letak sumber mencapai persegi panjang yang lebih tinggi.

Penjelasan

Berikut ini menjelaskan versi panjangnya 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)`

Cobalah online!


10
+1 untukr,e,c,t
Magic Gurita Guci

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 terima kasih kepada @Neil .

Gunakan String[]abukan var a; return-r<0;bukannya return r>0;; dan menambahkan komentar// di bagian paling akhir, jadi tidak ada spasi di baris pertama dan terakhir.

Perhatikan bahwa persegi panjang ini lebih pendek dari input baris tunggal, karena int r=1,...;harus diganti dengan int[]v{1,...};, dan semua penggunaan bilangan bulat akan menjadi v[n](di mana n adalah indeks variabel dalam array v).

Cobalah online.

Penjelasan:

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

Berikut adalah program dasar yang sama dengan spasi ( 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 terima kasih kepada @Neil .

Cobalah online.



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

Output 1 untuk persegi panjang, 0 sebaliknya. Saya harus menggunakan banyak paren dan kurung tambahan untuk menghilangkan ruang, saya yakin ada ruang luas untuk perbaikan.

Penjelasan :

Per opsi I / O yang diizinkan dan klarifikasi dalam komentar pertanyaan, input diambil sebagai baris terpisah dalam tabel yang sudah ada t . Karena data dalam SQL secara inheren tidak berurutan, tabel itu mencakup bidang identitas "nomor baris" i :

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

Pada dasarnya SQL saya melakukan 3 subqueries, yang masing-masing mengembalikan 0atau 1berdasarkan pada 3 kriteria kode "persegi panjang". 3 nilai tersebut dikalikan bersama, hanya mengembalikan 1kode yang memenuhi semua 3.

EDIT : Gabungan kriteria 2 dan 3 ke dalam SELECT yang sama untuk menghemat ruang

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

The TRIM(v)Fungsi hanya didukung oleh SQL 2017 dan di atas. Versi sebelumnya akan perluLTRIM(RTRIM(v)) , yang akan membutuhkan penyeimbangan ulang baris.

Satu catatan acak: LEN()fungsi dalam SQL mengabaikan spasi tambahan, jadi LEN('foo ') = 3. Untuk mendapatkan "benar" panjang Anda harus menempelkan karakter ke akhir lalu kurangi satu: P


3

C ++, 199 183 181 175 bytes

Fungsi templat ini menerima baris sebagai kumpulan string (yang mungkin string lebar), dilewatkan sebagai sepasang iterator.

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

Terima kasih karena pengguna Salah karena mengingatkan saya pada back()anggota std::stringdan telah menunjukkan itunpos+1 itu nol.

Setara tidak disatukan

Satu-satunya golf nyata adalah menyatukan baris pertama dan terakhir sehingga kita dapat melakukan satu finduntuk spasi di dalamnya.

#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 uji

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

Ini dapat lebih lanjut di-golf menjadi 183 byte dengan lebar garis 22, menggunakan .find(' ')+1==0, dan s.back()bukannya *s.rbegin().
Keliru


2

Python 2 , 82 byte

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

Cobalah online!

Diminta sebagai f("abcd", "e fg", "hijk").


2

Haskell , 106 102 98 110 109 102 byte

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

Terima kasih kepada @nimi dan @Laikoni untuk setiap byte!

Cobalah online!


2

Haskell , 79 byte

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

Cobalah online! Mengambil input sebagai daftar baris.

Pola g(x:r)= ...mengikat baris pertama ke xdan daftar (mungkin kosong) dari sisa baris r. Kemudian all((==(0<$x)).(0<$))rperiksa apakah semua baris rmemiliki panjang yang sama dengan x(Menggunakan ujung ini ).

Jika tidak, maka hubungan &&arus pendek dan kembali False, jika tidak sisi kanan dievaluasi. Ada string build yang terdiri dari xuntuk baris pertama, last(x:r)untuk baris terakhir r(atau baris pertama lagi dalam kasus rkosong) dan (head<$>r)untuk karakter pertama dan (last<$>r)terakhir dari setiap baris. Untuk string ini, all(>='!')periksa apakah tidak mengandung spasi apa pun (kami tidak dapat menggunakan (>' ')karena pembatasan kode sumber).


Kesalahan pada "\ n \ n"
Angs

@Angs tangkapan bagus. Untungnya, OP mengklarifikasi bahwa input contains at least one character that is neither a newline nor a space, yang juga memungkinkan untuk menjatuhkan case daftar kosong.
Laikoni

Oh bagus, tidak menyadari bahwa ditambahkan
Angs

2

MATL , 13 byte

ctgF6Lt&()32>

Input adalah larik string, dalam format {'abc' 'de'}.

Output array yang berisi satunya, yang truthy , atau array yang mengandung setidaknya nol, yang falsey .

Cobalah online! Atau verifikasi semua kasus uji , termasuk uji kebenaran / kesalahan.

Penjelasan

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=~ Cobalah online! Hanya nulls bagian non-perbatasan, lalu periksa apakah ada spasi.
sundar - Reinstate Monica

@sundar Ide bagus! Itu cukup berbeda, poskan sendiri
Luis Mendo

1
Nah, terasa terlalu mirip dengan jawaban Anda, terutama jika saya menuliskannya sebagai cF6Lt&(32=~. Jangan ragu untuk mengeditnya, atau jika tidak kita bisa membiarkannya di komentar.
sundar - Reinstate Monica

1

JavaScript (ES6), 88 byte

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

Cobalah online!


1

Kanvas , 17 15 byte

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

Coba di sini!

Penjelasan (ASCII-fied untuk 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
Saya merasa ironis bahwa karakter UTF8 ini dalam font seperti monospace memberikan perasaan bahwa ada banyak ruang di sumbernya. (Setidaknya, mereka melakukannya di browser saya.)
Arnauld

1
@Arnauld karakter fullwidth melakukan itu. Dan itulah mengapa saya membuat font untuk juru bahasa saya untuk membuat mereka lebih cantik: p
dzaima

1

Perl 5 , 70 byte

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

Cobalah online!

Keluaran 0untuk kebenaran, angka lain untuk falsey.


1

Merah , 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]

Cobalah online!

Saya meletakkan banyak tanda kurung yang tidak perlu di baris pertama dan terakhir.


0

Jelly , 17 byte

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

Cobalah online!


@ JonathanFrech Ah, diperbaiki. > _>
Erik the Outgolfer

@MagicOctopusUrn Huh? Bisakah Anda menautkan ke input di mana ini tidak berlaku dengan benar?
Erik the Outgolfer

Oh, tidak, kau memanggil milikku Does not seem to enforce equal line lengthjuga yang kukatakan.
Magic Gurita Guci

Tampaknya tidak berfungsi untuk " \n " Coba online!
Angs

1
@Angs Coba kutip. Ini tampaknya diurai sebagai tidak ada jika Anda mengatakannya seperti itu.
Erik the Outgolfer

0

Jelly , 15 byte

Menggunakan metode yang dikembangkan oleh Mnemonic dalam (saat ini - karena kegagalan kasus tepi) menghapus pengiriman Pyth. (jika sekarang sudah diperbaiki, beri kredit !)

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

Tautan monadik yang menerima daftar karakter yang mengembalikan 1 atau 0.

Cobalah online!

Bagaimana?

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

Jawaban tidak bersaing: ada bug yang dikenal di Japt , di mana rotasi array dua dimensi memotong hasilnya. Karena bug itu, kode di bawah ini hanya berfungsi pada input yang persegi. Namun, jika bug tidak ada, kode di bawah ini akan berfungsi dengan benar.

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.

Mengambil input sebagai array string. Menggunakan tanda kurung alih-alih spasi membuat persyaratan kode persegi cukup mudah.
Coba di sini .


0

Ruby 2.5+, 63 byte

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

Mengambil input sebagai array string. Tidak ada tautan tes, karena versi pada TIO (2.4) terlalu tua untuk yang satu ini. Sebaliknya, ini versi yang sedikit lebih panjang (69 byte) untuk pengujian:

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

Cobalah online!

Perbedaannya adalah bahwa sejak 2.5 Ruby mendukung secara langsung melewati pola Regex ke all?, any?, none?metode, yang menyelamatkan kita beberapa byte. Metode itu sendiri cukup jelas - kami menguji:

  1. Jika hanya ada 1 ukuran garis yang unik
  2. Jika ada spasi di batas garis
  3. Jika ada spasi di baris pertama dan terakhir.

0

C (gcc) , 119 byte

Mengambil input sebagai daftar n string.

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

Cobalah online!


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;

Cobalah 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

Tidak ada spasi di baris pertama.
FrownyFrog

@FrownyFrog S[0].IndexOf(" ")sedang mencari spasi di baris pertama dan S[S.Count()-1].IndexOf(" ")mencari di baris terakhir. Jika tidak ada spasi di baris pertama dan terakhir, itu -2 yang kemudian benar -2 < -1.
Hille

2
Maksud saya tantangannya, kode Anda memiliki batasan yang sama, sehingga Anda tidak dapat memiliki spasi di baris pertama.
FrownyFrog

1
Kode Anda harus kembali Trueketika diteruskan ke program Anda. Ini merupakan batasan tambahan dalam tantangan ini.
FrownyFrog

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.