Dikdörtgen Kod ile Dikdörtgen Metni Algılama


19

Ne yeni satır ne de boşluk olmayan en az bir karakter içeren yazdırılabilir ASCII metni dizisi (yeni satırlar ve boşluklar dahil) verildiğinde, dize dikdörtgense doğruluk değeri, aksi halde bir falsey değeri verir. Ayrıca, çözümünüzün kaynak kodu dikdörtgen olmalıdır .

Bir dize, aşağıdaki koşulların tümünü karşılıyorsa dikdörtgen şeklindedir:

  1. İlk satır ve son satır boşluk içermez.
  2. Her satırın ilk ve son karakteri boşluk değildir.
  3. Tüm satırlar aynı sayıda karaktere sahiptir.

Örneğin, aşağıdaki metin dikdörtgen şeklindedir:

abcd
e fg
hijk

Ancak bu metin dikdörtgen değildir (3. gereklilik):

1234
567
8900

Test Durumları

Doğru:

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

Bu , bu nedenle bayttaki en kısa çözüm kazanır.




9
Yani, boşluksuz bir astar geçerli bir sunum, doğru mu?
Arnauld


1
Her satır için bir tane olmak üzere bir dizi dizisi olarak girdi alabilir miyiz? Yoksa satır sonlarını içeren tek bir uzun dize mi girmeliyiz?
BradC

Yanıtlar:


12

C (gcc) , 127 125 124 118 bayt

  • Golf r*=!e&(!t|t==c);ile iki bayt kaydedildi r>>=e||t&&t-c;. (Bu golf benim son C ipuçları Ters bayrak güncelleme cevap ilham oldu .)
  • Golf *(_-2)ile bir bayt kaydedildi _[~1].
  • Artışı golf *_++-10||(...)yapmak *_++<11?...:0için yer tutucu sıfıra ...:0(yapıcı olarak kullanılmaz) golf yaparak ve onu kullanarak altı bayt tasarruf etti c++. Bu golfler biraz daha döngü değiştirmeye izin verdi.
  • Birden fazla falsey değeri kullanılabiliyorsa, 114 bayt mümkün olabilir.
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;}

Çevrimiçi deneyin!

Daha uzun bir dikdörtgen elde etmek için kaynak düzeni.

açıklama

Aşağıda 124 baytlık uzun versiyon açıklanmaktadır.

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

Çevrimiçi deneyin!


10
+1 içinr,e,c,t
Sihirli Ahtapot Urn

4

Java 10, 214 176 169 152 144 139 bayt

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

@Neil sayesinde -5 bayt .

String[]aBunun yerine kullanır var a; return-r<0;yerine return r>0;; ve //sonuna bir yorum ekledik , bu yüzden ilk ve son satırlarda boşluk yok.

Bu dikdörtgenin tek satırlık bir girişten daha kısa olduğuna int r=1,...;dikkat edilmelidir , çünkü bunun yerine değiştirilmesi gerekir int[]v{1,...};ve tamsayıların tüm kullanımları olur v[n](burada n dizideki değişkenin dizinidir v).

Çevrimiçi deneyin.

Açıklama:

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

İşte boşluklarla aynı temel program ( 128 126 bayt ):

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

@Neil sayesinde -2 bayt .

Çevrimiçi deneyin.



3

T-SQL, 237207 bayt

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

Dikdörtgen için çıkışlar 1, aksi takdirde 0. Boşlukları ortadan kaldırmak için tonlarca ekstra parens ve parantez kullanmak zorunda kaldım, eminim iyileştirilmesi için geniş bir alan var.

Açıklama :

İzin verilen I / O seçeneklerimiz ve soru yorumlarındaki açıklamalarımıza göre, giriş önceden var olan bir tabloda t ayrı satırlar olarak alınır . SQL'deki veriler doğal olarak sırasız olduğundan, bu tabloda bir "satır numarası" kimlik alanı i bulunur :

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

