Write a haiku-w detector

41

5

A haiku is a poem with three lines, with a 5/7/5 syllable count, respectively.

A haiku-w is poem with three lines, with a 5/7/5 word count, respectively.

Challenge

Write a program that will return true if the input is a haiku-w, and false if not.

A valid haiku-w input must consist of 3 lines, separated by a newline.

  • Line 1 must consist of 5 words, each word separated by a space.
  • Line 2 must consist of 7 words, each word separated by a space.
  • Line 3 must consist of 5 words, each word separated by a space.

Examples

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

Result: True

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

Result: False


Rules

  • This is , so the shortest answer in bytes wins.
  • Standard code-golf loopholes apply. Cheating is prohibited.
  • Other boolean return values, such as 1 and 0, are acceptable.
  • A length-3 list of strings as an input is also acceptable.
  • Valid haiku-w inputs should not have leading or trailing spaces, or multiple spaces separating words.

DomTheDeveloper

Posted 2017-01-29T10:12:05.660

Reputation: 461

Must the input be a single string (containing newlines), or can it be a length-3 list of strings? – Greg Martin – 2017-01-29T10:28:32.690

A length-3 list of strings is acceptable. Editing the OP to reflect this. – DomTheDeveloper – 2017-01-29T10:30:57.710

1Will the haiku-w always contain 3 lines? – user41805 – 2017-01-29T10:31:54.863

1Yes. If the input contains more than or fewer than 3 lines, the program should return false. – DomTheDeveloper – 2017-01-29T10:33:54.597

5Will there ever be leading or trailing spaces on any line? Or multiple spaces separating words? – Greg Martin – 2017-01-29T10:34:38.700

1Good question. Valid haiku-w inputs should not have leading or trailing spaces, or multiple spaces separating words. – DomTheDeveloper – 2017-01-29T10:38:07.300

8

By the way, clarifications like this are a primary reason to post proposed questions in the Sandbox first. :)

– Greg Martin – 2017-01-29T10:43:26.497

11Bonus points for submissions where the code itself is a haiku-w. – Glorfindel – 2017-01-30T07:22:54.233

1

@Glorfindel - done. http://codegolf.stackexchange.com/a/108849/9524

– ymbirtt – 2017-02-01T09:58:33.277

Answers

25

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

Thanks to Neil for saving 13 bytes

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

Explanation

This is a fat-arrow function that takes an array of strings as argument. It replaces each line by its word count. If it is a haiku-w, a now contains an array of a five, a seven and a five again. Since JavaScript doesn't allow us to compare 2 arrays at the same time, the array is converted to a string first, and then compared. This results in a boolean that is returned.

Luke

Posted 2017-01-29T10:12:05.660

Reputation: 4 675

1% and * have the same precedence, so you don't need the ()s, although I think (d*2|5) might also work. Also you can get away with a single &, although I think you can improve on even that by using (b...).length==3>b.some(...length-...). – Neil – 2017-01-29T10:29:44.903

Thanks for the tip about the parentheses. Also, I changed my approach, so I don't explicitly check for length anymore. – Luke – 2017-01-29T10:46:36.353

1Ah, in that case, don't bother with the calculation, just use a=>a.map(c=>c.split .length)=='5,7,5'. – Neil – 2017-01-29T10:55:56.587

Hehe, you're right. I should've thought of that... – Luke – 2017-01-29T10:56:37.633

You still don't need the +'' - == stringifies if the other argument is a string. – Neil – 2017-01-29T11:13:17.420

Really? Nice. Thanks – Luke – 2017-01-29T11:19:00.097

12

AWK (GNU Awk), 24, 30, 28, 20 bytes

Golfed

517253==$0=q=q NF NR

Will output "517253" for True, and empty string for False.

In awk, any nonzero numeric value or any nonempty string value is true. Any other value (zero or the null string, "") is false

The GNU Awk User's Guide

How It Works

Each awk statement (rule) consists of a pattern (or expression) with an associated action:

pattern {action}

Awk will read the input line by line (record by record) and evaluate pattern expression to see if a corresponding action is to be invoked.

The code above is a standalone Awk expression (pattern) w/o the action block, which is implied to be {print $0} in that case.

It should be read right-to-left:

q=q NF NR

Append a Number of Fields (words) and Number of Records (i.e. the current line number), to the variable q.

