Napisz wykrywacz haiku-w

41

Haiku to wiersz z trzech linii, z 5/7/5 sylaby zliczania, odpowiednio.

Haiku-W jest wiersz z trzech linii, z 5/7/5 słowo zliczania, odpowiednio.

Wyzwanie

Napisz program, który zwróci true, jeśli dane wejściowe to haiku-w, a false, jeśli nie.

Prawidłowe wejście haiku-w musi składać się z 3 linii oddzielonych znakiem nowej linii.

  • Wiersz 1 musi składać się z 5 słów, każde słowo oddzielone spacją.
  • Wiersz 2 musi składać się z 7 słów, każde słowo oddzielone spacją.
  • Wiersz 3 musi składać się z 5 słów, każde słowo oddzielone spacją.

Przykłady

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

Wynik: prawda

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

Wynik: fałsz


Zasady

  • To jest , więc wygrywa najkrótsza odpowiedź w bajtach.
  • Obowiązują standardowe luki w kodzie golfowym. Oszukiwanie jest zabronione.
  • Inne zwracane wartości logiczne, takie jak 1i 0, są dopuszczalne.
  • Dopuszczalna jest również lista ciągów o długości 3 jako danych wejściowych.
  • Prawidłowe dane wejściowe haiku-w nie powinny mieć spacji wiodących ani końcowych ani wielu spacji oddzielających słowa.
DomTheDeveloper
źródło
1
Czy haiku-w zawsze będzie zawierać 3 linie?
Kritixi Lithos
1
Tak. Jeśli dane wejściowe zawierają więcej niż 3 wiersze, program powinien zwrócić wartość false .
DomTheDeveloper
5
Czy na linii będą kiedyś spacje wiodące lub końcowe? Lub wiele spacji oddzielających słowa?
Greg Martin
8
Nawiasem mówiąc, takie wyjaśnienia są głównym powodem, aby najpierw opublikować proponowane pytania w piaskownicy . :)
Greg Martin
11
Punkty bonusowe za zgłoszenia, w których sam kod jest haiku-w.
Glorfindel

Odpowiedzi:

25

JavaScript (ES6), 73 72 64 63 54 42 39 bajtów

Dzięki Neil za uratowanie 13 bajtów

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

Wyjaśnienie

Jest to funkcja grubej strzałki, która przyjmuje jako argument tablicę ciągów. Zastępuje każdą linię liczbą słów. Jeśli jest to haiku-w, ateraz znowu zawiera tablicę pięciu, siedmiu i pięciu. Ponieważ JavaScript nie pozwala nam porównywać 2 tablic jednocześnie, tablica jest najpierw konwertowana na ciąg, a następnie porównywana. Powoduje to zwrócenie wartości logicznej.

Łukasz
źródło
1
%i *mają ten sam priorytet, więc nie potrzebujesz tych (), chociaż myślę, że (d*2|5)może również działać. Możesz też uciec od pojedynczego &, chociaż myślę, że możesz poprawić nawet za pomocą (b...).length==3>b.some(...length-...).
Neil
Dzięki za wskazówkę dotyczącą nawiasów. Zmieniłem też swoje podejście, więc nie sprawdzam już wyraźnie długości.
Łukasz
1
Ach, w takim przypadku nie przejmuj się obliczeniami, po prostu użyj a=>a.map(c=>c.split .length)=='5,7,5'.
Neil
Hehe, masz rację. Powinienem był pomyśleć o tym ...
Łukasz
Nadal nie potrzebujesz +''- ==stringify, jeśli drugi argument jest łańcuchem.
Neil
12

AWK (GNU Awk), 24, 30, 28, 20 bajtów

Grał w golfa

517253==$0=q=q NF NR

Wypisuje „517253” dla wartości True , a pusty ciąg dla wartości False .

W awk każda niezerowa wartość liczbowa lub każda niepusta wartość ciągu jest prawdą. Każda inna wartość (zero lub ciąg zerowy „”) jest fałszem

Podręcznik użytkownika GNU Awk

Jak to działa

Każda instrukcja (reguła) awk składa się ze wzorca (lub wyrażenia) z powiązaną akcją:

pattern {action}

Awk będzie czytać dane wejściowe linia po linii (zapis po rekordzie) i ocenia wyrażenie wzorca, aby sprawdzić, czy ma zostać wywołana odpowiednia akcja.

Powyższy kod jest samodzielnym wyrażeniem (wzorcem) Awk bez bloku akcji, co {print $0}w takim przypadku sugeruje się .

