Написать хайку-ш детектор


41

Хайку стихотворение с тремя линиями, с 5/7/5 слога счета, соответственно.

Хайку-ш стихотворение с тремя линиями, с 5/7/5 слова графа, соответственно.

Вызов

Напишите программу, которая будет возвращать истину, если ввод является haiku-w, и ложь, если нет.

Допустимый ввод haiku-w должен состоять из 3 строк, разделенных новой строкой.

  • Строка 1 должна состоять из 5 слов, каждое слово разделяется пробелом.
  • Строка 2 должна состоять из 7 слов, каждое слово разделяется пробелом.
  • Строка 3 должна состоять из 5 слов, каждое слово разделяется пробелом.

Примеры

The man in the suit
is the same man from the store.
He is a cool guy.

Результат: правда

Whitecaps on the bay:
A broken signboard banging
In the April wind.

Результат: Ложь


правила

  • Это , поэтому выигрывает самый короткий ответ в байтах.
  • Применяются стандартные лазейки для игры в гольф. Обман запрещен.
  • Другие логические возвращаемые значения, такие как 1и 0, являются приемлемыми.
  • Список строк длины 3 в качестве входных данных также допустим.
  • Допустимые входные данные haiku-w не должны иметь начальных или конечных пробелов или нескольких пробелов, разделяющих слова.

1
Хайку-ж всегда будет содержать 3 строки?
Kritixi Lithos

1
Да. Если вход содержит больше или меньше чем 3 строки, программа должна возвратить false .
DomTheDeveloper

5
Будут ли когда-нибудь пробелы в начале или в конце строки? Или несколько пробелов, разделяющих слова?
Грег Мартин

8
Кстати, подобные разъяснения являются основной причиной, чтобы сначала опубликовать предложенные вопросы в Песочнице . :)
Грег Мартин

11
Бонусные баллы за представления, где сам код является хайку-в.
Глорфиндель

Ответы:


25

JavaScript (ES6), 73 72 64 63 54 42 39 байт

Спасибо Нейлу за сохранение 13 байтов

a=>a.map(b=>b.split` `.length)=='5,7,5'

объяснение

Это функция жирной стрелки, которая принимает массив строк в качестве аргумента. Он заменяет каждую строку количеством слов. Если это хайку-в, aтеперь он содержит массив из пяти, семи и пяти раз. Поскольку JavaScript не позволяет сравнивать 2 массива одновременно, массив сначала преобразуется в строку, а затем сравнивается. Это приводит к логическому значению, которое возвращается.


1
%и *имеют такой же приоритет, так что вам не нужны ()s, хотя я думаю, что (d*2|5)может также работать. Также вы можете сойти с рук с одним &, хотя я думаю, что вы можете улучшить даже с помощью (b...).length==3>b.some(...length-...).
Нил

Спасибо за совет о скобках. Кроме того, я изменил свой подход, поэтому я больше не проверяю длину.
Лука

1
Ах, в этом случае, не беспокойтесь о расчете, просто используйте a=>a.map(c=>c.split .length)=='5,7,5'.
Нил

Хе-хе, ты прав. Я должен был подумать об этом ...
Лука

Вам по-прежнему не нужны строки +''- ==если другой аргумент является строкой.
Нил

12

AWK (GNU Awk), 24, 30, 2820 байтов

Golfed

517253==$0=q=q NF NR

Выведет «517253» для True и пустую строку для False .

В awk любое ненулевое числовое значение или любое непустое строковое значение имеет значение true. Любое другое значение (ноль или пустая строка, "") является ложным

Руководство пользователя GNU Awk

Как это работает

Каждый оператор (правило) awk состоит из шаблона (или выражения) со связанным действием:

pattern {action}

Awk будет читать входные данные построчно (запись за записью) и оценивать выражение шаблона, чтобы увидеть, должно ли быть вызвано соответствующее действие.

Приведенный выше код является автономным выражением (шаблоном) Awk без блока действий, что подразумевается {print $0}в этом случае.

Следует читать справа налево:

q=q NF NR

Присоединять Н умбру из F ields (слова) и N умбры из R ecords (т.е. номер текущей строки), к переменному ц .

Таким образом, при обработке правильного Haiku-w, q будет установлен в:

  • 51 - в строке № 1 (5 слов)
  • 5172 - в строке № 2 (5 слов + 7 слов)
  • 517253 - в строке № 3 (5 слов + 7 слов + 5 слов)

$0=q

Присвоить вновь вычисленное значение ц к $ 0 (который содержит всю текущую строку / запись по умолчанию).

517253==$0

Сравните его с «подписью» для правильного Haiku-w (517253), если есть совпадение, все выражение оценивается как «true», и выполняется соответствующее действие (неявное print $0), отправляя «517253» в stdout (True) иначе вывод будет пустым (False).

