Виявити прямокутний текст за допомогою прямокутного коду


19

З огляду на рядок тексту для друку ASCII (включаючи нові рядки та пробіли), що містить принаймні один символ, який не є ні новою лінією, ні пробілом, виведіть триєдине значення, якщо рядок прямокутний, а значення фальси - в іншому випадку. Крім того, вихідний код вашого рішення повинен бути прямокутним .

Рядок прямокутний, якщо він відповідає всім наступним умовам:

  1. Перший і останній рядки не містять пробілів.
  2. Перший і останній символи кожного рядка не є пробілом.
  3. Усі рядки мають однакову кількість символів.

Наприклад, наступний текст прямокутний:

abcd
e fg
hijk

Цей текст, однак, не є прямокутним (вимога №3):

1234
567
8900

Випробування

Truthy:

sdghajksfg
asdf
jkl;
qwerty
u i op
zxcvbn
1234
5  6
7890
abcd
e fg
hijk

Фальсі:

a b c
123
456
7 9
12
345
qwerty
 uiop
zxcvnm
1234
567
8900

Це , тому найкоротше рішення в байтах виграє.




9
Отже, однолінійний без будь-якого місця є коректним поданням, правильно?
— Арнольд


1
Чи можемо ми взяти введення як масив рядків, по одному для кожного рядка? Або ми мусимо ввести один довгий рядок, що включає розриви рядків?
— БредК

Відповіді:


12

C (gcc) , 127 125 124 118 байт

  • Зберегли два байти гольфу r*=!e&(!t|t==c);в r>>=e||t&&t-c;. (Цей гольф був натхненником для моїх останніх підказок C, які відповідають на зворотне оновлення прапора .)
  • Збережено байт, погравши *(_-2)в гольф _[~1].
  • Збережено шість байтів від гри в гольф , *_++-10||(...)щоб *_++<11?...:0і використовуючи заповнювач нуля ...:0(який не використовується конструктивно) для ГОЛЬФ c++збільшення. Ці гольфи дозволили зробити ще певну перестановку циклу.
  • Коли можна використовувати кілька значень фальси, може бути 114 байт .
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;}

Спробуйте в Інтернеті!

Макет джерела досягає більш високого прямокутника.

Пояснення

Далі пояснюється версія 124 байт.

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

Спробуйте в Інтернеті!


10
+1 заr,e,c,t
— Magic Octopus Urn

4

Java 10, 214 176 169 152 144 139 байт

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 байт завдяки @Neil .

Використовує String[]aзамість var a; return-r<0;замість return r>0;; і додав коментар //у самому кінці, тому в першому та останньому рядках немає пробілів.

Зауважте, що цей прямокутник коротший, ніж однорядковий вхід, тому що його int r=1,...;слід замінити int[]v{1,...};, і все використання цілих чисел потім стане v[n](де n - індекс змінної в масиві v).

Спробуйте в Інтернеті.

Пояснення:

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

Ось та сама базова програма з пробілами ( 128 126 байт ):

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 байти завдяки @Neil .

Спробуйте в Інтернеті.



3

T-SQL, 237 207 байт

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

Виходи 1 для прямокутних, 0 в іншому випадку. Мені довелося використовувати тонни додаткових парен і дужок для усунення простору, я впевнений, що є багато можливостей для вдосконалення.

Пояснення :

Згідно з нашими дозволеними параметрами вводу-виводу та уточненнями у коментарях до запитання, введення приймається окремими рядками у попередньо існуючій таблиці t . Оскільки дані в SQL невід'ємно невпорядковані, що таблиця включає в себе поле ідентифікатора «номер рядка» I :

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

В основному мій SQL виконує 3 підзапити, кожен з яких повертає 0або 1базується на 3 критеріях «прямокутного» коду. Ці 3 значення множимо разом, повертаючи лише 1код, який задовольняє всі 3.

EDIT : Об'єднані критерії 2 і 3 в один і той же SELECT для економії місця

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)Функція підтримується тільки SQL 2017 і вище. Потрібні більш ранні версії LTRIM(RTRIM(v)), які потребуватимуть переврівноваження рядків.

Одне випадкове зауваження: LEN()функція в SQL ігнорує проміжні пробіли, так LEN('foo ') = 3. Щоб отримати "справжню" довжину, вам потрібно докласти символ до кінця, а потім відняти один: P


3

C ++, 199 183 181 175 байт

Ця функція шаблону приймає рядки як сукупність рядків (які можуть бути широкими рядками), переданих у вигляді пари ітераторів.

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

Дякуємо користувачеві Помилково за те, що він нагадав мені про back()член std::stringта вказав, що npos+1це нуль.

Безголівковий еквівалент

Єдиний справжній гольф - це поєднання першої та останньої ліній, щоб ми могли виконати сингл findдля пробілів у них.

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

Тестова програма

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

Це може бути надано в гольф до 183 байт з шириною лінії 22, використовуючи .find(' ')+1==0і s.back()замість цього *s.rbegin().
— Помилково




2

Хаскелл , 79 байт

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

Спробуйте в Інтернеті! Вводиться як список рядків.