Należy go czytać od prawej do lewej:

q=q NF NR

Dołączenie N umbra z F ields (bity) i N umbra z R ecords (tj bieżący numer linii), na zmienną q .

W ten sposób, podczas przetwarzania właściwego Haiku-w, q zostanie ustawione na:

  • 51 - w linii nr 1 (5 słów)
  • 5172 - on-line nr 2 (5 słów + 7 słów)
  • 517253 - on-line nr 3 (5 słów + 7 słów + 5 słów)

$0=q

Przypisz nowo obliczoną wartość q do 0 USD (która domyślnie przechowuje całą bieżącą linię / rekord).

517253==$0

Porównaj to z „sygnaturą” dla właściwego Haiku-w (517253), jeśli istnieje dopasowanie, całe wyrażenie zostanie ocenione na „prawda” i uruchomiona zostanie odpowiednia akcja (niejawna print $0), wysyłając „517253” na standardowe wyjście (prawda) , w przeciwnym razie dane wyjściowe będą puste (False).

Zauważ, że rozpozna to poprawnie Haiku-w, nawet jeśli po nim następuje dowolna liczba linii śmieci, ale uważam, że jest to w porządku, ponieważ:

Dopuszczalna jest również lista ciągów o długości 3 jako danych wejściowych.

(tzn. możemy założyć, że dane wejściowe mają długość 3 linii)

Test

>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

Wypróbuj online!

zepelin
źródło
2
Nie udaje się to, jeśli dane wejściowe składają się z jednego wiersza zawierającego 575 słów lub dwóch wierszy zawierających 57 i 5 słów itp.
Lynn
@ Lynn, prawda, wstrzymywanie, dopóki nie zostanie to naprawione.
zeppelin
@ Lynn, powinno być teraz naprawione
zeppelin
1
Bardzo sprytna poprawka! :)
Lynn
9

Python , 42 bajty

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

Wypróbuj online!

Pobiera dane wejściowe jako listę wierszy, a słowa są oddzielone pojedynczymi spacjami.

Ponieważ gwarantujemy, że nie będzie początkowych ani końcowych spacji, a tylko pojedyncze spacje oddzielą każde słowo, możemy zweryfikować w-haiku, po prostu zliczając spacje w każdym wierszu.

Robimy to w formie listy, aby utworzyć listę liczby miejsc. Jeśli jest to prawidłowe haiku, powinno to wyglądać [4, 6, 4], więc porównujemy to z tym i zwrócimy wynik.

FlipTack
źródło
Jeśli nie masz nic przeciwko wspieraniu tylko Python 2, można zapisać dwa bajty: map(str.count,l,' ').
vaultah
8

Galaretka , 10 9 bajtów

ċ€⁶⁼“¥©¥‘

Wypróbuj online!

Wyjaśnienie

ċ€⁶⁼“¥©¥‘  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
mile
źródło
Ponadto ċ€⁶⁼4,6,4i ċ€⁶⁼464D¤… Nie mogę znaleźć niczego krótszego. (Oh, można go odwrócić, zbyt: 464D⁼ċ€⁶$)
Lynn
ċ€⁶Ḍ=464działa dobrze dla 8.
Jonathan Allan
Właściwie nie, nie , przepraszam.
Jonathan Allan
7

Partia, 102 bajty

@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%

Wychodzi z niezerowym poziomem błędu, gdy tylko odczyta wiersz z niewłaściwą liczbą słów.

Neil
źródło
1
...... cholera
tbodt
7

Mathematica, 21 bajtów

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

Nienazwana funkcja przyjmująca listę znaków jako dane wejściowe i zwracające Truelub False. Po prostu liczy, ile spacji jest na każdej liście znaków, które zgodnie z regułami wyzwania doskonale korelują z liczbą słów w każdej linii.

Poprzednie zgłoszenie:

Mathematica, 31 bajtów

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

Nienazwana funkcja przyjmująca listę ciągów jako dane wejściowe i zwracające Truelub False.

Greg Martin
źródło
6

Haskell, 34 33 bajty

f l=[sum[1|' '<-c]|c<-l]==[4,6,4]

Wypróbuj online! .

Edycja: dzięki @xnor za bajt!

nimi
źródło
Pointful jest krótszy: f l=[sum[1|' '<-c]|c<-l]==[4,6,4].
xnor
6

Siatkówka , 12 bajtów

