41
\$\begingroup\$

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.
\$\endgroup\$
  • 1
    \$\begingroup\$ Will the haiku-w always contain 3 lines? \$\endgroup\$ – Cows quack Jan 29 '17 at 10:31
  • 1
    \$\begingroup\$ Yes. If the input contains more than or fewer than 3 lines, the program should return false. \$\endgroup\$ – DomTheDeveloper Jan 29 '17 at 10:33
  • 5
    \$\begingroup\$ Will there ever be leading or trailing spaces on any line? Or multiple spaces separating words? \$\endgroup\$ – Greg Martin Jan 29 '17 at 10:34
  • 8
    \$\begingroup\$ By the way, clarifications like this are a primary reason to post proposed questions in the Sandbox first. :) \$\endgroup\$ – Greg Martin Jan 29 '17 at 10:43
  • 11
    \$\begingroup\$ Bonus points for submissions where the code itself is a haiku-w. \$\endgroup\$ – Glorfindel Jan 30 '17 at 7:22

42 Answers 42

1
\$\begingroup\$

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.

\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
  • \$\begingroup\$ 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; \$\endgroup\$ – VisualMelon Jan 30 '17 at 14:56
  • \$\begingroup\$ @VisualMelon Wow, that's some useful tricks right there. Thanks alot! I'll update my answer :) \$\endgroup\$ – Metoniem Jan 30 '17 at 15:14
  • \$\begingroup\$ I don't think there's any need to print the linebreak, so you can just use Write. \$\endgroup\$ – Bob Feb 1 '17 at 5:50
  • \$\begingroup\$ 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. \$\endgroup\$ – Bob Feb 1 '17 at 5:52
1
\$\begingroup\$

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

\$\endgroup\$
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ – Conor O'Brien Jan 31 '17 at 4:05
  • \$\begingroup\$ @ConorO'Brien Thanks \$\endgroup\$ – ZNix Jan 31 '17 at 6:25
1
\$\begingroup\$

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}.

\$\endgroup\$
1
\$\begingroup\$

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
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Magic Octopus Urn Jan 31 '17 at 19:41
  • \$\begingroup\$ @carusocomputing: That's an interesting idea. I think you could post that as ð¢464SïQ in 2sable for 8 bytes. \$\endgroup\$ – Emigna Jan 31 '17 at 20:41
  • \$\begingroup\$ You go ahead, that's more your answer than mine in all honesty (I think it's a winning answer too!) \$\endgroup\$ – Magic Octopus Urn Jan 31 '17 at 21:03
  • \$\begingroup\$ @carusocomputing: ð¢ is the main part of that answer and it was your idea :) \$\endgroup\$ – Emigna Jan 31 '17 at 21:20
  • \$\begingroup\$ ahhh, just give me a shoutout. If it ends up having a flaw I won't know how to fix it haha. \$\endgroup\$ – Magic Octopus Urn Jan 31 '17 at 21:24
1
\$\begingroup\$

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 !

\$\endgroup\$
  • \$\begingroup\$ 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.) \$\endgroup\$ – Kevin Cruijssen Jan 31 '17 at 10:37
  • 1
    \$\begingroup\$ Hi, thanks for the tip and the link. I managed to save another 2 bytes by switching echo to <?=. \$\endgroup\$ – roberto06 Jan 31 '17 at 10:58
1
\$\begingroup\$

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 `-`).
\$\endgroup\$
  • \$\begingroup\$ Are you sure that word_count()==0 will work for any $argv[1]? \$\endgroup\$ – Titus Jan 31 '17 at 14:27
  • \$\begingroup\$ @Titus, do you mean $argv[0]? The first argument when running with -r or passing code via stdin \$\endgroup\$ – aross Jan 31 '17 at 14:54
  • \$\begingroup\$ ... is always - \$\endgroup\$ – aross Jan 31 '17 at 15:06
  • \$\begingroup\$ ... in online interpreters. Save to file and try offline. ;) Yea ok ... it works for stdin. \$\endgroup\$ – Titus Jan 31 '17 at 15:32
  • \$\begingroup\$ 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) \$\endgroup\$ – aross Jan 31 '17 at 16:51
1
\$\begingroup\$

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).

\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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
\$\endgroup\$
0
\$\begingroup\$

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;}
\$\endgroup\$
0
\$\begingroup\$

Haskell, 29 bytes

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

Ungolfed

wordCount line = length (words line)
isHaikuW lines = map wordCount lines == [5, 7, 5]
\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – Laikoni Jan 31 '17 at 23:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.