Schreiben Sie einen Haiku-w-Detektor

41

Ein Haiku ist ein Gedicht mit drei Zeilen und einer Silbenzahl von 5/7/5 .

Ein haiku-w ist Dichtung mit drei Zeilen, mit einer 5/7/5 Wortzählung, respectively.

Herausforderung

Schreiben Sie ein Programm, das true zurückgibt, wenn die Eingabe ein Haiku-w ist, und false, wenn nicht.

Eine gültige Haiku-w-Eingabe muss aus 3 Zeilen bestehen, die durch eine neue Zeile getrennt sind.

  • Zeile 1 muss aus 5 Wörtern bestehen, wobei jedes Wort durch ein Leerzeichen getrennt sein muss.
  • Zeile 2 muss aus 7 Wörtern bestehen, wobei jedes Wort durch ein Leerzeichen getrennt sein muss.
  • Zeile 3 muss aus 5 Wörtern bestehen, wobei jedes Wort durch ein Leerzeichen getrennt sein muss.

Beispiele

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

Ergebnis: Richtig

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

Ergebnis: Falsch


Regeln

  • Das ist , also gewinnt die kürzeste Antwort in Bytes.
  • Es gelten Standard-Code-Golf-Regelungslücken. Schummeln ist verboten.
  • Andere boolesche Rückgabewerte wie 1und 0sind akzeptabel.
  • Eine Liste mit Zeichenfolgen der Länge 3 als Eingabe ist ebenfalls zulässig.
  • Gültige Haiku-w-Eingaben sollten keine führenden oder nachfolgenden Leerzeichen oder mehrere Leerzeichen zwischen Wörtern enthalten.
DomTheDeveloper
quelle
1
Wird das Haiku-w immer 3 Zeilen enthalten?
Kritixi Lithos
1
Ja. Wenn die Eingabe mehr als oder weniger als 3 Zeilen enthält, sollte das Programm false zurückgeben .
DomTheDeveloper
5
Wird es jemals führende oder nachfolgende Leerzeichen in einer Zeile geben? Oder mehrere Leerzeichen, die Wörter trennen?
Greg Martin
8
Klarstellungen wie diese sind übrigens ein Hauptgrund, um vorgeschlagene Fragen zuerst in die Sandbox zu stellen . :)
Greg Martin
11
Bonuspunkte für Einsendungen, bei denen der Code selbst ein Haiku-w ist.
Glorfindel

Antworten:

25

JavaScript (ES6), 73 72 64 63 54 42 39 Byte

Vielen Dank an Neil für das Speichern von 13 Bytes

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

Erläuterung

Dies ist eine Fettpfeil-Funktion, die ein Array von Zeichenfolgen als Argument verwendet. Es ersetzt jede Zeile durch ihre Wortzahl. Wenn es ein Haiku-w ist, aenthält es jetzt wieder eine Reihe von fünf, sieben und fünf. Da wir mit JavaScript nicht zwei Arrays gleichzeitig vergleichen können, wird das Array zuerst in einen String konvertiert und dann verglichen. Dies führt zu einem Booleschen Wert, der zurückgegeben wird.

Luke
quelle
1
%und *haben die gleiche Priorität, so dass Sie die ()s nicht benötigen , obwohl ich denke, (d*2|5)könnte auch funktionieren. Sie können auch mit einer Single davonkommen &, obwohl ich denke, Sie können sogar das verbessern, indem Sie verwenden (b...).length==3>b.some(...length-...).
Neil
Danke für den Tipp zu den Klammern. Außerdem habe ich meinen Ansatz geändert, sodass ich nicht mehr explizit nach der Länge suche.
Luke
1
Ah, in diesem Fall kümmere dich nicht um die Berechnung, sondern benutze einfach a=>a.map(c=>c.split .length)=='5,7,5'.
Neil
Hehe, du hast recht. Daran hätte ich denken sollen ...
Luke
Sie brauchen die Zeichenfolge +''- immer noch nicht, ==wenn das andere Argument eine Zeichenfolge ist.
Neil
12

AWK (GNU Awk), 24, 30, 2820 Bytes

Golf gespielt

517253==$0=q=q NF NR

Gibt "517253" für True und eine leere Zeichenfolge für False aus .

In awk ist jeder numerische Wert ungleich Null oder jeder nicht leere Zeichenfolgewert wahr. Jeder andere Wert (Null oder die Nullzeichenfolge "") ist falsch

Das GNU Awk Benutzerhandbuch

Wie es funktioniert

Jede awk-Anweisung (Regel) besteht aus einem Muster (oder Ausdruck) mit einer zugehörigen Aktion:

pattern {action}

Awk liest die Eingabe Zeile für Zeile (Datensatz für Datensatz) und wertet den Musterausdruck aus, um festzustellen, ob eine entsprechende Aktion aufgerufen werden soll.

