Last active
April 10, 2018 16:51
-
-
Save Beraliv/cdbc524b9d0dd3c1a3a3c97dc58a59ee to your computer and use it in GitHub Desktop.
Task 84. UniLecs. Find the number of anagrams.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// it can be optimised via lazy evaluation or cached values | |
function factorial(n) { | |
if (n < 0) { | |
throw new TypeError('n should be non-negative') | |
} | |
if (n < 2) { | |
return 1 | |
} | |
return n * factorial(n - 1) | |
} | |
// can be optimised as well | |
// k-permutations of n, link: https://en.wikipedia.org/wiki/Permutation | |
function permutations(n, k) { | |
return factorial(n) / (factorial(n - k) * factorial(k)) | |
} | |
// count the quantity of each letter in a word | |
function lettersIn(word) { | |
const hash = {} | |
for (let ch of word) { | |
hash[ch] = (hash[ch] || 0) + 1 | |
} | |
return Object.values(hash) | |
} | |
function anagramNumber(word) { | |
const ks = lettersIn(word) | |
const [_, quantity] = ks.reduce( | |
// n is a number of free elements where we can place k-letters (initial value is word.length) | |
// k is a number of letters which need to be placed (initial value is 1) | |
// q is a quantity of pre-calculated placements which we already calculated | |
([n, q], k) => [n - k, q * permutations(n, k)], | |
[word.length, 1] | |
) | |
return quantity | |
} | |
console.log(anagramNumber('линия')) // 60 | |
console.log(anagramNumber('вектор')) // 720 | |
console.log(anagramNumber('парабола')) // 6720 | |
console.log(anagramNumber('математика')) // 151200 | |
console.log(anagramNumber('биссектриса')) // 3326400 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment