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


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.