Hacker News new | ask | show | jobs
by llmzero 839 days ago
Just for fun, a solution in language j to the problem of selecting the longest word with less than 3 vowels.

solution =: >@:{.@:(\: #&>)@:(((+/@:(e.&'aeiou') <: 2:) # ])&.>)@:;:

Example

solution 'yes, today you are reading something that is not so easy to grasp'

the result is: today

Ruby : frase.split.select{|x| x.count("aeiou")<3}.sort_by(&:length).last => "today"

Edited: Added a comparison with Ruby. It seems Ruby here is easier to read and to compose.

4 comments

Shorter ruby version: phrase.split.select{|x| x.count("aeiou")<=2}.max_by(&:length)

The enumerable module of Ruby provides many methods that can be easily implemented in J. Just to show one of them

   max_by =: 1 : '{~ (i. >./)@:(u&>)'
For example the list.max_by(&:length) is (# max_by)
FWIW, I solved this in J as follows

F =: >@{.@(\: #@>)@(#~ (2 >: +/@e.&'aeoiu')@>)

which I think maybe composes a little better

This doesn't include the splitting. I would imagine I would be feeding this function from a boxed list from a word list, like: F 'b' fread 'dict.txt'

Also `;:` is unreliable on hyphenated words, etc. Better to use `cut`.

Haskell:

    maximumBy (on compare length) . filter ((< 3) . length . filter (`elem` "aeiou")) $ words phrase
That returns "grasp", though, because it doesn't sort the list.
The problem as stated does not have a unique solution in general, as you’ve found. One Julia program for this is

`sort(split(p)[count.(r"[aeiou]", split(p)) .< 3]; by=r -> length(r))[end]`

which also returns "grasp".

But this one appeals to me more, because it doesn’t split twice:

`sort(filter(w -> count(r"[aeiou]", w) < 3, split(p)); by=r -> length(r))[end]`

Plus, defining a few aliases for the punctuation-happy terseness-lovers among us, we can reduce the above to:

    maxBy(on cmp (#)).(((<3).(#).(el"aeiou"|=))|=)$words phrase
:(