6
\$\begingroup\$

English is such an inefficient language. We've got enormous words when there are plenty of two or three letter words we never used! As computer scientists, every keystroke matters. We need to be more efficient. Just think of how many words we could have had! In fact, don't think about it, tell me.

Given a string (or list) of letters, I want you to output how many words we could make using those letters. You must use every letter in the string exactly one time.

Words can't just be any old string of letters though, how would you say "yffghtjrufhr"? To be a word, it has to satisfy the following conditions:

  • It must contain at least one vowel ('y' is always a vowel).
  • There must be no more than 2 vowels in a row.
  • There must be no more than 3 consonants in row.
  • The combinations "ch", "sh", and "th" count as one consonant.
  • "s" counts as neither a consonant nor vowel ("length" is just as valid as "lengths").

For example:

Input    -> Output
a        -> 1       (a)
b        -> 0
ab       -> 2       (ab, ba)
abbbb    -> 3       (babbb, bbabb, bbbab)
abbbbbbb -> 0
essss    -> 5       (essss, sesss, ssess, ssses, sssse)
abbbth   -> 46      (thabbb, thbabb, thbbab, bathbb, ...)

Obviously, since this challenge is all about character efficiency, I think a challenge is in order. Standard rules apply!

(For clarification, an 's' breaks any streaks of vowels or consonants. The word "abbbsbbb" is ok, since there are no more than 3 consonants in a row".)

\$\endgroup\$
  • \$\begingroup\$ A bit late now that it's submitted, but would this question have been better as a "is it a word"-style question instead of "count all words"? \$\endgroup\$ – Lord Farquaad Jul 31 '17 at 20:20
  • \$\begingroup\$ You could probably post each one separately (as long as they aren't dupes) \$\endgroup\$ – Stephen Jul 31 '17 at 20:23
  • 1
    \$\begingroup\$ 3 consonants in a row surely you mean 2...? :P Nice challenge. \$\endgroup\$ – trichoplax Jul 31 '17 at 20:33
  • \$\begingroup\$ I actually found 46 words for the last test case. Maybe I misunderstand some of the rules, so please tell me which of these words are not allowed. \$\endgroup\$ – user72349 Jul 31 '17 at 21:14
  • \$\begingroup\$ @ThePirateBay You are right, thanks for bringing that up. When writing that test it completely slipped my mind that the 't' and 'h' could be separated. I just used combinatorics to calculate, and forgot that 'th' wasn't just one letter... \$\endgroup\$ – Lord Farquaad Jul 31 '17 at 21:19
1
\$\begingroup\$

Python 3, 166 Bytes

import itertools as i,re;print(len([w for w in[re.sub('[cst]h','b',''.join(x))for x in set(i.permutations(input()))]if not re.search('[aeiouy]{3}|[^aeiouys]{4}',w)]))

Takes a string from input(). The string is passed to itertool's (built-in library) permutations function, in this case taking a string and returning tuples of unique combinations when wrapped in set(). ''.join() turns the tuples into strings again. Combinations 'th', 'ch', and 'sh' are replaced with an arbitrary consonant, 'b' using re's (regular expression, built-in library) sub function. Words (variable 'w' in the list comprehension) are are then filtered based on if they contain 4 or more consonants, or 3 or more vowels using re's search.

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

JavaScript, 275 bytes

a=>(a.match(/[^aeiouys]/g)||[])[L='length']<a[L]*.85|0&&[...Array(1<<(n=(a=[...a])[L])*--n/2)].map((_,b)=>a.slice().sort(_=>(b/=2)*2&1?1:-1).join``).filter((a,b,c)=>c.indexOf(a)==b&&/[aeiouy]/[t='test'](d=a.replace(/[cst]h/,1))&!/[aeiouy]{3}/[t](d)&!/[^aeiouys]{4}/[t](d))[L]

Try it online

\$\endgroup\$

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.