Обратите внимание, что это правильно распознает Haiku-w, даже если за ним следует произвольное количество строк мусора, но я считаю, что это нормально, так как:

Список строк длины 3 в качестве входных данных также допустим.

(то есть мы можем предположить, что входное значение имеет длину 3 строки)

Тест

>awk '517253==$0=q=q NF NR'<<EOF
The man in the suit
is the same man from the store.
He is a cool guy.
EOF

517253

Попробуйте онлайн!


2
Это не удается, если входные данные состоят из одной строки, содержащей 575 слов, или двух строк, содержащих 57 и 5 слов и т. Д.
Линн

@ Линн, правда, отложено, пока это не исправлено.
Цеппелин

@Lynn, должен быть исправлен
дирижаблем

1
Очень умное исправление! :)
Линн

9

питон , 42 байта

lambda l:[s.count(' ')for s in l]==[4,6,4]

Попробуйте онлайн!

Вводит в виде списка строк со словами, разделенными пробелами.

Поскольку мы гарантируем, что не будет начальных или конечных пробелов, и каждое слово будет разделять только отдельные пробелы, мы можем проверить w-haiku, просто посчитав пробелы в каждой строке.

Мы делаем это в понимании списка, чтобы создать список счетчиков пробелов. Если это правильный хайку, он должен выглядеть следующим образом [4, 6, 4], поэтому мы сравним его с этим и вернем результат.


Если все в порядке с поддержкой только Python 2, вы можете сохранить два байта: map(str.count,l,' ').
пр.

8

Желе , 10 9 байт

ċ€⁶⁼“¥©¥‘

Попробуйте онлайн!

объяснение

ċ€⁶⁼“¥©¥‘  Input: length-3 list of strings
 €         For each string
ċ ⁶          Count the number of spaces
    “¥©¥‘  Convert string to code page indices, makes [4, 6, 4]
   ⁼       Match

Кроме того, ċ€⁶⁼4,6,4и ċ€⁶⁼464D¤... я не могу найти ничего короче, хотя. (Ах, вы можете перевернуть его, тоже: 464D⁼ċ€⁶$)
Lynn

ċ€⁶Ḍ=464отлично работает на 8.
Джонатан Аллан

На самом деле, нет, нет , извините.
Джонатан Аллан

7

Пакет, 102 байта

@echo off
call:c&&call:c 2||exit/b
:c
set/an=%1+5
set/ps=
for %%W in (%s%)do set/an-=1
exit/b%n%

Выход с ненулевым уровнем ошибки, как только он читает строку с неправильным количеством слов.


1
...... хорошо дерьмо
tbodt

7

Mathematica, 21 байт

{4,6,4}==Count@" "/@#&

Безымянная функция, принимающая список символов в качестве входных данных и возвращающая TrueилиFalse . Просто подсчитывает, сколько пробелов в каждом списке символов, которые по правилам задачи прекрасно соотносятся с количеством слов в каждой строке.

Предыдущее представление:

Mathematica, 31 байт

Length/@StringSplit/@#=={5,7,5}&

Безымянная функция, принимающая список строк в качестве входных данных и возвращающая Trueили False.



6

Сетчатка , 12 байт