Шаблон g(x:r)= ...прив'язує перший рядок до xта (можливо, порожній) список інших рядків r. Потім all((==(0<$x)).(0<$))rперевіряє, чи всі рядки rмають однакову довжину x(Використовуючи цю підказку ).

Якщо ні, то сполучення &&коротке замикання та повернення False, інакше оцінюється права частина. Там будується рядок, що складається з xпершого рядка, last(x:r)для останнього рядка r(або першого рядка знову у випадку, якщо rвін порожній) та (head<$>r)для першого та (last<$>r)останнього символу кожного рядка. Для цього рядка all(>='!')переконайтеся, що він не містить пробілів (ми не можемо використовувати (>' ')через обмеження вихідного коду).


Помилки на "\ n \ n"
— Angs

@Angs Хороший улов. На щастя, ОП уточнила, що вхід contains at least one character that is neither a newline nor a space, який також дозволяє скинути порожній список випадків.
— Лайконі

О, приємно, не помітили, що додано
— Angs

2

MATL , 13 байт

ctgF6Lt&()32>

Введення - це масив рядків у форматі {'abc' 'de'}.

Вихід - це масив, що містить лише ті, що є truthy , або масив, що містить принаймні нуль, який є фальсі .

Спробуйте в Інтернеті! Або перевірити всі тестові випадки , включаючи перевірку правдивості / фальшивості.

Пояснення

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 байт: cO6Lt&(32=~ Спробуйте в Інтернеті! Просто викреслює безмежні частини, а потім перевіряє, чи є пробіли.
— sundar

@sundar Хороша ідея! Це досить різне, опублікуйте самі
— Луїс Мендо

1
Ні, відчуваєш себе занадто схожою на твою відповідь, особливо якщо я записую її як cF6Lt&(32=~. Не соромтеся відредагувати його, а якщо ні, ми можемо просто залишити його в коментарях.
— sundar


1

Полотно , 17 15 байт

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

Спробуйте тут!

Пояснення (ASCII-файл для монопростору):

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
Я вважаю іронічним, що ці символи UTF8 моноспейковим шрифтом дають відчуття, що у джерелі є багато пробілів. (Принаймні, вони роблять у моєму браузері.)
— Арнольд

1
@Arnauld символи повної ширини роблять це. І тому я зробив шрифт для свого перекладача, щоб зробити їх красивішими: p
— dzaima



0

Желе , 17 байт

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

Спробуйте в Інтернеті!


@JonathanFrech Ах, виправлено. > _>
— Ерік Аутгольфер

@MagicOctopusUrn Так? Чи можете ви надати посилання на вклад, де це не так правильно?
— Ерік Аутгольфер

О, ні, ви теж зателефонували моєму, Does not seem to enforce equal line lengthце все, що я говорив.
— Чарівна восьминога урна

Схоже, це не працює для " \n " Спробуйте його онлайн!
— Ангс

1
@Angs Спробуйте цитувати його. Це, мабуть, розбирається як ніщо, якщо ви поставите це так.
— Ерік Аутгольфер

0

Желе , 15 байт

Використовує метод, розроблений Mnemonic у видаленому Pyth поданні (на даний момент - через збій у крайньому випадку). (якщо це зараз виправлено, ідіть, дайте кредит !)

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

Монадічне посилання, що приймає список символів, який повертає 1 або 0.

Спробуйте в Інтернеті!

Як?

Ỵµ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 :)
— Джонатан Аллан

0

Japt , 22 байти

Неконкурентна відповідь: у Japt є відома помилка , де двовимірні обертання масиву обрізають результати. Через цю помилку код нижче працює лише на введеннях, які є квадратними. Якщо ж помилки не було, код нижче повинен працювати повністю коректно.

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.

Приймає введення як масив рядків. Використання дужок замість пробілів робить вимогу прямокутного коду досить простою.
Спробуйте тут .


0

Рубін 2,5+, 63 байти

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

Приймає введення як масив рядків. Немає тестового посилання, оскільки версія TIO (2.4) занадто стара для цієї версії. Натомість, ось дещо довша (69 байт) версія для тестування:

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

Спробуйте в Інтернеті!

Різниця полягає в тому, що оскільки 2,5 Ruby підтримує пряму передачу шаблону Regex all?, any?, none?методам, що економить нам кілька байт. Сам метод досить зрозумілий - ми перевіряємо:

  1. Якщо є лише 1 унікальний розмір рядка
  2. Якщо на межі лінії є пробіли
  3. Якщо в першому та останньому рядках є пробіли.


0

C # (.NET Core) , 145 167 байт

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;

Спробуйте в Інтернеті!

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

У першому рядку немає пробілів.
— FrownyFrog

@FrownyFrog S[0].IndexOf(" ")шукає пробіл у першому рядку та S[S.Count()-1].IndexOf(" ")шукає в останньому рядку. Якщо в першому та останньому рядку немає місця, це -2, що відповідає дійсності в -2 < -1.
— Хілл

2
Я маю на увазі виклик, ваш код має однакове обмеження, тому ви не можете мати пробілів у першому рядку.
— FrownyFrog

1
Ваш код повинен повернутися Trueпісля передачі вашій програмі. Це додаткове обмеження в цьому виклику.
— FrownyFrog

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.