10
\$\begingroup\$

In Skyrim, the player character can use powerful magic shouts (Thu'ums) to achieve their goals. Every shout consists of three words, however, the player can use the first one or two words to achieve the same effect with less power but at a shorter cooldown.

Given a lowercase ASCII Thu'um phrase without punctuation or spaces, return how many words of power it contains.

Example:

fusrodah   -> 3
dur        -> 1
kaandrem   -> 2
odah       -> 2
vengaarnos -> 3

The input will always be a lowercase ASCII string formed by taking one of the shouts below, choosing the first 1, 2, or 3 words from that shout, and concatenating the words in order.

dur neh viir
faas ru maar
feim zii gron
fo krah diin
fus ro dah
gaan lah haas
gol hah dov
hun kaal zoor
iiz slen nus
joor zah frul
kaan drem ov
krii lun aus
laas yah nir
lok vah koor
mid vur shaan
mul qah diiv
od ah viing
raan mir tah
rii vaaz zol
strun bah qo
su grah dun
tiid klo ul
ven gaar nos
wuld nah kest
yol toor shul
zul mey gut
zun haal viik

So fus, fusro, and fusrodah are all valid inputs, but fusroviir isn't because it uses words from mixed shouts, and rodah isn't because it's not a prefix of a shout. You also don't have to handle the empty string input.


Shortest code in bytes wins.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ I will give a cookie for the first person to run this algorithm on each line of the Song of the Dragonborn (known as the "skyrim theme" by plebs) \$\endgroup\$
    – Cyoce
    Feb 14, 2016 at 8:18

3 Answers 3

17
\$\begingroup\$

Retina, 78 42 15 14 bytes

ul
xo
[aeiou]+

Try it online

tiidkloul is the only word that doesn't have the same amount of vowel sequences as the number supposed to be printed. Therefore we need to match the word to give it an extra vowel sequence. ou will only match tiidkloul and we can then replace ou with oxo which creates the extra sequence.

My initial approach wasn't this simple, but was build around removing all consonants, then removing a few vowel sequences (ai|ii|aa|...) and then finally counting the numbers of letters. But thanks to @Martin Büttner for thinking of [aeiou]+ instead.

\$\endgroup\$
2
  • \$\begingroup\$ Returns 3 for fusroviir, which was explicitly listed as invalid input. \$\endgroup\$
    – atk
    Feb 14, 2016 at 16:39
  • 1
    \$\begingroup\$ @atk I asked OP if their would be invalid input. The answer was no. \$\endgroup\$ Feb 14, 2016 at 16:46
1
\$\begingroup\$

Retina, 313 bytes

ah|aus|bah|d(ah|ii[nv]|ov|rem|u[nr])|[fhl]aas|f(eim|o|rul|us)|g(aa[nr]|ol|rah|ron|ut)|haal|hah|hun|iiz|joor|k(aa[ln]|est|lo|oor|rah|rii)|lah|lok|lun|m(aar|ey|i[dr]|ul)|n[ae]h|nir|n[ou]s|od|ov|qah|qo|r(aan|ii|o|u)|s(haan|hul|len|trun|u)|tah|tiid|toor|ul|v(aaz|ah|en|iin?[gkr]|ur)|wuld|yah|yol|z(ah|ii|[ou][ln]|oor)

Try it online!

Based on a few simple observations:

  • All words are unique, regardless of their position.
  • No word is a prefix of another word.
  • The input is guaranteed to be valid.

That means we can simply count how many of words appear in the string without overlap. That's exactly what a regex does. I've tried compressing the regex a little beyond just concatenating all the words with | (which would be 351 bytes), but I'm sure this is far from optimal. For a start, I've definitely not exploited all common parts optimally. But more importantly, it's possible to compress the string even further by making it match more strings than valid words, as long as those can't accidentally match part of a valid word (because then they'll just never be matched). I'm pretty sure one would have to automate the compressing to really be sure it's optimal.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Martin Büttner got outgolfed? Everyone get in your bunkers, the end is nigh! \$\endgroup\$
    – Cyoce
    Feb 14, 2016 at 8:21
  • 4
    \$\begingroup\$ @Cyoce it's okay, I golfed two thirds off that other answer. ;) \$\endgroup\$ Feb 14, 2016 at 11:42
1
\$\begingroup\$

Perl 5, 28 bytes

Byte count includes one for -p.

s/ou/oxo/;$_=()=/[aeiou]+/g

Stolen straight from dev-null. (Thanks, dev-null!)

\$\endgroup\$

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.