M%` 
^4¶6¶4$

(после первой строки есть пробел)

Попробуйте онлайн!

  • M%`  - Подсчитайте количество пробелов в каждой строке.

    • M - Режим матча - вывести количество матчей.
    • % - для каждой строки
    • ` - отдельная конфигурация и шаблон регулярных выражений
    • - просто пробел.
  • ^4¶6¶4$ - должно быть 4, 6 и 4 пробела и ровно три строки.

    • соответствует новым строкам Остальное - простое регулярное выражение.

Печать 1для правильного ввода, 0для недействительного.


4

Python, 58 44 байта

lambda h:[len(l.split())for l in h]==[5,7,5]

-14 от tbodt


Вам разрешено принимать входные данные в виде списка строк длиной 3. Вы можете сохранить использованные байты split("\n").
миль

44 байта:lambda h:[len(l.split())for l in h]==[5,7,5]
tbodt

Кто-то делает это короче, чтобы достичь вычеркнуты 44
Чарли


4

Pyth, 9 байт

qj464T/R;

Программа, которая принимает ввод списка "quoted strings"и печатает TrueилиFalse при необходимости.

Тестирование

Как это работает

qj464T/R;   Program. Input: Q
qj464T/R;Q  Implicit variable fill
     T      Are the base-10
 j          digits
  464       of 464
q           equal
      /     to the number
        ;   of spaces
       R    in each string
         Q  in the input?
            Implicitly print


4

PowerShell , 43 байта

"$args"-replace'\S'-match'^(    )
\1  
\1$'

Попробуйте онлайн!

объяснение

Принимает ввод в виде строки, разделенной новой строкой.

Удаляет все непустые пробелы, затем проверяет, что он точно соответствует «4 пробела, новая строка, 6 пробелов, новая строка, 4 пробела новая строка», используя регулярное выражение.

Группа захвата соответствует 4 пробелам, обратная ссылка \1относится к этому. Новые строки встраиваются в строку. Обратите внимание, что вторая строка регулярного выражения содержит два пробела после обратной ссылки.


1
Это интересный подход!
Исмаэль Мигель


3

J, 12 байт

4 6 4=#@;:@>

Ввод представляет собой список строк в штучной упаковке.

объяснение

Это вилка с постоянным левым зубцом. Это проверяет результат правильного зубца #@;:@>на равенство с 4 6 4. Правильное время распаковывает каждый ( >), затем ( @) преобразует каждую строку в слова ( ;:), затем ( @) принимает длину каждого ( #).


3

R, 48 байтов

all(stringr::str_count(scan(,"")," ")==c(4,6,4))

Читает 3-х символьный вектор из стандартного ввода и работает, считая количество пробелов. Для подсчета количества пробелов мы используем пакет str_countfrom stringr, который может рассчитывать вхождения на основе шаблона регулярных выражений.

Альтернативный подход без использования пакетов может быть:

all(sapply(scan(,""),function(x)length(el(strsplit(x," "))))==c(5,7,5))

Первый раз, когда я когда-либо видел el, спасибо за это.
BLT

3

C 142 байта

void f(){char *c;l=3;s[3]={0};while(l>0){if(*c==' ')s[l-1]++;if((*c=getchar())=='\n'){l--;}}printf("%d",(s[0]==4 && s[1]==6 && s[2]==4)?1:0);}

Безголовая версия:

void f()
{
  char *c;
  c = (char *)malloc(sizeof(char)); 
  int l=3;
  int s[3]= {0};


  while(l>0)
  {  
    if(*c==' ')
    s[l-1]++;

    if( (*c=getchar())=='\n')
    {    
      l--;
    }   
  }
  printf("%d",(s[0]==4 && s[1]==6 && s[2]==4)?1:0);
}

Возвращает 1 для последовательности 5/7/5, иначе 0.

Положительный тест:

введите описание изображения здесь


3

C ++, 357 байт

Что-то новенькое в коде гольфа, но это лучшее, что я мог сделать быстро

#include <iostream>
using namespace std;
int n(std::string s)
{
    int b = 0;
    for(char c: s)
        if(c == ' ') b++;
    cout << "C = " << b;
    return b;
}
int main()
{
    string a, b, c;
    getline(cin, a);
    getline(cin, b);
    getline(cin, c);
    if(n(a)==4 && n(b)==6 && n(c)==4)
        cout<<'1';
    else cout << '0';
    return 0;
}

4
Добро пожаловать в PPCG! Цель Code Golf - сделать ваш код максимально коротким; хорошим первым шагом было бы удалить все ненужные пробелы.
ETHproductions

3

Ruby 1.9.3

Не в гольф, но сам по себе хайку

def haiku_w(input)
  lines = input.split("\n")
  lengths = lines.map(&:split).map(&:length)
  lengths.eql?([5,7,5])
end

или...

lines equals input split (newlines)
lengths equals lines map split map length
lengths equals five seven five?

К сожалению, не работает с пробелами в начале строки, но справляется с трейлингом.


2

Python 2 , 57 64 байта

Редактирование Исправлено с добавлением 7 байтов после обратной связи от @Dada. Благодарность!

i,j=input,''
for x in i():j+=`len(x.split())`+' '
i(j=='5 7 5 ')

Попробуйте онлайн!

Не самый короткий Python-ответ на долгом пути, а просто хотел использовать новый трюк, который я недавно узнал, input()чтобы отобразить вывод и сохранить printоператор. Принимает список строк в качестве входных данных. Требуется Ctrl C (или любое другое нажатие клавиши), чтобы завершить программу (за исключением) в терминале, но прекрасно работает без TIO.


4
Это не удастся в таких случаях, как этот .
Дада

Я дам тебе это @Dada. Это один серьезный тестовый случай :)
ElPedro

Исправлено и проверено вашим тестовым примером.
ElPedro

2

MATL, 16 байт

"@Y:Ybn&h][ACA]=

Входные данные представляют собой массив ячеек строк и возвращают массив правдивости или ложности .

Попробуйте онлайн

объяснение

        % Implicitly grab input
"       % For each element in the cell array
@Y:Yb   % Split it on spaces
n       % Count the number of elements
&h      % Horizontally concatenate everything on the stack
[ACA]   % Create the array [5 7 5]
=       % Perform an element-wise equality
        % Implicitly display the truthy/falsey array

2

MATLAB / Octave, 38 байт

@(x)cellfun(@(y)sum(y==32),x)==[4 6 4]

Это решение принимает массив ячеек строк в качестве входных данных, подсчитывает количество пробелов в каждой строке, а затем сравнивает результат с массивом [4 6 4]и выдает массив true (все значения равны 1) или false (любое значение равно нулю).

Онлайн демо



2

Clojure, 44 байта

#(=(for[l %](count(filter #{\ }l)))'(4 6 4))

Ввод списка строк. Функция находит только пробелы и считает их. Это объяснение хайку. :)


2

Java 7, 154 байта

class M{public static void main(String[]a){System.out.print(a.length==3&&a[0].split(" ").length==5&a[1].split(" ").length==7&a[2].split(" ").length==5);}}

Требование программы и возможность иметь менее или более трех строк, не говоря уже о многословности Java, делают этот «гольфовый» код довольно большим.

Ungolfed:

Попробуй это здесь.

class M{
  public static void main(String[] a){
    System.out.print(a.length == 3
        && a[0].split(" ").length == 5
         & a[1].split(" ").length == 7
         & a[2].split(" ").length == 5);
  }
}

2

SimpleTemplate, 77 байт

К сожалению, регулярное выражение aproach является самым коротким.

{@if"@^([^\s]+ ?){5}\s([^\s]+ ?){7}\s([^\s]+ ?){5}+$@"is matchesargv}{@echo1}

Требует, чтобы в качестве первого аргумента был указан текст с символами новой строки * NIX. Это не будет работать с переводами в стиле Windows.

Ungolfed:

{@if "@^([^\s]+ ?){5}\s([^\s]+ ?){7}\s([^\s]+ ?){5}+$@"is matches argv}
    {@echo 1}
{@/}

Не на основе регулярных выражений, 114 байтов

{@setR 1}{@eachargv asL keyK}{@php$DATA[L]=count(explode(' ',$DATA[L]))!=5+2*($DATA[K]&1)}{@set*R R,L}{@/}{@echoR}

Это требует, чтобы каждая строка была задана в качестве аргумента функции.

Ungolfed:

{@set result 1}
{@each argv as line key k}
    {@php $DATA['line'] = count(explode(' ', $DATA['line'])) != 5+2*( $DATA['k'] & 1 )}
    {@set* result result, line}
{@/}
{@echo result}

2

Stacked, 22 байта

[' 'eq sum]map(4 6 4)=

Принимает ввод с вершины стека как список строк символов, как таковой:

($'The man in the suit' $'is the same man from the store.' $'He is a cool guy.')

объяснение

[' 'eq sum]map(4 6 4)=
[         ]map          map the following function over each item
 ' 'eq                  vectorized equality with ' '
       sum              summed
              (4 6 4)=  is equal to (4 6 4)

2

Java (OpenJDK) , 82 байта

-2 байта благодаря @ corvus_192!

s->s[0].split(" ").length==5&s[2].split(" ").length==5&s[1].split(" ").length==7

Попробуйте онлайн!

Выглядит так хорошо, но без встроенной функции карты я не могу найти хороший способ. Итерация по массиву занимает несколько байтов дольше, так же как и запись функции карты с использованием потоков.

Лямбда-выражение принимает массив строк и возвращает логическое значение.


Что делать, если у вас есть только две строки на входе или четыре?
Кевин Круйссен

@KevinCruijssen в соответствии с указанием: «Список строк длиной 3 в качестве входных данных также приемлем». Моя программа занимает список строк длиной 3.
Павел

Вы могли бы получить функцию карты, если бы вызвали ее Arrays.stream, но этого достаточно, чтобы ее не стоило использовать (особенно если вам нужно импортировать Arrays)
Pokechu22

@ Pokechu22 да, я попробовал это сделать, но все равно оказалось дольше.
Павел

Вы можете использовать &вместо того, &&чтобы сохранить два байта
corvus_192

2

SmileBASIC, 96 94 байта

INPUT A$,B$,C$?C(A$,4)*C(B$,6)*C(C$,4)DEF C(S,E)WHILE""<S
INC N,POP(S)<"!
WEND
RETURN N==E
END

1

R, 100 байт

f<-function(a){all(sapply(a,function(x){length(grep(" ",as.list(strsplit(x,"")[[1]])))})==c(4,6,4))}

Принимает в качестве аргумента список строк длиной 3. Вероятно, дальше не будут играть в гольф, так как дальнейший гольф превращает его в ответ @ Billywob.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.