M%` 
^4¶6¶4$

(po pierwszej linii jest spacja)

Wypróbuj online!

  • M%`  - Policz liczbę spacji w każdej linii.

    • M - Tryb dopasowania - drukuj liczbę dopasowań.
    • % - dla każdej linii
    • ` - osobna konfiguracja i wzorzec wyrażeń regularnych
    • - tylko przestrzeń.
  • ^4¶6¶4$ - Powinny być 4, 6 i 4 spacje oraz dokładnie trzy linie.

    • dopasowuje nowe linie. Reszta to proste wyrażenie regularne.

Drukuje 1dla prawidłowego wejścia, 0dla nieprawidłowego.

Kobi
źródło
4

Python, 58 44 bajtów

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

-14 autor: tbodt

sagiksp
źródło
Możesz wziąć dane wejściowe jako listę ciągów o długości 3. Możesz zapisać bajty wydane przy użyciu split("\n").
mile
44 bajty:lambda h:[len(l.split())for l in h]==[5,7,5]
tbodt
Ktoś skraca ten zasięg, by skreślić 44
Charlie
4

Perl , 26 bajtów

24 bajty kodu + 2 bajty na -apflagi.

$m.=@F}{$_=$m==575&$.==3

Wypróbuj online!

Dada
źródło
4

Pyth, 9 bajtów

qj464T/R;

Program, który pobiera dane z listy "quoted strings"i drukuje Truelub Falseodpowiednio.

Zestaw testowy

Jak to działa

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
TheBikingViking
źródło
4

Japt , 11 bajtów

Zaoszczędzono wiele bajtów dzięki produktom @ETH

To pobiera tablicę trzech ciągów jako danych wejściowych.

®¸lÃ¥"5,7,5

Uruchom to online!

Oliver
źródło
4

PowerShell , 43 bajty

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

Wypróbuj online!

Wyjaśnienie

Pobiera dane wejściowe jako ciąg rozdzielany znakiem nowej linii.

Usuwa wszystkie spacje, a następnie sprawdza, czy dokładnie pasuje do „4 spacji, nowej linii, 6 spacji, nowej linii, 4 spacji nowej linii”, używając wyrażenia regularnego.

Grupa przechwytywania odpowiada 4 spacjom, \1odnosi się do tego odniesienie wsteczne . Nowe linie są osadzone w ciągu. Zauważ, że drugi wiersz wyrażenia regularnego zawiera dwie spacje po odwołaniu wstecznym.

briantist
źródło
1
To ciekawe podejście!
Ismael Miguel
4

Pyke, 11 9 bajtów

dL/uq

Wypróbuj tutaj!

dL/       -  map(i.count(" "), input)
        q - ^ == V
   u  -  [4, 6, 4]

Po ubajcie są następujące bajty:0x03 0x04 0x06 0x04

niebieski
źródło
3

J, 12 bajtów

4 6 4=#@;:@>

Dane wejściowe to lista ciągów w ramkach.

Wyjaśnienie

To widelec ze stałym lewym palcem. To sprawdza wynik prawidłowego ustawienia zębów pod #@;:@>kątem równości z 4 6 4. Właściwy czas rozpakowuje each ( >), następnie ( @) konwertuje każdy ciąg znaków na słowa ( ;:), a następnie ( @) przyjmuje długość każdego ( #).

Conor O'Brien
źródło
3

R, 48 bajtów

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

Odczytuje 3-długościowy wektor znaków ze standardowego wejścia i działa poprzez zliczanie spacji. Aby policzyć liczbę spacji używamy str_countod stringrpakietu, który może liczyć wystąpienia w oparciu o wzorzec regex.

Alternatywnym podejściem bez użycia pakietów może być:

all(sapply(scan(,""),function(x)length(el(strsplit(x," "))))==c(5,7,5))
Billywob
źródło
Po raz pierwszy widziałem elwcześniej, dzięki za to.
BLT
3

C 142 bajty

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

Wersja bez golfa:

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

Zwraca 1 dla sekwencji 5/7/5, w przeciwnym razie 0.

Pozytywny przypadek testowy:

wprowadź opis zdjęcia tutaj

Abel Tom
źródło
3

C ++, 357 bajtów

Coś w rodzaju golfa kodowego, ale to najlepsze, co mogę zrobić szybko

#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;
}
Ricardo Iglesias
źródło
4
Witamy w PPCG! Celem gry w golfa jest uczynienie twojego kodu możliwie jak najkrótszym; dobrym pierwszym krokiem byłoby usunięcie wszystkich niepotrzebnych białych znaków.
ETHproductions
3

Ruby 1.9.3

Nie grał w golfa, ale sam w sobie jest haiku-w

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

lub...

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

Niestety nie działa z wiodącymi białymi znakami w żadnych liniach, ale radzi sobie z końcowymi znakami.

ymbirtt
źródło
2

Python 2 , 57 64 bajtów

Edycja Poprawiono, dodając 7 bajtów po otrzymaniu opinii od @Dada. Dzięki!

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

Wypróbuj online!

Nie jest to najkrótsza odpowiedź Pythona, ale po prostu chciałem użyć nowej sztuczki, której nauczyłem się ostatnio, input()do wyświetlania danych wyjściowych i zapisywania printinstrukcji. Pobiera na wejściu listę linii. Wymaga Ctrl C (lub dowolnego innego naciśnięcia klawisza w tym przypadku), aby zakończyć program (z wyjątkiem) w terminalu, ale działa dobrze bez TIO.

ElPedro
źródło
4
To nie w przypadkach takich jak ten jeden .
Dada
Dam ci to @Dada. To jeden poważny przypadek testowy :)
ElPedro
Poprawione i przetestowane w przypadku testowym.
ElPedro
2

MATL, 16 bajtów

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

Dane wejściowe to tablica komórek ciągów znaków i zwraca tablicę prawdy lub falseya .

Wypróbuj online

Wyjaśnienie

        % 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
Suever
źródło
2

MATLAB / oktawa, 38 bajtów

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

To rozwiązanie przyjmuje tablicę komórkową ciągów jako dane wejściowe, zlicza liczbę spacji w każdym wierszu, a następnie porównuje wynik z tablicą [4 6 4]i zwraca tablicę prawdy (wszystkie wartości to 1) lub falsey (każda wartość wynosi zero).

Demo online

Suever
źródło
2

Clojure, 44 bajty

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

Dane wejściowe to lista ciągów. Funkcja wyszukuje tylko spacje i je zlicza. To wyjaśnienie jest haiku. :)

NikoNyrh
źródło
2

Java 7, 154 bajtów

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

Wymagania programu i potencjał posiadania mniej lub więcej niż trzech linii, nie wspominając o samej gadatliwości Javy, powoduje, że ten „golfowy” kod jest dość duży.

Nie golfowany:

Wypróbuj tutaj.

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);
  }
}
Kevin Cruijssen
źródło
2

SimpleTemplate, 77 bajtów

Niestety podejście do wyrażenia regularnego jest najkrótsze.

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

Wymaga podania pierwszego tekstu z nowymi wierszami w stylu * NIX. To nie będzie działać z nowymi liniami w stylu Windows.

Nie golfowany:

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

Oparte na wyrażeniach regularnych, 114 bajtów

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

Wymaga to podania każdej linii jako argumentu funkcji.

Nie golfowany:

{@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}
Ismael Miguel
źródło
2

Ułożone, 22 bajty

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

Pobiera dane wejściowe z góry stosu jako listę ciągów znaków, takich jak:

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

Wyjaśnienie

[' '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)
Conor O'Brien
źródło
2

Java (OpenJDK) , 82 bajty

-2 bajty dzięki @ corvus_192!

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

Wypróbuj online!

Wygląda tak golfowo, ale bez wbudowanej funkcji mapy nie mogę znaleźć dobrego sposobu. Iteracja po tablicy jest kilka bajtów dłuższa, podobnie jak pisanie funkcji mapy za pomocą strumieni.

Wyrażenie lambda pobiera tablicę ciągów i zwraca wartość logiczną.

Pavel
źródło
Co jeśli masz tylko dwa wiersze jako wejście lub cztery?
Kevin Cruijssen
@KevinCruijssen zgodnie z op, „Dopuszczalna jest również lista ciągów o długości 3 jako danych wejściowych”. Mój program ma listę linii o długości 3.
Pavel
Możesz Arrays.streamwywołać funkcję mapy, jeśli zadzwonisz , ale jest to wystarczająco długo, aby nie była warta użycia (szczególnie, jeśli musisz zaimportować Arrays)
Pokechu22 30.01.2017
@ Pokechu22 tak, próbowałem tego, wciąż skończyło się to dłużej.
Pavel
Możesz użyć &zamiast &&zapisać dwa bajty
corvus_192
2

SmileBASIC, 96 94 bajtów

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
12Me21
źródło
1

R, 100 bajtów

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

Jako argument przyjmuje listę ciągów o długości 3. Prawdopodobnie nie będzie już grał w golfa, ponieważ dalsze golfa zamieniają go w odpowiedź @ Billywob.

BLT
źródło