Count how many vowels and consonants occur in a string: Difference between revisions

Content added Content deleted
(→‎{{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}}==