Temel olarak SQL'im, her biri döndürülen 0veya 1"dikdörtgen" kodun 3 ölçütüne dayanan 3 alt sorgu gerçekleştirir . Bu 3 değer birlikte çoğaltılır, yalnızca 13 kodun tümünü karşılayan kod için döndürülür.

DÜZENLEME : Yer kazanmak için ölçüt 2 ve 3'ü aynı SELECT içinde birleştirin

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

TRIM(v)İşlevi yalnızca SQL 2017 ve üstü tarafından desteklenmektedir. LTRIM(RTRIM(v))Satırların yeniden dengelenmesini gerektiren önceki sürümlere ihtiyaç duyulur .

Bir rasgele not: LEN()SQL'deki fonksiyon sondaki boşlukları yok sayar LEN('foo ') = 3. "Gerçek" bir uzunluk elde etmek için sonuna kadar bir karakteri yapıştırmanız ve ardından bir karakteri çıkarmanız gerekir: P


3

C ++, 199 183 181 175 bayt

Bu şablon işlevi, satırları bir çift yineleyici olarak iletilen bir dizi dizgi (geniş dizeler olabilir) olarak kabul eder.

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

Erroneous kullanıcısına bana back()üyeyi hatırlattığı std::stringve npos+1bunun sıfır olduğunu işaret ettiği için teşekkür ederiz .

Ungolfed eşdeğeri

Tek gerçek golf, ilk ve son çizgileri birleştirmektir, böylece findbu alanlarda boşluklar için bir tane yapabiliriz .

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

Test programı

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

Bu, çizgi genişliği 22 .find(' ')+1==0olan ve s.back()yerine 183 bayta daha da golf edilebilir *s.rbegin().
Hatalı



2

Haskell , 106 102 98 110 109 102 bayt

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

Her bayt için @nimi ve @Laikoni'ye teşekkürler!

Çevrimiçi deneyin!


2

Haskell , 79 bayt

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

Çevrimiçi deneyin! Girişi satır listesi olarak alır.

Desen g(x:r)= ..., ilk satırı xve kalan satırların (muhtemelen boş) listesini bağlar r. Ardından all((==(0<$x)).(0<$))r, tüm satırların ( Bu ucu kullanarak ) ile raynı uzunlukta olup olmadığını kontrol edin .x

Değilse, bağlantı &&kısa devre yapar ve geri döner False, aksi takdirde sağ taraf değerlendirilir. xİlk satır last(x:r)için, son satırın r(veya rboş olması durumunda yine ilk satırın ) ve her satırın (head<$>r)ilk ve (last<$>r)son karakterinden oluşan bir dize oluşturulur . Bu dize için all(>='!')boşluk içermediğini kontrol eder ( (>' ')kaynak kodu kısıtlaması nedeniyle kullanamayız ).


"\ N \ n" ile ilgili hatalar
18:18 Angs

@Angs İyi yakalama. Neyse ki OP contains at least one character that is neither a newline nor a space, boş liste durumunu bırakmaya izin veren girdinin de netleştiğini belirtti .
Laikoni

Oh güzel, eklendiğini fark etmedi
Angs

2

MATL , 13 bayt

ctgF6Lt&()32>

Girdi, biçimdeki dizelerden oluşan bir dizidir {'abc' 'de'}.

Çıkış sadece olanlar içeren bir dizi, bir truthy , ya da en az bir sıfır içeren bir dizi, Falsey .

Çevrimiçi deneyin! Veya doğruluk / yanlışlık testi de dahil olmak üzere tüm test durumlarını doğrulayın .

