Rileva testo rettangolare con codice rettangolare


19

Data una stringa di testo ASCII stampabile (inclusi righe e spazi nuovi) che contiene almeno un carattere che non è né una riga nuova né uno spazio, genera un valore di verità se la stringa è rettangolare e un valore di falsa in caso contrario. Inoltre, il codice sorgente per la soluzione deve essere rettangolare .

Una stringa è rettangolare se soddisfa tutte le seguenti condizioni:

  1. La prima riga e l'ultima riga non contengono spazi.
  2. Il primo e l'ultimo carattere di ogni riga non è uno spazio.
  3. Tutte le righe hanno lo stesso numero di caratteri.

Ad esempio, il seguente testo è rettangolare:

abcd
e fg
hijk

Questo testo, tuttavia, non è rettangolare (requisito n. 3):

1234
567
8900

Casi test

Truthy:

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

Questo è , quindi vince la soluzione più breve in byte.




9
Quindi, un one-liner senza spazio è una presentazione valida, giusto?
— Arnauld,


1
Possiamo prendere l'input come una matrice di stringhe, una per ogni riga? Oppure dobbiamo inserire una singola stringa lunga che include le interruzioni di riga?
— BradC,

Risposte:


12

C (gcc) , 127 125 124 118 byte

  • Salvato due byte giocando r*=!e&(!t|t==c);a r>>=e||t&&t-c;. (Questo golf è stato l'ispirazione per i miei recenti suggerimenti C in risposta a aggiornamento inverso della bandiera .)
  • Salvato un byte giocando *(_-2)a _[~1].
  • Hai salvato sei byte giocando *_++-10||(...)a golf *_++<11?...:0e utilizzando lo zero segnaposto ...:0(che non viene utilizzato in modo costruttivo) per golfare l' c++incremento. Quei campi da golf hanno permesso un ulteriore rimescolamento del circuito.
  • Quando si possono usare più valori di falso, potrebbero essere possibili 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;}

Provalo online!

Layout della sorgente che raggiunge un rettangolo più alto.

Spiegazione

