Count how many vowels and consonants occur in a string: Difference between revisions
→{{header|Python}}: Updated output |
→{{header|JavaScript}}: Added four possible interpretations |
||
Line 329: | Line 329: | ||
('t',1) |
('t',1) |
||
('v',1)</pre> |
('v',1)</pre> |
||
=={{header|JavaScript}}== |
|||
This is a new genre-of deliberately ambiguous task description, perhaps ? |
|||
I suppose it might be thought to offer scope for variety, |
|||
but is it really achieving the Rosetta goal of comparability ? |
|||
(There seem to have been a surprising number of these recently, often |
|||
associated with tasks of uncertain novelty ...) |
|||
===Count of "Vowels and Consonants" ?=== |
|||
<lang javascript>(() => { |
|||
"use strict"; |
|||
// -------- COUNT OF "VOWELS AND CONSONANTS" --------- |
|||
// countOfVowelsAndConsonants :: String -> Int |
|||
const countOfVowelsAndConsonants = s => |
|||
s.split("").filter(isAlpha).length; |
|||
// ---------------------- TEST ----------------------- |
|||
const main = () => |
|||
`${countOfVowelsAndConsonants( |
|||
"Forever Fortran 2018 programming language" |
|||
)} "vowels and consonants"`; |
|||
// --------------------- GENERIC --------------------- |
|||
// isAlpha :: Char -> Bool |
|||
const isAlpha = c => |
|||
(/[A-Za-z\u00C0-\u00FF]/u).test(c); |
|||
// MAIN --- |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>33 "vowels and consonants"</pre> |
|||
===Counts of distinct vowels and distinct consonants used ?=== |
|||
<lang javascript>(() => { |
|||
"use strict"; |
|||
// COUNTS OF DISTINCT VOWELS, AND DISTINCT CONSONANTS |
|||
// distinctVowelsAndConsonants :: |
|||
// String -> ([Char], [Char]) |
|||
const distinctVowelsAndConsonants = s => |
|||
both( |
|||
cs => sort(Array.from(new Set(cs))) |
|||
)( |
|||
partition(isVowel)( |
|||
Array.from(s).filter(isAlpha) |
|||
) |
|||
); |
|||
// ---------------------- TEST ----------------------- |
|||
// main :: IO () |
|||
const main = () => { |
|||
const vc = both( |
|||
cs => `(${cs.join("")}, ${cs.length})` |
|||
)( |
|||
distinctVowelsAndConsonants( |
|||
"Forever Fortran 2018 programming language" |
|||
) |
|||
); |
|||
return [ |
|||
`Distinct vowels: ${vc[0]}`, |
|||
`Distict consonants: ${vc[1]}` |
|||
].join("\n\n"); |
|||
}; |
|||
// --------------------- GENERIC --------------------- |
|||
// Tuple (,) :: a -> b -> (a, b) |
|||
const Tuple = a => |
|||
b => ({ |
|||
type: "Tuple", |
|||
"0": a, |
|||
"1": b, |
|||
length: 2 |
|||
}); |
|||
// both :: (a -> b) -> (a, a) -> (b, b) |
|||
const both = f => |
|||
ab => Tuple( |
|||
f(ab[0]) |
|||
)( |
|||
f(ab[1]) |
|||
); |
|||
// isAlpha :: Char -> Bool |
|||
const isAlpha = c => |
|||
(/[A-Za-z\u00C0-\u00FF]/u).test(c); |
|||
// isVowel :: Char -> Bool |
|||
const isVowel = c => |
|||
(/[AEIOUaeiou]/u).test(c); |
|||
// partition :: (a -> Bool) -> [a] -> ([a], [a]) |
|||
const partition = p => |
|||
// A tuple of two lists - those elements in |
|||
// xs which match p, and those which do not. |
|||
xs => xs.reduce( |
|||
(a, x) => p(x) ? ( |
|||
Tuple(a[0].concat(x))(a[1]) |
|||
) : Tuple(a[0])(a[1].concat(x)), |
|||
Tuple([])([]) |
|||
); |
|||
// sort :: Ord a => [a] -> [a] |
|||
const sort = xs => |
|||
// An A-Z sorted copy of xs. |
|||
xs.slice() |
|||
.sort((a, b) => a < b ? -1 : (a > b ? 1 : 0)); |
|||
// MAIN --- |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>Distinct vowels: (aeiou, 5) |
|||
Distict consonants: (Fglmnprtv, 9)</pre> |
|||
===Counts of vowel and consonant occurrences ?=== |
|||
<lang javascript>(() => { |
|||
"use strict"; |
|||
// ---- COUNTS OF VOWEL AND CONSONANT OCCURRENCES ---- |
|||
// vowelConsonantOccurrenceTotals :: String -> (Int, Int) |
|||
const vowelConsonantOccurrenceTotals = s => |
|||
Array.from(s).reduce( |
|||
(ab, c) => ( |
|||
isAlpha(c) ? ( |
|||
isVowel(c) ? ( |
|||
first(succ) |
|||
) : second(succ) |
|||
) : identity |
|||
)(ab), |
|||
Tuple(0)(0) |
|||
); |
|||
// ---------------------- TEST ----------------------- |
|||
const main = () => { |
|||
const vc = |
|||
vowelConsonantOccurrenceTotals( |
|||
"Forever Fortran 2018 programming language" |
|||
); |
|||
return [ |
|||
`Vowel occurrences: ${vc[0]}`, |
|||
`Consonent occurrences: ${vc[1]}` |
|||
].join("\n\n"); |
|||
}; |
|||
// --------------------- GENERIC --------------------- |
|||
// Tuple (,) :: a -> b -> (a, b) |
|||
const Tuple = a => |
|||
b => ({ |
|||
type: "Tuple", |
|||
"0": a, |
|||
"1": b, |
|||
length: 2 |
|||
}); |
|||
// first :: (a -> b) -> ((a, c) -> (b, c)) |
|||
const first = f => |
|||
// A simple function lifted to one which applies |
|||
// to a tuple, transforming only its first item. |
|||
xy => { |
|||
const tpl = Tuple(f(xy[0]))(xy[1]); |
|||
return Array.isArray(xy) ? ( |
|||
Array.from(tpl) |
|||
) : tpl; |
|||
}; |
|||
// identity :: a -> a |
|||
const identity = x => |
|||
// The identity function. |
|||
x; |
|||
// isAlpha :: Char -> Bool |
|||
const isAlpha = c => |
|||
(/[A-Za-z\u00C0-\u00FF]/u).test(c); |
|||
// isVowel :: Char -> Bool |
|||
const isVowel = c => |
|||
(/[AEIOUaeiou]/u).test(c); |
|||
// second :: (a -> b) -> ((c, a) -> (c, b)) |
|||
const second = f => |
|||
// A function over a simple value lifted |
|||
// to a function over a tuple. |
|||
// f (a, b) -> (a, f(b)) |
|||
xy => { |
|||
const tpl = Tuple(xy[0])(f(xy[1])); |
|||
return Array.isArray(xy) ? ( |
|||
Array.from(tpl) |
|||
) : tpl; |
|||
}; |
|||
// succ :: Int -> Int |
|||
const succ = x => |
|||
1 + x; |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>Vowel occurrences: 12 |
|||
Consonent occurrences: 21</pre> |
|||
===Counts of occurrence for each vowel and consonant ?=== |
|||
<lang javascript>(() => { |
|||
"use strict"; |
|||
// COUNTS OF OCCURRENCE FOR EACH VOWEL AND CONSONANT |
|||
// countsOfEachVowelAndConsonant :: |
|||
// String -> ([(Char, Int)], [(Char, Int)]) |
|||
const countsOfEachVowelAndConsonant = s => |
|||
partition( |
|||
cn => isVowel(cn[0]) |
|||
)( |
|||
sort( |
|||
Object.entries( |
|||
charCounts( |
|||
Array.from(s).filter(isAlpha) |
|||
) |
|||
) |
|||
) |
|||
.map(([c, n]) => Tuple(c)(n)) |
|||
); |
|||
// ---------------------- TEST ----------------------- |
|||
const main = () => { |
|||
const report = label => |
|||
cns => { |
|||
const |
|||
total = cns.reduce( |
|||
(a, cn) => a + cn[1], |
|||
0 |
|||
), |
|||
rows = cns.map( |
|||
compose(s => `\t${s}`, showTuple) |
|||
).join("\n"); |
|||
return [ |
|||
`${label} counts:\n${rows}`, |
|||
`\ttotal: ${total}` |
|||
].join("\n\n"); |
|||
}; |
|||
const counts = countsOfEachVowelAndConsonant( |
|||
"Forever Fortran 2018 programming language" |
|||
); |
|||
return Array.from( |
|||
bimap( |
|||
report("Vowel") |
|||
)( |
|||
report("Consonant") |
|||
)( |
|||
counts |
|||
) |
|||
).join("\n\n"); |
|||
}; |
|||
// --------------------- GENERIC --------------------- |
|||
// Tuple (,) :: a -> b -> (a, b) |
|||
const Tuple = a => |
|||
b => ({ |
|||
type: "Tuple", |
|||
"0": a, |
|||
"1": b, |
|||
length: 2 |
|||
}); |
|||
// bimap :: (a -> b) -> (c -> d) -> (a, c) -> (b, d) |
|||
const bimap = f => |
|||
// Tuple instance of bimap. |
|||
// A tuple of the application of f and g to the |
|||
// first and second values respectively. |
|||
g => tpl => Tuple(f(tpl[0]))( |
|||
g(tpl[1]) |
|||
); |
|||
// charCounts :: String -> Dict |
|||
const charCounts = s => { |
|||
// A dictionary of characters seen, |
|||
// with their frequencies. |
|||
const go = (dct, c) => |
|||
Object.assign(dct, { |
|||
[c]: 1 + (dct[c] || 0) |
|||
}); |
|||
return Array.from(s).reduce(go, {}); |
|||
}; |
|||
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c |
|||
const compose = (...fs) => |
|||
// A function defined by the right-to-left |
|||
// composition of all the functions in fs. |
|||
fs.reduce( |
|||
(f, g) => x => f(g(x)), |
|||
x => x |
|||
); |
|||
// isAlpha :: Char -> Bool |
|||
const isAlpha = c => |
|||
(/[A-Za-z\u00C0-\u00FF]/u).test(c); |
|||
// isVowel :: Char -> Bool |
|||
const isVowel = c => |
|||
(/[AEIOUaeiou]/u).test(c); |
|||
// partition :: (a -> Bool) -> [a] -> ([a], [a]) |
|||
const partition = p => |
|||
// A tuple of two lists - those elements in |
|||
// xs which match p, and those which do not. |
|||
xs => xs.reduce( |
|||
(a, x) => p(x) ? ( |
|||
Tuple(a[0].concat(x))(a[1]) |
|||
) : Tuple(a[0])(a[1].concat(x)), |
|||
Tuple([])([]) |
|||
); |
|||
// sort :: Ord a => [a] -> [a] |
|||
const sort = xs => |
|||
// An A-Z sorted copy of xs. |
|||
xs.slice() |
|||
.sort((a, b) => a < b ? -1 : (a > b ? 1 : 0)); |
|||
// showTuple :: Tuple -> String |
|||
const showTuple = tpl => |
|||
`(${tpl[0]}, ${tpl[1]})`; |
|||
// MAIN --- |
|||
return main(); |
|||
})();</lang> |
|||
{{Out}} |
|||
<pre>Vowel counts: |
|||
(a, 4) |
|||
(e, 3) |
|||
(i, 1) |
|||
(o, 3) |
|||
(u, 1) |
|||
total: 12 |
|||
Consonant counts: |
|||
(F, 2) |
|||
(g, 4) |
|||
(l, 1) |
|||
(m, 2) |
|||
(n, 3) |
|||
(p, 1) |
|||
(r, 6) |
|||
(t, 1) |
|||
(v, 1) |
|||
total: 21</pre> |
|||
=={{header|jq}}== |
=={{header|jq}}== |
Revision as of 11:10, 12 September 2021
- Task
- Count how many vowels and consonants occur in a string
- Metrics
- Counting
- Word frequency
- Letter frequency
- Jewels and stones
- I before E except after C
- Bioinformatics/base count
- Count occurrences of a substring
- Count how many vowels and consonants occur in a string
- Remove/replace
- XXXX redacted
- Conjugate a Latin verb
- Remove vowels from a string
- String interpolation (included)
- Strip block comments
- Strip comments from a string
- Strip a set of characters from a string
- Strip whitespace from a string -- top and tail
- Strip control codes and extended characters from a string
- Anagrams/Derangements/shuffling
- Word wheel
- ABC problem
- Sattolo cycle
- Knuth shuffle
- Ordered words
- Superpermutation minimisation
- Textonyms (using a phone text pad)
- Anagrams
- Anagrams/Deranged anagrams
- Permutations/Derangements
- Find/Search/Determine
- ABC words
- Odd words
- Word ladder
- Semordnilap
- Word search
- Wordiff (game)
- String matching
- Tea cup rim text
- Alternade words
- Changeable words
- State name puzzle
- String comparison
- Unique characters
- Unique characters in each string
- Extract file extension
- Levenshtein distance
- Palindrome detection
- Common list elements
- Longest common suffix
- Longest common prefix
- Compare a list of strings
- Longest common substring
- Find common directory path
- Words from neighbour ones
- Change e letters to i in words
- Non-continuous subsequences
- Longest common subsequence
- Longest palindromic substrings
- Longest increasing subsequence
- Words containing "the" substring
- Sum of the digits of n is substring of n
- Determine if a string is numeric
- Determine if a string is collapsible
- Determine if a string is squeezable
- Determine if a string has all unique characters
- Determine if a string has all the same characters
- Longest substrings without repeating characters
- Find words which contains all the vowels
- Find words which contain the most consonants
- Find words which contains more than 3 vowels
- Find words whose first and last three letters are equal
- Find words with alternating vowels and consonants
- Formatting
- Substring
- Rep-string
- Word wrap
- String case
- Align columns
- Literals/String
- Repeat a string
- Brace expansion
- Brace expansion using ranges
- Reverse a string
- Phrase reversals
- Comma quibbling
- Special characters
- String concatenation
- Substring/Top and tail
- Commatizing numbers
- Reverse words in a string
- Suffixation of decimal numbers
- Long literals, with continuations
- Numerical and alphabetical suffixes
- Abbreviations, easy
- Abbreviations, simple
- Abbreviations, automatic
- Song lyrics/poems/Mad Libs/phrases
- Mad Libs
- Magic 8-ball
- 99 bottles of beer
- The Name Game (a song)
- The Old lady swallowed a fly
- The Twelve Days of Christmas
- Tokenize
- Text between
- Tokenize a string
- Word break problem
- Tokenize a string with escaping
- Split a character string based on change of character
- Sequences
Ada
This solution uses Ada 2012 aspect clauses to define discontinuous subtypes <lang Ada>-- -- count vowels and consonants in a string -- with Ada.Text_IO; use Ada.Text_IO;
procedure count_vowels_and_consonants is
subtype letter is Character with Static_Predicate => letter in 'A' .. 'Z' | 'a' .. 'z'; subtype Vowel is Character with Static_Predicate => Vowel in 'A' | 'E' | 'I' | 'O' | 'U' | 'a' | 'e' | 'i' | 'o' | 'u'; subtype consonant is Character with Dynamic_Predicate => consonant in letter and then consonant not in Vowel;
Input : String (1 .. 1_024); length : Natural; consonant_count : Natural := 0; vowel_count : Natural := 0;
begin
Put ("Enter a string: "); Get_Line (Item => Input, Last => length); -- count consonants for char of Input (1 .. length) loop if char in consonant then consonant_count := consonant_count + 1; elsif char in Vowel then vowel_count := vowel_count + 1; end if; end loop; Put_Line ('"' & Input (1 .. length) & '"'); Put_Line ("contains" & vowel_count'Image & " vowels and" & consonant_count'Image & " consonants.");
end count_vowels_and_consonants;</lang>
- Output:
Enter a string: If not now then when? If not us then who? "If not now then when? If not us then who?" contains 10 vowels and 20 consonants.
ALGOL 68
Showing total and distinct vowel/consonant counts, as in the Go, Wren etc. samples. <lang algol68>BEGIN # count the vowels and consonants in a string #
# returns the 0-based index of the upper case letter c in the alphabet # # or -1 if c is not a letter # OP L = ( CHAR c )INT: IF c >= "A" AND c <= "Z" THEN ABS c - ABS "A" ELIF c >= "a" AND c <= "z" THEN ABS c - ABS "a" ELSE -1 FI; # prints the counts of vowels and consonants in s # PROC print vc counts = ( STRING s )VOID: BEGIN [ 0 : 26 ]BOOL used; FOR i FROM LWB used TO UPB used DO used[ i ] := FALSE OD; [ 0 : 26 ]BOOL vowel; FOR i FROM LWB vowel TO UPB vowel DO vowel[ i ] := FALSE OD; vowel[ L "A" ] := vowel[ L "E" ] := vowel[ L "I" ] := vowel[ L "O" ] := vowel[ L "U" ] := TRUE; INT v total := 0, c total := 0, v count := 0, c count := 0; FOR i FROM LWB s TO UPB s DO IF INT c index = L s[ i ]; c index >= LWB used THEN IF vowel[ c index ] THEN v total ELSE c total FI +:= 1; IF NOT used[ c index ] THEN IF vowel[ c index ] THEN v count ELSE c count FI +:= 1; used[ c index ] := TRUE FI FI OD; print( ( """", s, """ contains", newline ) ); print( ( " ", whole( v count, 0 ), " vowels and ", whole( c count, 0 ), " consonants (distinct)", newline ) ); print( ( " ", whole( v total, 0 ), " vowels and ", whole( c total, 0 ), " consonants (total)", newline ) ) END; # print vc counts # # test cases # print vc counts( "Now is the time for all good men to come to the aid of their country" ); print vc counts( "Help avoid turns" )
END</lang>
- Output:
"Now is the time for all good men to come to the aid of their country" contains 5 vowels and 13 consonants (distinct) 22 vowels and 31 consonants (total) "Help avoid turns" contains 5 vowels and 9 consonants (distinct) 5 vowels and 9 consonants (total)
F#
<lang fsharp> // Count how many vowels and consonants occur in a string. Nigel Galloway: August 1th., 202 type cType = Vowel |Consonant |Other let fN g=match g with 'a'|'e'|'i'|'o'|'u'->Vowel |g when System.Char.IsLetter g->Consonant |_->Other let n="Now is the time for all good men to come to the aid of their country."|>Seq.countBy(System.Char.ToLower>>fN) printfn "%A" n </lang>
- Output:
seq [(Consonant, 31); (Vowel, 22); (Other, 16)]
Factor
<lang factor>USING: ascii combinators io kernel math.statistics prettyprint sequences ;
- letter-type ( char -- str )
{ { [ dup "aeiouAEIOU" member? ] [ drop "vowel" ] } { [ Letter? ] [ "consonant" ] } [ "other" ] } cond ;
"Forever Factor programming language" "Now is the time for all good men to come to the aid of their country." [ dup ... " -> " write [ letter-type ] histogram-by . nl ] bi@</lang>
- Output:
"Forever Factor programming language" -> H{ { "other" 3 } { "consonant" 20 } { "vowel" 12 } } "Now is the time for all good men to come to the aid of their country." -> H{ { "other" 16 } { "consonant" 31 } { "vowel" 22 } }
Go
Same approach as the Wren entry. <lang go>package main
import (
"fmt" "strings"
)
func main() {
const ( vowels = "aeiou" consonants = "bcdfghjklmnpqrstvwxyz" ) strs := []string{ "Forever Go programming language", "Now is the time for all good men to come to the aid of their country.", } for _, str := range strs { fmt.Println(str) str = strings.ToLower(str) vc, cc := 0, 0 vmap := make(map[rune]bool) cmap := make(map[rune]bool) for _, c := range str { if strings.ContainsRune(vowels, c) { vc++ vmap[c] = true } else if strings.ContainsRune(consonants, c) { cc++ cmap[c] = true } } fmt.Printf("contains (total) %d vowels and %d consonants.\n", vc, cc) fmt.Printf("contains (distinct %d vowels and %d consonants.\n\n", len(vmap), len(cmap)) }
}</lang>
- Output:
Forever Go programming language contains (total) 11 vowels and 17 consonants. contains (distinct 5 vowels and 8 consonants. Now is the time for all good men to come to the aid of their country. contains (total) 22 vowels and 31 consonants. contains (distinct 5 vowels and 13 consonants.
Haskell
The English of the task description is (perhaps unintentionally ?) ambiguous.
One of (at least) four possible meanings here:
<lang haskell>import Control.Monad (join) import Data.Bifunctor (bimap, first, second) import Data.Bool (bool) import Data.Char (toUpper) import qualified Data.Set as S
SETS OF UNIQUE VOWELS AND CONSONANTS IN A STRING ---
vowelsAndConsonantsUsed ::
String -> String -> String -> (S.Set Char, S.Set Char)
vowelsAndConsonantsUsed vowels alphabet =
foldr ( \c vc -> if_ (S.member c vs) (first (S.insert c)) (if_ (S.member c cs) (second (S.insert c)) id) vc ) (S.empty, S.empty) where vs = S.fromList $ vowels <> fmap toUpper vowels cs = S.fromList $ filter (`S.notMember` vs) (alphabet <> fmap toUpper alphabet)
TEST -------------------------
main :: IO () main = do
putStrLn "Unique vowels and consonants used, with counts:\n" mapM_ print $ [(,) . S.toList <*> S.size] <*> ( [fst, snd] <*> [ vowelsAndConsonantsUsed "aeiou" ['a' .. 'z'] "Forever Fortran 2018 programming language" ] )
GENERAL ------------------------
both :: (a -> b) -> (a, a) -> (b, b) both = join bimap
if_ :: Bool -> a -> a -> a if_ p t f =
if p then t else f</lang>
- Output:
Unique vowels and consonants used, with counts: ("aeiou",5) ("Fglmnprtv",9)
Another of (at least) four possible meanings:
<lang haskell>import Control.Monad (join) import Data.Bifunctor (bimap) import Data.Char (isAlpha) import Data.List (partition) import qualified Data.Map.Strict as M
COUNTS OF EACH VOWEL AND CONSONANT ----------
vowelAndConsonantCounts ::
String -> ([(Char, Int)], [(Char, Int)])
vowelAndConsonantCounts =
join bimap M.toList . M.partitionWithKey (const . isVowel) . fst . M.partitionWithKey (const . isAlpha) . charCounts
charCounts :: String -> M.Map Char Int charCounts =
foldr (flip (M.insertWith (+)) 1) M.empty
isVowel :: Char -> Bool isVowel c = c `elem` "aeiouAEIOU"
TEST -------------------------
main :: IO () main = do
let (v, c) = vowelAndConsonantCounts "Forever Fortran 2018 programming language" (vTotal, cTotal) = both (foldr ((+) . snd) 0) (v, c)
putStrLn $ unlines $ [ show (vTotal + cTotal) <> " 'vowels and consonants'\n" ] <> fmap ('\t' :) ( [ show vTotal <> " characters drawn from " <> show (length v) <> " vowels:" ] <> (('\t' :) . show <$> v) <> [ "", show cTotal <> " characters drawn from " <> show (length c) <> " consonants:" ] <> (('\t' :) . show <$> c) )
GENERIC ------------------------
both :: (a -> b) -> (a, a) -> (b, b) both = join bimap</lang>
- Output:
33 'vowels and consonants' 12 characters drawn from 5 vowels: ('a',4) ('e',3) ('i',1) ('o',3) ('u',1) 21 characters drawn from 9 consonants: ('F',2) ('g',4) ('l',1) ('m',2) ('n',3) ('p',1) ('r',6) ('t',1) ('v',1)
JavaScript
This is a new genre-of deliberately ambiguous task description, perhaps ?
I suppose it might be thought to offer scope for variety, but is it really achieving the Rosetta goal of comparability ?
(There seem to have been a surprising number of these recently, often associated with tasks of uncertain novelty ...)
Count of "Vowels and Consonants" ?
<lang javascript>(() => {
"use strict";
// -------- COUNT OF "VOWELS AND CONSONANTS" ---------
// countOfVowelsAndConsonants :: String -> Int const countOfVowelsAndConsonants = s => s.split("").filter(isAlpha).length;
// ---------------------- TEST ----------------------- const main = () => `${countOfVowelsAndConsonants( "Forever Fortran 2018 programming language" )} "vowels and consonants"`;
// --------------------- GENERIC ---------------------
// isAlpha :: Char -> Bool const isAlpha = c => (/[A-Za-z\u00C0-\u00FF]/u).test(c);
// MAIN --- return main();
})();</lang>
- Output:
33 "vowels and consonants"
Counts of distinct vowels and distinct consonants used ?
<lang javascript>(() => {
"use strict";
// COUNTS OF DISTINCT VOWELS, AND DISTINCT CONSONANTS
// distinctVowelsAndConsonants :: // String -> ([Char], [Char]) const distinctVowelsAndConsonants = s => both( cs => sort(Array.from(new Set(cs))) )( partition(isVowel)( Array.from(s).filter(isAlpha) ) );
// ---------------------- TEST ----------------------- // main :: IO () const main = () => { const vc = both( cs => `(${cs.join("")}, ${cs.length})` )( distinctVowelsAndConsonants( "Forever Fortran 2018 programming language" ) );
return [ `Distinct vowels: ${vc[0]}`, `Distict consonants: ${vc[1]}` ].join("\n\n"); };
// --------------------- GENERIC ---------------------
// Tuple (,) :: a -> b -> (a, b) const Tuple = a => b => ({ type: "Tuple", "0": a, "1": b, length: 2 });
// both :: (a -> b) -> (a, a) -> (b, b) const both = f => ab => Tuple( f(ab[0]) )( f(ab[1]) );
// isAlpha :: Char -> Bool const isAlpha = c => (/[A-Za-z\u00C0-\u00FF]/u).test(c);
// isVowel :: Char -> Bool const isVowel = c => (/[AEIOUaeiou]/u).test(c);
// partition :: (a -> Bool) -> [a] -> ([a], [a]) const partition = p => // A tuple of two lists - those elements in // xs which match p, and those which do not. xs => xs.reduce( (a, x) => p(x) ? ( Tuple(a[0].concat(x))(a[1]) ) : Tuple(a[0])(a[1].concat(x)), Tuple([])([]) );
// sort :: Ord a => [a] -> [a] const sort = xs => // An A-Z sorted copy of xs. xs.slice() .sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));
// MAIN --- return main();
})();</lang>
- Output:
Distinct vowels: (aeiou, 5) Distict consonants: (Fglmnprtv, 9)
Counts of vowel and consonant occurrences ?
<lang javascript>(() => {
"use strict";
// ---- COUNTS OF VOWEL AND CONSONANT OCCURRENCES ----
// vowelConsonantOccurrenceTotals :: String -> (Int, Int) const vowelConsonantOccurrenceTotals = s => Array.from(s).reduce( (ab, c) => ( isAlpha(c) ? ( isVowel(c) ? ( first(succ) ) : second(succ) ) : identity )(ab), Tuple(0)(0) );
// ---------------------- TEST ----------------------- const main = () => { const vc = vowelConsonantOccurrenceTotals( "Forever Fortran 2018 programming language" );
return [ `Vowel occurrences: ${vc[0]}`, `Consonent occurrences: ${vc[1]}` ].join("\n\n"); };
// --------------------- GENERIC ---------------------
// Tuple (,) :: a -> b -> (a, b) const Tuple = a => b => ({ type: "Tuple", "0": a, "1": b, length: 2 });
// first :: (a -> b) -> ((a, c) -> (b, c)) const first = f => // A simple function lifted to one which applies // to a tuple, transforming only its first item. xy => { const tpl = Tuple(f(xy[0]))(xy[1]);
return Array.isArray(xy) ? ( Array.from(tpl) ) : tpl; };
// identity :: a -> a const identity = x => // The identity function. x;
// isAlpha :: Char -> Bool const isAlpha = c => (/[A-Za-z\u00C0-\u00FF]/u).test(c);
// isVowel :: Char -> Bool const isVowel = c => (/[AEIOUaeiou]/u).test(c);
// second :: (a -> b) -> ((c, a) -> (c, b)) const second = f => // A function over a simple value lifted // to a function over a tuple. // f (a, b) -> (a, f(b)) xy => { const tpl = Tuple(xy[0])(f(xy[1]));
return Array.isArray(xy) ? ( Array.from(tpl) ) : tpl; };
// succ :: Int -> Int const succ = x => 1 + x;
return main();
})();</lang>
- Output:
Vowel occurrences: 12 Consonent occurrences: 21
Counts of occurrence for each vowel and consonant ?
<lang javascript>(() => {
"use strict";
// COUNTS OF OCCURRENCE FOR EACH VOWEL AND CONSONANT
// countsOfEachVowelAndConsonant :: // String -> ([(Char, Int)], [(Char, Int)]) const countsOfEachVowelAndConsonant = s => partition( cn => isVowel(cn[0]) )( sort( Object.entries( charCounts( Array.from(s).filter(isAlpha) ) ) ) .map(([c, n]) => Tuple(c)(n)) );
// ---------------------- TEST ----------------------- const main = () => { const report = label => cns => { const total = cns.reduce( (a, cn) => a + cn[1], 0 ), rows = cns.map( compose(s => `\t${s}`, showTuple) ).join("\n");
return [ `${label} counts:\n${rows}`, `\ttotal: ${total}` ].join("\n\n"); };
const counts = countsOfEachVowelAndConsonant( "Forever Fortran 2018 programming language" );
return Array.from( bimap( report("Vowel") )( report("Consonant") )( counts ) ).join("\n\n"); };
// --------------------- GENERIC ---------------------
// Tuple (,) :: a -> b -> (a, b) const Tuple = a => b => ({ type: "Tuple", "0": a, "1": b, length: 2 });
// bimap :: (a -> b) -> (c -> d) -> (a, c) -> (b, d) const bimap = f => // Tuple instance of bimap. // A tuple of the application of f and g to the // first and second values respectively. g => tpl => Tuple(f(tpl[0]))( g(tpl[1]) );
// charCounts :: String -> Dict const charCounts = s => { // A dictionary of characters seen, // with their frequencies. const go = (dct, c) => Object.assign(dct, { [c]: 1 + (dct[c] || 0) });
return Array.from(s).reduce(go, {}); };
// compose (<<<) :: (b -> c) -> (a -> b) -> a -> c const compose = (...fs) => // A function defined by the right-to-left // composition of all the functions in fs. fs.reduce( (f, g) => x => f(g(x)), x => x );
// isAlpha :: Char -> Bool const isAlpha = c => (/[A-Za-z\u00C0-\u00FF]/u).test(c);
// isVowel :: Char -> Bool const isVowel = c => (/[AEIOUaeiou]/u).test(c);
// partition :: (a -> Bool) -> [a] -> ([a], [a]) const partition = p => // A tuple of two lists - those elements in // xs which match p, and those which do not. xs => xs.reduce( (a, x) => p(x) ? ( Tuple(a[0].concat(x))(a[1]) ) : Tuple(a[0])(a[1].concat(x)), Tuple([])([]) );
// sort :: Ord a => [a] -> [a] const sort = xs => // An A-Z sorted copy of xs. xs.slice() .sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));
// showTuple :: Tuple -> String const showTuple = tpl => `(${tpl[0]}, ${tpl[1]})`;
// MAIN --- return main();
})();</lang>
- Output:
Vowel counts: (a, 4) (e, 3) (i, 1) (o, 3) (u, 1) total: 12 Consonant counts: (F, 2) (g, 4) (l, 1) (m, 2) (n, 3) (p, 1) (r, 6) (t, 1) (v, 1) total: 21
jq
Works with gojq, the Go implementation of jq
This entry focuses solely on the A-Z alphabet. <lang jq> def is_lowercase_vowel: IN("a","e","i","o","u"); def is_lowercase_letter: "a" <= . and . <= "z"; def is_lowercase_consonant: is_lowercase_letter and (is_lowercase_vowel|not);
def synopsis:
# Output: a stream of the constituent characters def characters: ascii_downcase | explode[] | [.] | implode; # For the sake of DRYness: def s(stream; $vowels; $consonants): reduce stream as $c ({($vowels): 0, ($consonants):0}; if $c|is_lowercase_vowel then .[$vowels] += 1 elif $c|is_lowercase_consonant then .[$consonants] += 1 else . end);
s( characters; "vowels"; "consonants" ) + s( [characters]|unique[]; "distinct_vowels"; "distinct_consonants" );
def task:
def pp: "Synopsis for:", ., synopsis;
"Forever HOPL", "Now is the time for all good men to come to the aid of their country." | pp, "";
task</lang>
- Output:
Synopsis for: Forever HOPL { "vowels": 4, "consonants": 7, "distinct_vowels": 2, "distinct_consonants": 6 } Synopsis for: Now is the time for all good men to come to the aid of their country. { "vowels": 22, "consonants": 31, "distinct_vowels": 5, "distinct_consonants": 13 }
Julia
<lang julia>isvowel(c) = c in ['a', 'e', 'i', 'o', 'u', 'A', 'E', "I", 'O', 'U'] isletter(c) = 'a' <= c <= 'z' || 'A' <= c <= 'Z' isconsonant(c) = !isvowel(c) && isletter(c)
function vccounts(s)
a = collect(lowercase(s)) au = unique(a) count(isvowel, a), count(isconsonant, a), count(isvowel, au), count(isconsonant, au)
end
function testvccount()
teststrings = [ "Forever Julia programming language", "Now is the time for all good men to come to the aid of their country."] for s in teststrings vcnt, ccnt, vu, cu = vccounts(s) println("String: $s\n Vowels: $vcnt (distinct $vu)\n Consonants: $ccnt (distinct $cu)\n") end
end
testvccount()
</lang>
- Output:
String: Forever Julia programming language Vowels: 13 (distinct 5) Consonants: 18 (distinct 9) String: Now is the time for all good men to come to the aid of their country. Vowels: 22 (distinct 5) Consonants: 31 (distinct 13)
Nim
<lang Nim>import strutils
const
Vowels = {'a', 'e', 'i', 'o', 'u'} Consonants = {'a'..'z'} - Vowels
func value(val: int; unit: string): string =
$val & ' ' & unit & (if val > 1: "s" else: "")
proc vcCount(text: string) =
var vowels, consonants: set[char] var vowelCount, consonantCount = 0 for c in text.toLowerAscii: if c in Consonants: consonants.incl c inc consonantCount elif c in Vowels: vowels.incl c inc vowelCount echo "“$#” contains" % text echo " $1 and $2 (distinct)".format(value(vowels.card, "vowel"), value(consonants.card, "consonant")) echo " $1 and $2 (total)".format(value(vowelCount, "vowel"), value(consonantCount, "consonant"))
vcCount("Now is the time for all good men to come to the aid of their country.")</lang>
- Output:
“Now is the time for all good men to come to the aid of their country.” contains 5 vowels and 13 consonants (distinct) 22 vowels and 31 consonants (total)
Perl
<lang perl>#!/usr/bin/perl
use strict; # https://rosettacode.org/wiki/Count_how_many_vowels_and_consonants_occur_in_a_string use warnings;
while( )
{ print "@{[ $- = tr/aeiouAEIOU// ]} vowels @{[ tr/a-zA-Z// - $- ]} consonants in: $_\n" }
__DATA__ test one TEST ONE Now is the time for all good men to come to the aid of their country. Forever Perl Programming Language</lang>
- Output:
3 vowels 4 consonants in: test one 3 vowels 4 consonants in: TEST ONE 22 vowels 31 consonants in: Now is the time for all good men to come to the aid of their country. 11 vowels 19 consonants in: Forever Perl Programming Language
Phix
with javascript_semantics procedure count_vowels_and_consonants(string s) constant vco = {"vowels","consonants","other"}, fvco = {"%d %s (%d distinct)"} sequence r = sort(filter(apply(true,find,{lower(s),{"aeioubcdfghjklmnpqrstvwxyz"}}),"!=",0)) integer v = abs(binary_search(6,r))-1, uv = length(unique(r[1..v])), c = length(r)-v, uc = length(unique(r[v+1..$])), o = length(s)-length(r), uo = length(unique(lower(s)))-(uv+uc) string {sv,sc,so} = apply(true,sprintf,{fvco,columnize({{v,c,o},vco,{uv,uc,uo}})}) printf(1,"The string \"%s\"\n contains %s, %s, and %s.\n",{s,sv,sc,so}) end procedure count_vowels_and_consonants("Now is the time for all good men to come to the aid of their country.")
- Output:
The string "Now is the time for all good men to come to the aid of their country." contains 22 vowels (5 distinct), 31 consonants (13 distinct), and 16 other (2 distinct).
Python
<lang python>def isvowel(c):
""" true if c is an English vowel (ignore y) """ return c in ['a', 'e', 'i', 'o', 'u', 'A', 'E', "I", 'O', 'U']
def isletter(c):
""" true if in English standard alphabet """ return 'a' <= c <= 'z' or 'A' <= c <= 'Z'
def isconsonant(c):
""" true if an English consonant """ return not isvowel(c) and isletter(c)
def vccounts(s):
""" case insensitive vowel counts, total and unique """ a = list(s.lower()) au = set(a) return sum([isvowel(c) for c in a]), sum([isconsonant(c) for c in a]), \ sum([isvowel(c) for c in au]), sum([isconsonant(c) for c in au])
def testvccount():
teststrings = [ "Forever Python programming language", "Now is the time for all good men to come to the aid of their country."] for s in teststrings: vcnt, ccnt, vu, cu = vccounts(s) print(f"String: {s}\n Vowels: {vcnt} (distinct {vu})\n Consonants: {ccnt} (distinct {cu})\n")
testvccount()
</lang>
- Output:
String: Forever Python programming language
Vowels: 11 (distinct 5) Consonants: 21 (distinct 11)String: Now is the time for all good men to come to the aid of their country.
Vowels: 22 (distinct 5) Consonants: 31 (distinct 13)
Or, selecting another of the various possible meanings of an ambiguous task description:
<lang python>Total and individual counts of vowel and consonant instances
from functools import reduce
- vowelAndConsonantCounts :: String ->
- ([(Char, Int)], [(Char, Int)])
def vowelAndConsonantCounts(s):
The sorted character counts for each vowel seen in the string, tupled with the sorted character counts for each consonant seen. return both(sorted)( partition(lambda kv: isVowel(kv[0]))([ (k, v) for (k, v) in list(charCounts(s).items()) if k.isalpha() ]) )
- ------------------------- TEST -------------------------
- main :: IO ()
def main():
Total and individual counts for a given string
vs, cs = vowelAndConsonantCounts( "Forever Fortran 2018 programming language" ) nv, nc = valueSum(vs), valueSum(cs) print(f'{nv + nc} "vowels and consonants"\n')
print(f'\t{nv} characters drawn from {len(vs)} vowels:') print(showCharCounts(vs)) print(f'\n\t{nc} characters drawn from {len(cs)} consonants:') print(showCharCounts(cs))
- ----------------------- DISPLAY ------------------------
- showCharCounts :: [(Char, Int)] -> String
def showCharCounts(kvs):
Indented listing of character frequencies. return '\n'.join(['\t\t' + repr(kv) for kv in kvs])
- ----------------------- GENERIC ------------------------
- both :: (a -> b) -> (a, a) -> (b, b)
def both(f):
The same function applied to both values of a tuple. def go(ab): return f(ab[0]), f(ab[1]) return go
- charCount :: String -> Dict
def charCounts(s):
A dictionary of characters seen, with their frequencies. def go(dct, c): dct.update({c: 1 + dct.get(c, 0)}) return dct
return reduce(go, list(s), dict())
- isVowel :: Char -> Bool
def isVowel(c):
True if the character is an Anglo-Saxon vowel return c in "aeiouAEIOU"
- partition :: (a -> Bool) -> [a] -> ([a], [a])
def partition(p):
The pair of lists of those elements in xs which respectively do, and don't satisfy the predicate p. def go(a, x): ts, fs = a return (ts + [x], fs) if p(x) else (ts, fs + [x]) return lambda xs: reduce(go, xs, ([], []))
- valueSum :: [(String, Int)] -> Int
def valueSum(kvs):
The sum of values in a [(key, value)] list return sum(kv[1] for kv in kvs)
- MAIN ---
if __name__ == '__main__':
main()</lang>
- Output:
33 "vowels and consonants" 12 characters drawn from 5 vowels: ('a', 4) ('e', 3) ('i', 1) ('o', 3) ('u', 1) 21 characters drawn from 9 consonants: ('F', 2) ('g', 4) ('l', 1) ('m', 2) ('n', 3) ('p', 1) ('r', 6) ('t', 1) ('v', 1)
Raku
Note that the task does not ask for the total count of vowels and consonants, but for how many occur.
<lang perl6>my @vowels = <a e i o u>; my @consonants = ;
sub letter-check ($string) {
my $letters = $string.lc.comb.Set; "{sum $letters{@vowels}} vowels and {sum $letters{@consonants}} consonants occur in the string \"$string\"";
}
say letter-check "Forever Ring Programming Language";</lang>
- Output:
5 vowels and 8 consonants occur in the string "Forever Ring Programming Language"
REXX
version 1
<lang rexx>/* REXX */ Parse Arg s If s= Then
s='Forever Wren programming language'
con='BCDFGHJKLMNPQRSTVWXYZ' vow='AEIOU' su=translate(s) /* translate to uppercase */ suc=su sx= /* eliminate duplicate characters */ Do While suc<>
Parse Var suc c +1 suc If pos(c,sx)=0 Then sx=sx||c End
Say s /* show input string */ Call count su /* count all consonants and vowels */ Call count sx,'distinct' /* count unique consonants and vowels */ Exit count: Parse Arg s,tag sc=translate(s,copies('+',length(con))copies(' ',256),con||xrange('00'x,'ff'x)) sv=translate(s,copies('+',length(vow))copies(' ',256),vow||xrange('00'x,'ff'x)) Say length(space(sc,0)) tag 'consonants,' length(space(sv,0)) tag 'vowels' Return</lang>
- Output:
Forever Wren programming language 19 consonants, 11 vowels 9 distinct consonants, 5 distinct vowels
version 2
<lang rexx>/*REXX program counts the vowels and consonants (unique and total) in a given string. */ parse arg $ /*obtain optional argument from the CL.*/ if $= then $= 'Now is the time for all good men to come to the aid of their country.' say 'input: ' $ /*display the original string ──► term.*/ call init /*initialize some constants and input. */
- .= 0; call cnt 1; call cnt 2 /*count unique vowels and consonants.*/
say 'There are ' #.1 " unique vowels, there are " #.2 ' unique consonants.' say 'There are ' L - length( space( translate($, , @.1), 0)) " vowels total, " ,
'there are ' L - length( space( translate($, , @.2), 0)) " consonants total."
exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ cnt: arg k; do j=1 to length(@.k); if pos(substr(@.k,j,1),$)>0 then #.k=#.k+1; end; return init: @.1='AEIOU'; @.2="BCDFGHJKLMNPQRSTVWXYZ"; upper $; $=space($,0); L=length($); return</lang>
- output when using the default input:
input: Now is the time for all good men to come to the aid of their country. There are 5 unique vowels, there are 13 unique consonants. There are 22 vowels total, there are 31 consonants total.
Ring
<lang ring> load "stdlib.ring" see "working..." + nl str = '"' + "Forever Ring Programming Language" + '"' vowel = 0 cons =0
for n = 1 to len(str)
strc = str[n] if isvowel(str[n]) = 1 vowel += 1 ok if isconsonant(strc) cons += 1 ok
next
see "Input string = " + str + nl see "In string occur " + vowel + " vowels" + nl see "In string occur " + cons + " consonants" + nl see "done..." + nl
func isconsonant(c)
bool1 = not isvowel(c) bool2 = (ascii(c) > 64 and ascii(c) < 91) bool3 = (ascii(c) > 96 and ascii(c) < 123) if bool1 and (bool2 or bool3) return 1 else return 0 ok
</lang>
- Output:
working... Input string = "Forever Ring Programming Language" In string occur 11 vowels In string occur 19 consonants done...
Ruby
<lang ruby>RE_V = /[aeiou]/ RE_C = /[bcdfghjklmnpqrstvwxyz]/ str = "Now is the time for all good men to come to the aid of their country."
grouped = str.downcase.chars.group_by do |c|
case c when RE_V then :Vowels when RE_C then :Consonants else :Other end
end
grouped.each{|k,v| puts "#{k}: #{v.size}, #{v.uniq.size} unique."} </lang>
- Output:
Consonants: 31, 13 unique. Vowels: 22, 5 unique. Other: 16, 2 unique.
Wren
In the absence of any indications to the contrary, we take a simplistic view of only considering English ASCII vowels (not 'y') and consonants. <lang ecmascript>import "/str" for Str
var vowels = "aeiou" var consonants = "bcdfghjklmnpqrstvwxyz"
var strs = [
"Forever Wren programming language", "Now is the time for all good men to come to the aid of their country."
]
for (str in strs) {
System.print(str) str = Str.lower(str) var vc = 0 var cc = 0 var vmap = {} var cmap = {} for (c in str) { if (vowels.contains(c)) { vc = vc + 1 vmap[c] = true } else if (consonants.contains(c)) { cc = cc + 1 cmap[c] = true } } System.print("contains (total) %(vc) vowels and %(cc) consonants.") System.print("contains (distinct) %(vmap.count) vowels and %(cmap.count) consonants.\n")
}</lang>
- Output:
Forever Wren programming language contains (total) 11 vowels and 19 consonants. contains (distinct) 5 vowels and 9 consonants. Now is the time for all good men to come to the aid of their country. contains (total) 22 vowels and 31 consonants. contains (distinct) 5 vowels and 13 consonants.
X86 Assembly
Translation of XPL0. Assemble with tasm, tlink /t <lang asm> .model tiny
.code .486 org 100h
- Register assignments
- al = Char
- ebx = CSet
- cl = CTC
- ch = VTC
- dl = CDC
- dh = VDC
- si = Str
- edi = VSet
- ebp = Item
start: mov si, offset str1 ;Text(Str1)
call vowcon mov si, offset str2 ;Text(Str2)
- Display numbers of vowels and consonants in string at si
vowcon: push si
xor cx, cx ;CTC:= 0; VTC:= 0 xor dx, dx xor ebx, ebx xor edi, edi
- while Str(I) # 0 do
- Ch
- = Str(I); I++
cv10: lodsb ;al:= ds:[si++]
cmp al, 0 je cv90 ; if Ch>=^A & Ch<=^Z then cmp al, 'A' jb cv20 cmp al, 'Z' ja cv20 or al, 20h ; Ch:= Ch ! $20
cv20:
cmp al, 'a' ; if Ch>=^a & Ch<=^z then jb cv50 cmp al, 'z' ja cv50
push cx ; Item:= 1 << (Ch-^a) mov cl, al sub cl, 'a' xor ebp, ebp ; mov ebp, 1 inc bp shl ebp, cl pop cx
cmp al, 'a' ; case Ch of a e i o u vowels je cv22 cmp al, 'e' je cv22 cmp al, 'i' je cv22 cmp al, 'o' je cv22 cmp al, 'u' jne cv30
cv22: inc ch ; VTC++
test edi, ebp ; if (VSet&Item) = 0 then jne cv25 inc dh ; VDC++ or edi, ebp ; VSet:= VSet ! Item
cv25: jmp cv50 cv30: ; other: consonants
inc cl ; CTC++ test ebx, ebp ; if (CSet&Item) = 0 then jne cv50 inc dl ; CDC++ or ebx, ebp ; CSet:= CSet ! Item
cv50: jmp cv10 cv90:
pop si call strout mov si, offset crlf ;CrLf call strout mov di, offset msg2 ;Text(" total") call common
mov cx, dx ;get distinct counts mov di, offset msg2a;Text(" distinct") call common mov si, offset crlf jmp strout
- Common display code
common: mov si, offset msg1 ;Text("Contains ")
call strout mov al, ch ;numout(VTC/VDC) call numout mov si, di ;Text(" total/distinct") call strout mov si, offset msg3 ;Text(" vowels and ") call strout mov al, cl ;numout(CTC/CDC) call numout mov si, offset msg4 ;Text(" consonants.^M^J") jmp strout
- Display string pointed to by si
so10: int 29h strout: lodsb ;al:= ds:[si++]
cmp al, 0 jne so10 ret
- Display positive number in al (less than 100)
numout: aam 10 ;ah:= al/10; al:= rem
push ax test ah, ah je no10 mov al, ah call numout
no10: pop ax
add al, '0' int 29h ret
str1 db "X86 Assembly Language!", 0 str2 db "Now is the time for all good men to come to the aid of their country.", 0 msg1 db "Contains ", 0 msg2 db " total", 0 msg2a db " distinct", 0 msg3 db " vowels and ", 0 msg4 db " consonants." crlf db 0Dh, 0Ah, 0
end start</lang>
- Output:
X86 Assembly Language! Contains 6 total vowels and 11 consonants. Contains 3 distinct vowels and 8 consonants. Now is the time for all good men to come to the aid of their country. Contains 22 total vowels and 31 consonants. Contains 5 distinct vowels and 13 consonants.
XPL0
<lang XPL0>string 0; \use zero-terminated strings int VTC, VDC, \vowel total count, vowel distinct count
CTC, CDC, \consonant total count, consonant distinct count VSet, CSet, \vowel and consonant bit arrays Char, Item, I, J;
char Str; [Str:= ["Forever XPL0 programming language.",
"Now is the time for all good men to come to the aid of their country."];
for J:= 0 to 1 do
[I:= 0; VTC:= 0; VDC:= 0; CTC:= 0; CDC:= 0; VSet:= 0; CSet:= 0; while Str(J,I) do [Char:= Str(J,I); I:= I+1; if Char>=^A & Char<=^Z then Char:= Char - ^A + ^a; \to lower case if Char>=^a & Char<=^z then [Item:= 1 << (Char-^a); \item in character set [a..z] case Char of ^a, ^e, ^i, ^o, ^u: [VTC:= VTC+1; \vowel if (Item & VSet) = 0 then VDC:= VDC+1; VSet:= VSet ! Item; ] other [CTC:= CTC+1; \consonant if (Item & CSet) = 0 then CDC:= CDC+1; CSet:= CSet ! Item; ]; ]; ]; Text(0, @Str(J,0)); CrLf(0); Text(0, "Contains "); IntOut(0, VTC); Text(0, " total vowels and "); IntOut(0, CTC); Text(0, " consonants.^M^J"); Text(0, "Contains "); IntOut(0, VDC); Text(0, " distinct vowels and "); IntOut(0, CDC); Text(0, " consonants.^M^J"); CrLf(0); ];
]</lang>
- Output:
Forever XPL0 programming language. Contains 10 total vowels and 19 consonants. Contains 5 distinct vowels and 9 consonants. Now is the time for all good men to come to the aid of their country. Contains 22 total vowels and 31 consonants. Contains 5 distinct vowels and 13 consonants.