How many words of power did I shout?

10

0

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.

orlp

Posted 2016-02-13T22:53:35.623

Reputation: 37 067

1I 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) – Cyoce – 2016-02-14T08:18:56.210

Answers

17

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.

andlrc

Posted 2016-02-13T22:53:35.623

Reputation: 1 613

Returns 3 for fusroviir, which was explicitly listed as invalid input. – atk – 2016-02-14T16:39:43.150

1@atk I asked OP if their would be invalid input. The answer was no. – andlrc – 2016-02-14T16:46:46.293

1

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.

Martin Ender

Posted 2016-02-13T22:53:35.623

Reputation: 184 808

2Martin Büttner got outgolfed? Everyone get in your bunkers, the end is nigh! – Cyoce – 2016-02-14T08:21:46.547

4@Cyoce it's okay, I golfed two thirds off that other answer. ;) – Martin Ender – 2016-02-14T11:42:57.563

1

Perl 5, 28 bytes

Byte count includes one for -p.

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

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

msh210

Posted 2016-02-13T22:53:35.623

Reputation: 3 094