Der obige Code ist ein eigenständiger Awk-Ausdruck (Muster) ohne den Aktionsblock, der {print $0}in diesem Fall impliziert wird.

Es sollte von rechts nach links gelesen werden:

q=q NF NR

Anfügen einer N umber von F ields (Wörter) und N umber von R ecords (dh die aktuelle Zeilennummer) auf die Variable q .

Auf diese Weise wird bei der Verarbeitung eines richtigen Haiku-w q festgelegt auf:

  • 51 - in Zeile 1 (5 Wörter)
  • 5172 - in Zeile 2 (5 Wörter + 7 Wörter)
  • 517253 - in Zeile 3 (5 Wörter + 7 Wörter + 5 Wörter)

$0=q

Ordnen Sie den neu berechneten Wert von q zu $ 0 (die die gesamte aktuelle Zeile / Aufzeichnung standardmäßig hält).

517253==$0

Vergleichen Sie es mit einer "Signatur" für ein richtiges Haiku-w (517253). Wenn eine Übereinstimmung vorliegt, wird der gesamte Ausdruck mit "true" ausgewertet und eine entsprechende Aktion (implizit print $0) ausgeführt, wobei "517253" an stdout (True) gesendet wird. Andernfalls ist die Ausgabe leer (False).

Beachten Sie, dass dies ein Haiku-w richtig erkennt, auch wenn es von einer beliebigen Anzahl von Mülleimern gefolgt wird, aber ich halte das für in Ordnung, als:

Eine Liste mit Zeichenfolgen der Länge 3 als Eingabe ist ebenfalls zulässig.

(dh wir können davon ausgehen, dass die Eingabe 3 Zeilen lang ist)

Prüfung

>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

Probieren Sie es online!

Zeppelin
quelle
2
Dies schlägt fehl, wenn die Eingabe aus einer Zeile mit 575 Wörtern oder zwei Zeilen mit 57 und 5 Wörtern usw. besteht.
Lynn
@Lynn, true, wird gehalten, bis dies behoben ist.
Zeppelin
@Lynn, sollte jetzt behoben sein
Zeppelin
1
Sehr clevere Lösung! :)
Lynn
9

Python , 42 Bytes

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

Probieren Sie es online!

Nimmt die Eingabe als Liste von Zeilen entgegen, wobei die Wörter durch einzelne Leerzeichen getrennt sind.

Da garantiert keine führenden oder nachfolgenden Leerzeichen vorhanden sind und nur einzelne Leerzeichen jedes Wort trennen, können wir ein W-Haiku überprüfen, indem wir einfach die Leerzeichen in jeder Zeile zählen.

Wir tun dies in einem Listenverständnis, um eine Liste der Raumzählungen zu erstellen. Wenn es ein korrektes Haiku ist, sollte es so aussehen [4, 6, 4], also vergleichen wir es damit und geben das Ergebnis zurück.

FlipTack
quelle
Wenn Sie mit Unterstützung nur Python 2 in Ordnung sind, können Sie zwei Bytes speichern: map(str.count,l,' ').
Gewölbe
8

Gelee , 10 9 Bytes

ċ€⁶⁼“¥©¥‘

Probieren Sie es online!

Erläuterung

ċ€⁶⁼“¥©¥‘  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
Meilen
quelle
Also ċ€⁶⁼4,6,4und ċ€⁶⁼464D¤... ich kann nichts kürzeres finden. (Oh, man kann es drehen, auch: 464D⁼ċ€⁶$)
Lynn
ċ€⁶Ḍ=464Funktioniert gut für 8.
Jonathan Allan
Eigentlich nein tut es nicht , sorry.
Jonathan Allan
7

Batch, 102 Bytes

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

Beendet mit einer Fehlerstufe ungleich Null, sobald eine Zeile mit der falschen Anzahl von Wörtern gelesen wird.

Neil
quelle
1
...... also Mist
bis zum
7

Mathematica, 21 Bytes

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

Unbenannte Funktion, die eine Liste von Zeichenlisten als Eingabe und Rückgabe verwendet Trueoder False. Zählt einfach, wie viele Leerzeichen sich in jeder Liste von Zeichen befinden, die nach den Regeln der Herausforderung perfekt mit der Anzahl der Wörter in jeder Zeile korrelieren.

Vorherige Einreichung:

Mathematica, 31 Bytes

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

Unbenannte Funktion, die eine Liste von Zeichenfolgen als Eingabe verwendet und Trueoder zurückgibt False.

Greg Martin
quelle
6

Haskell, 34 33 Bytes

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

Probieren Sie es online! .

Edit: Danke an @xnor für ein Byte!