Di seguito viene descritta la versione lunga 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)`

Provalo online!


10
+1 perr,e,c,t
— Magic Octopus Urn

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 grazie a @Neil .

Utilizza String[]ainvece di var a; return-r<0;invece di return r>0;; e ha aggiunto un commento //alla fine, quindi non ci sono spazi nella prima e nell'ultima riga.

Si noti che questo rettangolo è più corto di un input a riga singola, perché int r=1,...;dovrebbe essere sostituito int[]v{1,...};e tutti gli usi degli interi diventerebbero v[n](dove n è l'indice della variabile nell'array v).

Provalo online.

Spiegazione:

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

Ecco lo stesso programma di base con spazi ( 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 grazie a @Neil .

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

Uscite 1 per rettangolare, 0 altrimenti. Ho dovuto usare tonnellate di parentesi e parentesi extra per eliminare gli spazi, sono sicuro che ci sia un ampio margine di miglioramento.

Spiegazione :

In base alle nostre opzioni I / O consentite e ai chiarimenti nei commenti alle domande, l'input viene preso come righe separate in una tabella preesistente t . Poiché i dati in SQL sono intrinsecamente non ordinati, quella tabella include un campo di identità "numero di riga" i :

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

Fondamentalmente il mio SQL esegue 3 sottoquery, ognuna delle quali restituisce 0o in 1base ai 3 criteri del codice "rettangolare". Questi 3 valori vengono moltiplicati insieme, restituendo solo il 1codice che soddisfa tutti e 3.

MODIFICA : Combina i criteri 2 e 3 nello stesso SELEZIONA per risparmiare spazio

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

La TRIM(v)funzione è supportata solo da SQL 2017 e versioni successive. Avrebbero bisogno di versioni precedenti LTRIM(RTRIM(v)), che richiederebbero il riequilibrio delle file.

Una nota a caso: la LEN()funzione in SQL ignora gli spazi finali, quindi LEN('foo ') = 3. Per ottenere una lunghezza "vera" devi virare un personaggio fino alla fine, quindi sottrarne uno: P


3

C ++, 199 183 181 175 byte

Questa funzione modello accetta le linee come una raccolta di stringhe (che possono essere stringhe estese), passate come una coppia di iteratori.

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

Grazie all'utente Erroneous per avermi ricordato il back()membro di std::stringe per aver sottolineato che npos+1è zero.

Equivalente non golfato

L'unico vero golf è concatenare la prima e l'ultima riga in modo da poter eseguire un singolo findper gli spazi in quelli.

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

Programma di test

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

Questo può essere ulteriormente golfato a 183 byte con una larghezza della linea di 22, usando .find(' ')+1==0e s.back()invece di *s.rbegin().
— Erroneo


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

Provalo online!

Invoke as 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

Grazie a @nimi e @Laikoni per un byte ciascuno!

Provalo online!


2

Haskell , 79 byte

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

Provalo online! Accetta input come un elenco di righe.

Il modello g(x:r)= ...lega la prima riga a xe l'elenco (possibilmente vuoto) delle righe rimanenti a r. Quindi all((==(0<$x)).(0<$))rcontrolla se tutte le linee rhanno la stessa lunghezza di x(Utilizzando questo suggerimento ).

In caso contrario, la congiunzione &&cortocircuita e ritorna False, altrimenti viene valutata la parte destra. Lì viene creata una stringa che consiste xper la prima riga, last(x:r)per l'ultima riga di r(o nuovamente la prima riga nel caso rsia vuota) e (head<$>r)per il primo e (last<$>r)l'ultimo carattere di ogni riga. Per questa stringa, all(>='!')verifica che non contenga spazi (non possiamo utilizzarli a (>' ')causa della restrizione del codice sorgente).


Errori su "\ n \ n"
— Angs

@Angs Buona cattura. Fortunatamente, OP ha chiarito che l'input contains at least one character that is neither a newline nor a space, che consente anche di eliminare il caso elenco vuoto.
— Laikoni,

Oh bello, non ho notato che l'aggiunta
— Angs

2

MATL , 13 byte

ctgF6Lt&()32>

L'input è una matrice di stringhe, nel formato {'abc' 'de'}.

L'output è un array contenente solo quelli, che è veritiero , o un array contenente almeno uno zero, che è falso .

Provalo online! Oppure verifica tutti i casi di test , incluso il test di veridicità / falsità.

Spiegazione

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=~ provalo online! Annulla semplicemente le parti non di confine, quindi controlla se ci sono spazi.
— Sundar - Ripristina Monica il

@sundar Buona idea! È abbastanza diverso, pubblicalo tu stesso
— Luis Mendo il

1
No, mi sento troppo simile alla tua risposta, specialmente se la scrivo come cF6Lt&(32=~. Sentiti libero di modificarlo o, in caso contrario, possiamo semplicemente lasciarlo nei commenti.
— Sundar - Ripristina Monica il

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

Provalo online!


1

Tela , 17 15 byte

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

Provalo qui!

Spiegazione (ASCII-fied per 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
Trovo ironico che questi personaggi UTF8 in un carattere monospaziale diano la sensazione che ci siano molti spazi nella fonte. (Almeno, lo fanno nel mio browser.)
— Arnauld

1
I personaggi @Arnauld a tutta larghezza lo fanno. Ed è per questo che ho creato un font per il mio interprete per renderli più
— belli

1

Perl 5 , 70 byte

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

Provalo online!

Uscite 0per la verità, qualsiasi altro numero per la falsità.


1

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

Provalo online!

Ho messo molte parentesi altrimenti non necessarie nella prima e nell'ultima riga.


0

Gelatina , 17 byte

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

Provalo online!


@JonathanFrech Ah, risolto. > _>
— Erik the Outgolfer,

@MagicOctopusUrn Huh? Puoi collegarti a un input in cui questo non si comporta correttamente?
— Erik the Outgolfer,

Oh, no, hai chiamato il mio perché Does not seem to enforce equal line lengthanche quello che stavo dicendo.
— Magic Octopus Urn

Non sembra funzionare per " \n " Provalo online!
— Angs,

1
@Angs Prova a citarlo. Apparentemente è analizzato come niente se lo metti così.
— Erik the Outgolfer,

0

Gelatina , 15 byte

Utilizza un metodo sviluppato da Mnemonic in una trasmissione Pyth eliminata (attualmente - a causa di un errore del case-edge). (se è stato risolto, vai a dare un po 'di credito !)

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

Un collegamento monadico che accetta un elenco di caratteri che restituisce 1 o 0.

Provalo online!

Come?

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

Risposta non competitiva: esiste un bug noto in Japt , in cui le rotazioni di array bidimensionali troncano i risultati. A causa di quel bug, il codice seguente funziona solo su input quadrati. Se il bug non era presente, tuttavia, il codice seguente dovrebbe funzionare in modo completamente corretto.

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.

Accetta input come una matrice di stringhe. L'uso delle parentesi al posto degli spazi rende abbastanza semplice il requisito del codice rettangolare.
Provalo qui .


0

Rubino 2.5+, 63 byte

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

Accetta input come una matrice di stringhe. Nessun link di test, poiché la versione su TIO (2.4) è troppo vecchia per questa. Invece, ecco una versione leggermente più lunga (69 byte) per il test:

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

Provalo online!

La differenza è che dal 2.5 Ruby supporta il passaggio diretto di un modello Regex ai all?, any?, none?metodi, il che ci consente di risparmiare qualche byte. Il metodo stesso è abbastanza autoesplicativo - testiamo:

  1. Se esiste solo 1 dimensione di linea unica
  2. Se ci sono spazi sui confini della linea
  3. Se ci sono spazi sulla prima e sull'ultima riga.

0

C (gcc) , 119 byte

Prende l'input come un elenco di n stringhe.

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

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

Provalo 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

Nessuno spazio nella prima riga.
— FrownyFrog,

@FrownyFrog S[0].IndexOf(" ")sta cercando uno spazio nella prima riga e S[S.Count()-1].IndexOf(" ")sta cercando nell'ultima riga. Se non c'è spazio nella prima e nell'ultima riga, è -2 che è quindi vero su -2 < -1.
— Hille,

2
Intendo la sfida, il tuo codice ha la stessa restrizione, quindi non puoi avere spazi nella prima riga.
— FrownyFrog,

1
Il codice deve restituire una Truevolta passato al programma. È un'ulteriore limitazione in questa sfida.
— FrownyFrog,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.