This way, when processing a proper Haiku-w, q will be set to:

  • 51 - on line #1 (5 words)
  • 5172 - on line #2 (5 words + 7 words)
  • 517253 - on line #3 (5 words + 7 words + 5 words)

$0=q

Assign the newly computed value of q to $0 (which holds the whole current line/record by default).

517253==$0

Compare it with a "signature" for a proper Haiku-w (517253), if there is a match, the whole expression evaluates to "true" and a corresponding action (implicit print $0) is run, sending "517253" to stdout (True), otherwise output will be empty (False).

Note that this will properly recognize a Haiku-w, even if it is followed by an arbitrary number of garbage lines, but I believe that is ok, as:

A length-3 list of strings as an input is also acceptable.

(i.e. we can assume the input to be 3 lines long)

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

Try It Online !

zeppelin

Posted 2017-01-29T10:12:05.660

Reputation: 7 884

2This fails if the input consists of one line containing 575 words, or two lines containing 57 and 5 words, etc. – Lynn – 2017-01-29T12:51:40.853

@Lynn, true, putting on hold, until this is fixed. – zeppelin – 2017-01-29T13:09:04.567

@Lynn, should be fixed now – zeppelin – 2017-01-29T15:47:36.030

1Very clever fix! :) – Lynn – 2017-01-29T15:55:33.030

9

Python, 42 bytes

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

Try it online!

Takes input as a list of lines, with the words separated by single spaces.

As we're guaranteed there'll be no leading or trailing spaces, and only single spaces will seperate each word, we can verify a w-haiku by simply counting the spaces in each line.

We do this in a list comprehension, to create a list of the space-counts. If it is a correct haiku, it should look like [4, 6, 4], so we compare it with this and return the result.

FlipTack

Posted 2017-01-29T10:12:05.660

Reputation: 13 242

If you're okay with supporting only Python 2, you can save two bytes: map(str.count,l,' '). – vaultah – 2017-01-31T17:07:48.087

8

Jelly, 10 9 bytes

ċ€⁶⁼“¥©¥‘

Try it online!

Explanation

ċ€⁶⁼“¥©¥‘  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

miles

Posted 2017-01-29T10:12:05.660

Reputation: 15 654

Also ċ€⁶⁼4,6,4 and ċ€⁶⁼464D¤… I can’t find anything shorter, though. (Oh, you can flip it, too: 464D⁼ċ€⁶$) – Lynn – 2017-01-29T13:01:27.600

ċ€⁶Ḍ=464 works fine for 8. – Jonathan Allan – 2017-01-29T13:42:48.480

Actually, no it does not, sorry.

– Jonathan Allan – 2017-01-29T13:58:58.947

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%

Exits with non-zero errorlevel as soon as it reads a line with the wrong number of words.

Neil

Posted 2017-01-29T10:12:05.660

Reputation: 95 035

1......well crap – tbodt – 2017-01-29T11:40:48.523

7

Mathematica, 21 bytes

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

Unnamed function taking a list of lists of characters as input and returning True or False. Simply counts how many spaces are in each list of characters, which under the rules of the challenge correlate perfectly with the number of words in each line.

Previous submission:

Mathematica, 31 bytes

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

Unnamed function taking a list of strings as input and returning True or False.

Greg Martin

Posted 2017-01-29T10:12:05.660

Reputation: 13 940

6

Haskell, 34 33 bytes

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

Try it online!.

Edit: thanks to @xnor for a byte!

nimi

Posted 2017-01-29T10:12:05.660

Reputation: 34 639

Pointful is shorter: f l=[sum[1|' '<-c]|c<-l]==[4,6,4]. – xnor – 2017-01-29T22:40:06.947

6

Retina, 12 bytes