nimi
quelle
Pointful kürzer: f l=[sum[1|' '<-c]|c<-l]==[4,6,4].
Xnor
6

Retina , 12 Bytes

M%` 
^4¶6¶4$

(Nach der ersten Zeile steht ein Leerzeichen)

Probieren Sie es online!

  • M%`  - Zählen Sie die Anzahl der Leerzeichen in jeder Zeile.

    • M - Übereinstimmungsmodus - Gibt die Anzahl der Übereinstimmungen aus.
    • % - für jede Zeile
    • ` - Separate Konfiguration und Regex-Muster
    • - Nur ein Leerzeichen.
  • ^4¶6¶4$ - Es sollten 4, 6 und 4 Leerzeichen und genau drei Zeilen vorhanden sein.

    • passt zu Zeilenumbrüchen. Der Rest ist ein einfacher regulärer Ausdruck.

Druckt 1für eine gültige Eingabe, 0für eine ungültige.

Kobi
quelle
4

Python, 58 44 Bytes

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

-14 von tbodt

sagiksp
quelle
Sie dürfen die Eingabe als Liste mit Zeichenfolgen der Länge 3 annehmen. Sie können die verwendeten Bytes mit speichern split("\n").
Meilen
44 Bytes:lambda h:[len(l.split())for l in h]==[5,7,5]
bis zum
Jemand macht dies kürzer, um die durchgestrichene
Charlie
4

Pyth, 9 Bytes

qj464T/R;

Ein Programm, das eine Liste von Einträgen aufnimmt "quoted strings"und druckt Trueoder Falsenach Bedarf.

Testsuite

Wie es funktioniert

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
quelle
4

Japt , 11 Bytes

Dank @ETHproductions wurden viele Bytes gespeichert

Hierfür wird ein Array mit drei Zeichenfolgen als Eingabe verwendet.

®¸lÃ¥"5,7,5

Lass es online laufen!

Oliver
quelle
4

PowerShell , 43 Byte

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

Probieren Sie es online!

Erläuterung

Übernimmt die Eingabe als durch Zeilenumbrüche getrennte Zeichenfolge.

Entfernt alle Nicht-Leerzeichen und prüft dann mithilfe eines regulären Ausdrucks, ob sie genau mit "4 Leerzeichen, Zeilenumbruch, 6 Leerzeichen, Zeilenumbruch, 4 Leerzeichen Zeilenumbruch" übereinstimmen.

Die Erfassungsgruppe entspricht 4 Leerzeichen, der Rückverweis \1bezieht sich darauf. Zeilenumbrüche werden in die Zeichenfolge eingebettet. Beachten Sie, dass die zweite Zeile des regulären Ausdrucks zwei Leerzeichen nach dem Rückverweis enthält.

Briantist
quelle
1
Das ist ein interessanter Ansatz!
Ismael Miguel
4

Pyke, 11 9 Bytes

dL/uq

Probieren Sie es hier aus!

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

Nach dem uByte stehen folgende Bytes:0x03 0x04 0x06 0x04

Blau
quelle
3

J, 12 Bytes

4 6 4=#@;:@>

Die Eingabe ist eine Box-Liste von Zeichenfolgen.

Erläuterung

Dies ist eine Gabel mit einem konstanten linken Zinken. Dies prüft das Ergebnis der richtigen Zeit #@;:@>auf Gleichheit mit 4 6 4. Die richtige Zeit setzt jedes ( >) außer Kraft , dann @konvertiert ( ) jede Zeichenkette in Wörter ( ;:), dann nimmt ( @) die Länge von jedem ( #) an.

Conor O'Brien
quelle
3

R, 48 Bytes

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

Liest einen Vektor mit 3 Zeichen aus stdin und zählt die Anzahl der Leerzeichen. Um die Anzahl der Leerzeichen zu zählen, verwenden wir die str_countaus dem stringrPaket, die Vorkommen basierend auf einem regulären Ausdrucksmuster zählen können.

Ein alternativer Ansatz ohne Verwendung von Paketen könnte sein:

all(sapply(scan(,""),function(x)length(el(strsplit(x," "))))==c(5,7,5))
Billywob
quelle
Ich habe es zum ersten Mal gesehen el, danke dafür.
BLT
3

C 142 Bytes

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

Ungolfed-Version:

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

Gibt 1 für die 5/7/5 Sequenz zurück, sonst 0.

Ein positiver Testfall:

Bildbeschreibung hier eingeben

Abel Tom
quelle
3

C ++, 357 Bytes

Ein bisschen neu im Code Golf, aber das ist das Beste, was ich schnell tun kann

#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
quelle
4
Willkommen bei PPCG! Das Ziel von Code Golf ist es, Ihren Code so kurz wie möglich zu halten. Ein guter erster Schritt wäre, alle unnötigen Leerzeichen zu entfernen.
ETHproductions
3

Ruby 1.9.3

Nicht golfen, sondern selbst ein Haiku-w

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

oder...

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

Funktioniert leider nicht mit führenden Whitespaces in irgendwelchen Zeilen, kommt aber mit Trailing zurecht.

ymbirtt
quelle
2

Python 2 , 57 64 Bytes

Edit Korrigiert mit der Hinzufügung von 7 Bytes nach Rückmeldung von @Dada. Vielen Dank!

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

Probieren Sie es online!

Bei weitem nicht die kürzeste Antwort von Python, sondern ich wollte nur den neuen Trick verwenden, den ich kürzlich gelernt habe input(), um die Ausgabe anzuzeigen und eine printAnweisung zu speichern . Nimmt eine Liste von Zeilen als Eingabe. Erfordert Strg + C (oder einen anderen Tastendruck), um das Programm (mit einer Ausnahme) in einem Terminal zu beenden, funktioniert jedoch ohne TIO.

ElPedro
quelle
4
Dies wird in solchen Fällen versagen diese .
Dada
Ich gebe dir das @Dada. Das ist ein schwerwiegender Testfall :)
ElPedro
Korrigiert und getestet mit Ihrem Testfall.
ElPedro
2

MATL, 16 Bytes

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

Die Eingabe ist ein Zellenarray von Zeichenfolgen und gibt ein wahrheitsgemäßes oder falsches Array zurück .

Probieren Sie es online

Erläuterung

        % 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
quelle
2

MATLAB / Octave, 38 Bytes

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

Diese Lösung akzeptiert ein Zellenarray von Zeichenfolgen als Eingabe, zählt die Anzahl der Leerzeichen in jeder Zeile und vergleicht dann das Ergebnis mit dem Array [4 6 4] und ergibt ein wahres (alle Werte sind 1) oder falsches (jeder Wert ist Null) Array.

Online-Demo

Suever
quelle
2

Clojure, 44 Bytes

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

Die Eingabe ist eine Liste von Zeichenfolgen. Funktion findet nur Leerzeichen und zählt sie. Diese Erklärung ist ein Haiku. :)

NikoNyrh
quelle
2

Java 7, 154 Bytes

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

Die Programmanforderung und das Potenzial, weniger oder mehr als drei Zeilen zu haben, sowie Javas Ausführlichkeit selbst, führen dazu, dass dieser 'Golf'-Code ziemlich groß ist.

Ungolfed:

Probieren Sie es hier aus.

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
quelle
2

SimpleTemplate, 77 Byte

Leider ist der Ansatz für reguläre Ausdrücke der kürzeste.

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

Erfordert, dass der Text als erstes Argument mit * NIX-Zeilenumbrüchen angegeben wird. Dies funktioniert nicht mit Newlines im Windows-Stil.

Ungolfed:

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

Nicht auf Regex basierend, 114 Byes

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

Dies setzt voraus, dass jede Zeile als Argument für die Funktion angegeben wird.

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}
Ismael Miguel
quelle
2

Gestapelt, 22 Bytes

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

Übernimmt die Eingabe vom oberen Rand des Stapels als Liste von Zeichenfolgen:

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

Erläuterung

[' '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
quelle
2

Java (OpenJDK) , 82 Byte

-2 Bytes dank @ corvus_192!

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

Probieren Sie es online!

Es sieht so gut aus, aber ohne eine eingebaute Kartenfunktion kann ich keinen guten Weg finden. Das Durchlaufen des Arrays ist einige Bytes länger, ebenso wie das Schreiben einer Map-Funktion unter Verwendung von Streams.

Lambda-Ausdruck nimmt ein Array von Strings und gibt einen Booleschen Wert zurück.

Pavel
quelle
Was ist, wenn Sie nur zwei oder vier Zeilen als Eingabe haben?
Kevin Cruijssen
@ KevinCruijssen laut op, "Eine Länge-3-Liste von Zeichenfolgen als Eingabe ist ebenfalls akzeptabel". Mein Programm hat eine Länge von 3 Zeilen.
Pavel
Sie könnten eine Kartenfunktion erhalten, wenn Sie Arrays.streamArrays
anrufen
@ Pokechu22 ja das habe ich probiert, am ende immer noch länger.
Pavel
Sie können &anstelle von &&zwei Bytes speichern
corvus_192
2

SmileBASIC, 96 94 Bytes

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
quelle
1

R, 100 Bytes

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

Nimmt als Argument eine Länge-3-Liste von Zeichenfolgen. Wahrscheinlich wird nicht weiter Golf gespielt, da es durch weiteres Golfen zu einer Antwort von @ Billywob wird.

BLT
quelle