DEV Community

Discussion on: Daily Challenge #229 - Haiku Validator

Collapse
 
peritract profile image
Dan Keefe • Edited

I enjoyed this one; I'm always a fan of mixing poetry and code. My Python solution is below.

I decided that the haiku came as single strings, with lines separated by \n, so the solution only works with haiku in that format. The only module required is re, for vowel counting.

Code

The solution rests on three small functions. The first is the clean_haiku function, which takes a single haiku string and processes it, returning a list of lower-case lines with all punctuation removed.

def clean_haiku(haiku):
    lines = haiku.split("\n")
    lines = [line.lower()
                 .replace("[^a-z]","")
                 .strip() for line in lines]
    return lines

The next function takes a single line as a string and returns a list of syllables. It does this by splitting the line into words, and then, for each word, counting clusters (1+) of vowels. The number of clusters in a word is (once you account for edge cases) the number of syllables.

def count_syllables(line):
  words = line.split(" ")
  count = 0
  for word in words:
    matches = re.findall("[aeiouy]+", word)
    if word.endswith("e") and len(matches) > 1:
        count -= 1
    count += len(matches)
  return count

The final function - validate_haiku takes a haiku string and calls clean_haiku to get processed lines, and then count_syllables for each line. If the final list of syllable counts matches [5, 7, 5], then the function returns True.

def validate_haiku(haiku):
    lines = clean_haiku(haiku)
    if len(lines) != 3:
        return False
    counts = [count_syllables(line) for line in lines]
    if counts != [5, 7, 5]:
        return False
    return True

Tests

tests = ["An old silent pond...\nA frog jumps into the pond,\nsplash! Silence again.",
         "My code is cool, right?\nJava # Python ; Ruby // Go:\nI know them all, yay!",
         "Autumn moonlight -\naworm digs silently\ninto the chestnut."]

for test in tests:
    print(validate_haiku(test))

# True
# True
# False
Collapse
 
georgewl profile image
George WL • Edited

Lemme check if this works though:

"Haikus are easy\n
But sometimes they don’t make sense\n
Refrigerator"

test shows false for it :p

Collapse
 
peritract profile image
Dan Keefe

You're absolutely right - my code passes the tests outlined above, but there are various edge cases that trip it up. "Sometimes" is one of them, because it's only two syllables really but contains two silent "e"s which register as syllables with this simplistic definition. Another one is "abalone", because the "e" at the end is pronounced as a separate syllable.

You can get the function closer to correct by changing the count_syllables function like so

if (word.endswith("e") or word.endswith("es")) and len(matches) > 1:

but it still struggles with that "ome".

Counting syllables is actually a really complex problem if you want to hit all the edge cases - this article goes into it more deeply. In the end, the best way is to use some kind of dictionary lookup, but that will still fail with unknown words.