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

44 Answers 44

1
2
1
\$\begingroup\$

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.

\$\endgroup\$
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\$
4
  • \$\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\$ Jan 30, 2017 at 14:56
  • \$\begingroup\$ @VisualMelon Wow, that's some useful tricks right there. Thanks alot! I'll update my answer :) \$\endgroup\$
    – Metoniem
    Jan 30, 2017 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, 2017 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, 2017 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\$
2
  • \$\begingroup\$ Welcome to PPCG! \$\endgroup\$ Jan 31, 2017 at 4:05
  • \$\begingroup\$ @ConorO'Brien Thanks \$\endgroup\$
    – ZNix
    Jan 31, 2017 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\$

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\$
2
  • \$\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\$ Jan 31, 2017 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, 2017 at 10:58
1
\$\begingroup\$

Haskell, 29 bytes

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

Ungolfed

wordCount line = length (words line)
isHaikuW lines = map wordCount lines == [5, 7, 5]
\$\endgroup\$
1
  • \$\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, 2017 at 23:26
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\$
6
  • \$\begingroup\$ Are you sure that word_count()==0 will work for any $argv[1]? \$\endgroup\$
    – Titus
    Jan 31, 2017 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, 2017 at 14:54
  • \$\begingroup\$ ... is always - \$\endgroup\$
    – aross
    Jan 31, 2017 at 15:06
  • \$\begingroup\$ ... in online interpreters. Save to file and try offline. ;) Yea ok ... it works for stdin. \$\endgroup\$
    – Titus
    Jan 31, 2017 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, 2017 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\$

05AB1E, 9 bytes

εð¢}ƵĆ7вQ

Try it online!

εð¢}ƵĆ7вQ  # full program
        Q  # is...
  ¢        # the list of the number of..
 ð         # spaces...
  ¢        # in...
           # (implicit) current element in...
ε          # for each element in...
           # implicit input...
        Q  # equal to...
       в   # the list of the base...
      7    # literal...
       в   # digits of...
    ƵĆ     # 242...
        Q  # ?
   }       # end map
           # implicit output
\$\endgroup\$
0
\$\begingroup\$

Thunno 2, 7 bytes

Oḷ575d⁼

Try it online!

Explanation

Oḷ575d⁼  # Implicit input
O        # Split each line on spaces
 ḷ       # Get the length of each inner list
      ⁼  # And check if it's exactly equal to
  575d   # The list [5,7,5]
         # Implicit output
\$\endgroup\$
1
2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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