açıklama

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 bayt: cO6Lt&(32=~ Çevrimiçi deneyin! Kenarlık olmayan kısımları geçersiz kılar, ardından boşluk olup olmadığını kontrol eder.
sundar - Monica'yı

@sundar İyi fikir! Bu yeterince farklı, kendiniz gönderin
Luis Mendo

1
Hayır, cevabınıza çok benziyor, özellikle de yazarsam cF6Lt&(32=~. Düzenlemek için çekinmeyin, yoksa değilse yorumlarda bırakabiliriz.
sundar - Eski Monica


1

Tuval , 17 15 bayt

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

Burada deneyin!

Açıklama (tek aralık için ASCII alanı):

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
Tek boşluklu bir yazı tipindeki bu UTF8 karakterlerinin kaynakta birçok boşluk olduğu hissini vermesi ironik buluyorum. (En azından tarayıcımda yapıyorlar.)
Arnauld

1
@ Tam genişlikli karakterler bunu yapabilir. Bu yüzden tercümanımın daha güzel olması için bir yazı tipi yaptım: p
dzaima


1

Kırmızı , 216 191 bayt

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]

Çevrimiçi deneyin!

İlk ve son sıralara çok fazla gerekli olmayan parantez koydum.


0

Jöle , 17 bayt

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

Çevrimiçi deneyin!


@JonathanFrech Ah, düzeltildi. > _>
Outgolfer Erik

@MagicOctopusUrn Huh? Lütfen bunun doğru davranmadığı bir girişe bağlantı verebilir misiniz?
Outgolfer Erik

Oh, hayır, sen de benim Does not seem to enforce equal line lengthsöylediğim tek şey benimkini çağırdın .
Sihirli Ahtapot Urn

İçin işe görünmüyor " \n " çevrimiçi deneyin!
Angs

1
@Angs Alıntı yapmayı deneyin. Eğer böyle koyarsanız görünüşte hiçbir şey olarak ayrıştırılır.
Outgolfer Erik

0

Jöle , 15 bayt

Mnemonic tarafından geliştirilen (şu anda - bir uç durum hatası nedeniyle) silinmiş Pyth sunumunda bir yöntem kullanır. (şimdi düzeltildiyse, git ve biraz kredi ver !)

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

1 veya 0 döndüren karakterlerin listesini kabul eden monadik bir bağlantı.

Çevrimiçi deneyin!

Nasıl?

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

Rekabetçi olmayan cevap: Japt'ta iki boyutlu dizi rotasyonlarının sonuçları kısalttığı bilinen bir hata var . Bu hata nedeniyle aşağıdaki kod yalnızca kare girişlerde çalışır. Hata yoksa, aşağıdaki kodun tamamen doğru çalışması gerekir.

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.

Girdiyi dizeler dizisi olarak alır. Boşluk yerine parantez kullanmak dikdörtgen kod gereksinimini oldukça kolaylaştırır.
Burada deneyin .


0

Ruby 2.5+, 63 bayt

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

Girdiyi dizeler dizisi olarak alır. Test bağlantısı yok, çünkü TIO (2.4) sürümü bu sürüm için çok eski. Bunun yerine, test için biraz daha uzun (69 bayt) bir sürüm var:

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

Çevrimiçi deneyin!

Aradaki fark, 2.5 Ruby'nin bir Regex modelini doğrudan all?, any?, none?yöntemlere geçirmeyi desteklemesidir , bu da bize birkaç bayt kazandırır. Yöntemin kendisi oldukça açıklayıcıdır - test ediyoruz:

  1. Yalnızca 1 benzersiz satır boyutu varsa
  2. Çizgi sınırlarında boşluk varsa
  3. İlk ve son satırlarda boşluklar varsa.

0

C (gcc) , 119 bayt

Girdiyi n karakter dizisinin listesi olarak alır.

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

Çevrimiçi deneyin!


0

C # (.NET Çekirdek) , 145 167 bayt

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;

Çevrimiçi deneyin!

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

İlk satırda boşluk yok.
FrownyFrog

@FrownyFrog S[0].IndexOf(" ")ilk satırda boşluk S[S.Count()-1].IndexOf(" ")arıyor ve son satırda arıyor. İlk ve son satırda boşluk yoksa, -2 olur ve bu da doğrudur -2 < -1.
Hille

2
Yani meydan okuma, kodunuz aynı kısıtlamaya sahip, bu yüzden ilk satırda boşluk olamaz.
FrownyFrog

1
Kodunuz Trueprogramınıza iletildiğinde geri dönmelidir . Bu mücadelede ek bir kısıtlama var.
FrownyFrog

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.