M%` 
^4¶6¶4$

(there's a trailing space after the first line)

Try it online!

  • M%`  - Count the number of spaces in each line.

    • M - Match mode - print the number of matches.
    • % - for each line
    • ` - separate configuration and regex pattern
    • - just a space.
  • ^4¶6¶4$ - There should be 4, 6, and 4 spaces, and exactly three lines.

    • matches newlines. The rest is a simple regular expression.

Prints 1 for valid input, 0 for invalid.

Kobi

Posted 2017-01-29T10:12:05.660

Reputation: 728

4

Python, 58 44 bytes

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

-14 by tbodt

sagiksp

Posted 2017-01-29T10:12:05.660

Reputation: 1 249

You're allowed to take the input as a length 3 list of strings. You can save the bytes spent using split("\n"). – miles – 2017-01-29T10:58:28.780

44 bytes: lambda h:[len(l.split())for l in h]==[5,7,5] – tbodt – 2017-01-29T11:40:25.817

Someone make this shorter to reach crossed out 44 – Charlie – 2017-02-02T20:56:53.860

4

Pyke, 11 9 bytes

dL/uq

Try it here!

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

After the u byte there are the following bytes: 0x03 0x04 0x06 0x04

Blue

Posted 2017-01-29T10:12:05.660

Reputation: 26 661

4

Perl, 26 bytes

24 bytes of code + 2 bytes for -ap flags.

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

Try it online!

Dada

Posted 2017-01-29T10:12:05.660

Reputation: 8 279

4

Pyth, 9 bytes

qj464T/R;

A program that takes input of a list of "quoted strings" and prints True or False as appropriate.

Test suite

How it works

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

Posted 2017-01-29T10:12:05.660

Reputation: 3 674

4

Japt, 11 bytes

Saved lots of bytes thanks to @ETHproductions

This takes an array of three strings as input.

®¸lÃ¥"5,7,5

Run it online!

Oliver

Posted 2017-01-29T10:12:05.660

Reputation: 7 160

4

PowerShell, 43 bytes

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

Try it online!

Explanation

Takes input as a newline separated string.

Removes all non-whitespace, then checks to see that it matches "4 spaces, newline, 6 spaces, newline, 4 spaces newline" exactly, using a regex.

The capture group matches 4 spaces, the backreference \1 refers to that. Newlines are embedded in the string. Note the second line of the regex contains two spaces after the backreference.

briantist

Posted 2017-01-29T10:12:05.660

Reputation: 3 110

1That is an interesting aproach! – Ismael Miguel – 2017-01-31T09:28:47.023

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

Returns 1 for 5/7/5 sequence else 0.

A positive testcase:

enter image description here

Abel Tom

Posted 2017-01-29T10:12:05.660

Reputation: 1 150

3

J, 12 bytes

4 6 4=#@;:@>

The input is a boxed list of strings.

Explanation

This is a fork with a constant left tine. This checks the result of the right tine, #@;:@>, for equality with 4 6 4. The right time unboxes each (>), then (@) converts each string to words (;:), then (@) takes the length of each (#).

Conor O'Brien

Posted 2017-01-29T10:12:05.660

Reputation: 36 228

3

C++, 357 bytes

Sort of new to code golf, but this is the best I could do quickly

#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

Posted 2017-01-29T10:12:05.660

Reputation: 131

4Welcome to PPCG! The goal of code golf is to make your code as short as possible; a good first step would be to remove all unnecessary whitespace. – ETHproductions – 2017-01-29T23:16:35.620

3

R, 48 bytes

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

Reads a 3-length character vector from stdin and works by counting the number of spaces. To count the number of spaces we use the str_count from the stringr package which can count occurrences based on a regex pattern.

An alternative approach without using packages could be:

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

Billywob

Posted 2017-01-29T10:12:05.660

Reputation: 3 363

First time I've ever seen el before, thanks for that. – BLT – 2017-01-30T05:48:31.100

3

Ruby 1.9.3

Not golfed, but is itself a haiku-w

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

or...

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

Unfortunately doesn't work with leading whitespace on any lines, but does cope with trailing.

ymbirtt

Posted 2017-01-29T10:12:05.660

Reputation: 1 792

2

Python 2, 57 64 bytes

Edit Corrected with the addition of 7 bytes after feedback from @Dada. Thanks!

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

Try it online!

Not the shortest Python answer by a long way but just wanted to use the new trick I learned recently of using input() to display the output and save a print statement. Takes a list of lines as input. Requires Ctrl C (or any other key-press for that matter) to terminate the program (with an exception) in a terminal but works fine without on TIO.

ElPedro

Posted 2017-01-29T10:12:05.660

Reputation: 5 301

4

This will fail in cases like this one.

– Dada – 2017-01-29T14:46:22.337

I'll give you that @Dada. That is one serious test case :) – ElPedro – 2017-01-29T14:49:00.683

Corrected and tested with your test case. – ElPedro – 2017-01-29T14:53:58.997

2

MATL, 16 bytes

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

The input is a cell array of strings and returns a truthy or falsey array.

Try it Online

Explanation

        % 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

Posted 2017-01-29T10:12:05.660

Reputation: 10 257

2

MATLAB / Octave, 38 bytes

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

This solution accepts a cell array of strings as input, counts the number of spaces in each line and then compares the result to the array [4 6 4] and yields a truthy (all values are 1) or falsey (any value is zero) array.

Online demo

Suever

Posted 2017-01-29T10:12:05.660

Reputation: 10 257

2

Perl 6, 25 bytes

{.lines».words~~(5,7,5)}

smls

Posted 2017-01-29T10:12:05.660

Reputation: 4 352

2

Java (OpenJDK), 82 bytes

-2 bytes thanks to @corvus_192!

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

Try it online!

It looks so golfable but without a builtin map function, I can't find a good way. Iterating through the array is a few bytes longer, as is writing a map function using streams.

Lambda expression takes an array of Strings and returns a Boolean.

Pavel

Posted 2017-01-29T10:12:05.660

Reputation: 8 585

What if you have only two lines as input, or four? – Kevin Cruijssen – 2017-01-30T10:30:10.053

@KevinCruijssen according the op, "A length-3 list of strings as an input is also acceptable". My program takes a length-3 list of lines. – Pavel – 2017-01-30T17:40:20.110

You could get a map function if you called Arrays.stream, but that's long enough that it may not be worth using (especially if you need to import Arrays) – Pokechu22 – 2017-01-30T18:11:34.450

@Pokechu22 yeah I tried that, still ended up being longer. – Pavel – 2017-01-30T21:18:25.767

You can use & instead of && to save two bytes – corvus_192 – 2017-01-31T09:53:21.540

2

Clojure, 44 bytes

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

Input is list of strings. Function finds only spaces and counts them. This explanation is a Haiku. :)

NikoNyrh

Posted 2017-01-29T10:12:05.660

Reputation: 2 361

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

Posted 2017-01-29T10:12:05.660

Reputation: 6 110

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

The program requirement and potential of having less or more than three lines, not too mention Java's verbosity itself, causes this 'golfed' code to be pretty big..

Ungolfed:

Try it here.

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

Posted 2017-01-29T10:12:05.660

Reputation: 67 575

2

SimpleTemplate, 77 bytes

Sadly, the regular expression aproach is the shortest.

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

Requires that the text is given as the first argument, with *NIX-style newlines. This won't work with Windows-style newlines.

Ungolfed:

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

Non-regex based, 114 byes

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

This requires that each line is given as an argument to the function.

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

Posted 2017-01-29T10:12:05.660

Reputation: 6 797

2

Stacked, 22 bytes

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

Takes input from the top of the stack as a list of character strings, as such:

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

Explanation

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

Posted 2017-01-29T10:12:05.660

Reputation: 36 228

1

R, 100 bytes

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

Takes as an argument a length-3 list of strings. Probably won't be golfed further since further golfing turns it into @Billywob's answer.

BLT

Posted 2017-01-29T10:12:05.660

Reputation: 931

1

SpecBAS - 135 bytes

1 INPUT a$: DIM b$(SPLIT a$,NOT ","): l$=""
2 FOR EACH c$ IN b$()
3 DIM d$(SPLIT c$,NOT " ")
4 l$=l$+STR$ ARSIZE d$()
5 NEXT c$
6  ?l$="575"

Input is a comma separated string, each part being put in an array. Then each of those elements are split up on spaces and the length of that array is appended to a string.

Prints 1 (true) or 0 (false) if it matches the 5-7-5 format.

Brian

Posted 2017-01-29T10:12:05.660

Reputation: 1 209

1

C#, 136 124 bytes

Saved 12 bytes thanks to VisualMelon

class P{static void Main(string[]s){var v="";foreach(var c in s)v+=c.Split(' ').Length;System.Console.WriteLine(v=="575");}}

Arguments require each sentence to be wrapped in double quotes and then separated by a space, like this:

"One two three four five" "One two three four five six seven" "One two three four five"

Ungolfed

    class P
{
    static void Main(string[]s)
    {
        var v=""; //Short way to make a string
        foreach(var c in s) //loop through all sentences
            v += c.Split(' ').Length; //split on space and append the array size as string
        );
        System.Console.WriteLine(v == "575"); //print the result!         
    }
}

Please note this is my first attempt on golfing ever, let me know if anything is against the rules. Also feel free to point out things that makes this golf even shorter!

Metoniem

Posted 2017-01-29T10:12:05.660

Reputation: 387

Doesn't look like there is anything illegal here, and it's refreshing to see a complete program submitted ;) Few standard tricks: you don't need the space in string[] s, you can often save bytes by adding a using System; clause, but in this case you don't need to as it's much cheaper to use a foreach loop instead of Array.ForEach: foreach(var c in s)v+=c.Split(' ').Length; – VisualMelon – 2017-01-30T14:56:53.947

@VisualMelon Wow, that's some useful tricks right there. Thanks alot! I'll update my answer :) – Metoniem – 2017-01-30T15:14:41.853

I don't think there's any need to print the linebreak, so you can just use Write. – Bob – 2017-02-01T05:50:23.803

Actually, instructions say "Other boolean return values, such as 1 and 0, are acceptable." -- so you can just return an exit code, dropping the print entirely. Added bonus, int Main is shorter than void Main. – Bob – 2017-02-01T05:52:43.463

1

Ruby, 39 bytes

puts ARGV.map{|l|l.split.size}==[5,7,5]

Try it online!

Accepts lines of input as command-line arguments, finds the word counts, and check they are 5/7/5

ZNix

Posted 2017-01-29T10:12:05.660

Reputation: 11

Welcome to PPCG! – Conor O'Brien – 2017-01-31T04:05:01.637

@ConorO'Brien Thanks – ZNix – 2017-01-31T06:25:09.443

1

C# 6 - 80 bytes (98 with using)

bool a(string[]s)=>s.Select(x=>x.Split(' ').Length).SequenceEqual(new[]{5,7,5});

This, as usual, assumes a method is enough, and doesn't include a complete program.

It also doesn't include using System.Linq;, as it is present as default in the standard C# class template from VS 2008 onwards. Add 18 bytes if you want to include it in the count.

The method accepts the input as an aray of strings (one per line), then splits every string using spaces as separators, keeping the length of every array generated this way. Finally, it checks if those lengths are equal to {5,7,5}.

BgrWorker

Posted 2017-01-29T10:12:05.660

Reputation: 351

1

05AB1E, 9 bytes

€#€g575SQ

Try it online!

Explanation

€#         # split each line on spaces
  €g       # get length of each line
    575    # push the number 575
       S   # split into list of digits
        Q  # compare for equality

Emigna

Posted 2017-01-29T10:12:05.660

Reputation: 50 798

I couldn't get away from vy and 10 bytes, nice solution. Using ð¢ and 464 instead was my approach, unfortunately 464 is still 2 bytes compressed, obviously. – Magic Octopus Urn – 2017-01-31T19:41:26.597

@carusocomputing: That's an interesting idea. I think you could post that as ð¢464SïQ in 2sable for 8 bytes. – Emigna – 2017-01-31T20:41:07.593

You go ahead, that's more your answer than mine in all honesty (I think it's a winning answer too!) – Magic Octopus Urn – 2017-01-31T21:03:46.123

@carusocomputing: ð¢ is the main part of that answer and it was your idea :) – Emigna – 2017-01-31T21:20:07.297

ahhh, just give me a shoutout. If it ends up having a flaw I won't know how to fix it haha. – Magic Octopus Urn – 2017-01-31T21:24:47.457

1

PHP - 78 75 bytes

Saved one byte thanks to Kevin Cruijssen

Here's my first ever submission on PPCG :

<?=preg_match('#^(\S+ ){4}\S+\r\n(\S+ ){6}\S+\r\n(\S+ ){4}\S+$#',$argv[1]);

Regex breakdown :

#                   Regex delimiter
^                   Starts with
(\S+ ){4}           [Any non-space character present n times, followed by a space] x 4
\S+                 Any non-space character present n times
\r\n                Carriage return
(\S+ ){6}           [Any non-space character present n times, followed by a space] x 6
\S+                 Any non-space character present n times
\r\n                Carriage return
(\S+ ){4}           [Any non-space character present n times, followed by a space] x 4
\S+                 Any non-space character present n times
$                   Ends with
#                   Regex delimiter

Try it online !

roberto06

Posted 2017-01-29T10:12:05.660

Reputation: 351

Hi, welcome to PPCG! This looks like a good first submission to me. Btw, you can save 1 more byte by removing the space after the comma. :) Enjoy your stay! (PS: If you haven't seen it yet, there is a Tips for golfing in PHP post you might find interesting to read through.)

– Kevin Cruijssen – 2017-01-31T10:37:56.597

1Hi, thanks for the tip and the link. I managed to save another 2 bytes by switching echo to <?=. – roberto06 – 2017-01-31T10:58:38.433

1

PHP, 46 bytes

<?=array_map(str_word_count,$argv)==[0,5,7,5];

Run like this:

echo '<?=array_map(str_word_count,$argv)==[0,5,7,5];' | php -- "The man in the suit" "is the same man from the store." "He is a cool guy." 2>/dev/null
> 1

Explanation

<?=                        # Print result of the expression.
  array_map(               # Apply function to each input line.
    str_word_count,        # Count words
    $argv
  )==[0,5,7,5];            # Check if result is 5,7,5 (need 0 because
                           # first arg is always `-`).

aross

Posted 2017-01-29T10:12:05.660

Reputation: 1 583

Are you sure that word_count()==0 will work for any $argv[1]? – Titus – 2017-01-31T14:27:38.037

@Titus, do you mean $argv[0]? The first argument when running with -r or passing code via stdin – aross – 2017-01-31T14:54:02.983

... is always - – aross – 2017-01-31T15:06:32.143

... in online interpreters. Save to file and try offline. ;) Yea ok ... it works for stdin. – Titus – 2017-01-31T15:32:49.027

My code is not intended to be run from file. So it's valid then. In any case, if you want to run it from a file, just add [0]+... at the beginning, and it will force the first array item to be 0, regardless of the script name. (4 bytes) – aross – 2017-01-31T16:51:21.307

No, it´s ok; but [0]+ is a nice hint. – Titus – 2017-02-01T14:40:27.303

1

Regex, 44 Bytes

I'm new to codegolfing, but have attempted one with a regex.

/^(\S+ ){4}\S+\n(\S+ ){6}\S+\n(\S+ ){4}\S+$/

will match exactly 5, 7, 5 words and not match anything else. ie.

Golfing with regex is fun
obscurity prevails; intention is hidden from view
and sanity is forever lost

First block (\S+ ){4}) matches four words (at least one nonspace character) with a trailing space. \S+\n matches a word and a newline.

Second block (\S+ ){6}\S+\n is similar but for 6 words, trailing space, word and newline. Third block is identical to first (\S+ ){4}\S+\n)

^(...)$ ensures that the match is found at the beginning and end, so it won't match a haiku inside a string.

Suggested improvements welcome as it's my first time golfing (and I'm rusty at regex).

KBroloes

Posted 2017-01-29T10:12:05.660

Reputation: 11

0

CJam, 15 bytes

5 7 5]qN/Sf/:,=

Try it online!

Explanation

5 7 5]           The array [5, 7, 5]
      q          Read all input
       N/        Split on newlines
         Sf/     Split each line on spaces
            :,   Get the length of each line (in words)
              =  Check if the two arrays are equal

Business Cat

Posted 2017-01-29T10:12:05.660

Reputation: 8 927

0

Scala, 34 bytes

_.map(_ split " "size)==Seq(5,7,5)

Usage:

val f:(Seq[String]=>Boolean)=_.map(_ split " "size)==Seq(5,7,5)
println(f(Seq("The man in the suit", "is the same man from the store.", "He is a cool guy.")))

Ungolfed:

array=>array.map(line=>line.split(" ").size)==Seq(5,7,5)

Explanation:

 _.map(               //map each line in the argument
     _ split " "size  //  to the number of parts when the line is splitted at spaces
 ) == Seq(5,7,5)      //compare that to a sequence of 5, 7, and 5

corvus_192

Posted 2017-01-29T10:12:05.660

Reputation: 1 889

0

C, 114 113 108 bytes

n,i,r,c;f(){n=i=r=1;while(n<4){c=getchar();c-32?c-10?1:++n%2?i-7?(r=0):(i=1):i-5?(r=0):(i=1):++i;}return r;}

Steadybox

Posted 2017-01-29T10:12:05.660

Reputation: 15 798

0

Haskell, 29 bytes

([5,7,5]==).(length.words<$>)

Ungolfed

wordCount line = length (words line)
isHaikuW lines = map wordCount lines == [5, 7, 5]

Joshua David

Posted 2017-01-29T10:12:05.660

Reputation: 211

I think this fails to validate the "Valid haiku-w inputs should not have leading or trailing spaces, or multiple spaces separating words."-rule specified in the challenge. – Laikoni – 2017-01-31T23:26:42.450