Find words with alternating vowels and consonants

From Rosetta Code
Revision as of 14:53, 3 January 2021 by Thundergnat (talk | contribs) (→‎{{header|Raku}}: Add a Raku example)
Find words with alternating vowels and consonants is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Using the dictionary   unixdict.txt,   find words which odd letters are consonants and even letters are vowels or vice versa.
Display the words here (on this page).

The length of any word shown should have a length   > 9.


ALGOL 68

<lang algol68># read the list of words and show words with alternating vowels and #

  1. consonants #

IF FILE input file;

   STRING file name = "unixdict.txt";
   open( input file, file name, stand in channel ) /= 0

THEN

   # failed to open the file #
   print( ( "Unable to open """ + file name + """", newline ) )

ELSE

   # file opened OK #
   BOOL at eof := FALSE;
   # set the EOF handler for the file #
   on logical file end( input file, ( REF FILE f )BOOL:
                                    BEGIN
                                        # note that we reached EOF on the #
                                        # latest read #
                                        at eof := TRUE;
                                        # return TRUE so processing can continue #
                                        TRUE
                                    END
                      );
   # returns the length of the string w                              #
   OP LENGTH  = ( STRING w )INT: ( UPB w - LWB w ) + 1;
   # returns TRUE if c is a vowel, FALSE otherwise                   #
   OP ISVOWEL = ( CHAR c )BOOL: ( c = "a" OR c = "e" OR c = "i" OR c = "o" OR c = "u" );
   # blank pads s on the left to width characters                    #
   PRIO PAD   = 1;
   OP   PAD   = ( INT width, STRING s )STRING:
        IF LENGTH s >= width THEN s
        ELSE
            STRING result := s;
            WHILE LENGTH result < width DO " " +=: result OD;
            result
        FI; # PAD #
   INT    alternating count := 0;
   WHILE STRING word;
         get( input file, ( word, newline ) );
         NOT at eof
   DO
       IF LENGTH word >= 10
       THEN
           # the word is at least 10 characters                      #
           BOOL is alternating  := TRUE;
           BOOL have vowel      := ISVOWEL word[ LWB word ];
           FOR w pos FROM LWB word + 1 TO UPB word
           WHILE BOOL had vowel  = have vowel;
                 have vowel     := ISVOWEL word[ w pos ];
                 is alternating := have vowel = NOT had vowel
           DO SKIP OD;
           IF is alternating THEN
               # the characters of word alternate between vowels and #
               # non-vowels                                          #
               alternating count +:= 1;
               print( ( " ", 15 PAD word ) );
               IF LENGTH word > 15 OR alternating count MOD 6 = 0 THEN
                   print( ( newline ) )
               FI
           FI
       FI
   OD;
   close( input file );
   print( ( newline, whole( alternating count, 0 ), " words of alternating vowels and consonants found", newline ) ) 

FI</lang>

Output:
      aboriginal      apologetic     bimolecular    borosilicate     calorimeter      capacitate
      capacitive      capitoline      capitulate      caricature      colatitude      coloratura
     colorimeter      debilitate      decelerate      decolonize      definitive      degenerate
      deliberate      demodulate      denominate      denotative      deregulate      desiderata
     desideratum      dilapidate      diminutive      epigenetic      facilitate     hemosiderin
      heretofore     hexadecimal      homogenate     inoperative      judicature     latitudinal
      legitimate      lepidolite      literature      locomotive      manipulate      metabolite
    nicotinamide      oratorical      paragonite      pejorative      peridotite     peripatetic
     polarimeter      recitative      recuperate    rehabilitate      rejuvenate      remunerate
      repetitive      reticulate      savonarola      similitude      solicitude      tananarive
     telekinesis     teratogenic      topologize      unilateral      unimodular      uninominal
  verisimilitude
67 words of alternating vowels and consonants found

AWK

<lang awk>( length( $1 ) >= 10 ) \ {

   # have an appropriate length word
   word          = $1;
   haveVowel     = word ~ /^[aeiou]/;
   isAlternating = 1;
   for( wPos = 2; isAlternating && wPos <= length( word ); wPos ++ )
   {
       hadVowel  = haveVowel;
       haveVowel = substr( word, wPos, 1 ) ~ /^[aeiou]/;
       isAlternating = ( hadVowel && ! haveVowel ) || ( ! hadVowel && haveVowel );
   } # for wPos
   if( isAlternating )
   {
       printf( " %16s%s", word, ( alternatingCount % 6 == 5 ) ? "\n" : "" );
       alternatingCount += 1;
   } # if isAlternating

}

END \ {

   printf( "\n%d words with alternating vowels and consonants found\n", alternatingCount );

} # END</lang>

Output:
       aboriginal       apologetic      bimolecular     borosilicate      calorimeter       capacitate
       capacitive       capitoline       capitulate       caricature       colatitude       coloratura
      colorimeter       debilitate       decelerate       decolonize       definitive       degenerate
       deliberate       demodulate       denominate       denotative       deregulate       desiderata
      desideratum       dilapidate       diminutive       epigenetic       facilitate      hemosiderin
       heretofore      hexadecimal       homogenate      inoperative       judicature      latitudinal
       legitimate       lepidolite       literature       locomotive       manipulate       metabolite
     nicotinamide       oratorical       paragonite       pejorative       peridotite      peripatetic
      polarimeter       recitative       recuperate     rehabilitate       rejuvenate       remunerate
       repetitive       reticulate       savonarola       similitude       solicitude       tananarive
      telekinesis      teratogenic       topologize       unilateral       unimodular       uninominal
   verisimilitude
67 words with alternating vowels and consonants found

Factor

Works with: Factor version 0.99 2020-08-14

<lang factor>USING: grouping.extras io.encodings.ascii io.files kernel math prettyprint sequences ;

"unixdict.txt" ascii file-lines [ length 9 > ] filter [ dup [ "aeiou" member? ] group-by [ length ] bi@ = ] filter .</lang>

Output:
{
    "aboriginal"
    "apologetic"
    "bimolecular"
    "borosilicate"
    "calorimeter"
    "capacitate"
    "capacitive"
    "capitoline"
    "capitulate"
    "caricature"
    "colatitude"
    "coloratura"
    "colorimeter"
    "debilitate"
    "decelerate"
    "decolonize"
    "definitive"
    "degenerate"
    "deliberate"
    "demodulate"
    "denominate"
    "denotative"
    "deregulate"
    "desiderata"
    "desideratum"
    "dilapidate"
    "diminutive"
    "epigenetic"
    "facilitate"
    "hemosiderin"
    "heretofore"
    "hexadecimal"
    "homogenate"
    "inoperative"
    "judicature"
    "latitudinal"
    "legitimate"
    "lepidolite"
    "literature"
    "locomotive"
    "manipulate"
    "metabolite"
    "nicotinamide"
    "oratorical"
    "paragonite"
    "pejorative"
    "peridotite"
    "peripatetic"
    "polarimeter"
    "recitative"
    "recuperate"
    "rehabilitate"
    "rejuvenate"
    "remunerate"
    "repetitive"
    "reticulate"
    "savonarola"
    "similitude"
    "solicitude"
    "tananarive"
    "telekinesis"
    "teratogenic"
    "topologize"
    "unilateral"
    "unimodular"
    "uninominal"
    "verisimilitude"
}

Go

<lang go>package main

import (

   "bytes"
   "fmt"
   "io/ioutil"
   "log"
   "strings"
   "unicode/utf8"

)

func isVowel(c rune) bool { return strings.ContainsRune("aeiou", c) }

func main() {

   wordList := "unixdict.txt"
   b, err := ioutil.ReadFile(wordList)
   if err != nil {
       log.Fatal("Error reading file")
   }
   bwords := bytes.Fields(b)
   var words []string
   for _, bword := range bwords {
       s := string(bword)
       if utf8.RuneCountInString(s) > 9 {
           words = append(words, s)
       }
   }
   count := 0
   fmt.Println("Words with alternate consonants and vowels in", wordList, "\b:\n")
   for _, word := range words {
       found := true
       for i, c := range word {
           if (i%2 == 0 && isVowel(c)) || (i%2 == 1 && !isVowel(c)) {
               found = false
               break
           }
       }
       if !found {
           found = true
           for i, c := range word {
               if (i%2 == 0 && !isVowel(c)) || (i%2 == 1 && isVowel(c)) {
                   found = false
                   break
               }
           }
       }
       if found {
           count++
           fmt.Printf("%2d: %s\n", count, word)
       }
   }

}</lang>

Output:
Words with alternate consonants and vowels in unixdict.txt:

 1: aboriginal
 2: apologetic
 3: bimolecular
 4: borosilicate
 5: calorimeter
 6: capacitate
 7: capacitive
 8: capitoline
 9: capitulate
10: caricature
11: colatitude
12: coloratura
13: colorimeter
14: debilitate
15: decelerate
16: decolonize
17: definitive
18: degenerate
19: deliberate
20: demodulate
21: denominate
22: denotative
23: deregulate
24: desiderata
25: desideratum
26: dilapidate
27: diminutive
28: epigenetic
29: facilitate
30: hemosiderin
31: heretofore
32: hexadecimal
33: homogenate
34: inoperative
35: judicature
36: latitudinal
37: legitimate
38: lepidolite
39: literature
40: locomotive
41: manipulate
42: metabolite
43: nicotinamide
44: oratorical
45: paragonite
46: pejorative
47: peridotite
48: peripatetic
49: polarimeter
50: recitative
51: recuperate
52: rehabilitate
53: rejuvenate
54: remunerate
55: repetitive
56: reticulate
57: savonarola
58: similitude
59: solicitude
60: tananarive
61: telekinesis
62: teratogenic
63: topologize
64: unilateral
65: unimodular
66: uninominal
67: verisimilitude

Julia

There have been a lot of "filter the dictionary" tasks almost identical to this one added to the wiki already. All call for filtering a word list, where the results of the filtering test depend on the characters in the word and its length, and may optionally also depend on what other words are in the same dictionary. Something like the generic function below can be used in most of these tasks. <lang julia>function foreachword(wordfile::String, condition::Function; minlen = 0, colwidth = 15, numcols = 6, toshow = 0)

   println("Word source: $wordfile\n")
   words = split(read(wordfile, String), r"\s+")
   dict, shown = Dict(w => 1 for w in words), 0
   for word in words
       if condition(word, dict) && (minlen < 1 || length(word) >= minlen)
           shown += 1
           print(rpad(word, colwidth), shown % numcols == 0 ? "\n" : "")
           toshow > 0 && toshow < shown && break
       end
   end

end

isvowel(c) = c in ['a', 'e', 'i', 'o', 'u'] # NB. leaves out 'α' and similar unicode vowels, and what about y? onlyodds(f, s) = all(c -> f(c), s[1:2:length(s)]) && !any(c -> f(c), s[2:2:length(s)]) onlyevens(f, s) = !any(c -> f(c), s[1:2:length(s)]) && all(c -> f(c), s[2:2:length(s)]) eitheronlyvowels(w, _) = onlyodds(isvowel, w) || onlyevens(isvowel, w)

foreachword("unixdict.txt", eitheronlyvowels, minlen = 10)

</lang>

Output:
aboriginal     apologetic     bimolecular    borosilicate   calorimeter    capacitate
capacitive     capitoline     capitulate     caricature     colatitude     coloratura     
colorimeter    debilitate     decelerate     decolonize     definitive     degenerate
deliberate     demodulate     denominate     denotative     deregulate     desiderata
desideratum    dilapidate     diminutive     epigenetic     facilitate     hemosiderin
heretofore     hexadecimal    homogenate     inoperative    judicature     latitudinal    
legitimate     lepidolite     literature     locomotive     manipulate     metabolite
nicotinamide   oratorical     paragonite     pejorative     peridotite     peripatetic
polarimeter    recitative     recuperate     rehabilitate   rejuvenate     remunerate
repetitive     reticulate     savonarola     similitude     solicitude     tananarive     
telekinesis    teratogenic    topologize     unilateral     unimodular     uninominal
verisimilitude

Raku

Sigh. Yet anther "Filter a word list" task. In a effort to make it a little more interesting, rather than just doing a one-liner, build a grammar and use that to filter.

<lang perl6>grammar VOWCON {

   token       TOP { <|w> <vowel>? ( <consonant> <vowel> )* <consonant>? <|w> }
   token     vowel { <[aeiou]> }
   token consonant { <[a..z] - [aeiou]> }

}

say ( grep { VOWCON.parse: .lc }, grep { .chars > 9 }, 'unixdict.txt'.IO.words ).batch(6)».fmt('%915s').join: "\n";</lang>

Output:
aboriginal      apologetic      bimolecular     borosilicate    calorimeter     capacitate     
capacitive      capitoline      capitulate      caricature      colatitude      coloratura     
colorimeter     debilitate      decelerate      decolonize      definitive      degenerate     
deliberate      demodulate      denominate      denotative      deregulate      desiderata     
desideratum     dilapidate      diminutive      epigenetic      facilitate      hemosiderin    
heretofore      hexadecimal     homogenate      inoperative     judicature      latitudinal    
legitimate      lepidolite      literature      locomotive      manipulate      metabolite     
nicotinamide    oratorical      paragonite      pejorative      peridotite      peripatetic    
polarimeter     recitative      recuperate      rehabilitate    rejuvenate      remunerate     
repetitive      reticulate      savonarola      similitude      solicitude      tananarive     
telekinesis     teratogenic     topologize      unilateral      unimodular      uninominal     
verisimilitude

Ring

<lang ring> cStr = read("unixdict.txt") wordList = str2list(cStr) words = [] num = 0 vowels = "aeiou" consonants = "bcdfghjklmnpqrstvwxyz"

see "working..." + nl

ln = len(wordList) for n = ln to 1 step -1

   if len(wordList[n]) < 10
      del(wordList,n)
   ok

next

see "Words are:" + nl + nl

for n = 1 to len(wordList)

   cflag = 0
   vflag = 0
   len = len(wordList[n])
   for m = 1 to len
       if m % 2 = 1
          cons = substr(consonants,wordList[n][m])
          if cons > 0
             cflag = 1
          else
             cflag = 0
             exit
          ok           
       ok
       if m % 2 = 0
          cons = substr(vowels,wordList[n][m])
          if cons > 0
             vflag = 1
          else
             vflag = 0
             exit
          ok           
       ok
   next
   if cflag = 1 and vflag = 1
      add(words,wordList[n])
   ok

next

for n = 1 to len(wordList)

   cflag = 0
   vflag = 0
   len = len(wordList[n])
   for m = 1 to len
       if m % 2 = 1
          cons = substr(vowels,wordList[n][m])
          if cons > 0
             cflag = 1
          else
             cflag = 0
             exit
          ok           
       ok
       if m % 2 = 0
          cons = substr(consonants,wordList[n][m])
          if cons > 0
             vflag = 1
          else
             vflag = 0
             exit
          ok           
       ok
   next
   if cflag = 1 and vflag = 1
      add(words,wordList[n])
   ok

next

words = sort(words)

for n = 1 to len(words)

   see "" + n + ". " + words[n] + nl

next

see "done..." + nl </lang> Output:

working...
Words are:

1. aboriginal
2. apologetic
3. bimolecular
4. borosilicate
5. calorimeter
6. capacitate
7. capacitive
8. capitoline
9. capitulate
10. caricature
11. colatitude
12. coloratura
13. colorimeter
14. debilitate
15. decelerate
16. decolonize
17. definitive
18. degenerate
19. deliberate
20. demodulate
21. denominate
22. denotative
23. deregulate
24. desiderata
25. desideratum
26. dilapidate
27. diminutive
28. epigenetic
29. facilitate
30. hemosiderin
31. heretofore
32. hexadecimal
33. homogenate
34. inoperative
35. judicature
36. latitudinal
37. legitimate
38. lepidolite
39. literature
40. locomotive
41. manipulate
42. metabolite
43. nicotinamide
44. oratorical
45. paragonite
46. pejorative
47. peridotite
48. peripatetic
49. polarimeter
50. recitative
51. recuperate
52. rehabilitate
53. rejuvenate
54. remunerate
55. repetitive
56. reticulate
57. savonarola
58. similitude
59. solicitude
60. tananarive
61. telekinesis
62. teratogenic
63. topologize
64. unilateral
65. unimodular
66. uninominal
67. verisimilitude
done...

Wren

Library: Wren-fmt

<lang ecmascript>import "io" for File import "/fmt" for Fmt

var isVowel = Fn.new { |c| "aeiou".contains(c) }

var wordList = "unixdict.txt" // local copy var words = File.read(wordList).trimEnd().split("\n").where { |w| w.count > 9 } var count = 0 System.print("Words with alternate consonants and vowels in %(wordList):\n") for (word in words) {

   var found = true
   for (i in 0...word.count) {
       var c = word[i]
       if ((i%2 == 0 && isVowel.call(c)) || (i%2 == 1 && !isVowel.call(c))) {
           found = false
           break
       }
   }
   if (!found) {
       found = true
       for (i in 0...word.count) {
           var c = word[i]
           if ((i%2 == 0 && !isVowel.call(c)) || (i%2 == 1 && isVowel.call(c))) {
               found = false
               break
           }
       }
   }
   if (found) {
       count = count + 1
       Fmt.print("$2d: $s", count, word)
   }

}</lang>

Output:
Words with alternate consonants and vowels in unixdict.txt:

 1: aboriginal
 2: apologetic
 3: bimolecular
 4: borosilicate
 5: calorimeter
 6: capacitate
 7: capacitive
 8: capitoline
 9: capitulate
10: caricature
11: colatitude
12: coloratura
13: colorimeter
14: debilitate
15: decelerate
16: decolonize
17: definitive
18: degenerate
19: deliberate
20: demodulate
21: denominate
22: denotative
23: deregulate
24: desiderata
25: desideratum
26: dilapidate
27: diminutive
28: epigenetic
29: facilitate
30: hemosiderin
31: heretofore
32: hexadecimal
33: homogenate
34: inoperative
35: judicature
36: latitudinal
37: legitimate
38: lepidolite
39: literature
40: locomotive
41: manipulate
42: metabolite
43: nicotinamide
44: oratorical
45: paragonite
46: pejorative
47: peridotite
48: peripatetic
49: polarimeter
50: recitative
51: recuperate
52: rehabilitate
53: rejuvenate
54: remunerate
55: repetitive
56: reticulate
57: savonarola
58: similitude
59: solicitude
60: tananarive
61: telekinesis
62: teratogenic
63: topologize
64: unilateral
65: unimodular
66: uninominal
67: verisimilitude